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 +8 -0
- package/README.md +0 -3
- package/package.json +1 -1
- package/src/composer.ts +2 -2
- package/src/options.ts +1 -5
- package/src/tui.tsx +0 -12
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
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
|
-
!
|
|
42
|
+
!node.id.startsWith("slot-layout-"),
|
|
43
43
|
)
|
|
44
|
-
if (siblings.length !==
|
|
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") {
|