canopus 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dac47b89af1ba7edf042a4fadccd34541f9d5911398fa083e503171df18fe387
4
- data.tar.gz: 659e1e6e40f34404ab9d31c8a106792051e8f255e7195b806189124b63d661a9
3
+ metadata.gz: 0cac04162944df2688afdf9c176a5fc0da5ae0d6bc624ea0435b83616ebcf57e
4
+ data.tar.gz: 95f7cc4d18be4aa3174d539096dc9365dd341ab94c339a3e236ec746f250c604
5
5
  SHA512:
6
- metadata.gz: b6a72df6cb9b0846584044cb6f480003f50452c170f54f14aff7b1a53b4801c2824d1acfb4e5f0a2e2e3d16a10631dad64e4f57be5d76ee3a9b567e83b0ecf34
7
- data.tar.gz: 2b447543c35849039cdf37b2a2bd78dbe10b57be8fee85468059c1bcb503ef8ce1fc9aace832d07c148d22dd0892f2931e6413ed67c54767ce20e341d525953c
6
+ metadata.gz: 81ebc4d784dace467207f064df0004978397b7364a320c4a6cdfba16668fa6b3770e22e967dc9fa774986fb6bff4eccc96fa6a0e7b0b051088c7294623d8b03d
7
+ data.tar.gz: 1e480cb252250bf58ab4c868c03ef1757b1db20d472c78814c467645e3a502478b5b4863b0a1842472b42aefb20847abfbe2b8c395aa72418600f34c2252176c
data/CHANGELOG.md CHANGED
@@ -2,58 +2,41 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Fix Windows terminal reads that could stop before the child process returned output.
6
+ - Complete the API v2 plugin host with declarative UI vocabulary, storage, external providers, and trust-aware operations.
7
+
8
+ ## 0.6.0 — 2026-09-19
9
+
10
+ - Add the Gienah-backed API v2 plugin host and declarative plugin panels.
11
+
5
12
  ## 0.5.0 — 2026-09-19
6
13
 
