* feat(plugin): OpenCode Companion beta.8 upgrade + streaming/overflow fixes Upgrade to plugin API 21 and reverse the chat so the newest message sits at the bottom with auto-scroll: - panel: reverse message list to oldest-first; pin the scroll to the bottom via stickToBottom, jump there on open and session switch via scrollToBottomRev, and clear the stick flag in onScroll when the user scrolls away so reading history doesn't yank them down. - composer: enable submitOnEnter so Enter sends and Shift+Enter inserts a newline; update en/vi placeholder and send-tooltip strings. - panel: render assistant replies as markdown (headings, lists, tables), keeping user messages as plain labels. Fix runtime errors surfaced during use: - panel: pin markdown width to WRAP — ui.markdown has no maxWidth prop, so a bare flexGrow left it unconstrained and single-line text overflowed. - panel: wrap fenced code blocks in monospace labels with a maxWidth — noctalia's MarkdownView never wraps code, so long bash/code lines spilled outside the panel. Text outside code fences stays markdown. - panel: coerce onScroll(offset, maxOffset) args with tonumber — the reconciler passes them as strings, raising "attempt to compare number <= string". - service: handle message.part.updated / message.updated streaming via throttled reload; acknowledge message.part.delta without reloading (the server emits one per token, and reloading on each decodes the whole history and blows the async callback CPU budget in json.decode). - service: handle session.updated / session.diff with a throttled session reload so auto-generated titles stay current in the chooser. Verified with luac syntax checks and a standalone split_markdown test (5 cases) and JSON validation of the translation files. * update version to 0.2.0
165 lines
4.6 KiB
TOML
165 lines
4.6 KiB
TOML
id = "weinguyen/opencode-companion"
|
|
name = "OpenCode Companion"
|
|
version = "0.2.0"
|
|
plugin_api = 21
|
|
author = "weinguyen"
|
|
license = "MIT"
|
|
icon = "code-circle"
|
|
description = "Integrate OpenCode AI agent directly into Noctalia bar with native chat panel, session management, and MCP status."
|
|
tags = ["ai", "productivity", "development", "bar", "panel"]
|
|
dependencies = ["opencode"]
|
|
|
|
# ── User settings ─────────────────────────────────────────────────────────────
|
|
[[setting]]
|
|
key = "server_mode"
|
|
type = "string"
|
|
default = "auto"
|
|
label_key = "settings.server_mode.label"
|
|
description_key = "settings.server_mode.description"
|
|
|
|
[[setting]]
|
|
key = "server_host"
|
|
type = "string"
|
|
default = "127.0.0.1"
|
|
label_key = "settings.server_host.label"
|
|
description_key = "settings.server_host.description"
|
|
|
|
[[setting]]
|
|
key = "server_port"
|
|
type = "double"
|
|
default = 4096
|
|
label_key = "settings.server_port.label"
|
|
description_key = "settings.server_port.description"
|
|
|
|
[[setting]]
|
|
key = "server_url"
|
|
type = "string"
|
|
default = ""
|
|
label_key = "settings.server_url.label"
|
|
description_key = "settings.server_url.description"
|
|
|
|
[[setting]]
|
|
key = "default_workspace"
|
|
type = "folder"
|
|
default = ""
|
|
label_key = "settings.default_workspace.label"
|
|
description_key = "settings.default_workspace.description"
|
|
|
|
[[setting]]
|
|
key = "default_model"
|
|
type = "string"
|
|
default = ""
|
|
label_key = "settings.default_model.label"
|
|
description_key = "settings.default_model.description"
|
|
|
|
[[setting]]
|
|
key = "default_agent"
|
|
type = "string"
|
|
default = "build"
|
|
label_key = "settings.default_agent.label"
|
|
description_key = "settings.default_agent.description"
|
|
|
|
[[setting]]
|
|
key = "auto_start"
|
|
type = "bool"
|
|
default = true
|
|
label_key = "settings.auto_start.label"
|
|
description_key = "settings.auto_start.description"
|
|
|
|
[[setting]]
|
|
key = "show_tool_calls"
|
|
type = "bool"
|
|
default = true
|
|
label_key = "settings.show_tool_calls.label"
|
|
description_key = "settings.show_tool_calls.description"
|
|
|
|
[[setting]]
|
|
key = "show_reasoning"
|
|
type = "bool"
|
|
default = false
|
|
label_key = "settings.show_reasoning.label"
|
|
description_key = "settings.show_reasoning.description"
|
|
|
|
# Integer slider: 1..100 caps loaded history; the top notch (101) means
|
|
# "unlimited" (service.luau treats >= 101 as an effectively unbounded limit).
|
|
[[setting]]
|
|
key = "max_messages_load"
|
|
type = "int"
|
|
default = 50
|
|
min = 1
|
|
max = 101
|
|
label_key = "settings.max_messages_load.label"
|
|
description_key = "settings.max_messages_load.description"
|
|
|
|
[[setting]]
|
|
key = "language"
|
|
type = "select"
|
|
default = "auto"
|
|
label_key = "settings.language.label"
|
|
description_key = "settings.language.description"
|
|
options = [
|
|
{ value = "auto", label_key = "settings.language.options.auto" },
|
|
{ value = "en", label_key = "settings.language.options.en" },
|
|
{ value = "vi", label_key = "settings.language.options.vi" },
|
|
]
|
|
|
|
[[setting]]
|
|
key = "ui_mode"
|
|
type = "select"
|
|
default = "full"
|
|
label_key = "settings.ui_mode.label"
|
|
description_key = "settings.ui_mode.description"
|
|
options = [
|
|
{ value = "full", label_key = "settings.ui_mode.options.full" },
|
|
{ value = "compact", label_key = "settings.ui_mode.options.compact" },
|
|
]
|
|
|
|
[[setting]]
|
|
key = "debug_logging"
|
|
type = "bool"
|
|
default = false
|
|
label_key = "settings.debug_logging.label"
|
|
description_key = "settings.debug_logging.description"
|
|
|
|
# Panel layout the widget opens. "fill_right" = full-height side bar pinned to
|
|
# the right edge; "compact" = the original floating panel near the click. Both
|
|
# are manifest-hosted panel entries, since placement/position are host-owned and
|
|
# read at load time (a plugin can't move its own panel at runtime).
|
|
[[setting]]
|
|
key = "panel_mode"
|
|
type = "select"
|
|
default = "fill_right"
|
|
label_key = "settings.panel_mode.label"
|
|
description_key = "settings.panel_mode.description"
|
|
options = [
|
|
{ value = "fill_right", label_key = "settings.panel_mode.options.fill_right" },
|
|
{ value = "compact", label_key = "settings.panel_mode.options.compact" },
|
|
]
|
|
|
|
# ── Entries ───────────────────────────────────────────────────────────────────
|
|
[[widget]]
|
|
id = "widget"
|
|
entry = "widget.luau"
|
|
|
|
# Full-height side bar, pinned to the right edge.
|
|
[[panel]]
|
|
id = "panel-fill"
|
|
entry = "panel.luau"
|
|
placement = "floating"
|
|
position = "center_right"
|
|
width = 560
|
|
height = "fill"
|
|
|
|
# Original floating panel near the click point.
|
|
[[panel]]
|
|
id = "panel"
|
|
entry = "panel.luau"
|
|
open_near_click = true
|
|
placement = "floating"
|
|
width = 560
|
|
height = 720
|
|
|
|
[[service]]
|
|
id = "service"
|
|
entry = "service.luau"
|