PluginsEarly
Limits
The time, size and count limits every plugin runs inside.
From the plugin interface of gr 0.2.16 (API 0.1, 0.2, 0.3). gr plugin api limits prints it on your machine.
Past a soft limit a plugin gets a warning; past the hard limit the call fails or the handler is stopped. The time budgets and memory can be raised for one plugin up to the cap, by its plugin.toml's [limits] or by the person with gr plugin config --limit.
Time
| Budget | Covers | Soft | Hard | Cap |
|---|---|---|---|---|
load | transform, compile, run the top level | 250 ms | 1,000 ms | 2,000 ms |
unload | the unload handler | 100 ms | ||
handler | command, act, pick | 16 ms | 500 ms | 2,000 ms |
view | a view's tree | 16 ms | 250 ms | 1,000 ms |
rows | rows and picker entries; soft is the first answer | 200 ms | 2,000 ms | 5,000 ms |
background | events, timers and promise continuations, a slice each | 50 ms | 500 ms | 2,000 ms |
Size and count
| Limit | Covers | Hard | Cap |
|---|---|---|---|
calls_per_event | calls back per event: a warning at soft, calls.over at hard Warns at 50. | 1,000 | |
calls_in_flight | calls an instance has in the daemon at once; the host holds the rest | 16 | |
exec_at_once | exec.run running at once, a plugin | 2 | |
fetch_at_once | net.fetch running at once, a plugin | 4 | |
memory_mb | a plugin's host process, sampled every 100 ms on Linux while it runs code and every second at rest | 256 MB | 1024 MB |
builtin_alloc_mb | one allocation by a built-in (repeat, padStart, typed arrays, JSON.parse); over it throws script.size | 64 MB | |
store_bytes | $.store, a plugin | 1 MB | |
state_bytes | $.state, an instance | 4 MB | |
message_bytes | one message on the host's pipes, encoded; over it the call fails result.too_large | 8 MB | |
fs_read_bytes | fs.read, unless maxBytes says more Warns at 1 MB. | 4 MB | |
exec_ms | an exec.run | 30,000 ms | |
exec_output_bytes | an exec.run's output each way, after encoding (control bytes count six times) | 1 MB | |
exec_memory_mb | an exec.run's program | 1024 MB | |
fetch_ms | a net.fetch | 30,000 ms | |
fetch_body_bytes | a net.fetch's body | 5 MB | |
fetch_redirects | a net.fetch's redirects, each checked again | 5 | |
timer_interval_ms | the least interval of a timer Warns at 100 ms. | ||
timers | live timers, a plugin | 64 | |
idle_unload_ms | an instance with nothing visible, subscribed or timed | 600,000 ms | |
hold_ms | keys typed after a key bound to plugin code are held this long at most ([gred] plugins_hold_ms, 0 to 500) Warns at 100 ms. | 500 ms | |
picker_entries | a picker's entries, and when live Warns at 500. | 10,000 | |
badge_set_nodes | nodes in one badge set | 100,000 | |
agent_sends | agents.send a plugin makes in a minute | 20 | |
agent_starts | agents a plugin starts in ten minutes; only the person raises it, in [plugins.<name>.limits] agent_starts | 3 | 30 |
agent_text_bytes | the text of one agents.send, one agents.start's prompt, or one attach of text, which holds no control character but newlines and tabs | 64 KB | |
transcript_blocks | the blocks one agents.transcript answers; soft when limit is not said Warns at 100. | 1,000 | |
transcript_block_bytes | the text of one block of a transcript; longer is cut | 4 KB | |
transcript_bytes | the text of one agents.transcript's answer; the oldest blocks past it are left out | 256 KB | |
clipboard_bytes | the text of one clipboard.write | 1 MB | |
terminals | terminals a plugin has open at once | 4 | |
edits | the edits of one edit command | 1,000 | |
edit_bytes | the text one edit command inserts | 1 MB | |
docs_lines | the lines one docs.lines answers | 5,000 | |
document_changes_bytes | the text the changes of one document.changed carry; past it they are left out | 64 KB | |
menus | the [[menus]] entries one manifest adds to the menu at one place; past it the manifest is refused (contribution.value) | 8 | |
tools | the tools one manifest offers agents | 16 | |
tool_description_chars | a tool's description, what an agent reads to decide to call it, and each of its properties' descriptions | 1,000 | |
tool_properties | the properties of a tool's [tools.input] | 32 | |
tool_input_bytes | the input of one tool call, as JSON | 1 MB | |
tool_answer_bytes | what one tool call answers: its text, or its json as encoded; over it the call fails result.too_large | 64 KB | |
tool_wait_ms | how long an agent's tool call waits for its answer, the plugin's loading included; past it the call fails tool.timeout and a late answer is dropped | 30,000 ms | |
mcp_servers | the MCP servers one manifest names in [[mcp]] | 4 | |
mcp_tools | the tools one MCP server offers agents; those it lists past it are left out, and the plugin's log says so | 64 | |
mcp_memory_mb | an MCP server's process tree, sampled as a host's is; past it the server is stopped and off for the session. Only the person raises it, in [plugins.<name>.limits] mcp_memory_mb | 512 MB | 4096 MB |
mcp_idle_ms | an MCP server with no call for this long stops; its tools stay offered, and the next call starts it again | 600,000 ms | |
mcp_start_ms | an MCP server's start, from its process to its tools listed; past it the start fails mcp.unavailable | 60,000 ms | |
agent_kinds | the agent kinds one manifest adds in [[agents]]. An agent kind is an ACP agent the plugin names, which a person may start beside Claude Code and Codex: [[agents]] id = "<plugin>.<name>" (in the plugin's one set of ids, and the harness name its agents carry), title (at most 40 characters, never what one of Graphide's own agents is called), command (a program [allow] exec names, its path recorded at approval), args, and probe (the program whose presence on the PATH agents start with says the agent is installed, when that is not the command; never run). It is offered only while the plugin is approved and switched on with exec:<command> granted, and it runs that path as Graphide's own ACP agents run: as the person, in the workspace, outside the sandbox, with what agents may do there. A plugin switched off or removed takes its kind out of the list; an agent of it already running keeps running | 4 | |
mentions | the mention sources one manifest adds to the composer's @ in [[mentions]] | 8 | |
mention_entries | the entries one mention's answer shows; past it the first are kept and the plugin's log says so | 50 | |
decoration_marks | the marks one set holds on one document | 10,000 | |
decoration_bytes | the text of one set's marks on one document, their details and commands included | 256 KB | |
decorations_root_marks | the marks every plugin's sets hold on the documents of one root, and in one window | 200,000 | |
decoration_detail_bytes | a mark's detail; longer is cut | 1 KB | |
queries | the [[queries]] one manifest declares: tree-sitter queries whose matches the editor marks itself, with no script | 16 | |
query_bytes | one query's .scm file | 64 KB | |
context_keys | the context keys a plugin may have set at once | 64 | |
context_value_bytes | a context key's string value | 256 bytes | |
layers | the key layers one manifest declares | 16 | |
layer_keys | the keys one key layer binds | 64 | |
layer_title_chars | a key layer's title, the words of the mode pill while it is on | 12 | |
layer_args_bytes | a layer.enter's args, as JSON | 4 KB | |
graph_write_ids | ids in one graph.move or graph.remove call, before duplicates are removed | 1,000 | |
graph_writes | graph write calls in one second per plugin, across every instance and root | 10 | |
lsp_diagnostics | the diagnostics one lsp.diagnostics answers; past it the least severe are left out | 1,000 | |
lsp_message_bytes | a diagnostic's message; longer is cut | 2 KB | |
lsp_symbols | the symbols one lsp.symbols answers, children counted; past it the rest are left out | 5,000 | |
lsp_paths | the paths one lsp.diagnostics event names; when more changed it names none | 1,000 | |
languages | the [[languages]] one manifest declares. A language pack is data: [[languages]] id (the language's own id, as editors and language servers name it: zig), name, extensions (without the dot), filenames (whole names), shebangs (the programs a #! line names), grammar (a tree-sitter grammar compiled to WebAssembly, a .wasm file of the folder named after the grammar, so zig.wasm exports tree_sitter_zig), [languages.queries] highlights, injections, locals, folds and indents (.scm files of the folder, in tree-sitter's query language, highlights capturing by the usual names, keyword, string, function.call, a dotted name painting as its parent), comment = { line = "//", block = ["/*", "*/"] }, brackets = [["(", ")"], ...], and [languages.server] command (a program [allow] exec names), args and settings (what answers the server's workspace/configuration, under the person's own [lsp.servers.<plugin>.<id>.settings]). The editor knows the language's files by extension, name and #! line, and colours, comments and matches brackets with it; it runs the grammar in WebAssembly, confined. the daemon runs the server for the workspaces the person trusts, as it runs the built-in ones, after the person's [lsp] and before the built-in table: approving the pack approves its server. A language the editor links (go, rust, ...) keeps its own grammar; a pack may still add its server | 16 | |
language_query_bytes | one of a language's .scm query files | 1 MB | |
pack_bytes | a language pack's folder, a plugin with [[languages]], for its grammars; another plugin's folder holds at most 2 MiB (manifest.size) | 16 MB | |
pack_files | the files of a language pack's folder; another plugin's holds at most 200 (manifest.size) | 400 |
Views and data
A view or value larger than these is refused whole.
elements | 5,000 |
text_bytes | 256 KB |
depth | 32 |
json_bytes | 1 MB |
list_items | 1,000 |
key_bytes | 128 bytes |
markdown_bytes | 64 KB |
tag_chars | 24 |
code_bytes | 64 KB |
These docs describe Graphide 0.2.16, the latest release. Something wrong or missing? Tell us onDiscord or at hello@graphide.com.