7
- - Configure automatic pairs and selection surrounding globally or per language without affecting paste, completion, or Vim insertion.
8
-
9
- - Add command-palette actions for cursors at every selected line start or end and selections for every regular-expression match.
10
-
11
- - Add rectangular Alt-drag selection and Ctrl-Alt-Up/Down cursor insertion across wrapped Unicode text.
12
-
13
- - Track shell commands and working directories through Tarazed OSC 133/7 integration, fold output, show exit status, and navigate command boundaries or failed commands.
14
- - Split the terminal panel horizontally or vertically, restore its layout and profiles, and inject editor integration variables.
15
- - Add `--wait` for blocking editor invocations such as `EDITOR="canopus --wait"`.
16
- - Periodically save bounded private snapshots of dirty buffers and offer valid crash recovery on the next startup.
17
- - Require Zaniah 0.5.2 so equal-position inline overlays preserve source order on every platform.
18
- - Delegate language-server protocol transport and lifecycle handling to Sadr.
19
- - Delegate terminal emulation and POSIX/Windows PTY handling to Tarazed; the editor UI is unchanged.
20
- - Delegate project walking and content search to Alkaid while retaining Canopus's search and replace UI.
21
- - Show language-server diagnostics as severity-colored wave underlines and optional line-end messages.
22
- - Collect LSP, task, and test diagnostics in one bounded registry with a filterable Problems panel and status counts.
23
- - Run opt-in formatting and configured source actions before saving without letting language-server failures block the write.
24
- - Route each language through ordered language servers, aggregate completion, diagnostics, and code actions, and restart individual servers.
25
- - Search symbols from every active routed language server with Cmd-T/Ctrl-T and fall back to bounded Alkaid project search.
26
- - Load bounded JSONC debug configurations, expand explicit launch variables, and resolve configured adapters.
27
- - Persist bounded conditional breakpoints with coalesced writes and keep their lines aligned through edits, undo, and redo.
28
- - Toggle breakpoints from the gutter and edit conditions, hit counts, log messages, and enabled state from its context menu.
29
- - Start Megrez-backed debug sessions, configure enabled breakpoints, and highlight safe workspace stop locations.
30
- - Browse stack frames, lazily expand fresh variable paths, reevaluate watches, and list breakpoints in the Debug panel.
31
- - Evaluate selected-frame REPL and hover expressions and show bounded, ordered adapter output in the Debug Console.
32
- - Run bounded JSONC project tasks through Tarazed PTYs in interactive, color-preserving Output tabs.
33
- - Publish bounded single-line, multi-line, and watch task problem matches through the shared diagnostics registry.
34
- - Keep regex-backed task diagnostics responsive on Ruby 3.1 with one deferred complete-line retry before fail-closed disabling.
35
- - Discover bounded Minitest and RSpec declarations with Alkaid and Prism and browse them in the Tests panel.
36
- - Run discovered tests from the gutter, display bounded results, and publish navigable failure diagnostics.
37
- - Preserve registration order for equal-priority decorations across Ruby versions and platforms.
38
- - Show cached, viewport-scoped language-server inlay hints inline with clickable label locations.
39
- - Show cached language-server code lenses above source lines and resolve them only when visible.
40
- - Highlight language-server read, write, and text occurrences for each visible editor caret.
41
- - Prefer language-server folding ranges with asynchronous Antares structure fallback.
42
- - Expand and shrink multiple selections from language-server ranges or asynchronous Antares structure data.
43
- - Validate rename targets asynchronously before opening the dialog when the language server supports preparation.
44
- - Underline and safely open language-server document links, resolving targets only when clicked.
45
- - Turn validated language-server linked ranges into multiple selections from the command palette, with a bounded HTML/XML tag fallback.
46
- - Browse call and type hierarchies in a lazily loaded side panel.
47
- - Color nested bracket pairs from Antares structure data and draw display-aware active indentation guides.
48
- - Render configurable space, tab, and ideographic-space markers without changing display coordinates.
49
- - Keep the active declaration chain visible with cached LSP symbols and an Antares fallback.
50
- - Navigate files and the cached declaration hierarchy from editor breadcrumbs.
51
- - Add an opt-in GUI minimap with shared, edit-aware line textures and Git, search, and diagnostic overview marks.
52
- - Route LSP, snippet, and extension completion through a bounded provider registry with stable fuzzy ranking.
53
- - Stage Git files, hunks, and lines and create or amend commits from the Source Control panel.
54
- - Compare Git changes and revisions inline or side by side, with word highlights and per-file history.
55
- - Resolve text merge regions in base/ours/theirs panes, stage the completed file atomically, and advance to the next conflict.
56
- - Browse and search bounded commit graphs, run cancellable authenticated remote transfers, and show cached inline blame on clean or edited buffers.
14
+ ### Editing and navigation
15
+
16
+ - Configure automatic pairs and selection surrounding globally or per language, and edit matching HTML/XML tags together when no language server provides linked ranges.
17
+ - Add rectangular selection, vertical cursor insertion, and multi-cursor commands for selected line starts, line ends, and regular-expression matches, including wrapped Unicode text.
18
+ - Add encoding detection, newline conversion, large-file handling, `.editorconfig` support, automatic save modes, persistent undo, and crash recovery.
19
+ - Add breadcrumbs, an optional minimap, whitespace markers, nested bracket colors, active indentation guides, and language-aware folding and selection expansion.
20
+ - Add inline diagnostics, inlay hints, code lenses, reference highlights, safe document links, rename preparation, and call/type hierarchies.
21
+
22
+ ### Language tooling and debugging
23
+
24
+ - Support multiple language servers with merged completion, diagnostics, code actions, workspace symbols, and restart recovery; collect results in a filterable Problems panel and run configured formatting or source actions before saving.
25
+ - Add JSONC debug configurations, persistent conditional breakpoints, debug sessions, stack and variable inspection, watches, REPL and hover evaluation, and a Debug Console.
26
+
27
+ ### Terminal, tasks, and tests
28
+
29
+ - Add shell integration for command boundaries, exit statuses, collapsible output, and working directories, plus split terminal layouts, profiles, and `--wait` for blocking editor invocations.
30
+ - Add interactive project tasks with problem matching in Output tabs, test discovery, and gutter-driven test execution with navigable failure diagnostics.
31
+
32
+ ### Git
33
+
34
+ - Add source-control staging for files, hunks, and lines; commit and amend support; rich diff and merge-conflict views; history and blame; and authenticated remote operations.
35
+
36
+ ### Settings, plugins, and distribution
37
+
38
+ - Add schema-driven settings editing and diagnostics, keymap presets, workspace trust, and a plugin registry with theme imports and sandboxed plugins.
39
+ - Add bundled Ruby to packages together with signed package verification, installers, and update feeds.
57
40
 
