opencode-miniterm 1.0.0 → 1.0.1

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.
Files changed (3) hide show
  1. package/bun.lock +1 -1
  2. package/package.json +2 -2
  3. package/src/index.ts +31 -67
package/bun.lock CHANGED
@@ -47,7 +47,7 @@
47
47
 
48
48
  "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
49
49
 
50
- "@opencode-ai/sdk": ["@opencode-ai/sdk@1.2.10", "", {}, "sha512-SyXcVqry2hitPVvQtvXOhqsWyFhSycG/+LTLYXrcq8AFmd9FR7dyBSDB3f5Ol6IPkYOegk8P2Eg2kKPNSNiKGw=="],
50
+ "@opencode-ai/sdk": ["@opencode-ai/sdk@1.2.14", "", {}, "sha512-nPkWAmzgPJYyfCJAV4NG7HTfN/iuO3B6fv8sT26NhPiR+EqD9i8sh4X1LwI7wEbbMOwWOX1PhrssW6gXQOOQZQ=="],
51
51
 
52
52
  "@trivago/prettier-plugin-sort-imports": ["@trivago/prettier-plugin-sort-imports@6.0.2", "", { "dependencies": { "@babel/generator": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "javascript-natural-sort": "^0.7.1", "lodash-es": "^4.17.21", "minimatch": "^9.0.0", "parse-imports-exports": "^0.2.4" }, "peerDependencies": { "@vue/compiler-sfc": "3.x", "prettier": "2.x - 3.x", "prettier-plugin-ember-template-tag": ">= 2.0.0", "prettier-plugin-svelte": "3.x", "svelte": "4.x || 5.x" }, "optionalPeers": ["@vue/compiler-sfc", "prettier-plugin-ember-template-tag", "prettier-plugin-svelte", "svelte"] }, "sha512-3DgfkukFyC/sE/VuYjaUUWoFfuVjPK55vOFDsxD56XXynFMCZDYFogH2l/hDfOsQAm1myoU/1xByJ3tWqtulXA=="],
53
53
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-miniterm",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A small front-end terminal UI for OpenCode",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -28,7 +28,7 @@
28
28
  "typescript": "^5"
29
29
  },
30
30
  "dependencies": {
31
- "@opencode-ai/sdk": "^1.2.10",
31
+ "@opencode-ai/sdk": "^1.2.14",
32
32
  "allmark": "^1.0.0"
33
33
  }
34
34
  }
package/src/index.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import { createOpencodeClient } from "@opencode-ai/sdk";
3
+ import { createOpencodeClient, createOpencodeServer } from "@opencode-ai/sdk";
4
4
  import type { Event, FileDiff, Part, Todo, ToolPart } from "@opencode-ai/sdk";
5
- import { spawn } from "node:child_process";
6
5
  import { mkdir } from "node:fs/promises";
7
6
  import { glob } from "node:fs/promises";
8
7
  import { stat } from "node:fs/promises";
@@ -53,7 +52,6 @@ let client: ReturnType<typeof createOpencodeClient>;
53
52
 
54
53
  let processing = true;
55
54
  let retryInterval: ReturnType<typeof setInterval> | null = null;
56
- let messageAbortController: AbortController | null = null;
57
55
 
