opencode-ghost 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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ 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.1] - 2026-10-08
9
+
10
+ ### Fixed
11
+
12
+ - **tui:** Expose suggest command in global keymap mode
13
+
8
14
  ## [1.0.0] - 2026-10-08
9
15
 
10
16
  ### Breaking changes
@@ -161,6 +167,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
161
167
  - Options for `model`, `acceptKeys`, `maxChars`, `idleDelayMs`,
162
168
  `recentMessages` and `system`.
163
169
 
170
+ [1.0.1]: https://github.com/ozandogrultan/opencode-ghost/compare/v1.0.0...v1.0.1
164
171
  [1.0.0]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.6.0...v1.0.0
165
172
  [0.6.0]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.5.1...v0.6.0
166
173
  [0.5.1]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.5.0...v0.5.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-ghost",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
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/keymap.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { KeymapCommand, KeymapLayer } from "@opencode/plugin/tui/context"
2
+
3
+ export function ghostKeymapLayers(
4
+ composerCommands: KeymapCommand[],
5
+ enabled: boolean,
6
+ suggest: KeymapCommand["run"],
7
+ ): KeymapLayer[] {
8
+ return [
9
+ { mode: "base", priority: 2, commands: composerCommands },
10
+ {
11
+ mode: "global",
12
+ commands: [{
13
+ id: "ghost.suggest",
14
+ title: `Prompt suggestions: ${enabled ? "on" : "off"}`,
15
+ description: "Toggle the suggested next prompt",
16
+ group: "Prompt",
17
+ palette: true,
18
+ slash: { name: "suggest", arguments: true },
19
+ run: suggest,
20
+ }],
21
+ },
22
+ ]
23
+ }
package/src/tui.tsx CHANGED
@@ -4,6 +4,7 @@ import { TextareaRenderable, InputRenderable, type BoxRenderable, type Renderabl
4
4
  import { createEffect, createRoot, createSignal, on, onCleanup } from "solid-js"
5
5
  import { composerAction, findComposerEditor, isEmptyComposer, keyName, observeComposerInput } from "./composer"
6
6
  import { createLifecycle } from "./lifecycle"
7
+ import { ghostKeymapLayers } from "./keymap"
7
8
  import { parseSuggestCommand, removedOptionKeys, resolveOptions, suggestionModel } from "./options"
8
9
  import { createInlinePlaceholder } from "./placeholder"
9
10
  import { generateSuggestion } from "./stateless"
@@ -153,10 +154,7 @@ export default Plugin.define({
153
154
  return Boolean(current && inline.visible(getComposer(current.sessionID).editor, current.text) && opts.acceptKeys.includes(key) && canGenerate(current.sessionID) && isComposerEmpty(current.sessionID))
154
155
  }, cancelSuggestion)
155
156
 
156
- context.keymap.layer(() => ({
157
- mode: "base",
158
- priority: 2,
159
- commands: [
157
+ const commandLayers = () => ghostKeymapLayers([
160
158
  ...opts.acceptKeys.map((key) => ({
161
159
  id: `ghost.accept.${key}`,
162
160
  bind: key,
@@ -181,14 +179,7 @@ export default Plugin.define({
181
179
  context.ui.router.navigate({ type: "home" })
182
180
  },
183
181
  },
184
- {
185
- id: "ghost.suggest",
186
- title: `Prompt suggestions: ${state.enabled ? "on" : "off"}`,
187
- description: "Toggle the suggested next prompt",
188
- group: "Prompt",
189
- palette: true,
190
- slash: { name: "suggest", arguments: true },
191
- run: async (input) => {
182
+ ], state.enabled, async (input) => {
192
183
  const command = parseSuggestCommand(input)
193
184
  if (command.type === "model") {
194
185
  cancelSuggestion()
@@ -212,10 +203,9 @@ export default Plugin.define({
212
203
  context.ui.toast.show({ message: "Prompt suggestions: on" })
213
204
  const route = context.ui.router.current()
214
205
  if (route.type === "session") void lifecycle.run(route.sessionID)
215
- },
216
- },
217
- ],
218
- }))
206
+ })
207
+ context.keymap.layer(() => commandLayers()[0]!)
208
+ context.keymap.layer(() => commandLayers()[1]!)
219
209
 
220
210
  const offComposer = context.ui.slot({
221
211
  append: "prompt.footer",