58
41
  ## 0.4.0 — 2026-09-15
59
42
 
data/README.md CHANGED
@@ -31,32 +31,14 @@ installable.
31
31
 
32
32
  ## Features
33
33
 
34
- - Native GPU windows on macOS, Linux, and Windows, plus TUI and headless modes
35
- - Persistent buffers, tabs, splits, sessions, and explicit save-conflict handling
36
- - LSP completion, diagnostics, hover, document and workspace symbols, formatting, prevalidated rename, and code actions
37
- - Bounded debug console output, stopped-frame REPL evaluation, and safe identifier hover evaluation
38
- - Filterable Problems tree for LSP, task, and test diagnostics, with error and warning status counts
39
- - Automatic read, write, and text highlights for the symbol at each visible editor's caret
40
- - Clickable LSP document links with on-demand resolution and safe HTTP or local-file navigation
41
- - LSP folding ranges with an asynchronous Antares fallback
42
- - LSP-aware selection expansion with an asynchronous Antares fallback
43
- - LSP linked-range selection for starting a multi-cursor edit from the command palette
44
- - Rectangular selection with Alt-drag and vertical cursor insertion
45
- - Multi-cursor expansion to selected line starts, line ends, or every regular-expression match
46
- - Lazy call and type hierarchy trees with bidirectional navigation
47
- - Menkar-based encoding detection, newline display and conversion, and encoding-aware saves
48
- - Ranked, extensible completion and inline-completion provider registry
49
- - Viewport-scoped LSP inlay hints with clickable label locations
50
- - Nested bracket colors and active indentation guides backed by Antares structure analysis
51
- - Optional GPU minimap with shared line textures, viewport navigation, and overview markers
52
- - Resizable integrated terminal with tabs, horizontal/vertical splits, profiles, scrollback, OSC 133 command history, colors, and clickable links
53
- - Bounded JSONC project tasks with color-preserving, interactive Output tabs
54
- - Git diff and staging, searchable commit graphs, cancellable fetch/pull/push, inline blame, and branch switching
55
- - Editable project-wide search results and safe project file operations
56
- - Optional Vim-compatible modes, motions, operators, registers, macros, and Ex commands
57
- - Layered JSONC settings, keymaps, themes, snippets, and trusted Ruby plugins
58
- - Overlay-aware wrapping and coordinates for inline hints and block decorations
59
- - Rendered panel and decoration nodes expose stable `test_id` conventions for UI tests
34
+ - Native GPU windows on macOS, Linux, and Windows, with TUI and headless modes
35
+ - Language-aware editing with LSP completion, diagnostics, code actions, navigation, and multiple language-server support
36
+ - Multi-cursor and rectangular editing, Vim bindings, linked editing, and encoding-aware file handling
37
+ - An integrated terminal with tabs, splits, profiles, shell integration, and `EDITOR="canopus --wait"` support
38
+ - An integrated Git workflow with diff, staging, commits, history, merge-conflict resolution, and remote operations
39
+ - Built-in debugging, interactive tasks, test discovery, and a filterable Problems panel
40
+ - Workspace persistence for tabs, splits, and sessions, plus automatic save, undo history, and crash recovery
41
+ - Extensible JSONC settings, keymaps, themes, and trusted plugins with permission controls and an optional OS sandbox
60
42
 
61
43
  ## Installation
62
44
 