58
56
  interface AccumulatedPart {
59
57
  key: string;
@@ -93,8 +91,17 @@ let logFilePath: string | null = null;
93
91
  async function main() {
94
92
  loadConfig();
95
93
 
96
- const serverProcess = await startOpenCodeServer();
94
+ console.log(`\n${ansi.BRIGHT_BLACK}Connecting to OpenCode server...${ansi.RESET}\n`);
97
95
 
96
+ let server: Awaited<ReturnType<typeof createOpencodeServer>> | undefined;
97
+ try {
98
+ server = await createOpencodeServer();
99
+ } catch {
100
+ // Probably the server already exists?
101
+ // Should figure out a better way to check this
102
+ }
103
+
104
+ const cwd = process.cwd();
98
105
  client = createOpencodeClient({
99
106
  baseUrl: SERVER_URL,
100
107
  headers: AUTH_PASSWORD
@@ -102,6 +109,14 @@ async function main() {
102
109
  Authorization: `Basic ${Buffer.from(`${AUTH_USERNAME}:${AUTH_PASSWORD}`).toString("base64")}`,
103
110
  }
104
111
  : undefined,
112
+ directory: cwd,
113
+ });
114
+
115
+ process.on("SIGINT", () => {
116
+ console.log("\nShutting down...");
117
+ saveConfig();
118
+ server?.close();
119
+ process.exit(0);
105
120
  });
106
121
 
107
122
  try {
@@ -330,21 +345,13 @@ async function main() {
330
345
  return;
331
346
  }
332
347
  case "escape": {
333
- if (messageAbortController) {
334
- messageAbortController.abort();
335
- stopAnimation();
336
- process.stdout.write(ansi.CURSOR_SHOW);
337
- process.stdout.write(`\r${ansi.BRIGHT_BLACK}Cancelled request${ansi.RESET}\n`);
338
- } else {
339
- inputBuffer = "";
340
- cursorPosition = 0;
341
- showCompletions = false;
342
- completionCycling = false;
343
- completions = [];
344
- readline.cursorTo(process.stdout, 0);
345
- readline.clearScreenDown(process.stdout);
346
- writePrompt();
348
+ if (state.sessionID) {
349
+ client.session.abort({ path: { id: state.sessionID } }).catch(() => {});
347
350
  }
351
+ stopAnimation();
352
+ process.stdout.write(ansi.CURSOR_SHOW);
353
+ process.stdout.write(`\r${ansi.BRIGHT_BLACK}Cancelled request${ansi.RESET}\n`);
354
+ writePrompt();
348
355
  return;
349
356
  }
350
357
  case "return": {
@@ -400,7 +407,7 @@ async function main() {
400
407
  writePrompt();
401
408
  } catch (error: any) {
402
409
  console.error("Error:", error.message);
403
- serverProcess.kill();
410
+ server?.close();
404
411
  process.exit(1);
405
412
  }
406
413
  }
@@ -409,46 +416,6 @@ async function main() {
409
416
  // SERVER COMMUNICATION
410
417
  // ====================
411
418
 
412
- async function startOpenCodeServer() {
413
- const serverProcess = spawn("opencode", ["serve"], {
414
- stdio: ["ignore", "pipe", "pipe"],
415
- shell: true,
416
- cwd: process.cwd(),
417
- });
418
-
419
- let started = false;
420
-
421
- console.log(`\n${ansi.BRIGHT_BLACK}Starting OpenCode server...${ansi.RESET}\n`);
422
-
423
- serverProcess.stdout.on("data", (data) => {
424
- if (!started) {
425
- process.stdout.write(`${ansi.CLEAR_SCREEN_UP}${ansi.CLEAR_FROM_CURSOR}`);
426
- process.stdout.write(ansi.CURSOR_HOME);
427
- started = true;
428
- console.log(`${ansi.BRIGHT_BLACK}Server started, connecting...${ansi.RESET}\n`);
429
- }
430
- });
431
-
432
- serverProcess.on("error", (error) => {
433
- console.error("Failed to start OpenCode server:", error.message);
434
- process.exit(1);
435
- });
436
-
437
- serverProcess.on("exit", (code) => {
438
- console.log(`OpenCode server exited with code ${code}`);
439
- process.exit(0);
440
- });
441
-
442
- process.on("SIGINT", () => {
443
- console.log("\nShutting down...");
444
- saveConfig();
445
- serverProcess.kill("SIGINT");
446
- });
447
-
448
- await new Promise((resolve) => setTimeout(resolve, 3000));
449
- return serverProcess;
450
- }
451
-
452
419
  async function createSession(): Promise<string> {
453
420
  const result = await client.session.create({
454
421
  body: {},
@@ -533,8 +500,6 @@ async function sendMessage(sessionID: string, message: string) {
533
500
 
534
501
  await writeToLog(`User: ${message}\n\n`);
535
502
 
536
- messageAbortController = new AbortController();
537
-
538
503
  const requestStartTime = Date.now();
539
504
 
540
505
  try {
@@ -547,7 +512,6 @@ async function sendMessage(sessionID: string, message: string) {
547
512
  },
548
513
  parts: [{ type: "text", text: message }],
549
514
  },
550
- signal: messageAbortController.signal,
551
515
  });
552
516
 
553
517
  if (result.error) {
@@ -566,14 +530,14 @@ async function sendMessage(sessionID: string, message: string) {
566
530
  console.log(`${ansi.BRIGHT_BLACK}Completed in ${durationText}${ansi.RESET}\n`);
567
531
 
568
532
  writePrompt();
569
- readline.cursorTo(process.stdout, 2);
533
+
534
+ // HACK:
535
+ setTimeout(() => {
536
+ readline.cursorTo(process.stdout, 2);
537
+ }, 200);
570
538
  } catch (error: any) {
571
- if (error.name === "AbortError" || messageAbortController?.signal.aborted) {
572
- throw new Error("Request cancelled");
573
- }
574
539
  throw error;
575
540
  } finally {
576
- messageAbortController = null;
577
541
  await closeLogFile();
578
542
  }
579
543
  }