opencode-ghost 1.0.6 → 1.0.7

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/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.7] - 2026-10-08
9
+
10
+ ### Fixed
11
+
12
+ - **tui:** Remove left-arrow home navigation
13
+ - **tui:** Ignore all slot wrappers when detecting the composer
14
+
8
15
  ## [1.0.6] - 2026-10-08
9
16
 
10
17
  ### Fixed
@@ -221,6 +228,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
221
228
  - Options for `model`, `acceptKeys`, `maxChars`, `idleDelayMs`,
222
229
  `recentMessages` and `system`.
223
230
 
231
+ [1.0.7]: https://github.com/ozandogrultan/opencode-ghost/compare/v1.0.6...v1.0.7
224
232
  [1.0.6]: https://github.com/ozandogrultan/opencode-ghost/compare/v1.0.5...v1.0.6
225
233
  [1.0.5]: https://github.com/ozandogrultan/opencode-ghost/compare/v1.0.4...v1.0.5
226
234
  [1.0.4]: https://github.com/ozandogrultan/opencode-ghost/compare/v1.0.3...v1.0.4
package/README.md CHANGED
@@ -24,8 +24,6 @@ a dimmed inline placeholder in the empty composer with
24
24
  - **Hides as you type.** Typing and pasting abort pending generation and hide the
25
25
  preview. Emptying the composer restores the same suggestion without another
26
26
  API call; focus changes also reuse it. Navigation keys leave it intact.
27
- Left on an empty eligible focused composer returns
28
- home, even when suggestions are off (`backOnEmptyLeft`).
29
27
  - **`/suggest` toggles it.** State is stored durably via the plugin's storage.
30
28
 
31
29
  ## Requirements
@@ -94,7 +92,6 @@ copy, use `/absolute/path/to/config/plugins/opencode-ghost`.
94
92
  | `idleDelayMs` | `number` | `500` | Debounce after a turn finishes before generating. |
95
93
  | `recentMessages` | `number` | `10` | How many recent messages feed the suggestion prompt. |
96
94
  | `system` | `string` | built-in | Override the system prompt sent to the suggestion model. |
97
- | `backOnEmptyLeft` | `boolean` | `true` | Return to the home screen with Left when the composer is empty. |
98
95
 
99
96
  ## Commands
100
97
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-ghost",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Stateless inline next-prompt ghosts for the empty OpenCode V2 composer, accepted with Tab or Right.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/composer.ts CHANGED
@@ -39,9 +39,9 @@ export function isEmptyComposer(editor: TextareaRenderable | undefined, focused:
39
39
  export function isEligibleComposer(editor: TextareaRenderable | undefined, mode: string, normal: boolean, selected: boolean): boolean {
40
40
  if (!editor?.parent || editor.parent.isDestroyed) return false
41
41
  const siblings = editor.parent.getChildren().filter((node) =>
42
- !(node.id.startsWith("slot-layout-") && node.getChildren().length === 0),
42
+ !node.id.startsWith("slot-layout-"),
43
43
  )
44
- if (siblings.length !== 2 || siblings[0] !== editor) return false
44
+ if (siblings.length !== 1 || siblings[0] !== editor) return false
45
45
  return normal && mode === "base" && !selected && !editor.isDestroyed && editor.plainText === "" && !editor.hasSelection() && !editor.traits.capture?.includes("navigate") && editor.extmarks.getAll().length === 0
46
46
  }
47
47
 
package/src/options.ts CHANGED
@@ -5,7 +5,6 @@ export type GhostOptions = {
5
5
  enabled?: boolean
6
6
  model?: string
7
7
  acceptKeys?: string[]
8
- backOnEmptyLeft?: boolean
9
8
  maxChars?: number
10
9
  idleDelayMs?: number
11
10
  recentMessages?: number
@@ -16,7 +15,6 @@ export type ResolvedOptions = {
16
15
  enabled: boolean
17
16
  model: string | undefined
18
17
  acceptKeys: string[]
19
- backOnEmptyLeft: boolean
20
18
  maxChars: number
21
19
  idleDelayMs: number
22
20
  recentMessages: number
@@ -48,13 +46,12 @@ export const DEFAULT_SYSTEM = [
48
46
  const DEFAULTS = {
49
47
  enabled: true,
50
48
  acceptKeys: ["tab", "right"],
51
- backOnEmptyLeft: true,
52
49
  maxChars: 120,
53
50
  idleDelayMs: 500,
54
51
  recentMessages: 10,
55
52
  }
56
53
 
57
- const REMOVED_OPTION_KEYS = ["endpoint", "apiKey", "internalSessionMarkerDir", "argHints"] as const
54
+ const REMOVED_OPTION_KEYS = ["endpoint", "apiKey", "internalSessionMarkerDir", "argHints", "backOnEmptyLeft"] as const
58
55
 
59
56
  export function removedOptionKeys(raw: Readonly<Record<string, unknown>> | undefined): string[] {
60
57
  if (!raw) return []
@@ -73,7 +70,6 @@ export function resolveOptions(options: Readonly<Record<string, unknown>> | unde
73
70
  enabled: typeof input.enabled === "boolean" ? input.enabled : DEFAULTS.enabled,
74
71
  model: typeof input.model === "string" && input.model.trim() ? input.model.trim() : undefined,
75
72
  acceptKeys: acceptKeys.length > 0 ? acceptKeys : [...DEFAULTS.acceptKeys],
76
- backOnEmptyLeft: typeof input.backOnEmptyLeft === "boolean" ? input.backOnEmptyLeft : DEFAULTS.backOnEmptyLeft,
77
73
  maxChars: typeof maxChars === "number" && maxChars > 0 ? maxChars : DEFAULTS.maxChars,
78
74
  idleDelayMs:
79
75
  typeof idleDelayMs === "number" && idleDelayMs >= 0 ? idleDelayMs : DEFAULTS.idleDelayMs,
package/src/tui.tsx CHANGED
@@ -161,18 +161,6 @@ export default Plugin.define({
161
161
  const route = context.ui.router.current()
162
162
  return route.type === "session" ? route.sessionID : undefined
163
163
  }, () => suggestion()?.sessionID, act)),
164
- {
165
- id: "ghost.home",
166
- bind: "left",
167
- enabled: () => opts.backOnEmptyLeft,
168
- run: () => {
169
- const route = context.ui.router.current()
170
- if (route.type !== "session") return false
171
- if (!isComposerEmpty(route.sessionID)) return false
172
- cancelSuggestion()
173
- context.ui.router.navigate({ type: "home" })
174
- },
175
- },
176
164
  ], state.enabled, async (input) => {
177
165
  const command = parseSuggestCommand(input)
178
166
  if (command.type === "model") {