@@ -148,157 +130,44 @@ Run `settings.open` from the command palette to edit project settings. User
148
130
  settings live at `$XDG_CONFIG_HOME/canopus/settings.jsonc` or
149
131
  `~/.config/canopus/settings.jsonc`.
150
132
 
151
- When enabled (the default), `.editorconfig` is read per file between user and
152
- project settings. `indent_style`, `indent_size`, `tab_width`,
153
- `trim_trailing_whitespace`, `insert_final_newline`, and `max_line_length` are
154
- supported. Set `editorconfig` to `false` to disable it. Project settings keep
155
- precedence over `.editorconfig`; malformed, oversized, or symlinked config
156
- files are ignored.
133
+ Settings are layered as defaults, user settings, project settings, explicit
134
+ `--settings` values, and language overrides. Invalid saved values leave the
135
+ previous valid settings active. `.editorconfig` is enabled by default between
136
+ user and project settings and supports the common indentation, whitespace,
137
+ final-newline, and line-length keys.
157
138
 
158
139
  ```jsonc
159
140
  {
160
141
  "theme": "auto",
161
142
  "font_size": 14,
162
143
  "vim_mode": false,
163
- "use_tabs": false,
164
- "auto_pairs": [["(", ")"], ["[", "]"], ["{", "}"], ["\"", "\""], ["'", "'"]],
165
- "diagnostics": { "inline": true, "inline_max_length": 80, "severity": "warning" },
166
- "inlay_hints": { "enabled": true, "parameter_names": true, "types": true, "max_length": 30 },
167
- "code_lens": { "enabled": true },
168
- "bracket_colorization": true,
169
- "indent_guides": { "enabled": true, "active": true },
170
- "render_whitespace": "boundary",
171
- "render_ideographic_space": true,
172
- "sticky_scroll": { "enabled": true, "max_lines": 5 },
173
- "breadcrumbs": { "enabled": true },
174
- "minimap": { "enabled": false, "width": 100, "show_diagnostics": true },
175
144
  "auto_save": "off",
176
- "auto_save_delay": 1000,
177
- "persistent_undo": { "enabled": true, "max_entries": 1000, "expire_days": 30 },
178
145
  "format_on_save": false,
179
- "code_actions_on_save": [],
180
- "format_on_save_timeout": 2000,
181
- "git": { "inline_blame": "off", "autofetch": false, "autofetch_interval": 180 },
182
- "recovery": { "enabled": true, "interval": 5000 },
183
- "tabs": { "activate_on_close": "history", "reopen_history_limit": 20 },
184
- "terminal": {
185
- "working_directory": "project", "scrollback_lines": 10000, "shell_integration": true,
186
- "profiles": { "bash": { "path": "/bin/bash", "args": ["--login"], "env": { "TERM_PROGRAM": "canopus" } } },
187
- "default_profile": "bash"
188
- },
189
- "dock": {
190
- "bottom": { "size": 280, "visible": false },
191
- "panels": { "terminal": { "size": 280, "visible": false } }
192
- },
193
- "keymap": [
194
- { "context": "Editor && !vim_mode", "bindings": { "ctrl-k ctrl-s": "file.save" } }
195
- ],
146
+ "terminal": { "shell_integration": true },
196
147
  "languages": { "ruby": { "tab_size": 2, "auto_pairs": [] } },
197
148
  "language_servers": {
198
149
  "ruby": [
199
150
  { "command": ["ruby-lsp"], "features": ["completion", "definition", "hover", "formatting"] },
200
151
  { "command": ["rubocop", "--lsp"], "features": ["diagnostics", "codeAction"] }
201
152
  ]
202
- },
203
- "debug_adapters": {
204
- "ruby": { "command": ["rdbg", "--open", "--stop-at-load"], "transport": "tcp" }
205
153
  }
206
154
  }
207
155
  ```
208
156
 
