pantheon-opencode 1.0.0 → 1.0.6
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/README.md +61 -109
- package/bin/pantheon-init.mjs +57 -136
- package/commands/pantheon-audit.md +1 -1
- package/commands/pantheon-deepwork.md +32 -81
- package/commands/pantheon-reflect.md +16 -0
- package/commands/pantheon-status.md +1 -1
- package/commands/pantheon-verify.md +17 -0
- package/opencode.json +25 -0
- package/package.json +24 -13
- package/scripts/ci-validate-yaml.py +19 -0
- package/scripts/doctor.mjs +10 -65
- package/scripts/install/opencode.mjs +69 -6
- package/scripts/install/shared.mjs +39 -13
- package/scripts/manifest.mjs +5 -30
- package/scripts/postinstall.mjs +47 -0
- package/scripts/release-bundle.mjs +2 -2
- package/scripts/uninstall.mjs +5 -5
- package/scripts/validate-routing.mjs +19 -16
- package/scripts/versioning.mjs +12 -1
- package/skills-lock.json +9 -2
- package/src/agents/aphrodite.md +15 -57
- package/src/agents/apollo.md +9 -48
- package/src/agents/athena.md +17 -54
- package/src/agents/demeter.md +10 -47
- package/src/agents/gaia.md +7 -40
- package/src/agents/hephaestus.md +9 -52
- package/src/agents/hermes.md +17 -52
- package/src/agents/iris.md +8 -45
- package/src/agents/mnemosyne.md +12 -47
- package/src/agents/nyx.md +8 -45
- package/src/agents/prometheus.md +11 -49
- package/src/agents/talos.md +6 -45
- package/src/agents/themis.md +10 -35
- package/src/agents/zeus.md +5 -7
- package/src/mcp/mcp_resources_server.py +2 -0
- package/src/plugins/tui/dist/tui.tsx +203 -93
- package/src/plugins/tui/src/index.tsx +203 -93
- package/src/routing.yml +33 -93
- package/src/skills/clonedeps/SKILL.md +45 -0
- package/src/skills/codemap/SKILL.md +47 -0
- package/src/skills/loop-engineering/SKILL.md +51 -0
- package/src/skills/reflect/SKILL.md +49 -0
- package/src/skills/simplify/SKILL.md +39 -0
- package/src/skills/verification-planning/SKILL.md +52 -0
- package/src/skills/worktrees/SKILL.md +43 -0
- package/commands/pantheon-bg.md +0 -10
- package/commands/pantheon-consolidate.md +0 -11
- package/commands/pantheon-doc.md +0 -10
- package/commands/pantheon-hash.md +0 -11
- package/commands/pantheon-todo.md +0 -11
- package/docs/AGENT-MCP.md +0 -194
- package/docs/ARCHITECTURE.md +0 -384
- package/docs/BRANCH-PROTECTION.md +0 -142
- package/docs/INDEX.md +0 -81
- package/docs/INSTALLATION.md +0 -217
- package/docs/MCP.md +0 -238
- package/docs/MEMORY.md +0 -471
- package/docs/MIGRATION-MEMORY-BANK.md +0 -139
- package/docs/PLATFORMS.md +0 -5
- package/docs/QUICKSTART.md +0 -49
- package/docs/README.md +0 -18
- package/docs/RELEASING.md +0 -256
- package/docs/SETUP.md +0 -5
- package/docs/UPGRADING.md +0 -41
- package/docs/mcp-recommendations.md +0 -439
- package/docs/mcp-tools.md +0 -156
- package/docs/mcp-user-guide.md +0 -204
- package/docs/persistence-mcp.md +0 -111
- package/scripts/init-pantheon-mcp.sh +0 -118
- package/scripts/install.mjs +0 -26
- package/src/instructions/documentation-standards.instructions.md +0 -53
- package/src/mcp/init-pantheon-mcp.sh +0 -118
package/src/agents/talos.md
CHANGED
|
@@ -1,49 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: talos
|
|
3
|
-
description: Hotfix express lane — direct fixes for small bugs, CSS, typos, minor
|
|
4
|
-
logic. No TDD ceremony, no orchestration overhead. Standalone, no subagents. Escalates
|
|
5
|
-
complex issues to zeus.
|
|
3
|
+
description: "Hotfix express lane — direct fixes for small bugs, CSS, typos, minor logic. No TDD ceremony, no orchestration overhead. Standalone, no subagents. Escalates complex issues to zeus."
|
|
6
4
|
mode: subagent
|
|
7
5
|
reasoning_effort: low
|
|
8
6
|
permission:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"git diff *": allow
|
|
13
|
-
"git log *": allow
|
|
14
|
-
"git status": allow
|
|
15
|
-
"git stash *": allow
|
|
16
|
-
"git checkout *": allow
|
|
17
|
-
"git commit *": allow
|
|
18
|
-
"git branch *": allow
|
|
19
|
-
"pantheon-resources_*": allow
|
|
20
|
-
"pantheon-memory_*": allow
|
|
21
|
-
|
|
22
|
-
tools:
|
|
23
|
-
agent: true
|
|
24
|
-
read/readFile: true
|
|
25
|
-
edit/editFiles: true
|
|
7
|
+
read: allow
|
|
8
|
+
edit: allow
|
|
9
|
+
bash: allow
|
|
26
10
|
temperature: 0.3
|
|
27
|
-
steps:
|
|
11
|
+
steps: 35
|
|
28
12
|
skills:
|
|
29
|
-
-
|
|
13
|
+
- incremental-implementation
|
|
30
14
|
mcp_tools:
|
|
31
15
|
pantheon-resources: all
|
|
32
16
|
pantheon-memory: [memory_recall]
|
|
33
17
|
pantheon-code-mode: [execute_code_script]
|
|
34
18
|
---
|
|
35
19
|
|
|
36
|
-
## Memory Protocol
|
|
37
|
-
|
|
38
|
-
See `instructions/memory-protocol.instructions.md` for universal rules.
|
|
39
|
-
|
|
40
|
-
### Override
|
|
41
|
-
- `memory_recall("hotfix", top_k=3)` before fix — read-only, no store
|
|
42
|
-
|
|
43
|
-
# Talos - Hotfix Express Lane
|
|
44
|
-
|
|
45
|
-
You are the **HOTFIX SPECIALIST** (Talos) for rapid, lightweight fixes. You handle small bugs, CSS tweaks, typos, and minor logic corrections with no orchestration overhead.
|
|
46
|
-
|
|
47
20
|
## Core Capabilities
|
|
48
21
|
|
|
49
22
|
### 1. Rapid Repairs
|
|
@@ -77,17 +50,5 @@ Escalate to @zeus if:
|
|
|
77
50
|
- If fix breaks existing tests, stop immediately and escalate
|
|
78
51
|
- No partial results — either fix is applied or escalate
|
|
79
52
|
|
|
80
|
-
## MCP Capabilities
|
|
81
|
-
|
|
82
|
-
Pantheon provides 3 native MCP servers. See [`docs/mcp-tools.md`](../docs/mcp-tools.md) for the full tool registry.
|
|
83
|
-
|
|
84
|
-
| Server | Tools | When to use |
|
|
85
|
-
|--------|-------|-------------|
|
|
86
|
-
| **pantheon-resources** | Read `pantheon://agents`, `pantheon://routing`, `pantheon://skills`, `pantheon://deepwork/{slug}` | Discover agents, routing rules, and skills at session start |
|
|
87
|
-
| **pantheon-memory** | `memory_recall(context, n_results?)` | Recall past hotfix patterns before making quick changes |
|
|
88
|
-
| **pantheon-code-mode** | `execute_code_script(script_name, args?)` | Run hotfix automation scripts |
|
|
89
|
-
|
|
90
|
-
Before a hotfix, `memory_recall()` for past quick-fix patterns. After fix, esculate to Zeus if persistence is needed. You are read-only for memory — Mnemosyne stores decisions.
|
|
91
|
-
|
|
92
53
|
## Skills
|
|
93
54
|
`code-review-checklist`, `git-workflow-and-versioning`
|
package/src/agents/themis.md
CHANGED
|
@@ -1,45 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: themis
|
|
3
|
-
description: Quality & security gate —
|
|
4
|
-
|
|
5
|
-
slop detection, hash-anchored edits, OWASP Top 10, coverage >80%. Called by implementers;
|
|
6
|
-
escalates blockers to zeus.
|
|
7
|
-
mode: primary
|
|
3
|
+
description: "Quality & security gate — Ruff/Biome linting, dead/legacy code detection, OWASP Top 10, coverage >80%, correctness, deprecation audit. Called by implementers; escalates blockers to zeus."
|
|
4
|
+
mode: subagent
|
|
8
5
|
reasoning_effort: high
|
|
9
6
|
permission:
|
|
7
|
+
read: allow
|
|
8
|
+
grep: allow
|
|
9
|
+
bash: allow
|
|
10
10
|
edit: ask
|
|
11
|
-
bash:
|
|
12
|
-
pytest *: allow
|
|
13
|
-
ruff *: allow
|
|
14
|
-
grep *: allow
|
|
15
|
-
npx vitest *: allow
|
|
16
|
-
pip-audit *: allow
|
|
17
|
-
dep-audit *: allow
|
|
18
|
-
"pantheon-resources_*": allow
|
|
19
|
-
"pantheon-memory_*": allow
|
|
20
|
-
"pantheon-persistence_*": allow
|
|
21
|
-
|
|
22
|
-
tools:
|
|
23
|
-
agent: true
|
|
24
|
-
vscode/askQuestions: true
|
|
25
|
-
search/codebase: true
|
|
26
|
-
search/usages: true
|
|
27
|
-
read/readFile: true
|
|
28
|
-
read/problems: true
|
|
29
|
-
execute/runInTerminal: true
|
|
30
|
-
execute/testFailure: true
|
|
31
|
-
edit/editFiles: true
|
|
32
|
-
browser/openBrowserPage: true
|
|
33
|
-
browser/navigatePage: true
|
|
34
|
-
browser/readPage: true
|
|
35
|
-
browser/clickElement: true
|
|
36
|
-
browser/screenshotPage: true
|
|
37
11
|
temperature: 0.1
|
|
38
|
-
steps:
|
|
12
|
+
steps: 30
|
|
39
13
|
skills:
|
|
40
|
-
- code-review-checklist
|
|
41
|
-
- security-hardening
|
|
42
|
-
- tdd-with-agents
|
|
14
|
+
- code-review-checklist
|
|
15
|
+
- security-hardening
|
|
16
|
+
- tdd-with-agents
|
|
17
|
+
- context-compression
|
|
43
18
|
mcp_tools:
|
|
44
19
|
pantheon-resources: all
|
|
45
20
|
pantheon-memory: [memory_search]
|
package/src/agents/zeus.md
CHANGED
|
@@ -7,12 +7,9 @@ permission:
|
|
|
7
7
|
bash: allow
|
|
8
8
|
task:
|
|
9
9
|
"*": allow
|
|
10
|
-
pantheon-resources_*: allow
|
|
11
|
-
pantheon-memory_*: allow
|
|
12
10
|
pantheon-code-mode_*: ask
|
|
13
|
-
pantheon-persistence_*: allow
|
|
14
11
|
temperature: 0.2
|
|
15
|
-
steps:
|
|
12
|
+
steps: 45
|
|
16
13
|
mcp_tools:
|
|
17
14
|
pantheon-resources: all
|
|
18
15
|
pantheon-memory:
|
|
@@ -27,12 +24,13 @@ mcp_tools:
|
|
|
27
24
|
- kv_search
|
|
28
25
|
skills:
|
|
29
26
|
- agent-coordination
|
|
27
|
+
- session-goal
|
|
30
28
|
- artifact-management
|
|
31
|
-
- auto-continue
|
|
32
29
|
- context-compression
|
|
33
|
-
-
|
|
30
|
+
- auto-continue
|
|
34
31
|
- orchestration-workflow
|
|
35
|
-
-
|
|
32
|
+
- incremental-implementation
|
|
33
|
+
|
|
36
34
|
---
|
|
37
35
|
|
|
38
36
|
## Memory Protocol
|
|
@@ -111,6 +111,8 @@ async def list_skills() -> str:
|
|
|
111
111
|
async def get_routing() -> str:
|
|
112
112
|
"""Return the full content of routing.yml."""
|
|
113
113
|
routing_file = _PANTHEON_HOME / "routing.yml"
|
|
114
|
+
if not routing_file.exists() and _PANTHEON_PROJECT:
|
|
115
|
+
routing_file = _PANTHEON_PROJECT / "src" / "routing.yml"
|
|
114
116
|
if not routing_file.exists():
|
|
115
117
|
return "routing.yml not found."
|
|
116
118
|
return routing_file.read_text(encoding="utf-8")
|
|
@@ -1,144 +1,254 @@
|
|
|
1
|
+
// biome-ignore-all lint/suspicious/noExplicitAny: necessary for TuiPluginApi dynamic state access
|
|
2
|
+
// biome-ignore-all lint/a11y/noStaticElementInteractions: TUI elements, not DOM
|
|
1
3
|
/** @jsxImportSource @opentui/solid */
|
|
2
|
-
import type { TuiPlugin, TuiPluginApi, TuiPluginModule, TuiSlotContext, TuiSlotPlugin } from '@opencode-ai/plugin/tui'
|
|
3
|
-
import type { JSX } from '@opentui/solid'
|
|
4
|
-
import { createMemo, createSignal, Show, For } from 'solid-js'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from '@opencode-ai/plugin/tui'
|
|
6
|
+
import { createMemo, createSignal, createResource, For, Show } from 'solid-js'
|
|
7
|
+
|
|
8
|
+
async function readPantheonVersion(api: TuiPluginApi): Promise<string> {
|
|
9
|
+
try {
|
|
10
|
+
const worktree = ((api.state as any).path?.worktree ?? '') as string
|
|
11
|
+
const filePath = worktree ? `${worktree}/package.json` : 'package.json'
|
|
12
|
+
const result = await api.client.file.read({ query: { path: filePath } })
|
|
13
|
+
const content = typeof result.content === 'string' ? result.content : String(result.content ?? '')
|
|
14
|
+
const match = content.match(/"version":\s*"([^"]+)"/)
|
|
15
|
+
if (match?.[1]) return match[1]
|
|
16
|
+
} catch { /* fall through */ }
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const proc = (api as any).client?.process
|
|
20
|
+
if (typeof proc?.exec === 'function') {
|
|
21
|
+
const result = await proc.exec({ command: 'git', args: ['describe', '--tags', '--always'] })
|
|
22
|
+
const stdout = (result.stdout ?? result.output ?? '') as string
|
|
23
|
+
const tag = stdout.trim().replace(/^v/, '')
|
|
24
|
+
if (tag) return tag
|
|
25
|
+
}
|
|
26
|
+
} catch { /* fall through */ }
|
|
27
|
+
|
|
28
|
+
return '1.0.1'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const COMMANDS = [
|
|
32
|
+
{ name: '/pantheon', desc: 'Council synthesis' },
|
|
33
|
+
{ name: '/pantheon-status', desc: 'System status' },
|
|
34
|
+
{ name: '/pantheon-audit', desc: 'Full audit' },
|
|
35
|
+
{ name: '/pantheon-bg', desc: 'List background tasks' },
|
|
36
|
+
{ name: '/pantheon-cancel', desc: 'Cancel task' },
|
|
37
|
+
{ name: '/pantheon-deepwork', desc: 'Deep work mode' },
|
|
38
|
+
{ name: '/pantheon-focus', desc: 'Focus on scope' },
|
|
39
|
+
{ name: '/pantheon-remember', desc: 'Memory store/recall' },
|
|
40
|
+
{ name: '/pantheon-search', desc: 'Memory search' },
|
|
41
|
+
{ name: '/pantheon-consolidate', desc: 'Merge memories' },
|
|
42
|
+
{ name: '/pantheon-forget', desc: 'Compress memories' },
|
|
10
43
|
] as const
|
|
11
44
|
|
|
12
|
-
const
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
45
|
+
const AGENTS = [
|
|
46
|
+
{ name: 'zeus', tier: 'default' as const, role: 'Orchestrator' },
|
|
47
|
+
{ name: 'athena', tier: 'premium' as const, role: 'Strategic planner' },
|
|
48
|
+
{ name: 'apollo', tier: 'fast' as const, role: 'Codebase discovery' },
|
|
49
|
+
{ name: 'hermes', tier: 'default' as const, role: 'Backend' },
|
|
50
|
+
{ name: 'aphrodite', tier: 'default' as const, role: 'Frontend' },
|
|
51
|
+
{ name: 'demeter', tier: 'default' as const, role: 'Database' },
|
|
52
|
+
{ name: 'themis', tier: 'premium' as const, role: 'Quality & security' },
|
|
53
|
+
{ name: 'prometheus', tier: 'default' as const, role: 'Infrastructure' },
|
|
54
|
+
{ name: 'hephaestus', tier: 'default' as const, role: 'AI pipelines' },
|
|
55
|
+
{ name: 'nyx', tier: 'fast' as const, role: 'Observability' },
|
|
56
|
+
{ name: 'gaia', tier: 'fast' as const, role: 'Remote sensing' },
|
|
57
|
+
{ name: 'iris', tier: 'fast' as const, role: 'GitHub operations' },
|
|
58
|
+
{ name: 'mnemosyne', tier: 'fast' as const, role: 'Memory bank' },
|
|
59
|
+
{ name: 'talos', tier: 'fast' as const, role: 'Hotfixes' },
|
|
18
60
|
] as const
|
|
19
61
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const [
|
|
62
|
+
function safeNum(v: unknown): number {
|
|
63
|
+
return typeof v === 'number' && Number.isFinite(v) ? v : 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function View(props: { api: TuiPluginApi; sessionID: string; version: string }) {
|
|
67
|
+
const [showCommands, setShowCommands] = createSignal(false)
|
|
68
|
+
const [showAgents, setShowAgents] = createSignal(false)
|
|
69
|
+
const [showConfig, setShowConfig] = createSignal(false)
|
|
70
|
+
const [showMemory, setShowMemory] = createSignal(false)
|
|
71
|
+
const [showSubagents, setShowSubagents] = createSignal(false)
|
|
72
|
+
|
|
73
|
+
const theme = () => props.api.theme.current
|
|
74
|
+
|
|
75
|
+
const branch = createMemo(() =>
|
|
76
|
+
props.api.state.vcs?.branch ? `\u2387 ${props.api.state.vcs.branch}` : null,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
const configInfo = createMemo(() => {
|
|
80
|
+
const cfg = (props.api.state as any).config
|
|
81
|
+
if (!cfg) return null
|
|
82
|
+
return {
|
|
83
|
+
plugins: Array.isArray(cfg.plugin) ? cfg.plugin : [],
|
|
84
|
+
mcpCount: cfg.mcp ? Object.keys(cfg.mcp).length : 0,
|
|
85
|
+
autoCompaction: cfg.compaction?.auto === true,
|
|
86
|
+
}
|
|
87
|
+
})
|
|
26
88
|
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
89
|
+
const memoryInfo = createMemo(() => {
|
|
90
|
+
const mem = (props.api.state as any).memory
|
|
91
|
+
if (mem) {
|
|
92
|
+
const entries = safeNum(mem?.entries) || safeNum(mem?.count)
|
|
93
|
+
return entries > 0 ? { entries } : null
|
|
94
|
+
}
|
|
95
|
+
return null
|
|
30
96
|
})
|
|
31
97
|
|
|
32
|
-
const
|
|
33
|
-
|
|
98
|
+
const [subagents] = createResource(
|
|
99
|
+
() => showSubagents(),
|
|
100
|
+
async () => {
|
|
101
|
+
try {
|
|
102
|
+
const proc = (props.api as any).client?.process
|
|
103
|
+
if (typeof proc?.exec !== 'function') return null
|
|
104
|
+
const result = await proc.exec({
|
|
105
|
+
command: 'opencode',
|
|
106
|
+
args: ['session', 'list', '--format', 'json'],
|
|
107
|
+
timeoutMs: 5000,
|
|
108
|
+
})
|
|
109
|
+
const stdout = (result.stdout ?? result.output ?? '') as string
|
|
110
|
+
const sessions = JSON.parse(stdout)
|
|
111
|
+
if (!Array.isArray(sessions)) return null
|
|
112
|
+
return sessions
|
|
113
|
+
.filter((s: any) => s.id !== props.sessionID)
|
|
114
|
+
.sort((a: any, b: any) => (b.updated ?? 0) - (a.updated ?? 0))
|
|
115
|
+
.slice(0, 10)
|
|
116
|
+
} catch { return null }
|
|
117
|
+
},
|
|
118
|
+
)
|
|
34
119
|
|
|
35
120
|
return (
|
|
36
121
|
<box flexDirection="column" width="100%">
|
|
37
|
-
|
|
38
|
-
|
|
122
|
+
{/* Header */}
|
|
123
|
+
<text fg={theme().accent} attributes={{ bold: true }}>
|
|
124
|
+
{`Pantheon v${props.version}`}
|
|
39
125
|
</text>
|
|
40
126
|
|
|
41
127
|
<Show when={branch()}>
|
|
42
|
-
{(b) => <box marginTop={1}><text fg={
|
|
128
|
+
{(b) => (<box marginTop={1}><text fg={theme().textMuted}>{b()}</text></box>)}
|
|
43
129
|
</Show>
|
|
44
130
|
|
|
45
|
-
{/*
|
|
46
|
-
<box marginTop={0} onMouseDown={() =>
|
|
47
|
-
<text fg={
|
|
48
|
-
{
|
|
49
|
-
</text>
|
|
50
|
-
<text fg={props.api.theme.current.textMuted}>
|
|
51
|
-
({(props.api.state as any).session?.count?.() ?? '?'} total)
|
|
131
|
+
{/* Subagents */}
|
|
132
|
+
<box marginTop={0} onMouseDown={() => setShowSubagents((x) => !x)}>
|
|
133
|
+
<text fg={theme().text} attributes={{ bold: true }}>
|
|
134
|
+
{`${showSubagents() ? '\u25bc' : '\u25b6'} Subagents`}
|
|
52
135
|
</text>
|
|
136
|
+
<text fg={theme().textMuted}>{` (${String(props.api.state.session.count())})`}</text>
|
|
53
137
|
</box>
|
|
54
138
|
|
|
139
|
+
<Show when={showSubagents()}>
|
|
140
|
+
<Show when={subagents()} fallback={<box marginLeft={1}><text fg={theme().textMuted}>{`sessions: ${String(props.api.state.session.count())}`}</text></box>}>
|
|
141
|
+
{(sessions) => (
|
|
142
|
+
<Show when={sessions().length > 0} fallback={<box marginLeft={1}><text fg={theme().textMuted}>(idle)</text></box>}>
|
|
143
|
+
<box marginLeft={1} flexDirection="column">
|
|
144
|
+
<For each={sessions().slice(0, 5)}>
|
|
145
|
+
{(s: any) => (
|
|
146
|
+
<text fg={theme().textMuted}>{`${s.id.slice(0, 8)}... ${s.title?.slice(0, 30) ?? ''}`}</text>
|
|
147
|
+
)}
|
|
148
|
+
</For>
|
|
149
|
+
</box>
|
|
150
|
+
</Show>
|
|
151
|
+
)}
|
|
152
|
+
</Show>
|
|
153
|
+
</Show>
|
|
154
|
+
|
|
55
155
|
{/* Commands */}
|
|
56
|
-
<box marginTop={0} onMouseDown={() =>
|
|
57
|
-
<text fg={
|
|
58
|
-
{
|
|
156
|
+
<box marginTop={0} onMouseDown={() => setShowCommands((x) => !x)}>
|
|
157
|
+
<text fg={theme().text} attributes={{ bold: true }}>
|
|
158
|
+
{`${showCommands() ? '\u25bc' : '\u25b6'} Commands`}
|
|
59
159
|
</text>
|
|
60
|
-
<text fg={
|
|
160
|
+
<text fg={theme().textMuted}>{` (${String(COMMANDS.length)})`}</text>
|
|
61
161
|
</box>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
162
|
+
|
|
163
|
+
<Show when={showCommands()}>
|
|
164
|
+
<For each={COMMANDS}>
|
|
165
|
+
{(cmd) => (
|
|
166
|
+
<box marginLeft={1} onMouseDown={(e) => {
|
|
167
|
+
e.stopPropagation()
|
|
168
|
+
try {
|
|
169
|
+
const cmdApi = (props.api as any).command
|
|
170
|
+
const cmdName = cmd.name.replace('/', '')
|
|
171
|
+
if (cmdApi?.trigger?.(cmdName)) return
|
|
172
|
+
} catch {}
|
|
173
|
+
props.api.ui?.toast?.({ title: 'Command', message: `Type ${cmd.name} in chat` })
|
|
174
|
+
}}>
|
|
175
|
+
<text fg={cmd.name === '/pantheon' ? theme().accent : theme().textMuted}>{cmd.name}</text>
|
|
176
|
+
<text fg={theme().textMuted}>{` — ${cmd.desc}`}</text>
|
|
177
|
+
</box>
|
|
178
|
+
)}
|
|
179
|
+
</For>
|
|
68
180
|
</Show>
|
|
69
181
|
|
|
70
182
|
{/* Agents */}
|
|
71
|
-
<box marginTop={0} onMouseDown={() =>
|
|
72
|
-
<text fg={
|
|
73
|
-
{
|
|
183
|
+
<box marginTop={0} onMouseDown={() => setShowAgents((x) => !x)}>
|
|
184
|
+
<text fg={theme().text} attributes={{ bold: true }}>
|
|
185
|
+
{`${showAgents() ? '\u25bc' : '\u25b6'} Agents`}
|
|
74
186
|
</text>
|
|
75
|
-
<text fg={
|
|
187
|
+
<text fg={theme().textMuted}>{` (${String(AGENTS.length)})`}</text>
|
|
76
188
|
</box>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
189
|
+
|
|
190
|
+
<Show when={showAgents()}>
|
|
191
|
+
<For each={AGENTS}>
|
|
192
|
+
{(agent) => (
|
|
193
|
+
<box marginLeft={1}>
|
|
194
|
+
<text fg={agent.tier === 'premium' ? theme().accent : theme().textMuted}>
|
|
195
|
+
{`${agent.tier === 'premium' ? '\u2726 ' : '\u00b7 '}${agent.name}`}
|
|
196
|
+
</text>
|
|
197
|
+
<text fg={theme().textMuted}>{` — ${agent.role}`}</text>
|
|
198
|
+
</box>
|
|
199
|
+
)}
|
|
200
|
+
</For>
|
|
83
201
|
</Show>
|
|
84
202
|
|
|
85
203
|
{/* Config */}
|
|
86
|
-
<box marginTop={0} onMouseDown={() =>
|
|
87
|
-
<text fg={
|
|
88
|
-
{
|
|
204
|
+
<box marginTop={0} onMouseDown={() => setShowConfig((x) => !x)}>
|
|
205
|
+
<text fg={theme().text} attributes={{ bold: true }}>
|
|
206
|
+
{`${showConfig() ? '\u25bc' : '\u25b6'} Config`}
|
|
89
207
|
</text>
|
|
90
208
|
</box>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
209
|
+
|
|
210
|
+
<Show when={showConfig()}>
|
|
211
|
+
<Show when={configInfo()} fallback={<box marginLeft={1}><text fg={theme().textMuted}>(no config data)</text></box>}>
|
|
212
|
+
{(cfg) => (
|
|
213
|
+
<box marginLeft={1} flexDirection="column">
|
|
214
|
+
<text fg={theme().textMuted}>{`MCP servers: ${String(cfg().mcpCount)}`}</text>
|
|
215
|
+
<text fg={theme().textMuted}>{`Auto-compaction: ${cfg().autoCompaction ? 'ON' : 'OFF'}`}</text>
|
|
216
|
+
</box>
|
|
217
|
+
)}
|
|
218
|
+
</Show>
|
|
100
219
|
</Show>
|
|
101
220
|
|
|
102
221
|
{/* Memory */}
|
|
103
|
-
<box marginTop={0} onMouseDown={() =>
|
|
104
|
-
<text fg={
|
|
105
|
-
{
|
|
222
|
+
<box marginTop={0} onMouseDown={() => setShowMemory((x) => !x)}>
|
|
223
|
+
<text fg={theme().text} attributes={{ bold: true }}>
|
|
224
|
+
{`${showMemory() ? '\u25bc' : '\u25b6'} Memory`}
|
|
106
225
|
</text>
|
|
107
226
|
</box>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
</box>
|
|
227
|
+
|
|
228
|
+
<Show when={showMemory()}>
|
|
229
|
+
<Show when={memoryInfo()} fallback={<box marginLeft={1}><text fg={theme().textMuted}>(no data)</text></box>}>
|
|
230
|
+
{(mem) => (<box marginLeft={1}><text fg={theme().textMuted}>{`Entries: ${String(mem().entries)}`}</text></box>)}
|
|
231
|
+
</Show>
|
|
114
232
|
</Show>
|
|
115
233
|
</box>
|
|
116
234
|
)
|
|
117
235
|
}
|
|
118
236
|
|
|
119
|
-
|
|
120
|
-
|
|
237
|
+
const tui: TuiPlugin = async (api, _options, _meta) => {
|
|
238
|
+
const version = await readPantheonVersion(api)
|
|
239
|
+
api.slots.register({
|
|
121
240
|
order: 900,
|
|
122
241
|
slots: {
|
|
123
|
-
sidebar_content(_ctx
|
|
124
|
-
return <
|
|
242
|
+
sidebar_content(_ctx, props) {
|
|
243
|
+
return <View api={api} sessionID={props.session_id} version={version} />
|
|
125
244
|
},
|
|
126
245
|
},
|
|
127
|
-
}
|
|
246
|
+
})
|
|
128
247
|
}
|
|
129
248
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
try {
|
|
134
|
-
const wt = api.state.path?.worktree ?? ''
|
|
135
|
-
const fp = wt ? `${wt}/package.json` : 'package.json'
|
|
136
|
-
const r = await api.client.file.read({ query: { path: fp } })
|
|
137
|
-
const m = String(r?.content ?? '').match(/"version":\s*"([^"]+)"/)
|
|
138
|
-
if (m?.[1]) version = m[1]
|
|
139
|
-
} catch { /* fallback */ }
|
|
140
|
-
|
|
141
|
-
api.slots.register(createSlot(api, version))
|
|
249
|
+
const plugin: TuiPluginModule & { id: string } = {
|
|
250
|
+
id: 'pantheon.tui',
|
|
251
|
+
tui,
|
|
142
252
|
}
|
|
143
253
|
|
|
144
|
-
export default
|
|
254
|
+
export default plugin
|