opencode-miniterm 1.0.1 → 1.0.2
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 +164 -1
- package/bun.lock +1 -1
- package/package.json +1 -1
- package/src/commands/diff.ts +3 -2
- package/src/commands/init.ts +3 -2
- package/src/commands/new.ts +1 -1
- package/src/commands/sessions.ts +4 -4
- package/src/commands/undo.ts +4 -3
- package/src/config.ts +2 -1
- package/src/index.ts +2 -4
- package/src/commands/kill.ts +0 -33
package/README.md
CHANGED
|
@@ -2,4 +2,167 @@
|
|
|
2
2
|
|
|
3
3
|
A small front-end terminal UI for [OpenCode](https://github.com/anomalyco/opencode).
|
|
4
4
|
|
|
5
|
-
This project is not affiliated with OpenCode.
|
|
5
|
+
> **Note:** This project is not affiliated with OpenCode.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Slash Commands** - Quick access to common operations
|
|
10
|
+
- **File Auto-Completion** - Type `@` followed by file path for intelligent completions
|
|
11
|
+
- **Real-Time Streaming** - See AI responses as they're being generated
|
|
12
|
+
- **Logging Support** - Optional conversation logging for debugging
|
|
13
|
+
- **Keyboard Navigation** - Readline support with history and editing
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Prerequisites
|
|
18
|
+
|
|
19
|
+
- [OpenCode](https://github.com/anomalyco/opencode) - OpenCode server
|
|
20
|
+
- [Bun](https://bun.sh/) - Required runtime
|
|
21
|
+
|
|
22
|
+
### Install from npm
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g opencode-miniterm
|
|
26
|
+
# or
|
|
27
|
+
pnpm add -g opencode-miniterm
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Install from Source
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git clone https://github.com/your-repo/opencode-miniterm.git
|
|
34
|
+
cd opencode-miniterm
|
|
35
|
+
bun install
|
|
36
|
+
bun link
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Quick Start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
ocmt
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This will:
|
|
46
|
+
|
|
47
|
+
1. Start the OpenCode server (if not already running)
|
|
48
|
+
2. Create or resume a session for the current directory
|
|
49
|
+
3. Present the interactive prompt
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
Configuration is stored in `~/.config/opencode-miniterm/opencode-miniterm.json`:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"providerID": "opencode",
|
|
58
|
+
"modelID": "big-pickle",
|
|
59
|
+
"agentID": "build",
|
|
60
|
+
"sessionIDs": {
|
|
61
|
+
"/path/to/project1": "session-id-1",
|
|
62
|
+
"/path/to/project2": "session-id-2"
|
|
63
|
+
},
|
|
64
|
+
"loggingEnabled": false
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Environment Variables
|
|
69
|
+
|
|
70
|
+
- `OPENCODE_SERVER_USERNAME` - Server username (default: "opencode")
|
|
71
|
+
- `OPENCODE_SERVER_PASSWORD` - Server password (required if server has auth)
|
|
72
|
+
- `OPENCODE_MT_CONFIG_CONTENT` - Override config as JSON string
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
### Basic Interaction
|
|
77
|
+
|
|
78
|
+
Simply type your question or request at the prompt and press Enter:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
> Help me fix the bug in auth.ts
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Slash Commands
|
|
85
|
+
|
|
86
|
+
| Command | Description |
|
|
87
|
+
| ------------------ | ------------------------------------------- |
|
|
88
|
+
| `/help` | Show available commands |
|
|
89
|
+
| `/init` | Analyze project and create/update AGENTS.md |
|
|
90
|
+
| `/new` | Create a new session |
|
|
91
|
+
| `/sessions` | List and switch sessions |
|
|
92
|
+
| `/diff` | Show file additions and deletions |
|
|
93
|
+
| `/undo` | Undo last assistant request |
|
|
94
|
+
| `/details` | Show detailed info for the previous request |
|
|
95
|
+
| `/page` | Page through the detailed info |
|
|
96
|
+
| `/agents` | Show available agents |
|
|
97
|
+
| `/models` | Show available models |
|
|
98
|
+
| `/log` | Enable/disable logging |
|
|
99
|
+
| `/run <cmd>` | Run a shell command from within miniterm |
|
|
100
|
+
| `/exit` or `/quit` | Exit the application |
|
|
101
|
+
|
|
102
|
+
### File References
|
|
103
|
+
|
|
104
|
+
Reference files in your conversation using `@` followed by the path:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
> Review @src/index.ts and suggest improvements
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Tab completion is supported for file paths:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
> @sr<tab> → @src/
|
|
114
|
+
> @src/in<tab> → @src/index.ts
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Keyboard Shortcuts
|
|
118
|
+
|
|
119
|
+
| Key | Action |
|
|
120
|
+
| ---------------------- | ---------------------------- |
|
|
121
|
+
| `↑` / `↓` | Navigate command history |
|
|
122
|
+
| `←` / `→` | Move cursor |
|
|
123
|
+
| `Opt+←` / `Opt+→` | Move by word boundaries |
|
|
124
|
+
| `Tab` | Auto-complete commands/files |
|
|
125
|
+
| `Backspace` / `Delete` | Delete characters |
|
|
126
|
+
| `Esc` | Cancel current request |
|
|
127
|
+
| `Ctrl+C` | Force quit application |
|
|
128
|
+
|
|
129
|
+
## Session Management
|
|
130
|
+
|
|
131
|
+
OpenCode Miniterm automatically manages sessions per directory:
|
|
132
|
+
|
|
133
|
+
- **First Launch**: Creates a new session for the current directory
|
|
134
|
+
- **Subsequent Launches**: Resumes the last session for that directory
|
|
135
|
+
- **New Session**: Use `/new` to create a fresh session
|
|
136
|
+
- **Switch Sessions**: Use `/sessions` to browse and switch between all your sessions
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
### Running Locally
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
bun run dev
|
|
144
|
+
# or
|
|
145
|
+
bun src/index.ts
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Build
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
bun build src/index.ts --outdir dist
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Type Check
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
bun run check
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Formatting
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
bunx prettier --write "**/*.{ts,json,md}"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
ISC
|
package/bun.lock
CHANGED
package/package.json
CHANGED
package/src/commands/diff.ts
CHANGED
|
@@ -20,7 +20,8 @@ interface DiffLine {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
async function run(client: OpencodeClient, state: State): Promise<void> {
|
|
23
|
-
|
|
23
|
+
const cwd = process.cwd();
|
|
24
|
+
if (!config.sessionIDs[cwd]) {
|
|
24
25
|
console.log("No active session.\n");
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
@@ -28,7 +29,7 @@ async function run(client: OpencodeClient, state: State): Promise<void> {
|
|
|
28
29
|
console.log("Fetching file changes...");
|
|
29
30
|
|
|
30
31
|
const result = await client.session.diff({
|
|
31
|
-
path: { id: config.
|
|
32
|
+
path: { id: config.sessionIDs[cwd] },
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
if (result.error) {
|
package/src/commands/init.ts
CHANGED
|
@@ -14,11 +14,12 @@ let command: Command = {
|
|
|
14
14
|
export default command;
|
|
15
15
|
|
|
16
16
|
async function run(_client: OpencodeClient, _state: State): Promise<void> {
|
|
17
|
-
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
if (!config.sessionIDs[cwd]) return;
|
|
18
19
|
|
|
19
20
|
console.log("Running /init command (analyzing project and creating AGENTS.md)...");
|
|
20
21
|
const result = await _client.session.init({
|
|
21
|
-
path: { id: config.
|
|
22
|
+
path: { id: config.sessionIDs[cwd] },
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
if (result.error) {
|
package/src/commands/new.ts
CHANGED
|
@@ -16,7 +16,7 @@ export default command;
|
|
|
16
16
|
|
|
17
17
|
async function run(client: OpencodeClient, state: State): Promise<void> {
|
|
18
18
|
state.sessionID = await createSession(client);
|
|
19
|
-
config.
|
|
19
|
+
config.sessionIDs[process.cwd()] = state.sessionID;
|
|
20
20
|
saveConfig();
|
|
21
21
|
|
|
22
22
|
await updateSessionTitle();
|
package/src/commands/sessions.ts
CHANGED
|
@@ -44,7 +44,7 @@ async function run(client: OpencodeClient, state: State): Promise<void> {
|
|
|
44
44
|
if (sessions.length === 0) {
|
|
45
45
|
console.log("No sessions found. Creating a new session...");
|
|
46
46
|
state.sessionID = await createSession(client);
|
|
47
|
-
config.
|
|
47
|
+
config.sessionIDs[process.cwd()] = state.sessionID;
|
|
48
48
|
saveConfig();
|
|
49
49
|
console.log(`Created new session: ${state.sessionID}...\n`);
|
|
50
50
|
await updateSessionTitle();
|
|
@@ -135,7 +135,7 @@ async function handleKey(_client: OpencodeClient, key: Key, str?: string) {
|
|
|
135
135
|
readline.cursorTo(process.stdout, 0);
|
|
136
136
|
readline.clearScreenDown(process.stdout);
|
|
137
137
|
if (selected) {
|
|
138
|
-
config.
|
|
138
|
+
config.sessionIDs[process.cwd()] = selected.id;
|
|
139
139
|
saveConfig();
|
|
140
140
|
console.log(`Switched to session: ${selected.id.substring(0, 8)}...`);
|
|
141
141
|
if (selected.title) {
|
|
@@ -222,7 +222,7 @@ function renderSessionList(): void {
|
|
|
222
222
|
const globalIndex = sessionList.indexOf(session);
|
|
223
223
|
const filteredIndex = sessionFilteredIndices.indexOf(globalIndex);
|
|
224
224
|
const isSelected = filteredIndex === selectedSessionIndex;
|
|
225
|
-
const isActive = session.id === config.
|
|
225
|
+
const isActive = session.id === config.sessionIDs[process.cwd()];
|
|
226
226
|
const prefix = isSelected ? " >" : " -";
|
|
227
227
|
const title = session.title || "(no title)";
|
|
228
228
|
const name = isSelected ? `\x1b[33;1m${title}\x1b[0m` : title;
|
|
@@ -250,7 +250,7 @@ function updateSessionFilter(): void {
|
|
|
250
250
|
}
|
|
251
251
|
if (sessionFilteredIndices.length > 0) {
|
|
252
252
|
selectedSessionIndex = sessionFilteredIndices.indexOf(
|
|
253
|
-
sessionList.findIndex((s) => s.id === config.
|
|
253
|
+
sessionList.findIndex((s) => s.id === config.sessionIDs[process.cwd()]),
|
|
254
254
|
);
|
|
255
255
|
if (selectedSessionIndex === -1) selectedSessionIndex = 0;
|
|
256
256
|
}
|
package/src/commands/undo.ts
CHANGED
|
@@ -13,12 +13,13 @@ let command: Command = {
|
|
|
13
13
|
export default command;
|
|
14
14
|
|
|
15
15
|
async function run(client: OpencodeClient, _state: State): Promise<void> {
|
|
16
|
-
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
if (!config.sessionIDs[cwd]) return;
|
|
17
18
|
|
|
18
19
|
console.log("Fetching session messages...");
|
|
19
20
|
|
|
20
21
|
const messagesRes = await client.session.messages({
|
|
21
|
-
path: { id: config.
|
|
22
|
+
path: { id: config.sessionIDs[cwd] },
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
if (messagesRes.error) {
|
|
@@ -49,7 +50,7 @@ async function run(client: OpencodeClient, _state: State): Promise<void> {
|
|
|
49
50
|
console.log(`Reverting last assistant message (${lastMessage.info.id})...`);
|
|
50
51
|
|
|
51
52
|
const revertRes = await client.session.revert({
|
|
52
|
-
path: { id: config.
|
|
53
|
+
path: { id: config.sessionIDs[process.cwd()] },
|
|
53
54
|
body: {
|
|
54
55
|
messageID: lastMessage.info.id,
|
|
55
56
|
},
|
package/src/config.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface Config {
|
|
|
5
5
|
providerID: string;
|
|
6
6
|
modelID: string;
|
|
7
7
|
agentID: string;
|
|
8
|
-
|
|
8
|
+
sessionIDs: Record<string, string>;
|
|
9
9
|
loggingEnabled: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -15,6 +15,7 @@ export const config: Config = {
|
|
|
15
15
|
providerID: "opencode",
|
|
16
16
|
modelID: "big-pickle",
|
|
17
17
|
agentID: "build",
|
|
18
|
+
sessionIDs: {},
|
|
18
19
|
loggingEnabled: false,
|
|
19
20
|
};
|
|
20
21
|
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,6 @@ import detailsCommand from "./commands/details";
|
|
|
14
14
|
import diffCommand from "./commands/diff";
|
|
15
15
|
import exitCommand from "./commands/exit";
|
|
16
16
|
import initCommand from "./commands/init";
|
|
17
|
-
import killCommand from "./commands/kill";
|
|
18
17
|
import logCommand, { isLoggingEnabled } from "./commands/log";
|
|
19
18
|
import modelsCommand from "./commands/models";
|
|
20
19
|
import newCommand from "./commands/new";
|
|
@@ -42,7 +41,6 @@ const SLASH_COMMANDS = [
|
|
|
42
41
|
debugCommand,
|
|
43
42
|
logCommand,
|
|
44
43
|
pageCommand,
|
|
45
|
-
killCommand,
|
|
46
44
|
exitCommand,
|
|
47
45
|
quitCommand,
|
|
48
46
|
runCommand,
|
|
@@ -122,11 +120,11 @@ async function main() {
|
|
|
122
120
|
try {
|
|
123
121
|
let isNewSession = false;
|
|
124
122
|
|
|
125
|
-
const initialSessionID = config.
|
|
123
|
+
const initialSessionID = config.sessionIDs[cwd];
|
|
126
124
|
if (!initialSessionID || !(await validateSession(initialSessionID))) {
|
|
127
125
|
state.sessionID = await createSession();
|
|
128
126
|
isNewSession = true;
|
|
129
|
-
config.
|
|
127
|
+
config.sessionIDs[cwd] = state.sessionID;
|
|
130
128
|
saveConfig();
|
|
131
129
|
} else {
|
|
132
130
|
state.sessionID = initialSessionID;
|
package/src/commands/kill.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
2
|
-
import type { State } from "../index";
|
|
3
|
-
import type { Command } from "../types";
|
|
4
|
-
|
|
5
|
-
let command: Command = {
|
|
6
|
-
name: "/kill",
|
|
7
|
-
description: "Abort a session (e.g. `/kill ses_123`)",
|
|
8
|
-
run,
|
|
9
|
-
running: false,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export default command;
|
|
13
|
-
|
|
14
|
-
async function run(client: OpencodeClient, _state: State, input?: string): Promise<void> {
|
|
15
|
-
if (!input) {
|
|
16
|
-
console.log("Usage: /kill <session_id>");
|
|
17
|
-
console.log();
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const result = await client.session.abort({
|
|
22
|
-
path: { id: input },
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
if (result.error) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`Failed to abort session (${result.response.status}): ${JSON.stringify(result.error)}`,
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
console.log(`Session aborted successfully.`);
|
|
32
|
-
console.log();
|
|
33
|
-
}
|