209
- A legacy argument array such as `"ruby": ["ruby-lsp"]` still configures one
210
- server. With multiple servers, completion, diagnostics, and code actions are
211
- merged; workspace symbols are collected from every matching active server;
212
- other features use the first matching server in configuration order. Workspace
213
- symbol search falls back to bounded project-content search when no usable
214
- provider is active. Override `language.workspace_symbols` in `keymap` to change
215
- its Cmd-T / Ctrl-T binding.
216
-
217
- `render_whitespace` accepts `none`, `boundary`, `selection`, or `all`.
218
- `boundary` hides only single spaces between non-whitespace characters. Tabs use
219
- `→`, spaces use `·`, and ideographic spaces use `□`; the last remains visible
220
- independently when `render_ideographic_space` is enabled.
221
-
222
- `auto_pairs` replaces the opener/closer list for the current settings layer;
223
- set it to `[]` globally or for one language to disable automatic pairing and
224
- selection surrounding. Each opener and closer must be one Unicode grapheme.
225
-
226
- Sticky scroll keeps the declarations containing the first visible source byte
227
- above the editor body. It prefers cached LSP document symbols and falls back to
228
- cached Antares structure regions; `sticky_scroll.enabled` and
229
- `sticky_scroll.max_lines` can also be overridden per language.
230
-
231
- Breadcrumbs show the project-relative file, containing type, and callable above
232
- sticky scroll. Selecting an item opens its same-directory files or same-parent
233
- symbols in the palette. `breadcrumbs.enabled` can be overridden per language.
234
-
235
- The GUI-only minimap is disabled by default. When enabled, it reserves its
236
- configured width only in panes wide enough to keep the editor usable, reuses
237
- bounded low-resolution line textures across splits, and shows Git, search, and
238
- optionally diagnostic overview marks. Click or drag it to center that source
239
- position without moving the selection. All minimap options can be overridden
240
- per language.
241
-
242
- Closing a dirty tab asks whether to save, discard, or cancel. Reopening restores
243
- the file, selections, position, and pane while Canopus is running; discarded
244
- unsaved changes are never restored. Dock and panel visibility and sizes are also
245
- restored. Terminal session restoration, when enabled,
246
- starts fresh shells with the saved tab count and working directories and does
247
- not restore processes or scrollback.
248
-
249
- Dirty buffers are also written every five seconds to private, atomically
250
- replaced files under `.canopus/recovery/`. After an abnormal exit, the newest
251
- valid snapshot is offered at startup; normal exit removes this run's snapshot.
252
- Set `recovery.enabled` to `false` or change `recovery.interval` (milliseconds)
253
- in settings. Recovery files contain local unsaved text, so disable the feature
254
- for workspaces where even a mode-0600 local copy is unacceptable. Individual
255
- buffers over 10 MiB and snapshots over 64 MiB are not retained.
256
-
257
- Set `auto_save` to `after_delay` to save dirty named files after the debounce
258
- interval in `auto_save_delay` milliseconds, or to `on_focus_change` to save a
259
- file when switching away from it. Untitled, read-only, and conflicting files
260
- are skipped or reported without forcing a write.
261
-
262
- Persistent undo keeps up to `persistent_undo.max_entries` undo entries for
263
- clean regular files under `.canopus/undo/`. Records are project- and file
264
- identity-bound, expire after `expire_days`, and are ignored when corrupt or
265
- when the file changes. Dirty buffers remain in recovery storage instead.
266
-
267
- Settings are layered from defaults through user, project, explicit `--settings`,
268
- and language overrides. Invalid saved settings leave the previous valid values
269
- active. Keymap groups extend defaults; later matching bindings win, and `null`
270
- removes a default binding.
271
-
272
- Language servers are separate programs and are auto-detected or configured by
273
- argument array. See [Language servers](docs/lsp.md) for configuration and
274
- restart behavior.
275
-
276
- Debug launch definitions and the persistent, edit-aware breakpoint gutter
277
- are described in [Debug configurations](docs/debugging.md). `debug.start`
278
- selects and starts a configuration, and `debug.stop` ends the active session.
279
- When execution stops, the Debug panel provides safe stack navigation, lazy
280
- variables, per-stop watch evaluation (`debug.watch.add` /
281
- `debug.watch.remove`), and the breakpoint list. Variable expansion is restored
282
- by name path rather than adapter reference IDs.
283
- `debug.console.evaluate` accepts REPL input for the selected frame and
284
- `panel.debug_console` toggles ordered adapter output. Hovering a simple
285
- local, instance, class, or global variable while stopped evaluates it in the
286
- selected frame.
287
- Breakpoint files use an atomic rename
288
- for normal same-user workspace consistency; concurrent malicious workspace
289
- mutation is outside that guarantee.
290
-
291
- Project task definitions, variables, Output tabs, and reveal behavior are
292
- described in [Tasks](docs/tasks.md). `task.run` opens the task picker,
293
- `task.stop` stops the selected running Output tab, and `panel.output` toggles
294
- the panel. Single-line, multi-line, and watch problem matchers publish task
295
- output into the shared Problems panel and editor diagnostics.
296
-
297
- The [Test explorer](docs/testing.md) discovers Minitest and RSpec declarations
298
- with a bounded Alkaid walk and Prism AST inspection. `panel.test` opens the
299
- tree and `test.refresh` rescans it. Gutter buttons run static tests in bounded
300
- Task Output tabs and show running, passed, failed, or skipped state; selecting
301
- a failed test opens its reported failure line.
157
+ The example shows the settings most people change first. Use `auto_pairs`,
158
+ `render_whitespace`, `inlay_hints`, `code_lens`, `minimap`, `breadcrumbs`,
159
+ `persistent_undo`, `recovery`, `terminal.profiles`, `keymap`, and per-language
160
+ overrides for more control. Set `auto_pairs` to `[]` to disable automatic
161
+ pairing for a language.
162
+
163
+ Language servers can be configured with one command array or multiple server
164
+ entries. Completion, diagnostics, and code actions are merged across matching
165
+ servers; workspace symbols use all of them, while other capabilities use the
166
+ first matching server. See [Language servers](docs/lsp.md).
167
+
168
+ Debugging, tasks, and test discovery have dedicated guides:
169
+ [Debug configurations](docs/debugging.md), [Tasks](docs/tasks.md), and
170
+ [Test explorer](docs/testing.md).
302
171
 
