opencode-ghost 0.4.0 → 0.5.0

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
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-09-30
11
+
12
+ ### Added
13
+
14
+ - Support `--all` and explicit directory targets in `install.sh` to install across both global OpenCode v1 (`~/.config/opencode`) and sandbox/v2 configurations.
15
+
16
+ ### Fixed
17
+
18
+ - Support OpenCode v1 and v2 plugin loading conventions (named and default `tui`/`id` exports, snake_case and camelCase slot props, object model specs).
10
19
  ## [0.4.0] - 2026-09-30
11
20
 
12
21
  ### Added
@@ -137,7 +146,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
137
146
  - Options for `model`, `acceptKeys`, `maxChars`, `idleDelayMs`,
138
147
  `recentMessages` and `system`.
139
148
 
140
- [Unreleased]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.4.0...HEAD
149
+ [Unreleased]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.5.0...HEAD
150
+ [0.5.0]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.4.0...v0.5.0
141
151
  [0.4.0]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.3.1...v0.4.0
142
152
  [0.3.1]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.3.0...v0.3.1
143
153
  [0.3.0]: https://github.com/ozandogrultan/opencode-ghost/compare/v0.2.7...v0.3.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-ghost",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Claude Code-style next-prompt suggestions in the opencode TUI, shown as dimmed ghost text and accepted with Tab. An opencode plugin.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/text.ts CHANGED
@@ -1,7 +1,27 @@
1
1
  export function parseModel(
2
- spec: string | undefined,
2
+ spec: unknown,
3
3
  ): { providerID: string; modelID: string } | undefined {
4
4
  if (!spec) return undefined
5
+ if (typeof spec === "object" && spec !== null) {
6
+ const obj = spec as Record<string, unknown>
7
+ const providerID =
8
+ typeof obj.providerID === "string"
9
+ ? obj.providerID
10
+ : typeof obj.provider === "string"
11
+ ? obj.provider
12
+ : undefined
13
+ const modelID =
14
+ typeof obj.modelID === "string"
15
+ ? obj.modelID
16
+ : typeof obj.id === "string"
17
+ ? obj.id
18
+ : typeof obj.model === "string"
19
+ ? obj.model
20
+ : undefined
21
+ if (providerID && modelID) return { providerID, modelID }
22
+ return undefined
23
+ }
24
+ if (typeof spec !== "string") return undefined
5
25
  const index = spec.indexOf("/")
6
26
  if (index <= 0 || index === spec.length - 1) return undefined
7
27
  return { providerID: spec.slice(0, index), modelID: spec.slice(index + 1) }
package/src/tui.tsx CHANGED
@@ -562,10 +562,11 @@ const tui: TuiPlugin = async (api, rawOptions) => {
562
562
  } catch {
563
563
  // ignore
564
564
  }
565
+ const config = api.state.config as Record<string, unknown> | undefined
565
566
  return (
566
567
  parseModel(opts.model) ??
567
- parseModel(api.state.config.small_model) ??
568
- parseModel(api.state.config.model)
568
+ parseModel(config?.small_model ?? config?.smallModel) ??
569
+ parseModel(config?.model)
569
570
  )
570
571
  }
571
572
 
@@ -829,9 +830,10 @@ const tui: TuiPlugin = async (api, rawOptions) => {
829
830
  order: 60,
830
831
  slots: {
831
832
  session_prompt(_ctx, props) {
833
+ const sid = props.session_id ?? (props as any).sessionID
832
834
  const overlay = () => {
833
835
  const current = inBox()
834
- return current && current.sessionID === props.session_id ? current : undefined
836
+ return current && current.sessionID === sid ? current : undefined
835
837
  }
836
838
  return (
837
839
  <box
@@ -841,15 +843,16 @@ const tui: TuiPlugin = async (api, rawOptions) => {
841
843
  }}
842
844
  >
843
845
  <api.ui.Prompt
844
- sessionID={props.session_id}
846
+ sessionID={sid}
845
847
  visible={props.visible}
846
848
  disabled={props.disabled}
847
849
  showPlaceholder={false}
848
- right={<api.ui.Slot name="session_prompt_right" session_id={props.session_id} />}
850
+ right={<api.ui.Slot name="session_prompt_right" session_id={sid} />}
849
851
  onSubmit={() => {
850
852
  showGhost(undefined)
851
853
  setInBox(undefined)
852
854
  props.on_submit?.()
855
+ ;(props as any).onSubmit?.()
853
856
  }}
854
857
  ref={(ref) => {
855
858
  promptRef = ref
@@ -931,7 +934,6 @@ const tui: TuiPlugin = async (api, rawOptions) => {
931
934
  })
932
935
  }
933
936
 
934
- export default {
935
- id: "ghost",
936
- tui,
937
- }
937
+ export const id = "ghost"
938
+ export { tui }
939
+ export default Object.assign(tui, { id: "ghost", tui })