303
172
  Plugins require explicit trust and permissions:
304
173
 
@@ -312,6 +181,9 @@ The default separate process also requests Saiph's OS sandbox. Set
312
181
  supported backend, or to `"off"` to retain the legacy process-only isolation.
313
182
  The legacy `process` permission is accepted as an alias for `exec`.
314
183
 
184
+ Manifest-based isolated plugins use the Gienah host and declarative Zaniah UI;
185
+ see [Plugins](docs/plugins.md).
186
+
315
187
  ## Documentation
316
188
 
317
189
  - [Language servers](docs/lsp.md)
@@ -320,6 +192,7 @@ The legacy `process` permission is accepted as an alias for `exec`.
320
192
  - [Vim mode](docs/vim.md)
321
193
  - [Snippets](docs/snippets.md)
322
194
  - [Completion providers](docs/providers.md)
195
+ - [Plugins](docs/plugins.md)
323
196
  - [Workspace edits](docs/workspace_edits.md)
324
197
  - [Packaging](docs/distribution.md)
325
198
  - [Profiling and local crash reports](docs/performance.md)
data/docs/plugins.md ADDED
@@ -0,0 +1,62 @@
1
+ # Plugins
2
+
3
+ Canopus supports two plugin APIs. Existing Ruby plugins use `Workspace#plugins`
4
+ and remain available for compatibility. New plugins use the isolated Gienah
5
+ host and a `plugin.json` manifest.
6
+
7
+ ```json
8
+ {
9
+ "id": "word-count",
10
+ "name": "Word Count",
11
+ "version": "0.1.0",
12
+ "api_version": 2,
13
+ "entry": "plugin.rb",
14
+ "activation": ["onCommand:word-count.refresh"],
15
+ "capabilities": ["buffer.read", "ui.panel"],
16
+ "contributes": {
17
+ "commands": [{"id": "word-count.refresh", "title": "Refresh word count"}],
18
+ "panels": [{"id": "word-count", "title": "Word Count", "dock": "right"}]
19
+ }
20
+ }
21
+ ```
22
+
23
+ The host discovers manifests without starting processes. A workspace must be
24
+ trusted before a manifest is activated. Capabilities are denied by default;
25
+ `process.exec`, filesystem, and network access additionally require Saiph.
26
+
27
+ Plugin entrypoints use Gienah's SDK and communicate with Canopus through the
28
+ declared host methods:
29
+
30
+ ```ruby
31
+ require "gienah"
32
+
33
+ Gienah::Plugin.on("ui/event") { |event| Gienah::Plugin.call("workspace/notify", "text" => event["id"]) }
34
+ Gienah::Plugin.export("word-count.refresh") do
35
+ text = Gienah::Plugin.call("buffer/text")
36
+ Gienah::Plugin.call("ui/render", "panel" => "word-count", "tree" => {
37
+ "type" => "text", "props" => {"value" => "#{text.split.size} words"}, "children" => []
38
+ })
39
+ nil
40
+ end
41
+ Gienah::Plugin.run
42
+ ```
43
+
44
+ Panels use the allow-listed declarative vocabulary (`column`, `row`, `spacer`,
45
+ `scroll`, `divider`, `text`, `icon`, `badge`, `progress`, `code`, `button`,
46
+ `checkbox`, `text_field`, `select`, `list`, `tree`, and `section`). Raw colors,
47
+ images, fonts, and coordinates are not accepted. UI rendering is cached in the
48
+ editor, so a slow plugin cannot block a frame. Completion providers have a
49
+ 200 ms response budget.
50
+
51
+ The host also exposes `storage/get`, `storage/set`, `process/exec`,
52
+ `net/fetch`, `ui/status`, `ui/quick_pick`, `ui/input`, and `ui/confirm`.
53
+ Storage is scoped to the workspace and plugin ID. Network requests must match
54
+ the manifest's `net:` host pattern, and dangerous operations remain gated by
55
+ the manifest capability and workspace trust.
56
+
57
+ `buffer/text` limits an unbounded request to 1 MiB; larger documents must be
58
+ read with a byte range. Calling `buffer/subscribe` with the active buffer URI
59
+ starts diff notifications for that plugin only. The host sends
60
+ `buffer/didChange`, `buffer/didOpen`, `buffer/didSave`, `buffer/didClose`, and
61
+ throttled `selection/didChange` notifications for the subscribed buffer, plus
62
+ `workspace/didChangeFiles` and `settings/didChange` to subscribed plugins.
@@ -123,7 +123,7 @@ module Canopus
123
123
  unless item.row.nil? || (item.row.is_a?(Integer) && item.row >= 0)
124
124
  raise ArgumentError, "decoration row must be nonnegative"
125
125
  end
126
- unless item.range.nil? || (item.range.is_a?(Range) && item.range.begin.is_a?(Integer) && item.range.end.is_a?(Integer))
126
+ unless item.range.nil? || (item.range.is_a?(Range) && item.range.begin.is_a?(Integer) && item.range.end.is_a?(Integer) && item.range.begin >= 0 && item.range.end >= item.range.begin)
127
127
  raise ArgumentError, "decoration range must contain integer offsets"
128
128
  end
129
129
  raise ArgumentError, "decoration click handler must be callable" unless item.on_click.nil? || item.on_click.respond_to?(:call)
@@ -15,7 +15,11 @@ module Canopus
15
15
  end
16
16
  def text
17
17
  permit!("read_buffer")
18
- @workspace.editor.buffer.text.dup.freeze
18
+ buffer = @workspace.editor&.buffer
19
+ raise Canopus::Error, "buffer is not available" unless buffer
20
+ raise Canopus::Error, "plugin buffer text exceeds 1 MiB" if buffer.rope.bytesize > Plugins::BUFFER_CONTEXT_LIMIT
21
+
22
+ buffer.text.dup.freeze
19
23
  end
20
24
  def replace(range, text)
21
25
  permit!("edit_buffer")