# Fen core API

Generated from Fennel sources. Each module section lists exported
public functions and documented data values in source order. Items
with an inline `;; @doc` block include their summary and signature;
undocumented functions show their name only. Undocumented data/state
re-exports are folded into an omitted note per module.

Run `make docs` to regenerate.

## Table of contents

- [fen.core.agent](#fen-core-agent)
- [fen.core.diagnostics](#fen-core-diagnostics)
- [fen.core.docs.contracts](#fen-core-docs-contracts)
- [fen.core.extensions.events](#fen-core-extensions-events)
- [fen.core.extensions.loader](#fen-core-extensions-loader)
- [fen.core.extensions.loader.discover](#fen-core-extensions-loader-discover)
- [fen.core.extensions.loader.manifest](#fen-core-extensions-loader-manifest)
- [fen.core.extensions.loader.reload](#fen-core-extensions-loader-reload)
- [fen.core.extensions.register](#fen-core-extensions-register)
- [fen.core.extensions.register.auth_backend](#fen-core-extensions-register-auth-backend)
- [fen.core.extensions.register.command](#fen-core-extensions-register-command)
- [fen.core.extensions.register.control](#fen-core-extensions-register-control)
- [fen.core.extensions.register.hook](#fen-core-extensions-register-hook)
- [fen.core.extensions.register.introspect](#fen-core-extensions-register-introspect)
- [fen.core.extensions.register.panel](#fen-core-extensions-register-panel)
- [fen.core.extensions.register.presenter](#fen-core-extensions-register-presenter)
- [fen.core.extensions.register.prompt](#fen-core-extensions-register-prompt)
- [fen.core.extensions.register.provider](#fen-core-extensions-register-provider)
- [fen.core.extensions.register.session_backend](#fen-core-extensions-register-session-backend)
- [fen.core.extensions.register.status](#fen-core-extensions-register-status)
- [fen.core.extensions.register.tool](#fen-core-extensions-register-tool)
- [fen.core.extensions.rocks](#fen-core-extensions-rocks)
- [fen.core.extensions.state](#fen-core-extensions-state)
- [fen.core.extensions.test_api](#fen-core-extensions-test-api)
- [fen.core.extensions.util](#fen-core-extensions-util)
- [fen.core.llm](#fen-core-llm)
- [fen.core.llm.event_stream](#fen-core-llm-event-stream)
- [fen.core.llm.models](#fen-core-llm-models)
- [fen.core.llm.retry](#fen-core-llm-retry)
- [fen.core.prompt](#fen-core-prompt)
- [fen.core.settings](#fen-core-settings)
- [fen.core.thinking](#fen-core-thinking)
- [fen.core.tools](#fen-core-tools)
- [fen.core.types](#fen-core-types)
- [fen.extensions.agent_state](#fen-extensions-agent-state)
- [fen.extensions.agent_state.tool](#fen-extensions-agent-state-tool)
- [fen.extensions.builtin_tools](#fen-extensions-builtin-tools)
- [fen.extensions.builtin_tools.bash](#fen-extensions-builtin-tools-bash)
- [fen.extensions.builtin_tools.edit](#fen-extensions-builtin-tools-edit)
- [fen.extensions.builtin_tools.find](#fen-extensions-builtin-tools-find)
- [fen.extensions.builtin_tools.grep](#fen-extensions-builtin-tools-grep)
- [fen.extensions.builtin_tools.ls](#fen-extensions-builtin-tools-ls)
- [fen.extensions.builtin_tools.read](#fen-extensions-builtin-tools-read)
- [fen.extensions.builtin_tools.registry](#fen-extensions-builtin-tools-registry)
- [fen.extensions.builtin_tools.truncate](#fen-extensions-builtin-tools-truncate)
- [fen.extensions.builtin_tools.util](#fen-extensions-builtin-tools-util)
- [fen.extensions.builtin_tools.write](#fen-extensions-builtin-tools-write)
- [fen.extensions.compact](#fen-extensions-compact)
- [fen.extensions.default_prompt](#fen-extensions-default-prompt)
- [fen.extensions.default_prompt.resources](#fen-extensions-default-prompt-resources)
- [fen.extensions.docs](#fen-extensions-docs)
- [fen.extensions.docs.state](#fen-extensions-docs-state)
- [fen.extensions.essentials](#fen-extensions-essentials)
- [fen.extensions.essentials.commands.help](#fen-extensions-essentials-commands-help)
- [fen.extensions.essentials.commands.model](#fen-extensions-essentials-commands-model)
- [fen.extensions.essentials.commands.thinking](#fen-extensions-essentials-commands-thinking)
- [fen.extensions.extensions_inspector](#fen-extensions-extensions-inspector)
- [fen.extensions.extensions_inspector.commands.extension](#fen-extensions-extensions-inspector-commands-extension)
- [fen.extensions.extensions_inspector.state.extensions](#fen-extensions-extensions-inspector-state-extensions)
- [fen.extensions.extensions_inspector.util](#fen-extensions-extensions-inspector-util)
- [fen.extensions.handoff](#fen-extensions-handoff)
- [fen.extensions.mem](#fen-extensions-mem)
- [fen.extensions.mem.state](#fen-extensions-mem-state)
- [fen.extensions.print](#fen-extensions-print)
- [fen.extensions.prompt](#fen-extensions-prompt)
- [fen.extensions.prompt.commands.prompt](#fen-extensions-prompt-commands-prompt)
- [fen.extensions.prompt.state.prompt](#fen-extensions-prompt-state-prompt)
- [fen.extensions.provider_anthropic](#fen-extensions-provider-anthropic)
- [fen.extensions.provider_anthropic.anthropic_messages](#fen-extensions-provider-anthropic-anthropic-messages)
- [fen.extensions.provider_openai](#fen-extensions-provider-openai)
- [fen.extensions.provider_openai.openai_codex_keychain](#fen-extensions-provider-openai-openai-codex-keychain)
- [fen.extensions.provider_openai.openai_codex_login](#fen-extensions-provider-openai-openai-codex-login)
- [fen.extensions.provider_openai.openai_codex_oauth](#fen-extensions-provider-openai-openai-codex-oauth)
- [fen.extensions.provider_openai.openai_codex_responses](#fen-extensions-provider-openai-openai-codex-responses)
- [fen.extensions.provider_openai.openai_completions](#fen-extensions-provider-openai-openai-completions)
- [fen.extensions.provider_openai.openai_responses](#fen-extensions-provider-openai-openai-responses)
- [fen.extensions.provider_openai.openai_responses_shared](#fen-extensions-provider-openai-openai-responses-shared)
- [fen.extensions.queue](#fen-extensions-queue)
- [fen.extensions.queue.commands.queue](#fen-extensions-queue-commands-queue)
- [fen.extensions.queue.state.queue](#fen-extensions-queue-state-queue)
- [fen.extensions.queue.util](#fen-extensions-queue-util)
- [fen.extensions.session_jsonl](#fen-extensions-session-jsonl)
- [fen.extensions.session_jsonl.session](#fen-extensions-session-jsonl-session)
- [fen.extensions.session_jsonl.state](#fen-extensions-session-jsonl-state)
- [fen.extensions.sessions](#fen-extensions-sessions)
- [fen.extensions.sessions.commands.session](#fen-extensions-sessions-commands-session)
- [fen.extensions.skills](#fen-extensions-skills)
- [fen.extensions.skills.bundled](#fen-extensions-skills-bundled)
- [fen.extensions.skills.ignore](#fen-extensions-skills-ignore)
- [fen.extensions.skills.state](#fen-extensions-skills-state)
- [fen.extensions.status](#fen-extensions-status)
- [fen.extensions.status.commands.status](#fen-extensions-status-commands-status)
- [fen.extensions.status.state.status](#fen-extensions-status-state-status)
- [fen.extensions.status.util](#fen-extensions-status-util)
- [fen.extensions.stdio](#fen-extensions-stdio)
- [fen.extensions.todo](#fen-extensions-todo)
- [fen.extensions.todo.state](#fen-extensions-todo-state)
- [fen.extensions.tui](#fen-extensions-tui)
- [fen.extensions.tui.draw](#fen-extensions-tui-draw)
- [fen.extensions.tui.ingest](#fen-extensions-tui-ingest)
- [fen.extensions.tui.input](#fen-extensions-tui-input)
- [fen.extensions.tui.markdown](#fen-extensions-tui-markdown)
- [fen.extensions.tui.paint](#fen-extensions-tui-paint)
- [fen.extensions.tui.panels.busy](#fen-extensions-tui-panels-busy)
- [fen.extensions.tui.panels.errors](#fen-extensions-tui-panels-errors)
- [fen.extensions.tui.panels.status](#fen-extensions-tui-panels-status)
- [fen.extensions.tui.panels.transcript](#fen-extensions-tui-panels-transcript)
- [fen.extensions.tui.redraw](#fen-extensions-tui-redraw)
- [fen.extensions.tui.select](#fen-extensions-tui-select)
- [fen.extensions.tui.state](#fen-extensions-tui-state)
- [fen.extensions.web](#fen-extensions-web)
- [fen.extensions.web.ingest](#fen-extensions-web-ingest)
- [fen.extensions.web.layout](#fen-extensions-web-layout)
- [fen.extensions.web.page](#fen-extensions-web-page)
- [fen.extensions.web.server](#fen-extensions-web-server)
- [fen.extensions.web.state](#fen-extensions-web-state)
- [fen.provider_help](#fen-provider-help)
- [fen.script_runner](#fen-script-runner)
- [fen.testing](#fen-testing)
- [fen.testing.macros](#fen-testing-macros)
- [fen.testing.pty](#fen-testing-pty)
- [fen.testing.tui](#fen-testing-tui)
- [fen.turn_lifecycle](#fen-turn-lifecycle)
- [fen.update](#fen-update)
- [fen.util.base64](#fen-util-base64)
- [fen.util.checksum](#fen-util-checksum)
- [fen.util.flat_extensions](#fen-util-flat-extensions)
- [fen.util.http](#fen-util-http)
- [fen.util.http.backends.native](#fen-util-http-backends-native)
- [fen.util.id](#fen-util-id)
- [fen.util.json](#fen-util-json)
- [fen.util.log](#fen-util-log)
- [fen.util.log_sink](#fen-util-log-sink)
- [fen.util.path](#fen-util-path)
- [fen.util.process](#fen-util-process)
- [fen.util.random](#fen-util-random)
- [fen.util.search.bitap](#fen-util-search-bitap)
- [fen.util.sha256](#fen-util-sha256)
- [fen.util.sse](#fen-util-sse)
- [fen.util.text](#fen-util-text)
- [fen.version](#fen-version)

## <a id="fen-core-agent"></a>fen.core.agent

### <a id="fen-core-agent-make-agent-packages-core-src-fen-core-agent-fnl-494"></a>`fen.core.agent.make-agent`
`(make-agent {:provider-name :model :system :tools :api-key :on-event :max-tokens :convert-to-llm :provider-options}) -> Agent`
Construct an Agent record with empty messages, ready for repeated step calls. :api-key and :max-tokens are auto-injected into provider-options. :convert-to-llm projects custom AgentMessages onto canonical Messages before each provider call.
*tags:* agent, loop
_packages/core/src/fen/core/agent.fnl:47_

### <a id="fen-core-agent-step-packages-core-src-fen-core-agent-fnl-494"></a>`fen.core.agent.step`
`(step agent user-msg ?cancel-fn) -> string`
Run one user turn. Appends a UserMessage, then iterates provider-call -> tool-execution until a non-tool stop reason or the safety cap. Cooperative yields when called inside a coroutine; ?cancel-fn polled at every yield.
*tags:* agent, loop, step
_packages/core/src/fen/core/agent.fnl:454_

### <a id="fen-core-agent-safety-cap-packages-core-src-fen-core-agent-fnl-494"></a>`fen.core.agent.SAFETY-CAP`
`number`
Hard ceiling on tool-call iterations per step. Bump if a real workflow needs more, don't remove.
*tags:* agent, loop, limits
_packages/core/src/fen/core/agent.fnl:15_

### <a id="fen-core-agent-complete-messages-packages-core-src-fen-core-agent-fnl-494"></a>`fen.core.agent.complete-messages`
`(complete-messages agent messages ?model ?opts ?on-event ?yield-fn) -> AssistantMessage`
Run one provider completion using an agent's provider configuration, explicit canonical messages, and no tools.
*tags:* agent, llm, extensions
_packages/core/src/fen/core/agent.fnl:376_

## <a id="fen-core-diagnostics"></a>fen.core.diagnostics

### <a id="fen-core-diagnostics-set-runtime-info-bang-packages-core-src-fen-core-diagnostics-fnl-39"></a>`fen.core.diagnostics.set-runtime-info!`
`(set-runtime-info! info) -> table|nil`
Store sanitized runtime/build metadata for durable error/provider diagnostics.
*tags:* diagnostics, version, runtime
_packages/core/src/fen/core/diagnostics.fnl:34_

### <a id="fen-core-diagnostics-runtime-info-packages-core-src-fen-core-diagnostics-fnl-49"></a>`fen.core.diagnostics.runtime-info`
`(runtime-info) -> table|nil`
Return runtime/build metadata previously injected by fen.main, if available.
*tags:* diagnostics, version, runtime
_packages/core/src/fen/core/diagnostics.fnl:44_

## <a id="fen-core-docs-contracts"></a>fen.core.docs.contracts

### <a id="fen-core-docs-contracts-types-packages-core-src-fen-core-docs-contracts-fnl-20"></a>`fen.core.docs.contracts.types`
`table`
Canonical message, content, tool, usage, and agent-context type contracts shared by providers, tools, sessions, and docs.
*tags:* docs, contracts, types
_packages/core/src/fen/core/docs/contracts.fnl:15_

### <a id="fen-core-docs-contracts-register-kinds-packages-core-src-fen-core-docs-contracts-fnl-20"></a>`fen.core.docs.contracts.register-kinds`
`table`
Extension registration kind contracts describing required fields for tools, commands, providers, presenters, panels, hooks, and prompt fragments.
*tags:* docs, contracts, extensions, register
_packages/core/src/fen/core/docs/contracts.fnl:158_

### <a id="fen-core-docs-contracts-events-packages-core-src-fen-core-docs-contracts-fnl-20"></a>`fen.core.docs.contracts.events`
`table`
Event bus contract table documenting emitted runtime event shapes and fields consumed by presenters and extensions.
*tags:* docs, contracts, events, bus
_packages/core/src/fen/core/docs/contracts.fnl:295_

### <a id="fen-core-docs-contracts-interfaces-packages-core-src-fen-core-docs-contracts-fnl-20"></a>`fen.core.docs.contracts.interfaces`
`table`
Interface contract table for provider, auth backend, session backend, and presenter records.
*tags:* docs, contracts, interfaces, providers, sessions
_packages/core/src/fen/core/docs/contracts.fnl:614_

## <a id="fen-core-extensions-events"></a>fen.core.extensions.events

### <a id="fen-core-extensions-events-error-log-path-packages-core-src-fen-core-extensions-events-fnl-50"></a>`fen.core.extensions.events.error-log-path`
`(error-log-path) -> string`
Lazily compute and return the JSONL file path where extension event-bus failures are persisted.
*tags:* extensions, events, diagnostics
_packages/core/src/fen/core/extensions/events.fnl:45_

### <a id="fen-core-extensions-events-list-errors-packages-core-src-fen-core-extensions-events-fnl-101"></a>`fen.core.extensions.events.list-errors`
`(list-errors) -> [ExtensionError]`
Return the bounded in-memory list of sanitized extension error records captured by the event bus.
*tags:* extensions, events, diagnostics
_packages/core/src/fen/core/extensions/events.fnl:96_

### <a id="fen-core-extensions-events-emit-packages-core-src-fen-core-extensions-events-fnl-134"></a>`fen.core.extensions.events.emit`
`(emit ev) -> nil`
Record error events, dispatch ev to handlers for ev.type, and then dispatch to wildcard `:*` subscribers.
*tags:* extensions, events, bus
_packages/core/src/fen/core/extensions/events.fnl:129_

### <a id="fen-core-extensions-events-on-packages-core-src-fen-core-extensions-events-fnl-147"></a>`fen.core.extensions.events.on`
`(on event-name handler ?owner) -> unsubscribe-fn`
Subscribe a handler to one event name with optional owner tagging and return a closure that removes that exact handler.
*tags:* extensions, events, subscribe
_packages/core/src/fen/core/extensions/events.fnl:142_

### <a id="fen-core-extensions-events-unregister-by-owner-packages-core-src-fen-core-extensions-events-fnl-158"></a>`fen.core.extensions.events.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove every event handler tagged with owner from all event buckets during extension reload or teardown.
*tags:* extensions, events, reload
_packages/core/src/fen/core/extensions/events.fnl:153_

### <a id="fen-core-extensions-events-list-packages-core-src-fen-core-extensions-events-fnl-167"></a>`fen.core.extensions.events.list`
`(list) -> table`
Return a safe introspection table of subscribed event names and handler owners without exposing handler functions.
*tags:* extensions, events, introspection
_packages/core/src/fen/core/extensions/events.fnl:162_

## <a id="fen-core-extensions-loader"></a>fen.core.extensions.loader

### <a id="fen-core-extensions-loader-load-sibling-packages-core-src-fen-core-extensions-loader-init-fnl-224"></a>`fen.core.extensions.loader.load-sibling`
`(load-sibling spec sibling) -> any`
Load a sibling .fnl/.lua file for a path-shaped extension's api.load helper without requiring a global namespace.
*tags:* extensions, loader, files
_packages/core/src/fen/core/extensions/loader/init.fnl:219_

### <a id="fen-core-extensions-loader-load-bang-packages-core-src-fen-core-extensions-loader-init-fnl-257"></a>`fen.core.extensions.loader.load!`
`(load! opts ?mode) -> ExtensionLoadSummary`
Discover, gate, and load admissible extensions, failing fast only after collecting first-party load failures.
*tags:* extensions, loader, lifecycle
_packages/core/src/fen/core/extensions/loader/init.fnl:240_

### <a id="fen-core-extensions-loader-summarize-packages-core-src-fen-core-extensions-loader-init-fnl-291"></a>`fen.core.extensions.loader.summarize`
`(summarize items) -> ExtensionLoadSummary`
Fold per-extension load entries into aggregate loaded/changed/failed counters plus the original extension list.
*tags:* extensions, loader, diagnostics
_packages/core/src/fen/core/extensions/loader/init.fnl:286_

### <a id="fen-core-extensions-loader-reload-extension-bang-packages-core-src-fen-core-extensions-loader-init-fnl-308"></a>`fen.core.extensions.loader.reload-extension!`
`(reload-extension! name) -> ok?, err`
Reload a previously loaded extension by name using its retained spec and interactive TUI reload mode.
*tags:* extensions, loader, reload
_packages/core/src/fen/core/extensions/loader/init.fnl:303_

## <a id="fen-core-extensions-loader-discover"></a>fen.core.extensions.loader.discover

### <a id="fen-core-extensions-loader-discover-first-party-roots-packages-core-src-fen-core-extensions-loader-discover-fnl-121"></a>`fen.core.extensions.loader.discover.first-party-roots`
`(first-party-roots) -> [string]`
Return trusted flat first-party overlay roots supplied by the single-file launcher.
*tags:* extensions, loader, discovery
_packages/core/src/fen/core/extensions/loader/discover.fnl:116_

### <a id="fen-core-extensions-loader-discover-project-roots-packages-core-src-fen-core-extensions-loader-discover-fnl-136"></a>`fen.core.extensions.loader.discover.project-roots`
`(project-roots) -> [string]`
Return .fen/extensions roots from cwd upward to the worktree boundary, nearest first for project-local override priority.
*tags:* extensions, loader, discovery
_packages/core/src/fen/core/extensions/loader/discover.fnl:131_

### <a id="fen-core-extensions-loader-discover-user-roots-packages-core-src-fen-core-extensions-loader-discover-fnl-161"></a>`fen.core.extensions.loader.discover.user-roots`
`(user-roots) -> [string]`
Return user extension roots from FEN_EXTENSIONS_PATH plus the XDG fen/extensions directory.
*tags:* extensions, loader, discovery
_packages/core/src/fen/core/extensions/loader/discover.fnl:156_

### <a id="fen-core-extensions-loader-discover-discover-packages-core-src-fen-core-extensions-loader-discover-fnl-301"></a>`fen.core.extensions.loader.discover.discover`
`(discover explicit-paths) -> [ExtensionSpec]`
Build the deduped extension spec list in load-priority order: explicit, first-party flat overlays, project, user, then embedded first-party.
*tags:* extensions, loader, discovery
_packages/core/src/fen/core/extensions/loader/discover.fnl:296_

## <a id="fen-core-extensions-loader-manifest"></a>fen.core.extensions.loader.manifest

### <a id="fen-core-extensions-loader-manifest-strip-ext-packages-core-src-fen-core-extensions-loader-manifest-fnl-25"></a>`fen.core.extensions.loader.manifest.strip-ext`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:25_

### <a id="fen-core-extensions-loader-manifest-load-file-packages-core-src-fen-core-extensions-loader-manifest-fnl-42"></a>`fen.core.extensions.loader.manifest.load-file`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:42_

### <a id="fen-core-extensions-loader-manifest-manifest-path-packages-core-src-fen-core-extensions-loader-manifest-fnl-48"></a>`fen.core.extensions.loader.manifest.manifest-path`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:48_

### <a id="fen-core-extensions-loader-manifest-entry-path-for-dir-packages-core-src-fen-core-extensions-loader-manifest-fnl-55"></a>`fen.core.extensions.loader.manifest.entry-path-for-dir`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:55_

### <a id="fen-core-extensions-loader-manifest-read-manifest-packages-core-src-fen-core-extensions-loader-manifest-fnl-62"></a>`fen.core.extensions.loader.manifest.read-manifest`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:62_

### <a id="fen-core-extensions-loader-manifest-entry-module-of-packages-core-src-fen-core-extensions-loader-manifest-fnl-68"></a>`fen.core.extensions.loader.manifest.entry-module-of`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:68_

### <a id="fen-core-extensions-loader-manifest-entry-of-packages-core-src-fen-core-extensions-loader-manifest-fnl-72"></a>`fen.core.extensions.loader.manifest.entry-of`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:72_

### <a id="fen-core-extensions-loader-manifest-interactive-only-q-packages-core-src-fen-core-extensions-loader-manifest-fnl-76"></a>`fen.core.extensions.loader.manifest.interactive-only?`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:76_

### <a id="fen-core-extensions-loader-manifest-presenter-of-packages-core-src-fen-core-extensions-loader-manifest-fnl-81"></a>`fen.core.extensions.loader.manifest.presenter-of`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:81_

### <a id="fen-core-extensions-loader-manifest-first-party-q-packages-core-src-fen-core-extensions-loader-manifest-fnl-84"></a>`fen.core.extensions.loader.manifest.first-party?`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:84_

### <a id="fen-core-extensions-loader-manifest-reload-modules-packages-core-src-fen-core-extensions-loader-manifest-fnl-89"></a>`fen.core.extensions.loader.manifest.reload-modules`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:89_

### <a id="fen-core-extensions-loader-manifest-reload-exclude-packages-core-src-fen-core-extensions-loader-manifest-fnl-95"></a>`fen.core.extensions.loader.manifest.reload-exclude`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:95_

### <a id="fen-core-extensions-loader-manifest-enabled-q-packages-core-src-fen-core-extensions-loader-manifest-fnl-100"></a>`fen.core.extensions.loader.manifest.enabled?`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:100_

### <a id="fen-core-extensions-loader-manifest-entry-register-packages-core-src-fen-core-extensions-loader-manifest-fnl-106"></a>`fen.core.extensions.loader.manifest.entry-register`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:106_

### <a id="fen-core-extensions-loader-manifest-requires-modules-packages-core-src-fen-core-extensions-loader-manifest-fnl-126"></a>`fen.core.extensions.loader.manifest.requires-modules`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:126_

### <a id="fen-core-extensions-loader-manifest-requires-shared-libs-packages-core-src-fen-core-extensions-loader-manifest-fnl-132"></a>`fen.core.extensions.loader.manifest.requires-shared-libs`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:132_

### <a id="fen-core-extensions-loader-manifest-missing-requires-modules-packages-core-src-fen-core-extensions-loader-manifest-fnl-137"></a>`fen.core.extensions.loader.manifest.missing-requires-modules`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:137_

### <a id="fen-core-extensions-loader-manifest-missing-deps-packages-core-src-fen-core-extensions-loader-manifest-fnl-146"></a>`fen.core.extensions.loader.manifest.missing-deps`
_packages/core/src/fen/core/extensions/loader/manifest.fnl:146_

## <a id="fen-core-extensions-loader-reload"></a>fen.core.extensions.loader.reload

### <a id="fen-core-extensions-loader-reload-file-changed-q-bang-packages-core-src-fen-core-extensions-loader-reload-fnl-47"></a>`fen.core.extensions.loader.reload.file-changed?!`
`(file-changed?! file-path) -> boolean`
Update and compare the cached fingerprint for a path-shaped extension file, returning true only after a prior baseline changed.
*tags:* extensions, loader, reload, fingerprint
_packages/core/src/fen/core/extensions/loader/reload.fnl:42_

### <a id="fen-core-extensions-loader-reload-change-summary-packages-core-src-fen-core-extensions-loader-reload-fnl-56"></a>`fen.core.extensions.loader.reload.change-summary`
`(change-summary mods) -> ReloadChangeSummary`
Probe module fingerprints, update the reload cache, and return checked/changed counts plus changed module names.
*tags:* extensions, loader, reload, fingerprint
_packages/core/src/fen/core/extensions/loader/reload.fnl:51_

### <a id="fen-core-extensions-loader-reload-clear-reload-modules-bang-packages-core-src-fen-core-extensions-loader-reload-fnl-88"></a>`fen.core.extensions.loader.reload.clear-reload-modules!`
`(clear-reload-modules! manifest fallback) -> ReloadChangeSummary`
Re-require manifest reload modules in place, respecting reload-exclude, and return one summary for user-facing reload diagnostics.
*tags:* extensions, loader, reload
_packages/core/src/fen/core/extensions/loader/reload.fnl:83_

## <a id="fen-core-extensions-register"></a>fen.core.extensions.register

### <a id="fen-core-extensions-register-register-packages-core-src-fen-core-extensions-register-init-fnl-43"></a>`fen.core.extensions.register.register`
`(register kind spec owner) -> register-result`
Dispatch one extension contribution to the per-kind registry module and return its owner-tagged unregister handle.
*tags:* extensions, register, dispatcher
_packages/core/src/fen/core/extensions/register/init.fnl:38_

### <a id="fen-core-extensions-register-unregister-by-owner-packages-core-src-fen-core-extensions-register-init-fnl-62"></a>`fen.core.extensions.register.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Sweep every registry kind and event-handler bucket, removing contributions tagged with owner during reload or teardown.
*tags:* extensions, register, reload
_packages/core/src/fen/core/extensions/register/init.fnl:57_

### <a id="fen-core-extensions-register-list-packages-core-src-fen-core-extensions-register-init-fnl-112"></a>`fen.core.extensions.register.list`
`(list kind) -> frozen-table`
Return a frozen introspection list for the requested registry kind, including extensions, hooks, event handlers, and prompt fragments.
*tags:* extensions, register, introspection
_packages/core/src/fen/core/extensions/register/init.fnl:107_

### <a id="fen-core-extensions-register-collect-introspection-packages-core-src-fen-core-extensions-register-init-fnl-135"></a>`fen.core.extensions.register.collect-introspection`
`(collect-introspection ?owner ?ctx) -> table`
Evaluate registered introspection snapshots through the centralized pcall-isolated collector.
*tags:* extensions, register, introspection, snapshots
_packages/core/src/fen/core/extensions/register/init.fnl:130_

## <a id="fen-core-extensions-register-auth-backend"></a>fen.core.extensions.register.auth_backend

### <a id="fen-core-extensions-register-auth-backend-register-packages-core-src-fen-core-extensions-register-auth-backend-fnl-11"></a>`fen.core.extensions.register.auth_backend.register`
`(register spec owner handle-result) -> register-result`
Validate and install a singleton auth-backend contribution keyed by :name for provider credential lookup.
*tags:* extensions, register, auth
_packages/core/src/fen/core/extensions/register/auth_backend.fnl:6_

### <a id="fen-core-extensions-register-auth-backend-unregister-by-owner-packages-core-src-fen-core-extensions-register-auth-backend-fnl-22"></a>`fen.core.extensions.register.auth_backend.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove every auth backend installed by owner without disturbing backends registered by other extensions.
*tags:* extensions, register, auth, reload
_packages/core/src/fen/core/extensions/register/auth_backend.fnl:17_

### <a id="fen-core-extensions-register-auth-backend-find-packages-core-src-fen-core-extensions-register-auth-backend-fnl-32"></a>`fen.core.extensions.register.auth_backend.find`
`(find name) -> AuthBackend|nil`
Return the registered auth backend for name, or nil when no matching backend is installed.
*tags:* extensions, register, auth
_packages/core/src/fen/core/extensions/register/auth_backend.fnl:27_

### <a id="fen-core-extensions-register-auth-backend-list-packages-core-src-fen-core-extensions-register-auth-backend-fnl-40"></a>`fen.core.extensions.register.auth_backend.list`
`(list) -> [AuthBackendInfo]`
Return auth backend metadata for introspection, including owner and optional credential capability flags.
*tags:* extensions, register, auth, introspection
_packages/core/src/fen/core/extensions/register/auth_backend.fnl:35_

## <a id="fen-core-extensions-register-command"></a>fen.core.extensions.register.command

### <a id="fen-core-extensions-register-command-register-packages-core-src-fen-core-extensions-register-command-fnl-12"></a>`fen.core.extensions.register.command.register`
`(register spec owner handle-result) -> register-result`
Validate and install a slash-command contribution keyed by :name with its handler and command metadata.
*tags:* extensions, register, commands
_packages/core/src/fen/core/extensions/register/command.fnl:7_

### <a id="fen-core-extensions-register-command-unregister-by-owner-packages-core-src-fen-core-extensions-register-command-fnl-26"></a>`fen.core.extensions.register.command.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove all slash commands installed by owner so extension reloads replace commands without stale aliases.
*tags:* extensions, register, commands, reload
_packages/core/src/fen/core/extensions/register/command.fnl:21_

### <a id="fen-core-extensions-register-command-dispatch-packages-core-src-fen-core-extensions-register-command-fnl-49"></a>`fen.core.extensions.register.command.dispatch`
`(dispatch line caller-state) -> nil`
Parse a slash command line, enforce idle-only guards, pcall-isolate the handler, and emit user-facing errors.
*tags:* extensions, commands, events
_packages/core/src/fen/core/extensions/register/command.fnl:44_

### <a id="fen-core-extensions-register-command-list-packages-core-src-fen-core-extensions-register-command-fnl-74"></a>`fen.core.extensions.register.command.list`
`(list) -> [CommandInfo]`
Return command metadata used by help, docs, and diagnostics without exposing handler functions.
*tags:* extensions, commands, introspection
_packages/core/src/fen/core/extensions/register/command.fnl:69_

## <a id="fen-core-extensions-register-control"></a>fen.core.extensions.register.control

### <a id="fen-core-extensions-register-control-register-packages-core-src-fen-core-extensions-register-control-fnl-11"></a>`fen.core.extensions.register.control.register`
`(register spec owner handle-result) -> register-result`
Validate and append a presenter-neutral control contribution with owner tagging for reload cleanup.
*tags:* extensions, register, controls
_packages/core/src/fen/core/extensions/register/control.fnl:6_

### <a id="fen-core-extensions-register-control-unregister-by-owner-packages-core-src-fen-core-extensions-register-control-fnl-22"></a>`fen.core.extensions.register.control.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove all control contributions installed by owner from the ordered controls registry.
*tags:* extensions, register, controls, reload
_packages/core/src/fen/core/extensions/register/control.fnl:17_

### <a id="fen-core-extensions-register-control-list-packages-core-src-fen-core-extensions-register-control-fnl-31"></a>`fen.core.extensions.register.control.list`
`(list) -> [ControlInfo]`
Return control metadata for presenters and docs, including keys/order while hiding mutable registry records.
*tags:* extensions, controls, introspection
_packages/core/src/fen/core/extensions/register/control.fnl:26_

## <a id="fen-core-extensions-register-hook"></a>fen.core.extensions.register.hook

### <a id="fen-core-extensions-register-hook-register-packages-core-src-fen-core-extensions-register-hook-fnl-11"></a>`fen.core.extensions.register.hook.register`
`(register spec owner handle-result) -> register-result`
Validate and append a before-tool hook contribution that can inspect or veto pending tool execution.
*tags:* extensions, register, hooks, tools
_packages/core/src/fen/core/extensions/register/hook.fnl:6_

### <a id="fen-core-extensions-register-hook-unregister-by-owner-packages-core-src-fen-core-extensions-register-hook-fnl-24"></a>`fen.core.extensions.register.hook.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove all before-tool hooks installed by owner during extension reload or teardown.
*tags:* extensions, hooks, reload
_packages/core/src/fen/core/extensions/register/hook.fnl:19_

### <a id="fen-core-extensions-register-hook-list-packages-core-src-fen-core-extensions-register-hook-fnl-33"></a>`fen.core.extensions.register.hook.list`
`(list) -> [HookInfo]`
Return hook contributions without exposing hook functions.
*tags:* extensions, hooks, introspection
_packages/core/src/fen/core/extensions/register/hook.fnl:28_

### <a id="fen-core-extensions-register-hook-run-before-tool-packages-core-src-fen-core-extensions-register-hook-fnl-44"></a>`fen.core.extensions.register.hook.run-before-tool`
`(run-before-tool tool-name args ctx) -> {:block? boolean :reason string|nil}`
Run registered before-tool hooks in order and return the first veto decision, or an explicit non-blocking decision.
*tags:* extensions, hooks, tools
_packages/core/src/fen/core/extensions/register/hook.fnl:39_

## <a id="fen-core-extensions-register-introspect"></a>fen.core.extensions.register.introspect

### <a id="fen-core-extensions-register-introspect-register-packages-core-src-fen-core-extensions-register-introspect-fnl-17"></a>`fen.core.extensions.register.introspect.register`
_packages/core/src/fen/core/extensions/register/introspect.fnl:17_

### <a id="fen-core-extensions-register-introspect-unregister-by-owner-packages-core-src-fen-core-extensions-register-introspect-fnl-26"></a>`fen.core.extensions.register.introspect.unregister-by-owner`
_packages/core/src/fen/core/extensions/register/introspect.fnl:26_

### <a id="fen-core-extensions-register-introspect-list-packages-core-src-fen-core-extensions-register-introspect-fnl-38"></a>`fen.core.extensions.register.introspect.list`
_packages/core/src/fen/core/extensions/register/introspect.fnl:38_

### <a id="fen-core-extensions-register-introspect-collect-packages-core-src-fen-core-extensions-register-introspect-fnl-83"></a>`fen.core.extensions.register.introspect.collect`
_packages/core/src/fen/core/extensions/register/introspect.fnl:83_

## <a id="fen-core-extensions-register-panel"></a>fen.core.extensions.register.panel

### <a id="fen-core-extensions-register-panel-register-packages-core-src-fen-core-extensions-register-panel-fnl-32"></a>`fen.core.extensions.register.panel.register`
`(register spec owner handle-result) -> register-result`
Validate a panel contribution, fill default placement/order fields, and append it to the presenter panel registry.
*tags:* extensions, register, panels, ui
_packages/core/src/fen/core/extensions/register/panel.fnl:27_

### <a id="fen-core-extensions-register-panel-unregister-by-owner-packages-core-src-fen-core-extensions-register-panel-fnl-52"></a>`fen.core.extensions.register.panel.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove all panel contributions installed by owner while preserving the shared panel registry table identity.
*tags:* extensions, panels, reload
_packages/core/src/fen/core/extensions/register/panel.fnl:47_

### <a id="fen-core-extensions-register-panel-list-packages-core-src-fen-core-extensions-register-panel-fnl-69"></a>`fen.core.extensions.register.panel.list`
`(list) -> [Panel]`
Return panel contributions sorted by order, owner, and name for deterministic presenter layout.
*tags:* extensions, panels, introspection
_packages/core/src/fen/core/extensions/register/panel.fnl:64_

## <a id="fen-core-extensions-register-presenter"></a>fen.core.extensions.register.presenter

### <a id="fen-core-extensions-register-presenter-promote-ui-slot-bang-packages-core-src-fen-core-extensions-register-presenter-fnl-15"></a>`fen.core.extensions.register.presenter.promote-ui-slot!`
`(promote-ui-slot!) -> nil`
Recompute the shared UI slot from the first active presenter that supplies one after unregister or reload.
*tags:* extensions, presenter, ui, reload
_packages/core/src/fen/core/extensions/register/presenter.fnl:10_

### <a id="fen-core-extensions-register-presenter-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-27"></a>`fen.core.extensions.register.presenter.active-presenter`
`(active-presenter) -> Presenter|nil`
Return the first registered presenter marked active, or nil when no presenter has claimed the run.
*tags:* extensions, presenter, ui
_packages/core/src/fen/core/extensions/register/presenter.fnl:22_

### <a id="fen-core-extensions-register-presenter-register-packages-core-src-fen-core-extensions-register-presenter-fnl-40"></a>`fen.core.extensions.register.presenter.register`
`(register spec owner handle-result) -> register-result`
Validate and append a presenter contribution, promoting its UI slot immediately when it is active.
*tags:* extensions, register, presenter, ui
_packages/core/src/fen/core/extensions/register/presenter.fnl:35_

### <a id="fen-core-extensions-register-presenter-unregister-by-owner-packages-core-src-fen-core-extensions-register-presenter-fnl-57"></a>`fen.core.extensions.register.presenter.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove presenters installed by owner and promote the next active UI slot so extension APIs keep working after reload.
*tags:* extensions, presenter, reload
_packages/core/src/fen/core/extensions/register/presenter.fnl:52_

### <a id="fen-core-extensions-register-presenter-init-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-80"></a>`fen.core.extensions.register.presenter.init-active-presenter`
`(init-active-presenter ctx) -> ok?, result`
Call the active presenter's optional :init lifecycle method through a pcall-style result pair.
*tags:* extensions, presenter, lifecycle
_packages/core/src/fen/core/extensions/register/presenter.fnl:75_

### <a id="fen-core-extensions-register-presenter-shutdown-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-88"></a>`fen.core.extensions.register.presenter.shutdown-active-presenter`
`(shutdown-active-presenter ctx) -> ok?, result`
Call the active presenter's optional :shutdown lifecycle method during process teardown.
*tags:* extensions, presenter, lifecycle
_packages/core/src/fen/core/extensions/register/presenter.fnl:83_

### <a id="fen-core-extensions-register-presenter-run-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-96"></a>`fen.core.extensions.register.presenter.run-active-presenter`
`(run-active-presenter ctx) -> ok?, result`
Call the active presenter's required :run lifecycle method and report an error pair when no runnable presenter exists.
*tags:* extensions, presenter, lifecycle
_packages/core/src/fen/core/extensions/register/presenter.fnl:91_

### <a id="fen-core-extensions-register-presenter-build-ui-slot-packages-core-src-fen-core-extensions-register-presenter-fnl-129"></a>`fen.core.extensions.register.presenter.build-ui-slot`
`(build-ui-slot) -> table`
Build the stable extension-facing UI facade whose methods dispatch to the active presenter or lightweight fallbacks.
*tags:* extensions, presenter, ui, api
_packages/core/src/fen/core/extensions/register/presenter.fnl:124_

### <a id="fen-core-extensions-register-presenter-list-packages-core-src-fen-core-extensions-register-presenter-fnl-140"></a>`fen.core.extensions.register.presenter.list`
`(list) -> [PresenterInfo]`
Return presenter metadata and lifecycle capability flags for diagnostics and runtime docs.
*tags:* extensions, presenter, introspection
_packages/core/src/fen/core/extensions/register/presenter.fnl:135_

## <a id="fen-core-extensions-register-prompt"></a>fen.core.extensions.register.prompt

### <a id="fen-core-extensions-register-prompt-contribute-packages-core-src-fen-core-extensions-register-prompt-fnl-21"></a>`fen.core.extensions.register.prompt.contribute`
`(contribute text-or-fn ?opts owner handle-result) -> register-result`
Append an ordered system-prompt fragment from api.prompt, tagging owner metadata and returning an unregister handle.
*tags:* extensions, prompt, register
_packages/core/src/fen/core/extensions/register/prompt.fnl:16_

### <a id="fen-core-extensions-register-prompt-unregister-by-owner-packages-core-src-fen-core-extensions-register-prompt-fnl-40"></a>`fen.core.extensions.register.prompt.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove all system-prompt fragments contributed by owner during reload or extension teardown.
*tags:* extensions, prompt, reload
_packages/core/src/fen/core/extensions/register/prompt.fnl:35_

### <a id="fen-core-extensions-register-prompt-render-packages-core-src-fen-core-extensions-register-prompt-fnl-73"></a>`fen.core.extensions.register.prompt.render`
`(render ?ctx) -> string|nil`
Render registered prompt fragments in final order, omitting nil/empty fragments and isolating fragment function errors.
*tags:* extensions, prompt, render
_packages/core/src/fen/core/extensions/register/prompt.fnl:68_

### <a id="fen-core-extensions-register-prompt-list-packages-core-src-fen-core-extensions-register-prompt-fnl-99"></a>`fen.core.extensions.register.prompt.list`
`(list) -> [PromptFragmentInfo]`
Return prompt-fragment metadata in final render order without exposing raw fragment text content.
*tags:* extensions, prompt, introspection
_packages/core/src/fen/core/extensions/register/prompt.fnl:94_

## <a id="fen-core-extensions-register-provider"></a>fen.core.extensions.register.provider

### <a id="fen-core-extensions-register-provider-register-packages-core-src-fen-core-extensions-register-provider-fnl-11"></a>`fen.core.extensions.register.provider.register`
`(register spec owner handle-result) -> register-result`
Validate and install a singleton provider contribution keyed by name, defaulting name from api when omitted.
*tags:* extensions, register, providers
_packages/core/src/fen/core/extensions/register/provider.fnl:6_

### <a id="fen-core-extensions-register-provider-unregister-by-owner-packages-core-src-fen-core-extensions-register-provider-fnl-27"></a>`fen.core.extensions.register.provider.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove every provider installed by owner without clobbering same-name providers registered later by other owners.
*tags:* extensions, providers, reload
_packages/core/src/fen/core/extensions/register/provider.fnl:22_

### <a id="fen-core-extensions-register-provider-find-packages-core-src-fen-core-extensions-register-provider-fnl-37"></a>`fen.core.extensions.register.provider.find`
`(find name) -> Provider|nil`
Find a provider by its unique registry name; provider :api is protocol metadata, not the deterministic dispatch key.
*tags:* extensions, providers, lookup
_packages/core/src/fen/core/extensions/register/provider.fnl:32_

### <a id="fen-core-extensions-register-provider-list-by-api-packages-core-src-fen-core-extensions-register-provider-fnl-47"></a>`fen.core.extensions.register.provider.list-by-api`
`(list-by-api api) -> [Provider]`
Return all providers whose protocol/family metadata matches api for introspection and delegation.
*tags:* extensions, providers, lookup
_packages/core/src/fen/core/extensions/register/provider.fnl:42_

### <a id="fen-core-extensions-register-provider-find-by-api-packages-core-src-fen-core-extensions-register-provider-fnl-62"></a>`fen.core.extensions.register.provider.find-by-api`
`(find-by-api api) -> Provider|nil`
Return the first provider matching an api family for legacy/introspection callers that cannot require unique provider names.
*tags:* extensions, providers, lookup
_packages/core/src/fen/core/extensions/register/provider.fnl:57_

### <a id="fen-core-extensions-register-provider-list-packages-core-src-fen-core-extensions-register-provider-fnl-73"></a>`fen.core.extensions.register.provider.list`
`(list) -> [ProviderInfo]`
Return provider metadata for model selection, docs, and diagnostics while preserving provider implementation records internally.
*tags:* extensions, providers, introspection
_packages/core/src/fen/core/extensions/register/provider.fnl:68_

## <a id="fen-core-extensions-register-session-backend"></a>fen.core.extensions.register.session_backend

### <a id="fen-core-extensions-register-session-backend-register-packages-core-src-fen-core-extensions-register-session-backend-fnl-18"></a>`fen.core.extensions.register.session_backend.register`
`(register spec owner handle-result) -> register-result`
Validate required session backend methods and install the backend by name for session persistence selection.
*tags:* extensions, register, session
_packages/core/src/fen/core/extensions/register/session_backend.fnl:13_

### <a id="fen-core-extensions-register-session-backend-unregister-by-owner-packages-core-src-fen-core-extensions-register-session-backend-fnl-33"></a>`fen.core.extensions.register.session_backend.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove session backends installed by owner and clear active session state if the active backend is removed.
*tags:* extensions, session, reload
_packages/core/src/fen/core/extensions/register/session_backend.fnl:28_

### <a id="fen-core-extensions-register-session-backend-find-packages-core-src-fen-core-extensions-register-session-backend-fnl-46"></a>`fen.core.extensions.register.session_backend.find`
`(find name) -> SessionBackend|nil`
Return the registered session backend for name, or nil when no backend is installed under that name.
*tags:* extensions, session, lookup
_packages/core/src/fen/core/extensions/register/session_backend.fnl:41_

### <a id="fen-core-extensions-register-session-backend-set-active-bang-packages-core-src-fen-core-extensions-register-session-backend-fnl-54"></a>`fen.core.extensions.register.session_backend.set-active!`
`(set-active! name) -> SessionBackend|nil`
Record the active session backend name, resolve it immediately, and return the selected backend if present.
*tags:* extensions, session, state
_packages/core/src/fen/core/extensions/register/session_backend.fnl:49_

### <a id="fen-core-extensions-register-session-backend-active-packages-core-src-fen-core-extensions-register-session-backend-fnl-64"></a>`fen.core.extensions.register.session_backend.active`
`(active) -> SessionBackend|nil`
Return the cached active backend or resolve the active backend name after reload restored the registry.
*tags:* extensions, session, state
_packages/core/src/fen/core/extensions/register/session_backend.fnl:59_

### <a id="fen-core-extensions-register-session-backend-set-info-bang-packages-core-src-fen-core-extensions-register-session-backend-fnl-73"></a>`fen.core.extensions.register.session_backend.set-info!`
`(set-info! info) -> info`
Store the active session info record for later runtime inspection by commands, tools, and docs.
*tags:* extensions, session, introspection
_packages/core/src/fen/core/extensions/register/session_backend.fnl:68_

### <a id="fen-core-extensions-register-session-backend-info-packages-core-src-fen-core-extensions-register-session-backend-fnl-82"></a>`fen.core.extensions.register.session_backend.info`
`(info) -> SessionInfo|nil`
Return the cached active session info record without touching backend storage.
*tags:* extensions, session, introspection
_packages/core/src/fen/core/extensions/register/session_backend.fnl:77_

### <a id="fen-core-extensions-register-session-backend-list-packages-core-src-fen-core-extensions-register-session-backend-fnl-89"></a>`fen.core.extensions.register.session_backend.list`
`(list) -> [SessionBackendInfo]`
Return session backend names and owners for diagnostics and generated runtime documentation.
*tags:* extensions, session, introspection
_packages/core/src/fen/core/extensions/register/session_backend.fnl:84_

## <a id="fen-core-extensions-register-status"></a>fen.core.extensions.register.status

### <a id="fen-core-extensions-register-status-register-packages-core-src-fen-core-extensions-register-status-fnl-17"></a>`fen.core.extensions.register.status.register`
`(register spec owner handle-result) -> register-result`
Validate a status-line contributor, fill default side/order fields, and append it to the status registry.
*tags:* extensions, register, status
_packages/core/src/fen/core/extensions/register/status.fnl:12_

### <a id="fen-core-extensions-register-status-unregister-by-owner-packages-core-src-fen-core-extensions-register-status-fnl-35"></a>`fen.core.extensions.register.status.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove all status contributors installed by owner while preserving contributors from other extensions.
*tags:* extensions, register, status, reload
_packages/core/src/fen/core/extensions/register/status.fnl:30_

### <a id="fen-core-extensions-register-status-list-packages-core-src-fen-core-extensions-register-status-fnl-52"></a>`fen.core.extensions.register.status.list`
`(list) -> [StatusItem]`
Return status contributors sorted by order, owner, and name for deterministic presenter rendering.
*tags:* extensions, status, introspection
_packages/core/src/fen/core/extensions/register/status.fnl:47_

## <a id="fen-core-extensions-register-tool"></a>fen.core.extensions.register.tool

### <a id="fen-core-extensions-register-tool-register-packages-core-src-fen-core-extensions-register-tool-fnl-11"></a>`fen.core.extensions.register.tool.register`
`(register spec owner handle-result) -> register-result`
Validate and append an AgentTool contribution so the agent can expose it to providers and execute ToolCalls by name.
*tags:* extensions, register, tools
_packages/core/src/fen/core/extensions/register/tool.fnl:6_

### <a id="fen-core-extensions-register-tool-unregister-by-owner-packages-core-src-fen-core-extensions-register-tool-fnl-22"></a>`fen.core.extensions.register.tool.unregister-by-owner`
`(unregister-by-owner owner) -> nil`
Remove every tool contribution installed by owner from the extension tool registry.
*tags:* extensions, register, tools, reload
_packages/core/src/fen/core/extensions/register/tool.fnl:17_

### <a id="fen-core-extensions-register-tool-merged-packages-core-src-fen-core-extensions-register-tool-fnl-31"></a>`fen.core.extensions.register.tool.merged`
`(merged base) -> [AgentTool]`
Return base tools followed by extension-contributed tools in registry order for agent-step tool exposure.
*tags:* extensions, tools, agent
_packages/core/src/fen/core/extensions/register/tool.fnl:26_

### <a id="fen-core-extensions-register-tool-list-packages-core-src-fen-core-extensions-register-tool-fnl-43"></a>`fen.core.extensions.register.tool.list`
`(list) -> [ToolInfo]`
Return lightweight tool metadata for docs and diagnostics without exposing execute functions.
*tags:* extensions, tools, introspection
_packages/core/src/fen/core/extensions/register/tool.fnl:38_

## <a id="fen-core-extensions-rocks"></a>fen.core.extensions.rocks

### <a id="fen-core-extensions-rocks-default-tree-packages-core-src-fen-core-extensions-rocks-fnl-17"></a>`fen.core.extensions.rocks.default-tree`
`(default-tree) -> string`
Return the fen-managed LuaRocks tree, honoring FEN_ROCKS_TREE before falling back to the user data directory.
*tags:* extensions, rocks, paths
_packages/core/src/fen/core/extensions/rocks.fnl:12_

### <a id="fen-core-extensions-rocks-lua-path-fragment-packages-core-src-fen-core-extensions-rocks-fnl-28"></a>`fen.core.extensions.rocks.lua-path-fragment`
`(lua-path-fragment tree) -> string`
Build the package.path fragment that exposes pure-Lua modules installed in a fen rocks tree.
*tags:* extensions, rocks, paths
_packages/core/src/fen/core/extensions/rocks.fnl:23_

### <a id="fen-core-extensions-rocks-lua-cpath-fragment-packages-core-src-fen-core-extensions-rocks-fnl-37"></a>`fen.core.extensions.rocks.lua-cpath-fragment`
`(lua-cpath-fragment tree) -> string`
Build the package.cpath fragment that exposes native Lua 5.4 modules installed in a fen rocks tree.
*tags:* extensions, rocks, paths
_packages/core/src/fen/core/extensions/rocks.fnl:32_

### <a id="fen-core-extensions-rocks-prepend-tree-bang-packages-core-src-fen-core-extensions-rocks-fnl-50"></a>`fen.core.extensions.rocks.prepend-tree!`
`(prepend-tree! ?tree) -> true|nil`
Prepend an existing fen rocks tree to package.path and package.cpath so extension dependencies can be required.
*tags:* extensions, rocks, paths
_packages/core/src/fen/core/extensions/rocks.fnl:45_

### <a id="fen-core-extensions-rocks-rockspecs-packages-core-src-fen-core-extensions-rocks-fnl-72"></a>`fen.core.extensions.rocks.rockspecs`
`(rockspecs dir) -> [string]`
List top-level .rockspec files in an extension directory for build and missing-dependency diagnostics.
*tags:* extensions, rocks, build
_packages/core/src/fen/core/extensions/rocks.fnl:67_

### <a id="fen-core-extensions-rocks-rockspec-present-q-packages-core-src-fen-core-extensions-rocks-fnl-82"></a>`fen.core.extensions.rocks.rockspec-present?`
`(rockspec-present? dir) -> boolean`
Return true when an extension directory contains at least one rockspec for fen ext build guidance.
*tags:* extensions, rocks, build
_packages/core/src/fen/core/extensions/rocks.fnl:77_

### <a id="fen-core-extensions-rocks-single-rockspec-packages-core-src-fen-core-extensions-rocks-fnl-90"></a>`fen.core.extensions.rocks.single-rockspec`
`(single-rockspec dir) -> rockspec|nil, err|nil`
Require exactly one rockspec in an extension directory and return a user-facing error when zero or multiple are present.
*tags:* extensions, rocks, build
_packages/core/src/fen/core/extensions/rocks.fnl:85_

### <a id="fen-core-extensions-rocks-parse-missing-module-packages-core-src-fen-core-extensions-rocks-fnl-104"></a>`fen.core.extensions.rocks.parse-missing-module`
`(parse-missing-module err) -> string|nil`
Extract the missing module name from Lua's standard require error so loader failures can suggest installation actions.
*tags:* extensions, rocks, diagnostics
_packages/core/src/fen/core/extensions/rocks.fnl:99_

### <a id="fen-core-extensions-rocks-manual-install-command-packages-core-src-fen-core-extensions-rocks-fnl-115"></a>`fen.core.extensions.rocks.manual-install-command`
`(manual-install-command module-name ?tree) -> string`
Format the LuaRocks install command users can run to install a missing dependency into the fen rocks tree.
*tags:* extensions, rocks, diagnostics
_packages/core/src/fen/core/extensions/rocks.fnl:110_

### <a id="fen-core-extensions-rocks-build-command-packages-core-src-fen-core-extensions-rocks-fnl-124"></a>`fen.core.extensions.rocks.build-command`
`(build-command dir) -> string`
Format the fen ext build command for an extension directory that declares a rockspec.
*tags:* extensions, rocks, build
_packages/core/src/fen/core/extensions/rocks.fnl:119_

### <a id="fen-core-extensions-rocks-missing-module-message-packages-core-src-fen-core-extensions-rocks-fnl-141"></a>`fen.core.extensions.rocks.missing-module-message`
`(missing-module-message spec module-name) -> string`
Build an actionable loader error for one missing Lua module, preferring fen ext build when the extension has a rockspec.
*tags:* extensions, rocks, diagnostics
_packages/core/src/fen/core/extensions/rocks.fnl:136_

### <a id="fen-core-extensions-rocks-missing-modules-message-packages-core-src-fen-core-extensions-rocks-fnl-156"></a>`fen.core.extensions.rocks.missing-modules-message`
`(missing-modules-message spec modules) -> string`
Build an actionable loader error for declared missing modules, including shared-library hints from the manifest.
*tags:* extensions, rocks, diagnostics
_packages/core/src/fen/core/extensions/rocks.fnl:151_

### <a id="fen-core-extensions-rocks-build-bang-packages-core-src-fen-core-extensions-rocks-fnl-212"></a>`fen.core.extensions.rocks.build!`
`(build! dir) -> exit-code`
Build an extension rockspec into the fen rocks tree using bundled LuaRocks when available, returning process-style exit codes.
*tags:* extensions, rocks, build
_packages/core/src/fen/core/extensions/rocks.fnl:207_

## <a id="fen-core-extensions-state"></a>fen.core.extensions.state

### <a id="fen-core-extensions-state-version-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.version`
`number`
Schema/version marker for the persistent extension state table shared across reloadable extension modules.
*tags:* extensions, state, reload
_packages/core/src/fen/core/extensions/state.fnl:3_

### <a id="fen-core-extensions-state-handlers-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.handlers`
`table`
Event-bus handler buckets keyed by event name, preserving subscriptions across reloadable event-module updates.
*tags:* extensions, state, events
_packages/core/src/fen/core/extensions/state.fnl:9_

### <a id="fen-core-extensions-state-tools-extra-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.tools-extra`
`[AgentTool]`
Array registry of extension-contributed tools appended to the agent's base tool set each step.
*tags:* extensions, state, tools
_packages/core/src/fen/core/extensions/state.fnl:15_

### <a id="fen-core-extensions-state-commands-extra-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.commands-extra`
`table`
Singleton registry of slash-command contributions keyed by command name for dispatch and help introspection.
*tags:* extensions, state, commands
_packages/core/src/fen/core/extensions/state.fnl:21_

### <a id="fen-core-extensions-state-controls-extra-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.controls-extra`
`[Control]`
Array registry of presenter-neutral keyboard/control contributions exposed to active presenters.
*tags:* extensions, state, controls
_packages/core/src/fen/core/extensions/state.fnl:27_

### <a id="fen-core-extensions-state-status-extra-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.status-extra`
`[StatusItem]`
Array registry of status-line contributors sorted by presenters into left/right status regions.
*tags:* extensions, state, status
_packages/core/src/fen/core/extensions/state.fnl:33_

### <a id="fen-core-extensions-state-panel-extra-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.panel-extra`
`[Panel]`
Array registry of non-modal panel contributions rendered by presenters that support panel regions.
*tags:* extensions, state, panels
_packages/core/src/fen/core/extensions/state.fnl:39_

### <a id="fen-core-extensions-state-presenters-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.presenters`
`[Presenter]`
Array registry of presenter contributions, including lifecycle callbacks and optional UI slot implementations.
*tags:* extensions, state, presenter
_packages/core/src/fen/core/extensions/state.fnl:45_

### <a id="fen-core-extensions-state-introspectors-extra-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.introspectors-extra`
`[Introspector]`
Array registry of extension-owned read-only snapshot providers exposed through agent_state, /extensions, and runtime diagnostics.
*tags:* extensions, state, introspection
_packages/core/src/fen/core/extensions/state.fnl:51_

### <a id="fen-core-extensions-state-providers-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.providers`
`table`
Singleton registry of LLM provider contributions keyed by provider name for deterministic model dispatch.
*tags:* extensions, state, providers
_packages/core/src/fen/core/extensions/state.fnl:57_

### <a id="fen-core-extensions-state-auth-backends-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.auth-backends`
`table`
Singleton registry of auth backend contributions keyed by name for provider credential resolution.
*tags:* extensions, state, auth
_packages/core/src/fen/core/extensions/state.fnl:63_

### <a id="fen-core-extensions-state-session-backends-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.session-backends`
`table`
Singleton registry of session persistence backend contributions keyed by backend name.
*tags:* extensions, state, session
_packages/core/src/fen/core/extensions/state.fnl:69_

### <a id="fen-core-extensions-state-session-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.session`
`table`
Active session backend selection and cached SessionInfo shared by session commands, tools, and backends.
*tags:* extensions, state, session
_packages/core/src/fen/core/extensions/state.fnl:75_

### <a id="fen-core-extensions-state-hooks-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.hooks`
`table`
Lifecycle hook registries, currently the before-tool hook array consulted before tool execution.
*tags:* extensions, state, hooks
_packages/core/src/fen/core/extensions/state.fnl:81_

### <a id="fen-core-extensions-state-prompt-fragments-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.prompt-fragments`
`[PromptFragment]`
Ordered system-prompt fragment registry rendered into the agent context before provider calls.
*tags:* extensions, state, prompt
_packages/core/src/fen/core/extensions/state.fnl:87_

### <a id="fen-core-extensions-state-prompt-next-seq-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.prompt-next-seq`
`number`
Monotonic sequence counter used to keep prompt-fragment ordering stable when fragments share the same order.
*tags:* extensions, state, prompt
_packages/core/src/fen/core/extensions/state.fnl:93_

### <a id="fen-core-extensions-state-extensions-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.extensions`
`table`
Loader status records keyed by extension name for runtime docs, diagnostics, and extension-listing commands.
*tags:* extensions, state, loader
_packages/core/src/fen/core/extensions/state.fnl:99_

### <a id="fen-core-extensions-state-reload-fingerprints-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.reload-fingerprints`
`table`
Cached file/module fingerprints that let extension reload report checked and changed modules across reloads.
*tags:* extensions, state, reload
_packages/core/src/fen/core/extensions/state.fnl:105_

### <a id="fen-core-extensions-state-runtime-info-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.runtime-info`
`table|nil`
Sanitized runtime/build metadata injected by fen.main and attached to durable diagnostics.
*tags:* extensions, state, diagnostics
_packages/core/src/fen/core/extensions/state.fnl:111_

### <a id="fen-core-extensions-state-errors-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.errors`
`[ExtensionError]`
Bounded in-memory list of sanitized extension/event-bus errors for diagnostics and user-facing commands.
*tags:* extensions, state, diagnostics
_packages/core/src/fen/core/extensions/state.fnl:117_

### <a id="fen-core-extensions-state-error-log-path-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.error-log-path`
`string|nil`
Lazily initialized JSONL path where extension and event-bus errors are mirrored for postmortem inspection.
*tags:* extensions, state, diagnostics
_packages/core/src/fen/core/extensions/state.fnl:123_

### <a id="fen-core-extensions-state-ui-packages-core-src-fen-core-extensions-state-fnl-135"></a>`fen.core.extensions.state.ui`
`table`
Persistent presenter UI slot wrapper whose identity survives reload while active presenter behavior changes underneath.
*tags:* extensions, state, ui, reload
_packages/core/src/fen/core/extensions/state.fnl:129_

## <a id="fen-core-extensions-test-api"></a>fen.core.extensions.test_api

### <a id="fen-core-extensions-test-api-reset-bang-packages-core-src-fen-core-extensions-test-api-fnl-41"></a>`fen.core.extensions.test_api.reset!`
`(reset!) -> nil`
Wipe all extension registries in place for tests without requiring the broad runtime facade.
*tags:* extensions, testing, reset
_packages/core/src/fen/core/extensions/test_api.fnl:36_

### <a id="fen-core-extensions-test-api-make-runtime-api-packages-core-src-fen-core-extensions-test-api-fnl-74"></a>`fen.core.extensions.test_api.make-runtime-api`
_packages/core/src/fen/core/extensions/test_api.fnl:74_

### <a id="fen-core-extensions-test-api-make-packages-core-src-fen-core-extensions-test-api-fnl-86"></a>`fen.core.extensions.test_api.make`
`(make ?owner ?manifest) -> ExtensionApi`
Build a captured extension API for tests, resetting global extension state and recording registrations, prompts, and events.
*tags:* extensions, testing, api
_packages/core/src/fen/core/extensions/test_api.fnl:81_

## <a id="fen-core-extensions-util"></a>fen.core.extensions.util

### <a id="fen-core-extensions-util-deep-copy-packages-core-src-fen-core-extensions-util-fnl-8"></a>`fen.core.extensions.util.deep-copy`
`(deep-copy v) -> any`
Recursively copy Lua tables so extension registry records cannot mutate caller-owned contribution specs.
*tags:* extensions, registry, util
_packages/core/src/fen/core/extensions/util.fnl:3_

### <a id="fen-core-extensions-util-freeze-packages-core-src-fen-core-extensions-util-fnl-21"></a>`fen.core.extensions.util.freeze`
`(freeze t) -> table`
Return a recursive read-only proxy around a copied table for safe extension-facing introspection lists.
*tags:* extensions, registry, introspection
_packages/core/src/fen/core/extensions/util.fnl:16_

### <a id="fen-core-extensions-util-remove-where-packages-core-src-fen-core-extensions-util-fnl-46"></a>`fen.core.extensions.util.remove-where`
`(remove-where t pred) -> nil`
Mutate an array-like table in place, removing entries whose predicate returns true while iterating from the end.
*tags:* extensions, registry, util
_packages/core/src/fen/core/extensions/util.fnl:41_

### <a id="fen-core-extensions-util-clear-table-packages-core-src-fen-core-extensions-util-fnl-57"></a>`fen.core.extensions.util.clear-table`
`(clear-table t) -> nil`
Delete every key from an existing table so long-lived state table identity survives reloads and resets.
*tags:* extensions, reload, state
_packages/core/src/fen/core/extensions/util.fnl:52_

### <a id="fen-core-extensions-util-add-tagged-bang-packages-core-src-fen-core-extensions-util-fnl-65"></a>`fen.core.extensions.util.add-tagged!`
`(add-tagged! list spec owner) -> record, unregister-fn`
Append a deep-copied owner-tagged contribution to an array registry and return the record plus identity-based unregister closure.
*tags:* extensions, registry, owner
_packages/core/src/fen/core/extensions/util.fnl:60_

### <a id="fen-core-extensions-util-set-tagged-bang-packages-core-src-fen-core-extensions-util-fnl-81"></a>`fen.core.extensions.util.set-tagged!`
`(set-tagged! dict name spec owner) -> record, unregister-fn`
Install a deep-copied owner-tagged singleton registry entry and return a stale-safe unregister closure.
*tags:* extensions, registry, owner
_packages/core/src/fen/core/extensions/util.fnl:76_

## <a id="fen-core-llm"></a>fen.core.llm

### <a id="fen-core-llm-register-packages-core-src-fen-core-llm-init-fnl-78"></a>`fen.core.llm.register`
`(register provider) -> provider`
Compatibility helper for in-process callers/tests. Prefer (extensions.register :provider provider owner) in extensions.
*tags:* provider, llm
_packages/core/src/fen/core/llm/init.fnl:11_

### <a id="fen-core-llm-get-provider-packages-core-src-fen-core-llm-init-fnl-78"></a>`fen.core.llm.get-provider`
`(get-provider provider-name) -> provider`
Resolve a provider by registered :name. Errors if the name is unknown.
*tags:* provider, llm
_packages/core/src/fen/core/llm/init.fnl:22_

### <a id="fen-core-llm-complete-packages-core-src-fen-core-llm-init-fnl-78"></a>`fen.core.llm.complete`
`(complete provider-name model context options ?on-event ?yield-fn) -> AssistantMessage`
Dispatch a completion to the named provider. Returns a canonical AssistantMessage. The provider chooses native streaming, cooperative-yield streaming, or blocking based on which callbacks are present.
*tags:* provider, llm
_packages/core/src/fen/core/llm/init.fnl:67_

### <a id="fen-core-llm-emit-block-events-packages-core-src-fen-core-llm-init-fnl-78"></a>`fen.core.llm.emit-block-events`
`(emit-block-events asst emit) -> nil`
Synthesize streaming block events from a complete AssistantMessage. Compatibility bridge for providers that do not implement :complete-stream natively.
*tags:* provider, llm, streaming
_packages/core/src/fen/core/llm/init.fnl:31_

## <a id="fen-core-llm-event-stream"></a>fen.core.llm.event_stream

### <a id="fen-core-llm-event-stream-new-stream-packages-core-src-fen-core-llm-event-stream-fnl-65"></a>`fen.core.llm.event_stream.new-stream`
`(new-stream on-event) -> AssistantEventStream`
Create a synchronous assistant-event sink that records events, forwards them to an observer, and captures the final result.
*tags:* llm, events, stream
_packages/core/src/fen/core/llm/event_stream.fnl:30_

### <a id="fen-core-llm-event-stream-terminal-event-q-packages-core-src-fen-core-llm-event-stream-fnl-65"></a>`fen.core.llm.event_stream.terminal-event?`
`(terminal-event? ev) -> boolean`
Return true when an assistant stream event terminates the stream with either :done or :error.
*tags:* llm, events, stream
_packages/core/src/fen/core/llm/event_stream.fnl:9_

### <a id="fen-core-llm-event-stream-event-result-packages-core-src-fen-core-llm-event-stream-fnl-65"></a>`fen.core.llm.event_stream.event-result`
`(event-result ev) -> AssistantMessage|string|nil`
Extract the final AssistantMessage or error payload carried by a terminal assistant stream event.
*tags:* llm, events, stream
_packages/core/src/fen/core/llm/event_stream.fnl:18_

## <a id="fen-core-llm-models"></a>fen.core.llm.models

### <a id="fen-core-llm-models-config-dir-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.config-dir`
`(config-dir) -> string`
Return fen's user configuration directory, honoring XDG_CONFIG_HOME through the shared path helper.
*tags:* models, config, paths
_packages/core/src/fen/core/llm/models.fnl:16_

### <a id="fen-core-llm-models-config-path-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.config-path`
`(config-path) -> string`
Return the models.json path used for custom provider and model registry configuration.
*tags:* models, config, paths
_packages/core/src/fen/core/llm/models.fnl:24_

### <a id="fen-core-llm-models-load-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.load`
`(load) -> table`
Load and cache the raw providers map from models.json, returning an empty table for missing or malformed config.
*tags:* models, config, providers
_packages/core/src/fen/core/llm/models.fnl:94_

### <a id="fen-core-llm-models-get-provider-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.get-provider`
`(get-provider name) -> ModelsProvider|nil`
Return the normalized models.json provider record for name, including api, base-url, api-key, compat, and models.
*tags:* models, config, providers
_packages/core/src/fen/core/llm/models.fnl:120_

### <a id="fen-core-llm-models-register-providers-bang-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.register-providers!`
`(register-providers!) -> number`
Register every valid models.json provider into the extension registry under owner :models_json and return the count installed.
*tags:* models, providers, extensions
_packages/core/src/fen/core/llm/models.fnl:173_

### <a id="fen-core-llm-models-resolve-api-key-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.resolve-api-key`
`(resolve-api-key value) -> string|nil`
Resolve a models.json apiKey field by treating nil/empty values as absent and all-caps values as environment variable names.
*tags:* models, config, auth
_packages/core/src/fen/core/llm/models.fnl:58_

### <a id="fen-core-llm-models-looks-like-env-var-q-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.looks-like-env-var?`
`(looks-like-env-var? s) -> boolean`
Return true when an apiKey string looks like an environment variable name rather than a literal credential.
*tags:* models, config, auth
_packages/core/src/fen/core/llm/models.fnl:41_

### <a id="fen-core-llm-models-first-model-id-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.first-model-id`
`(first-model-id provider) -> string|nil`
Pick the first declared model id from a normalized provider record for default-model selection.
*tags:* models, providers, defaults
_packages/core/src/fen/core/llm/models.fnl:130_

### <a id="fen-core-llm-models-available-models-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.available-models`
`(available-models opts) -> [ModelRef]`
Return selectable model refs from registered providers, filtering credential-gated built-ins until auth is configured.
*tags:* models, providers, resolve
_packages/core/src/fen/core/llm/models.fnl:256_

### <a id="fen-core-llm-models-canonical-model-id-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.canonical-model-id`
`(canonical-model-id model-ref) -> string`
Format a model reference as the canonical provider/id string accepted by model resolution and displayed by commands.
*tags:* models, resolve
_packages/core/src/fen/core/llm/models.fnl:208_

### <a id="fen-core-llm-models-resolve-model-exact-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.resolve-model-exact`
`(resolve-model-exact query models) -> {:status :model :candidates}`
Resolve an exact model query by canonical provider/id first and then by unique bare model id.
*tags:* models, resolve
_packages/core/src/fen/core/llm/models.fnl:290_

### <a id="fen-core-llm-models-resolve-model-packages-core-src-fen-core-llm-models-fnl-325"></a>`fen.core.llm.models.resolve-model`
`(resolve-model query models) -> {:status :model :candidates}`
Resolve a model query by exact provider/id or bare id first, then by unique substring over provider/id or id.
*tags:* models, resolve
_packages/core/src/fen/core/llm/models.fnl:305_

## <a id="fen-core-llm-retry"></a>fen.core.llm.retry

### <a id="fen-core-llm-retry-default-max-attempts-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.DEFAULT-MAX-ATTEMPTS`
`number`
Default maximum number of provider HTTP attempts, including the initial try and transient retries.
*tags:* llm, retry, defaults
_packages/core/src/fen/core/llm/retry.fnl:9_

### <a id="fen-core-llm-retry-default-base-delay-ms-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.DEFAULT-BASE-DELAY-MS`
`number`
Default base delay in milliseconds used as the first exponential-backoff jitter cap.
*tags:* llm, retry, defaults
_packages/core/src/fen/core/llm/retry.fnl:16_

### <a id="fen-core-llm-retry-default-max-delay-ms-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.DEFAULT-MAX-DELAY-MS`
`number`
Default maximum jitter cap in milliseconds for provider retry backoff delays.
*tags:* llm, retry, defaults
_packages/core/src/fen/core/llm/retry.fnl:23_

### <a id="fen-core-llm-retry-transient-q-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.transient?`
`(transient? status err-message ?curl-code) -> boolean`
Return true for provider HTTP status or curl code that is safe to retry below the agent message layer.
*tags:* llm, http, retry
_packages/core/src/fen/core/llm/retry.fnl:53_

### <a id="fen-core-llm-retry-mark-incomplete-stream-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.mark-incomplete-stream`
_packages/core/src/fen/core/llm/retry.fnl:237_

### <a id="fen-core-llm-retry-options-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.options`
`(options provider ?opts ?on-event) -> table`
Build with-retry options from provider request opts, honoring AGENT_FENNEL_RETRY=0 and emitting tagged :provider-retry events.
*tags:* llm, http, retry
_packages/core/src/fen/core/llm/retry.fnl:175_

### <a id="fen-core-llm-retry-parse-retry-after-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.parse-retry-after`
`(parse-retry-after headers) -> number|nil`
Parse Retry-After or retry-after-ms response headers into a millisecond delay for provider backoff.
*tags:* llm, http, retry
_packages/core/src/fen/core/llm/retry.fnl:97_

### <a id="fen-core-llm-retry-backoff-delay-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.backoff-delay`
`(backoff-delay attempt base-ms max-ms) -> number`
Compute a full-jitter exponential backoff delay in milliseconds for the given failed attempt number.
*tags:* llm, http, retry
_packages/core/src/fen/core/llm/retry.fnl:116_

### <a id="fen-core-llm-retry-with-retry-packages-core-src-fen-core-llm-retry-fnl-237"></a>`fen.core.llm.retry.with-retry`
`(with-retry opts make-request ?yield!) -> response`
Run a provider request with bounded retry, Retry-After support, jittered backoff, and cooperative cancellation yields.
*tags:* llm, http, retry
_packages/core/src/fen/core/llm/retry.fnl:202_

## <a id="fen-core-prompt"></a>fen.core.prompt

### <a id="fen-core-prompt-build-context-packages-core-src-fen-core-prompt-fnl-16"></a>`fen.core.prompt.build-context`
`(build-context opts tools) -> table`
Build the minimal context table passed to registered system-prompt fragment renderers.
*tags:* prompt, extensions, context
_packages/core/src/fen/core/prompt.fnl:11_

### <a id="fen-core-prompt-build-packages-core-src-fen-core-prompt-fnl-25"></a>`fen.core.prompt.build`
`(build opts tools) -> string`
Render all extension-contributed system-prompt fragments for opts/tools and return an empty string when none render.
*tags:* prompt, extensions
_packages/core/src/fen/core/prompt.fnl:20_

## <a id="fen-core-settings"></a>fen.core.settings

### <a id="fen-core-settings-config-dir-packages-core-src-fen-core-settings-fnl-20"></a>`fen.core.settings.config-dir`
`(config-dir) -> string`
Return fen's user configuration directory, honoring XDG_CONFIG_HOME through the shared path helper.
*tags:* settings, config, paths
_packages/core/src/fen/core/settings.fnl:15_

### <a id="fen-core-settings-config-path-packages-core-src-fen-core-settings-fnl-28"></a>`fen.core.settings.config-path`
`(config-path) -> string`
Return the settings.json path used for mutable user preferences such as the default provider and model.
*tags:* settings, config, paths
_packages/core/src/fen/core/settings.fnl:23_

### <a id="fen-core-settings-load-packages-core-src-fen-core-settings-fnl-65"></a>`fen.core.settings.load`
`(load ?p) -> Settings`
Load normalized user settings from settings.json, returning an empty record for missing or malformed files.
*tags:* settings, config
_packages/core/src/fen/core/settings.fnl:60_

### <a id="fen-core-settings-save-bang-packages-core-src-fen-core-settings-fnl-92"></a>`fen.core.settings.save!`
`(save! settings ?p) -> Settings`
Atomically write normalized default-provider/default-model settings while preserving unknown top-level keys already on disk.
*tags:* settings, config, write
_packages/core/src/fen/core/settings.fnl:87_

### <a id="fen-core-settings-set-defaults-bang-packages-core-src-fen-core-settings-fnl-111"></a>`fen.core.settings.set-defaults!`
`(set-defaults! provider model ?p) -> Settings`
Persist the default provider and model selected by commands, then return the normalized settings record.
*tags:* settings, config, models
_packages/core/src/fen/core/settings.fnl:106_

### <a id="fen-core-settings-set-thinking-default-bang-packages-core-src-fen-core-settings-fnl-120"></a>`fen.core.settings.set-thinking-default!`
`(set-thinking-default! level ?p) -> Settings`
Persist the default provider-neutral thinking level and return the normalized settings record.
*tags:* settings, config, thinking
_packages/core/src/fen/core/settings.fnl:115_

## <a id="fen-core-thinking"></a>fen.core.thinking

### <a id="fen-core-thinking-normalize-level-packages-core-src-fen-core-thinking-fnl-61"></a>`fen.core.thinking.normalize-level`
_packages/core/src/fen/core/thinking.fnl:61_

### <a id="fen-core-thinking-valid-level-q-packages-core-src-fen-core-thinking-fnl-61"></a>`fen.core.thinking.valid-level?`
_packages/core/src/fen/core/thinking.fnl:61_

### <a id="fen-core-thinking-levels-packages-core-src-fen-core-thinking-fnl-61"></a>`fen.core.thinking.levels`
_packages/core/src/fen/core/thinking.fnl:61_

### <a id="fen-core-thinking-level-list-packages-core-src-fen-core-thinking-fnl-61"></a>`fen.core.thinking.level-list`
_packages/core/src/fen/core/thinking.fnl:61_

### <a id="fen-core-thinking-level-packages-core-src-fen-core-thinking-fnl-61"></a>`fen.core.thinking.level-`
_packages/core/src/fen/core/thinking.fnl:61_

_Undocumented data/state re-exports omitted from the public API listing:_ `fen.core.thinking.LEVELS`

## <a id="fen-core-tools"></a>fen.core.tools

### <a id="fen-core-tools-descriptors-packages-core-src-fen-core-tools-fnl-124"></a>`fen.core.tools.descriptors`
`(descriptors reg) -> [Tool]`
Strip executable AgentTool records down to canonical Tool descriptors passed to providers.
*tags:* tools, providers
_packages/core/src/fen/core/tools.fnl:22_

### <a id="fen-core-tools-execute-call-packages-core-src-fen-core-tools-fnl-124"></a>`fen.core.tools.execute-call`
`(execute-call reg tool-call ctx ?yield-fn) -> {:message :result :duration-seconds :tool-call}`
Execute one canonical ToolCall against the registered tools and wrap the result as a ToolResultMessage plus diagnostics.
*tags:* tools, agent
_packages/core/src/fen/core/tools.fnl:101_

## <a id="fen-core-types"></a>fen.core.types

### <a id="fen-core-types-now-ms-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.now-ms`
`(now-ms) -> number`
Current epoch in milliseconds. Used as the :timestamp field on canonical messages.
*tags:* types, time
_packages/core/src/fen/core/types.fnl:101_

### <a id="fen-core-types-text-block-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.text-block`
`(text-block s) -> TextContent`
Build a {:type :text :text s} block. The visible-text content kind.
*tags:* types, content-block
_packages/core/src/fen/core/types.fnl:108_

### <a id="fen-core-types-thinking-block-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.thinking-block`
`(thinking-block {: thinking : thinking-signature : redacted}) -> ThinkingContent`
Build a {:type :thinking ...} block. Carries reasoning text plus the opaque echo signature required by Anthropic extended thinking and OpenAI Responses for multi-turn echo.
*tags:* types, content-block, thinking
_packages/core/src/fen/core/types.fnl:116_

### <a id="fen-core-types-tool-call-block-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.tool-call-block`
`(tool-call-block id name args) -> ToolCall`
Build a {:type :tool-call :id :name :arguments} block. Arguments is a parsed Lua table — providers JSON-decode wire arguments before calling this.
*tags:* types, content-block, tool-call
_packages/core/src/fen/core/types.fnl:128_

### <a id="fen-core-types-user-message-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.user-message`
`(user-message content) -> UserMessage`
Build a {:role :user :content :timestamp} message. content is a string or [TextContent].
*tags:* types, message
_packages/core/src/fen/core/types.fnl:137_

### <a id="fen-core-types-assistant-message-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.assistant-message`
`(assistant-message {: content : api : provider : model : usage : stop-reason : error-message}) -> AssistantMessage`
Build a canonical AssistantMessage. Content defaults to []; usage and stop-reason fall back to safe defaults; error-message is set only when provided.
*tags:* types, message, assistant
_packages/core/src/fen/core/types.fnl:148_

### <a id="fen-core-types-tool-result-message-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.tool-result-message`
`(tool-result-message {: tool-call-id : tool-name : content : details : is-error?}) -> ToolResultMessage`
Build a canonical ToolResultMessage. content is always an array; details is opaque presenter payload.
*tags:* types, message, tool-result
_packages/core/src/fen/core/types.fnl:166_

### <a id="fen-core-types-assistant-error-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.assistant-error`
`(assistant-error api provider model error-message) -> AssistantMessage`
Build an AssistantMessage representing a transport/HTTP failure. Sets stop-reason :error and inserts a synthetic "[error] ..." text block.
*tags:* types, message, error
_packages/core/src/fen/core/types.fnl:182_

### <a id="fen-core-types-incomplete-stream-msg-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.INCOMPLETE-STREAM-MSG`
`string`
Error message for a 2xx stream that closed without a terminal completion event. Shared so provider finalizers and their tests can't drift.
*tags:* types, message, error, streaming
_packages/core/src/fen/core/types.fnl:195_

### <a id="fen-core-types-assistant-text-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.assistant-text`
`(assistant-text msg) -> string`
Concatenate every TextContent block in msg.content. Returns "" if there are no text blocks.
*tags:* types, message, accessor
_packages/core/src/fen/core/types.fnl:202_

### <a id="fen-core-types-assistant-tool-calls-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.assistant-tool-calls`
`(assistant-tool-calls msg) -> [ToolCall]`
Return every :tool-call block in msg.content, in source order.
*tags:* types, message, accessor, tool-call
_packages/core/src/fen/core/types.fnl:222_

### <a id="fen-core-types-assistant-thinking-packages-core-src-fen-core-types-fnl-236"></a>`fen.core.types.assistant-thinking`
`(assistant-thinking msg) -> [ThinkingContent]`
Return every :thinking block in msg.content, in source order.
*tags:* types, message, accessor, thinking
_packages/core/src/fen/core/types.fnl:229_

## <a id="fen-extensions-agent-state"></a>fen.extensions.agent_state

### <a id="fen-extensions-agent-state-register-extensions-behaviors-companions-agent-state-init-fnl-12"></a>`fen.extensions.agent_state.register`
_extensions/behaviors/companions/agent-state/init.fnl:12_

## <a id="fen-extensions-agent-state-tool"></a>fen.extensions.agent_state.tool

### <a id="fen-extensions-agent-state-tool-execute-extensions-behaviors-companions-agent-state-tool-fnl-558"></a>`fen.extensions.agent_state.tool.execute`
`(execute args ctx ?api ?yield-fn) -> AgentToolResult`
Execute an agent_state query against sanitized agent context and render the result as JSON or Fennel with truncation. Cooperative: yields before evaluation and inside expensive branches when ?yield-fn is given.
*tags:* tool, agent-state, execute
_extensions/behaviors/companions/agent-state/tool.fnl:531_

### <a id="fen-extensions-agent-state-tool-parse-query-extensions-behaviors-companions-agent-state-tool-fnl-558"></a>`fen.extensions.agent_state.tool.parse-query`
`(parse-query s) -> expr|nil, err|nil`
Parse the agent_state mini-query language into an expression tree, returning a user-facing parse error on invalid input.
*tags:* tool, agent-state, query
_extensions/behaviors/companions/agent-state/tool.fnl:146_

### <a id="fen-extensions-agent-state-tool-eval-query-extensions-behaviors-companions-agent-state-tool-fnl-558"></a>`fen.extensions.agent_state.tool.eval-query`
`(eval-query expr state) -> any`
Evaluate the parsed agent_state query operators against the sanitized snapshot without exposing general code execution.
*tags:* tool, agent-state, query, eval
_extensions/behaviors/companions/agent-state/tool.fnl:503_

### <a id="fen-extensions-agent-state-tool-sanitized-state-extensions-behaviors-companions-agent-state-tool-fnl-558"></a>`fen.extensions.agent_state.tool.sanitized-state`
`(sanitized-state agent api ?ctx) -> table`
Build the redacted agent-state snapshot exposed to the agent_state tool without leaking raw mutable agent internals.
*tags:* tool, agent-state, introspection
_extensions/behaviors/companions/agent-state/tool.fnl:389_

## <a id="fen-extensions-builtin-tools"></a>fen.extensions.builtin_tools

### <a id="fen-extensions-builtin-tools-register-extensions-behaviors-kernel-builtin-tools-init-fnl-11"></a>`fen.extensions.builtin_tools.register`
_extensions/behaviors/kernel/builtin-tools/init.fnl:11_

## <a id="fen-extensions-builtin-tools-bash"></a>fen.extensions.builtin_tools.bash

### <a id="fen-extensions-builtin-tools-bash-name-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.name`
`keyword`
Registry name for the built-in Bash tool descriptor advertised to providers and slash-command docs.
*tags:* builtin, tools, bash, descriptor
_extensions/behaviors/kernel/builtin-tools/bash.fnl:3_

### <a id="fen-extensions-builtin-tools-bash-bash-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.bash`
`AgentToolSpec`
Complete Bash tool specification exported by the module for registration in the built-in tool registry.
*tags:* builtin, tools, bash, descriptor
_extensions/behaviors/kernel/builtin-tools/bash.fnl:9_

### <a id="fen-extensions-builtin-tools-bash-label-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.label`
`string`
Human-readable label shown in tool-running status and generated tool listings before shell commands.
*tags:* builtin, tools, bash, ui
_extensions/behaviors/kernel/builtin-tools/bash.fnl:15_

### <a id="fen-extensions-builtin-tools-bash-snippet-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.snippet`
`string`
Short Bash tool teaser used by generated docs and compact tool summaries before the full description.
*tags:* builtin, tools, bash, docs
_extensions/behaviors/kernel/builtin-tools/bash.fnl:21_

### <a id="fen-extensions-builtin-tools-bash-description-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.description`
`string`
Provider-facing Bash tool description documenting merged stdout/stderr and tail-truncation behavior.
*tags:* builtin, tools, bash, docs
_extensions/behaviors/kernel/builtin-tools/bash.fnl:27_

### <a id="fen-extensions-builtin-tools-bash-parameters-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.parameters`
`JSONSchema`
JSON schema for Bash tool arguments, including command text, optional timeout, and checked working directory.
*tags:* builtin, tools, bash, schema
_extensions/behaviors/kernel/builtin-tools/bash.fnl:33_

### <a id="fen-extensions-builtin-tools-bash-execute-extensions-behaviors-kernel-builtin-tools-bash-fnl-110"></a>`fen.extensions.builtin_tools.bash.execute`
`(execute args ctx yield-fn?) -> AgentToolResult`
Bash tool executor that runs a shell command through the timed/cancellable process helper and returns capped output with exit status.
*tags:* builtin, tools, bash, execution
_extensions/behaviors/kernel/builtin-tools/bash.fnl:39_

## <a id="fen-extensions-builtin-tools-edit"></a>fen.extensions.builtin_tools.edit

### <a id="fen-extensions-builtin-tools-edit-name-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.name`
`keyword`
Registry name for the built-in exact-replacement edit tool descriptor.
*tags:* builtin, tools, edit, descriptor
_extensions/behaviors/kernel/builtin-tools/edit.fnl:5_

### <a id="fen-extensions-builtin-tools-edit-edit-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.edit`
`AgentToolSpec`
Complete edit tool specification exported for registration with batch and single-file replacement modes.
*tags:* builtin, tools, edit, descriptor
_extensions/behaviors/kernel/builtin-tools/edit.fnl:11_

### <a id="fen-extensions-builtin-tools-edit-label-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.label`
`string`
Human-readable label shown in tool-running status and generated listings for exact text edits.
*tags:* builtin, tools, edit, ui
_extensions/behaviors/kernel/builtin-tools/edit.fnl:17_

### <a id="fen-extensions-builtin-tools-edit-snippet-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.snippet`
`string`
Short edit tool teaser describing precise replacements for compact generated docs.
*tags:* builtin, tools, edit, docs
_extensions/behaviors/kernel/builtin-tools/edit.fnl:23_

### <a id="fen-extensions-builtin-tools-edit-description-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.description`
`string`
Provider-facing edit tool description covering uniqueness, snapshot application, and all-or-nothing batch validation.
*tags:* builtin, tools, edit, docs
_extensions/behaviors/kernel/builtin-tools/edit.fnl:29_

### <a id="fen-extensions-builtin-tools-edit-parameters-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.parameters`
`JSONSchema`
JSON schema for single-file and batch edit payloads, including exact old and replacement strings.
*tags:* builtin, tools, edit, schema
_extensions/behaviors/kernel/builtin-tools/edit.fnl:35_

### <a id="fen-extensions-builtin-tools-edit-execute-extensions-behaviors-kernel-builtin-tools-edit-fnl-203"></a>`fen.extensions.builtin_tools.edit.execute`
`(execute args ctx? yield-fn?) -> AgentToolResult`
Edit tool executor that validates mutually exclusive modes, yields between large validation/write phases, applies exact replacements, and reports write summaries.
*tags:* builtin, tools, edit, execution
_extensions/behaviors/kernel/builtin-tools/edit.fnl:41_

## <a id="fen-extensions-builtin-tools-find"></a>fen.extensions.builtin_tools.find

### <a id="fen-extensions-builtin-tools-find-name-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.name`
`keyword`
Registry name for the built-in recursive file find tool descriptor.
*tags:* builtin, tools, find, descriptor
_extensions/behaviors/kernel/builtin-tools/find.fnl:5_

### <a id="fen-extensions-builtin-tools-find-find-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.find`
`AgentToolSpec`
Complete find tool specification exported for name-glob file discovery through the built-in registry.
*tags:* builtin, tools, find, descriptor
_extensions/behaviors/kernel/builtin-tools/find.fnl:11_

### <a id="fen-extensions-builtin-tools-find-label-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.label`
`string`
Human-readable label shown in tool-running status and generated listings for file discovery.
*tags:* builtin, tools, find, ui
_extensions/behaviors/kernel/builtin-tools/find.fnl:17_

### <a id="fen-extensions-builtin-tools-find-snippet-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.snippet`
`string`
Short find tool teaser used by generated docs and compact tool summaries.
*tags:* builtin, tools, find, docs
_extensions/behaviors/kernel/builtin-tools/find.fnl:23_

### <a id="fen-extensions-builtin-tools-find-description-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.description`
`string`
Provider-facing find tool description for recursive filename-glob searches.
*tags:* builtin, tools, find, docs
_extensions/behaviors/kernel/builtin-tools/find.fnl:29_

### <a id="fen-extensions-builtin-tools-find-parameters-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.parameters`
`JSONSchema`
JSON schema for find arguments, including required name glob, optional root path, and result limit.
*tags:* builtin, tools, find, schema
_extensions/behaviors/kernel/builtin-tools/find.fnl:35_

### <a id="fen-extensions-builtin-tools-find-execute-extensions-behaviors-kernel-builtin-tools-find-fnl-64"></a>`fen.extensions.builtin_tools.find.execute`
`(execute args ctx? yield-fn?) -> AgentToolResult`
Find tool executor that shells out to POSIX find, limits result lines, and cooperatively drains output when a yield-fn is provided.
*tags:* builtin, tools, find, execution
_extensions/behaviors/kernel/builtin-tools/find.fnl:41_

## <a id="fen-extensions-builtin-tools-grep"></a>fen.extensions.builtin_tools.grep

### <a id="fen-extensions-builtin-tools-grep-name-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.name`
`keyword`
Registry name for the built-in recursive grep tool descriptor.
*tags:* builtin, tools, grep, descriptor
_extensions/behaviors/kernel/builtin-tools/grep.fnl:5_

### <a id="fen-extensions-builtin-tools-grep-grep-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.grep`
`AgentToolSpec`
Complete grep tool specification exported for content search through the built-in registry.
*tags:* builtin, tools, grep, descriptor
_extensions/behaviors/kernel/builtin-tools/grep.fnl:11_

### <a id="fen-extensions-builtin-tools-grep-label-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.label`
`string`
Human-readable label shown in tool-running status and generated listings for text searches.
*tags:* builtin, tools, grep, ui
_extensions/behaviors/kernel/builtin-tools/grep.fnl:17_

### <a id="fen-extensions-builtin-tools-grep-snippet-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.snippet`
`string`
Short grep tool teaser used by generated docs before the full search option contract.
*tags:* builtin, tools, grep, docs
_extensions/behaviors/kernel/builtin-tools/grep.fnl:23_

### <a id="fen-extensions-builtin-tools-grep-description-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.description`
`string`
Provider-facing grep tool description covering recursive regex search behavior.
*tags:* builtin, tools, grep, docs
_extensions/behaviors/kernel/builtin-tools/grep.fnl:29_

### <a id="fen-extensions-builtin-tools-grep-parameters-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.parameters`
`JSONSchema`
JSON schema for grep arguments, including pattern, path, glob, literal, case, context, and limit controls.
*tags:* builtin, tools, grep, schema
_extensions/behaviors/kernel/builtin-tools/grep.fnl:35_

### <a id="fen-extensions-builtin-tools-grep-execute-extensions-behaviors-kernel-builtin-tools-grep-fnl-72"></a>`fen.extensions.builtin_tools.grep.execute`
`(execute args ctx? yield-fn?) -> AgentToolResult`
Grep tool executor that builds a POSIX grep pipeline, enforces an output limit, and cooperatively drains matches when a yield-fn is provided.
*tags:* builtin, tools, grep, execution
_extensions/behaviors/kernel/builtin-tools/grep.fnl:41_

## <a id="fen-extensions-builtin-tools-ls"></a>fen.extensions.builtin_tools.ls

### <a id="fen-extensions-builtin-tools-ls-name-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.name`
`keyword`
Registry name for the built-in directory listing tool descriptor.
*tags:* builtin, tools, ls, descriptor
_extensions/behaviors/kernel/builtin-tools/ls.fnl:7_

### <a id="fen-extensions-builtin-tools-ls-ls-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.ls`
`AgentToolSpec`
Complete ls tool specification exported for listing directory entries through the built-in registry.
*tags:* builtin, tools, ls, descriptor
_extensions/behaviors/kernel/builtin-tools/ls.fnl:13_

### <a id="fen-extensions-builtin-tools-ls-label-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.label`
`string`
Human-readable label shown in tool-running status and generated listings for directory scans.
*tags:* builtin, tools, ls, ui
_extensions/behaviors/kernel/builtin-tools/ls.fnl:19_

### <a id="fen-extensions-builtin-tools-ls-snippet-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.snippet`
`string`
Short ls tool teaser used by generated docs and compact tool summaries.
*tags:* builtin, tools, ls, docs
_extensions/behaviors/kernel/builtin-tools/ls.fnl:25_

### <a id="fen-extensions-builtin-tools-ls-description-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.description`
`string`
Provider-facing ls tool description for shallow directory entry listings.
*tags:* builtin, tools, ls, docs
_extensions/behaviors/kernel/builtin-tools/ls.fnl:31_

### <a id="fen-extensions-builtin-tools-ls-parameters-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.parameters`
`JSONSchema`
JSON schema for ls arguments, including optional target directory and output line limit.
*tags:* builtin, tools, ls, schema
_extensions/behaviors/kernel/builtin-tools/ls.fnl:37_

### <a id="fen-extensions-builtin-tools-ls-execute-extensions-behaviors-kernel-builtin-tools-ls-fnl-72"></a>`fen.extensions.builtin_tools.ls.execute`
`(execute args ctx? yield-fn?) -> AgentToolResult`
Ls tool executor that shells out to POSIX ls, cooperatively drains output when a yield-fn is provided, applies optional limits, and caps long output.
*tags:* builtin, tools, ls, execution
_extensions/behaviors/kernel/builtin-tools/ls.fnl:43_

## <a id="fen-extensions-builtin-tools-read"></a>fen.extensions.builtin_tools.read

### <a id="fen-extensions-builtin-tools-read-name-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.name`
`keyword`
Registry name for the built-in file read tool descriptor.
*tags:* builtin, tools, read, descriptor
_extensions/behaviors/kernel/builtin-tools/read.fnl:7_

### <a id="fen-extensions-builtin-tools-read-read-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.read`
`AgentToolSpec`
Complete read tool specification exported for single-file and batched file inspection.
*tags:* builtin, tools, read, descriptor
_extensions/behaviors/kernel/builtin-tools/read.fnl:13_

### <a id="fen-extensions-builtin-tools-read-label-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.label`
`string`
Human-readable label shown in tool-running status and generated listings for file reads.
*tags:* builtin, tools, read, ui
_extensions/behaviors/kernel/builtin-tools/read.fnl:19_

### <a id="fen-extensions-builtin-tools-read-snippet-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.snippet`
`string`
Short read tool teaser used by generated docs before the full paging and truncation contract.
*tags:* builtin, tools, read, docs
_extensions/behaviors/kernel/builtin-tools/read.fnl:25_

### <a id="fen-extensions-builtin-tools-read-description-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.description`
`string`
Provider-facing read tool description covering full slurps, offset/limit paging, batched reads, and truncation tags.
*tags:* builtin, tools, read, docs
_extensions/behaviors/kernel/builtin-tools/read.fnl:31_

### <a id="fen-extensions-builtin-tools-read-parameters-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.parameters`
`JSONSchema`
JSON schema for read arguments, including path, batched paths, and optional line window controls.
*tags:* builtin, tools, read, schema
_extensions/behaviors/kernel/builtin-tools/read.fnl:37_

### <a id="fen-extensions-builtin-tools-read-execute-extensions-behaviors-kernel-builtin-tools-read-fnl-120"></a>`fen.extensions.builtin_tools.read.execute`
`(execute args ctx? yield-fn?) -> AgentToolResult`
Read tool executor that dispatches single or batch reads, yielding during large file and batch work when cooperative.
*tags:* builtin, tools, read, execution
_extensions/behaviors/kernel/builtin-tools/read.fnl:43_

## <a id="fen-extensions-builtin-tools-registry"></a>fen.extensions.builtin_tools.registry

### <a id="fen-extensions-builtin-tools-registry-registry-extensions-behaviors-kernel-builtin-tools-registry-fnl-17"></a>`fen.extensions.builtin_tools.registry.registry`
`[AgentToolSpec]`
Ordered list of built-in tool specifications registered by the builtin-tools extension and reused by tests.
*tags:* builtin, tools, registry
_extensions/behaviors/kernel/builtin-tools/registry.fnl:3_

## <a id="fen-extensions-builtin-tools-truncate"></a>fen.extensions.builtin_tools.truncate

### <a id="fen-extensions-builtin-tools-truncate-default-max-lines-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181"></a>`fen.extensions.builtin_tools.truncate.DEFAULT-MAX-LINES`
`number`
Default maximum number of tool-output lines kept inline before truncation spills the full output.
*tags:* builtin, tools, truncate, defaults
_extensions/behaviors/kernel/builtin-tools/truncate.fnl:3_

### <a id="fen-extensions-builtin-tools-truncate-default-max-bytes-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181"></a>`fen.extensions.builtin_tools.truncate.DEFAULT-MAX-BYTES`
`number`
Default maximum number of tool-output bytes kept inline before truncation writes a spill file.
*tags:* builtin, tools, truncate, defaults
_extensions/behaviors/kernel/builtin-tools/truncate.fnl:10_

### <a id="fen-extensions-builtin-tools-truncate-truncate-head-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181"></a>`fen.extensions.builtin_tools.truncate.truncate-head`
`(truncate-head s opts? yield-fn?) -> string, truncated?`
Keep the beginning of tool output within max-lines/max-bytes, yielding during scans and full-output spills when cooperative.
*tags:* tools, output, truncate
_extensions/behaviors/kernel/builtin-tools/truncate.fnl:96_

### <a id="fen-extensions-builtin-tools-truncate-truncate-tail-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181"></a>`fen.extensions.builtin_tools.truncate.truncate-tail`
`(truncate-tail s opts? yield-fn?) -> string, truncated?`
Keep the end of tool output within max-lines/max-bytes, yielding during scans and full-output spills when cooperative.
*tags:* tools, output, truncate
_extensions/behaviors/kernel/builtin-tools/truncate.fnl:133_

## <a id="fen-extensions-builtin-tools-util"></a>fen.extensions.builtin_tools.util

### <a id="fen-extensions-builtin-tools-util-agent-result-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.agent-result`
`(agent-result content is-error? details) -> AgentToolResult`
Build the common AgentToolResult shape used by built-in tools, preserving optional presenter details.
*tags:* tools, results, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:3_

### <a id="fen-extensions-builtin-tools-util-ok-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.ok`
`(ok text) -> AgentToolResult`
Wrap successful plain text output as a canonical non-error AgentToolResult.
*tags:* tools, results, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:13_

### <a id="fen-extensions-builtin-tools-util-err-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.err`
`(err message) -> AgentToolResult`
Wrap an error message as a canonical AgentToolResult whose text is prefixed with error:.
*tags:* tools, results, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:21_

### <a id="fen-extensions-builtin-tools-util-shellquote-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.shellquote`
`(shellquote s) -> string`
Quote a built-in tool path or argument as one POSIX shell word for system probes.
*tags:* tools, shell, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:29_

### <a id="fen-extensions-builtin-tools-util-int-arg-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.int-arg`
`(int-arg v default) -> number`
Normalize numeric tool arguments by converting to an integer or returning the provided default.
*tags:* tools, args, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:37_

### <a id="fen-extensions-builtin-tools-util-result-text-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.result-text`
`(result-text r) -> string`
Extract the first text block from an AgentToolResult for tests and composed tool helpers.
*tags:* tools, results, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:47_

### <a id="fen-extensions-builtin-tools-util-dir-exists-q-extensions-behaviors-kernel-builtin-tools-util-fnl-69"></a>`fen.extensions.builtin_tools.util.dir-exists?`
`(dir-exists? path) -> boolean`
Check whether a path is a directory using a shell-quoted POSIX test probe.
*tags:* tools, filesystem, util
_extensions/behaviors/kernel/builtin-tools/util.fnl:56_

## <a id="fen-extensions-builtin-tools-write"></a>fen.extensions.builtin_tools.write

### <a id="fen-extensions-builtin-tools-write-name-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.name`
`keyword`
Registry name for the built-in file write tool descriptor.
*tags:* builtin, tools, write, descriptor
_extensions/behaviors/kernel/builtin-tools/write.fnl:5_

### <a id="fen-extensions-builtin-tools-write-write-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.write`
`AgentToolSpec`
Complete write tool specification exported for creating or overwriting files.
*tags:* builtin, tools, write, descriptor
_extensions/behaviors/kernel/builtin-tools/write.fnl:11_

### <a id="fen-extensions-builtin-tools-write-label-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.label`
`string`
Human-readable label shown in tool-running status and generated listings for file writes.
*tags:* builtin, tools, write, ui
_extensions/behaviors/kernel/builtin-tools/write.fnl:17_

### <a id="fen-extensions-builtin-tools-write-snippet-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.snippet`
`string`
Short write tool teaser used by generated docs and compact tool summaries.
*tags:* builtin, tools, write, docs
_extensions/behaviors/kernel/builtin-tools/write.fnl:23_

### <a id="fen-extensions-builtin-tools-write-description-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.description`
`string`
Provider-facing write tool description documenting overwrite semantics and parent-directory creation.
*tags:* builtin, tools, write, docs
_extensions/behaviors/kernel/builtin-tools/write.fnl:29_

### <a id="fen-extensions-builtin-tools-write-parameters-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.parameters`
`JSONSchema`
JSON schema for write arguments containing the destination path and complete file content.
*tags:* builtin, tools, write, schema
_extensions/behaviors/kernel/builtin-tools/write.fnl:35_

### <a id="fen-extensions-builtin-tools-write-execute-extensions-behaviors-kernel-builtin-tools-write-fnl-84"></a>`fen.extensions.builtin_tools.write.execute`
`(execute args ctx? yield-fn?) -> AgentToolResult`
Write tool executor that creates missing parent directories, yields during large content writes, and reports byte counts.
*tags:* builtin, tools, write, execution
_extensions/behaviors/kernel/builtin-tools/write.fnl:41_

## <a id="fen-extensions-compact"></a>fen.extensions.compact

### <a id="fen-extensions-compact-register-extensions-behaviors-companions-compact-init-fnl-242"></a>`fen.extensions.compact.register`
_extensions/behaviors/companions/compact/init.fnl:242_

### <a id="fen-extensions-compact-register-bang-extensions-behaviors-companions-compact-init-fnl-242"></a>`fen.extensions.compact.register!`
_extensions/behaviors/companions/compact/init.fnl:242_

### <a id="fen-extensions-compact-test-extensions-behaviors-companions-compact-init-fnl-242"></a>`fen.extensions.compact._test`
_extensions/behaviors/companions/compact/init.fnl:242_

## <a id="fen-extensions-default-prompt"></a>fen.extensions.default_prompt

### <a id="fen-extensions-default-prompt-tool-list-section-extensions-behaviors-kernel-default-prompt-init-fnl-35"></a>`fen.extensions.default_prompt.tool-list-section`
`(tool-list-section tools) -> string|nil`
Render the available-tools prompt section from registered tool snippets, omitting the section when none are present.
*tags:* prompt, default, tools
_extensions/behaviors/kernel/default-prompt/init.fnl:30_

### <a id="fen-extensions-default-prompt-guidelines-section-extensions-behaviors-kernel-default-prompt-init-fnl-49"></a>`fen.extensions.default_prompt.guidelines-section`
`(guidelines-section tools) -> string`
Render built-in model guidance tailored to the currently available file, bash, read/edit, and agent_state tools.
*tags:* prompt, default, guidelines, tools
_extensions/behaviors/kernel/default-prompt/init.fnl:44_

### <a id="fen-extensions-default-prompt-context-section-extensions-behaviors-kernel-default-prompt-init-fnl-73"></a>`fen.extensions.default_prompt.context-section`
`(context-section context-files) -> string|nil`
Render loaded project context files as titled prompt sections for the default system prompt.
*tags:* prompt, default, context
_extensions/behaviors/kernel/default-prompt/init.fnl:68_

### <a id="fen-extensions-default-prompt-default-prompt-extensions-behaviors-kernel-default-prompt-init-fnl-144"></a>`fen.extensions.default_prompt.default-prompt`
`string`
Built-in fallback system prompt used when no SYSTEM.md or CLI system override is available.
*tags:* prompt, default, data
_extensions/behaviors/kernel/default-prompt/init.fnl:139_

### <a id="fen-extensions-default-prompt-register-extensions-behaviors-kernel-default-prompt-init-fnl-151"></a>`fen.extensions.default_prompt.register`
`function`
Registration entrypoint alias for installing the default prompt fragments into the extension registry.
*tags:* prompt, default, register
_extensions/behaviors/kernel/default-prompt/init.fnl:146_

### <a id="fen-extensions-default-prompt-register-bang-extensions-behaviors-kernel-default-prompt-init-fnl-152"></a>`fen.extensions.default_prompt.register!`
`function`
Registration entrypoint alias for installing the default prompt fragments into the extension registry.
*tags:* prompt, default, register
_extensions/behaviors/kernel/default-prompt/init.fnl:146_

### <a id="fen-extensions-default-prompt-current-loader-extensions-behaviors-kernel-default-prompt-init-fnl-159"></a>`fen.extensions.default_prompt.current-loader`
`function`
Loader accessor alias returning the cached default-prompt resource loader, creating it on first use.
*tags:* prompt, default, resources
_extensions/behaviors/kernel/default-prompt/init.fnl:154_

## <a id="fen-extensions-default-prompt-resources"></a>fen.extensions.default_prompt.resources

### <a id="fen-extensions-default-prompt-resources-make-extensions-behaviors-kernel-default-prompt-resources-fnl-78"></a>`fen.extensions.default_prompt.resources.make`
`(make opts) -> ResourceLoader`
Create and immediately load a reloadable resource snapshot for SYSTEM overlays and project context files.
*tags:* prompt, resources, context, reload
_extensions/behaviors/kernel/default-prompt/resources.fnl:73_

### <a id="fen-extensions-default-prompt-resources-cwd-extensions-behaviors-kernel-default-prompt-resources-fnl-92"></a>`fen.extensions.default_prompt.resources.cwd`
`function`
Path helper alias returning the current logical working directory for resource scans.
*tags:* prompt, resources, paths
_extensions/behaviors/kernel/default-prompt/resources.fnl:87_

### <a id="fen-extensions-default-prompt-resources-config-dir-extensions-behaviors-kernel-default-prompt-resources-fnl-99"></a>`fen.extensions.default_prompt.resources.config-dir`
`function`
Helper alias returning fen's XDG configuration directory for prompt overlays and global context.
*tags:* prompt, resources, paths
_extensions/behaviors/kernel/default-prompt/resources.fnl:94_

### <a id="fen-extensions-default-prompt-resources-load-project-context-files-extensions-behaviors-kernel-default-prompt-resources-fnl-106"></a>`fen.extensions.default_prompt.resources.load-project-context-files`
`function`
Helper alias loading global and ancestor AGENTS.md or CLAUDE.md context files in prompt order.
*tags:* prompt, resources, context
_extensions/behaviors/kernel/default-prompt/resources.fnl:101_

### <a id="fen-extensions-default-prompt-resources-load-system-file-extensions-behaviors-kernel-default-prompt-resources-fnl-113"></a>`fen.extensions.default_prompt.resources.load-system-file`
`function`
Helper alias resolving the effective SYSTEM.md or APPEND_SYSTEM.md overlay for the current project.
*tags:* prompt, resources, system
_extensions/behaviors/kernel/default-prompt/resources.fnl:108_

### <a id="fen-extensions-default-prompt-resources-ancestors-root-to-leaf-extensions-behaviors-kernel-default-prompt-resources-fnl-120"></a>`fen.extensions.default_prompt.resources._ancestors-root-to-leaf`
`function`
Test helper alias exposing the root-to-leaf ancestor walker used by prompt resource discovery.
*tags:* prompt, resources, tests, paths
_extensions/behaviors/kernel/default-prompt/resources.fnl:115_

## <a id="fen-extensions-docs"></a>fen.extensions.docs

### <a id="fen-extensions-docs-register-extensions-behaviors-kernel-docs-init-fnl-482"></a>`fen.extensions.docs.register`
`(register api?) -> true`
Register the /docs command, fen_docs tool, docs panel, and dismiss handler against the extension API.
*tags:* docs, register, command, tool, panel
_extensions/behaviors/kernel/docs/init.fnl:477_

## <a id="fen-extensions-docs-state"></a>fen.extensions.docs.state

### <a id="fen-extensions-docs-state-visible-q-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.visible?`
`boolean`
Visibility flag for the persistent /docs panel that lists generated API and contract entries.
*tags:* docs, state, panel
_extensions/behaviors/kernel/docs/state.fnl:3_

### <a id="fen-extensions-docs-state-selected-topic-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.selected-topic`
`string|nil`
Current /docs topic selection used to keep the active group stable across row refreshes.
*tags:* docs, state, selection
_extensions/behaviors/kernel/docs/state.fnl:9_

### <a id="fen-extensions-docs-state-selected-name-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.selected-name`
`string|nil`
Current /docs entry selection within the active topic for keyboard focus and detail rendering.
*tags:* docs, state, selection
_extensions/behaviors/kernel/docs/state.fnl:15_

### <a id="fen-extensions-docs-state-cached-rows-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.cached-rows`
`[PresenterRow]|nil`
Cached rendered /docs panel rows reused while topic, selection, and terminal width are unchanged.
*tags:* docs, state, cache
_extensions/behaviors/kernel/docs/state.fnl:21_

### <a id="fen-extensions-docs-state-cached-at-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.cached-at`
`number`
Timestamp for the /docs panel cache, allowing registry documentation to be refreshed predictably.
*tags:* docs, state, cache
_extensions/behaviors/kernel/docs/state.fnl:27_

### <a id="fen-extensions-docs-state-cached-w-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.cached-w`
`number`
Terminal width associated with cached /docs rows so resize events rebuild wrapped documentation text.
*tags:* docs, state, cache
_extensions/behaviors/kernel/docs/state.fnl:33_

### <a id="fen-extensions-docs-state-cached-selected-topic-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.cached-selected-topic`
`string|nil`
Topic selection value associated with cached /docs rows so topic changes invalidate the panel cache.
*tags:* docs, state, cache, selection
_extensions/behaviors/kernel/docs/state.fnl:39_

### <a id="fen-extensions-docs-state-cached-selected-name-extensions-behaviors-kernel-docs-state-fnl-51"></a>`fen.extensions.docs.state.cached-selected-name`
`string|nil`
Entry selection value associated with cached /docs rows so focus changes invalidate detail rendering.
*tags:* docs, state, cache, selection
_extensions/behaviors/kernel/docs/state.fnl:45_

## <a id="fen-extensions-essentials"></a>fen.extensions.essentials

### <a id="fen-extensions-essentials-register-extensions-behaviors-kernel-essentials-init-fnl-9"></a>`fen.extensions.essentials.register`
_extensions/behaviors/kernel/essentials/init.fnl:9_

## <a id="fen-extensions-essentials-commands-help"></a>fen.extensions.essentials.commands.help

### <a id="fen-extensions-essentials-commands-help-register-extensions-behaviors-kernel-essentials-commands-help-fnl-93"></a>`fen.extensions.essentials.commands.help.register`
`(register api) -> nil`
Register the /help command that lists available slash commands and controls grouped by extension owner.
*tags:* commands, help, register
_extensions/behaviors/kernel/essentials/commands/help.fnl:88_

## <a id="fen-extensions-essentials-commands-model"></a>fen.extensions.essentials.commands.model

### <a id="fen-extensions-essentials-commands-model-register-extensions-behaviors-kernel-essentials-commands-model-fnl-120"></a>`fen.extensions.essentials.commands.model.register`
`(register api) -> nil`
Register the /model command for selecting configured models by overlay, index, exact id, or substring query.
*tags:* commands, model, register
_extensions/behaviors/kernel/essentials/commands/model.fnl:115_

## <a id="fen-extensions-essentials-commands-thinking"></a>fen.extensions.essentials.commands.thinking

### <a id="fen-extensions-essentials-commands-thinking-register-extensions-behaviors-kernel-essentials-commands-thinking-fnl-114"></a>`fen.extensions.essentials.commands.thinking.register`
`(register api) -> nil`
Register the /thinking command for inspecting and setting provider-neutral thinking effort.
*tags:* commands, thinking, register
_extensions/behaviors/kernel/essentials/commands/thinking.fnl:109_

## <a id="fen-extensions-extensions-inspector"></a>fen.extensions.extensions_inspector

### <a id="fen-extensions-extensions-inspector-register-extensions-behaviors-inspectors-extensions-init-fnl-7"></a>`fen.extensions.extensions_inspector.register`
_extensions/behaviors/inspectors/extensions/init.fnl:7_

## <a id="fen-extensions-extensions-inspector-commands-extension"></a>fen.extensions.extensions_inspector.commands.extension

### <a id="fen-extensions-extensions-inspector-commands-extension-register-extensions-behaviors-inspectors-extensions-commands-extension-fnl-463"></a>`fen.extensions.extensions_inspector.commands.extension.register`
`(register api) -> nil`
Register extension management commands plus the extension picker/detail panel and dismiss handler.
*tags:* commands, extensions, register
_extensions/behaviors/inspectors/extensions/commands/extension.fnl:458_

## <a id="fen-extensions-extensions-inspector-state-extensions"></a>fen.extensions.extensions_inspector.state.extensions

### <a id="fen-extensions-extensions-inspector-state-extensions-visible-q-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.visible?`
`boolean`
Visibility flag for the persistent /extensions panel, kept across hot reloads until dismissed or toggled.
*tags:* builtin, commands, state, extensions, panel
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:3_

### <a id="fen-extensions-extensions-inspector-state-extensions-view-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.view`
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:39_

### <a id="fen-extensions-extensions-inspector-state-extensions-extensions-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.extensions`
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:39_

### <a id="fen-extensions-extensions-inspector-state-extensions-selected-name-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.selected-name`
`string|nil`
Currently selected extension name used by the /extensions panel to keep focus stable while rows refresh.
*tags:* builtin, commands, state, extensions, selection
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:9_

### <a id="fen-extensions-extensions-inspector-state-extensions-registry-kind-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.registry-kind`
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:39_

### <a id="fen-extensions-extensions-inspector-state-extensions-cached-rows-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.cached-rows`
`[PresenterRow]|nil`
Cached rendered /extensions panel rows reused between paints when width and selection have not changed.
*tags:* builtin, commands, state, extensions, cache
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:15_

### <a id="fen-extensions-extensions-inspector-state-extensions-cached-at-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.cached-at`
`number`
Timestamp for the /extensions panel row cache, allowing throttled refreshes of registry-derived content.
*tags:* builtin, commands, state, extensions, cache
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:21_

### <a id="fen-extensions-extensions-inspector-state-extensions-cached-w-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.cached-w`
`number`
Terminal width associated with cached /extensions rows so resizes invalidate wrapped panel content.
*tags:* builtin, commands, state, extensions, cache
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:27_

### <a id="fen-extensions-extensions-inspector-state-extensions-cached-selected-name-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.cached-selected-name`
`string|nil`
Extension selection value associated with cached rows so focus changes trigger a panel rerender.
*tags:* builtin, commands, state, extensions, cache, selection
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:33_

### <a id="fen-extensions-extensions-inspector-state-extensions-cached-view-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.cached-view`
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:39_

### <a id="fen-extensions-extensions-inspector-state-extensions-cached-registry-kind-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39"></a>`fen.extensions.extensions_inspector.state.extensions.cached-registry-kind`
_extensions/behaviors/inspectors/extensions/state/extensions.fnl:39_

## <a id="fen-extensions-extensions-inspector-util"></a>fen.extensions.extensions_inspector.util

### <a id="fen-extensions-extensions-inspector-util-approx-tokens-extensions-behaviors-inspectors-extensions-util-fnl-12"></a>`fen.extensions.extensions_inspector.util.approx-tokens`
`(approx-tokens s) -> number`
Estimate token count from text length for status displays when provider-reported usage is unavailable.
*tags:* commands, tokens, status
_extensions/behaviors/inspectors/extensions/util.fnl:7_

### <a id="fen-extensions-extensions-inspector-util-safe-json-extensions-behaviors-inspectors-extensions-util-fnl-24"></a>`fen.extensions.extensions_inspector.util.safe-json`
`(safe-json v) -> string`
JSON-encode a value for token estimation, falling back to tostring when encoding fails.
*tags:* commands, json, tokens
_extensions/behaviors/inspectors/extensions/util.fnl:19_

### <a id="fen-extensions-extensions-inspector-util-content-tokens-extensions-behaviors-inspectors-extensions-util-fnl-33"></a>`fen.extensions.extensions_inspector.util.content-tokens`
`(content-tokens content) -> number`
Estimate tokens for canonical message content, including text, thinking blocks, and tool-call names/arguments.
*tags:* commands, tokens, messages
_extensions/behaviors/inspectors/extensions/util.fnl:28_

### <a id="fen-extensions-extensions-inspector-util-estimated-context-tokens-extensions-behaviors-inspectors-extensions-util-fnl-56"></a>`fen.extensions.extensions_inspector.util.estimated-context-tokens`
`(estimated-context-tokens agent) -> number`
Estimate the current agent context size from system prompt, messages, content blocks, and tool-result names.
*tags:* commands, tokens, agent
_extensions/behaviors/inspectors/extensions/util.fnl:51_

### <a id="fen-extensions-extensions-inspector-util-usage-totals-extensions-behaviors-inspectors-extensions-util-fnl-69"></a>`fen.extensions.extensions_inspector.util.usage-totals`
`(usage-totals messages) -> Usage`
Sum provider usage counters across assistant messages for status and session diagnostics.
*tags:* commands, tokens, usage
_extensions/behaviors/inspectors/extensions/util.fnl:64_

### <a id="fen-extensions-extensions-inspector-util-fmt-tokens-extensions-behaviors-inspectors-extensions-util-fnl-88"></a>`fen.extensions.extensions_inspector.util.fmt-tokens`
`(fmt-tokens n) -> string`
Format a token count compactly with raw, k, or M suffixes for slash-command status output.
*tags:* commands, tokens, format
_extensions/behaviors/inspectors/extensions/util.fnl:83_

### <a id="fen-extensions-extensions-inspector-util-format-token-summary-extensions-behaviors-inspectors-extensions-util-fnl-101"></a>`fen.extensions.extensions_inspector.util.format-token-summary`
`(format-token-summary usage approx) -> string`
Build the one-line input/output/cache/context token summary shown by /status.
*tags:* commands, tokens, status
_extensions/behaviors/inspectors/extensions/util.fnl:96_

### <a id="fen-extensions-extensions-inspector-util-runtime-version-extensions-behaviors-inspectors-extensions-util-fnl-114"></a>`fen.extensions.extensions_inspector.util.runtime-version`
`(runtime-version) -> string`
Return the build-stamped fen version, or unknown when running from source/tests without dist metadata.
*tags:* commands, status, version
_extensions/behaviors/inspectors/extensions/util.fnl:109_

### <a id="fen-extensions-extensions-inspector-util-nth-arg-extensions-behaviors-inspectors-extensions-util-fnl-125"></a>`fen.extensions.extensions_inspector.util.nth-arg`
`(nth-arg args n) -> string|nil`
Extract the nth whitespace-delimited argument from a slash-command argument string.
*tags:* commands, args, parsing
_extensions/behaviors/inspectors/extensions/util.fnl:120_

### <a id="fen-extensions-extensions-inspector-util-first-arg-extensions-behaviors-inspectors-extensions-util-fnl-134"></a>`fen.extensions.extensions_inspector.util.first-arg`
`(first-arg args) -> string|nil`
Extract the first whitespace-delimited argument from a slash-command argument string.
*tags:* commands, args, parsing
_extensions/behaviors/inspectors/extensions/util.fnl:129_

## <a id="fen-extensions-handoff"></a>fen.extensions.handoff

### <a id="fen-extensions-handoff-register-extensions-behaviors-companions-handoff-init-fnl-153"></a>`fen.extensions.handoff.register`
_extensions/behaviors/companions/handoff/init.fnl:153_

### <a id="fen-extensions-handoff-register-bang-extensions-behaviors-companions-handoff-init-fnl-153"></a>`fen.extensions.handoff.register!`
`(register!) -> true`
Register the /handoff command that summarizes the current session and seeds a fresh session with the result.
*tags:* handoff, command, session
_extensions/behaviors/companions/handoff/init.fnl:135_

## <a id="fen-extensions-mem"></a>fen.extensions.mem

### <a id="fen-extensions-mem-report-rows-extensions-behaviors-companions-mem-init-fnl-135"></a>`fen.extensions.mem.report-rows`
`(report-rows run-state opts?) -> [PresenterRow]`
Build memory diagnostics rows for the /mem panel, including optional GC before/after output, app state, registries, and history.
*tags:* mem, panel, diagnostics, rows
_extensions/behaviors/companions/mem/init.fnl:130_

### <a id="fen-extensions-mem-panel-spec-extensions-behaviors-companions-mem-init-fnl-203"></a>`fen.extensions.mem.panel-spec`
`(panel-spec) -> PanelSpec`
Return the /mem panel contribution that sizes and renders the cached memory diagnostics above the input.
*tags:* mem, panel, register
_extensions/behaviors/companions/mem/init.fnl:198_

### <a id="fen-extensions-mem-register-extensions-behaviors-companions-mem-init-fnl-297"></a>`fen.extensions.mem.register`
`function`
Registration entrypoint alias for installing the /mem command, panel, sampling hook, and dismiss handler.
*tags:* mem, register, command, panel
_extensions/behaviors/companions/mem/init.fnl:292_

### <a id="fen-extensions-mem-register-bang-extensions-behaviors-companions-mem-init-fnl-298"></a>`fen.extensions.mem.register!`
`function`
Registration entrypoint alias for installing the /mem command, panel, sampling hook, and dismiss handler.
*tags:* mem, register, command, panel
_extensions/behaviors/companions/mem/init.fnl:292_

### <a id="fen-extensions-mem-state-extensions-behaviors-companions-mem-init-fnl-305"></a>`fen.extensions.mem._state`
`table`
Test and diagnostics alias for the persistent memory diagnostics state table.
*tags:* mem, state, tests
_extensions/behaviors/companions/mem/init.fnl:300_

## <a id="fen-extensions-mem-state"></a>fen.extensions.mem.state

### <a id="fen-extensions-mem-state-samples-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.samples`
`[number]`
Rolling Lua heap samples used by the memory diagnostics panel to render its history sparkline.
*tags:* mem, state, samples, panel
_extensions/behaviors/companions/mem/state.fnl:3_

### <a id="fen-extensions-mem-state-max-samples-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.max-samples`
`number`
Maximum number of memory samples retained for the diagnostics panel history window.
*tags:* mem, state, samples, config
_extensions/behaviors/companions/mem/state.fnl:9_

### <a id="fen-extensions-mem-state-peak-kb-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.peak-kb`
`number`
Largest observed Lua heap size in kilobytes, used for peak reporting and sparkline scaling.
*tags:* mem, state, samples, peak
_extensions/behaviors/companions/mem/state.fnl:15_

### <a id="fen-extensions-mem-state-visible-q-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.visible?`
`boolean`
Visibility flag for the persistent memory diagnostics panel toggled by the /mem command.
*tags:* mem, state, panel
_extensions/behaviors/companions/mem/state.fnl:21_

### <a id="fen-extensions-mem-state-run-state-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.run-state`
`table|nil`
Last presenter run-state snapshot used by the memory panel to display agent and session details.
*tags:* mem, state, runtime, panel
_extensions/behaviors/companions/mem/state.fnl:27_

### <a id="fen-extensions-mem-state-cached-rows-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.cached-rows`
`[PresenterRow]|nil`
Cached rendered memory panel rows reused between paints to avoid noisy heap recomputation.
*tags:* mem, state, cache, panel
_extensions/behaviors/companions/mem/state.fnl:33_

### <a id="fen-extensions-mem-state-cached-at-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.cached-at`
`number`
Timestamp for the memory panel cache, supporting its one-hertz refresh throttle.
*tags:* mem, state, cache, panel
_extensions/behaviors/companions/mem/state.fnl:39_

### <a id="fen-extensions-mem-state-cached-w-extensions-behaviors-companions-mem-state-fnl-51"></a>`fen.extensions.mem.state.cached-w`
`number`
Terminal width associated with cached memory rows so resize events rebuild the bordered panel.
*tags:* mem, state, cache, panel
_extensions/behaviors/companions/mem/state.fnl:45_

## <a id="fen-extensions-print"></a>fen.extensions.print

### <a id="fen-extensions-print-run-extensions-adapters-presenters-print-init-fnl-18"></a>`fen.extensions.print.run`
`(run ctx) -> nil`
Execute the one-shot print presenter by stepping the agent with the supplied prompt and printing the final text.
*tags:* print, presenter, run
_extensions/adapters/presenters/print/init.fnl:13_

### <a id="fen-extensions-print-register-extensions-adapters-presenters-print-init-fnl-29"></a>`fen.extensions.print.register`
_extensions/adapters/presenters/print/init.fnl:29_

## <a id="fen-extensions-prompt"></a>fen.extensions.prompt

### <a id="fen-extensions-prompt-register-extensions-behaviors-inspectors-prompt-init-fnl-7"></a>`fen.extensions.prompt.register`
_extensions/behaviors/inspectors/prompt/init.fnl:7_

## <a id="fen-extensions-prompt-commands-prompt"></a>fen.extensions.prompt.commands.prompt

### <a id="fen-extensions-prompt-commands-prompt-register-extensions-behaviors-inspectors-prompt-commands-prompt-fnl-104"></a>`fen.extensions.prompt.commands.prompt.register`
`(register api) -> nil`
Register the /prompt command and prompt-fragment panel for inspecting rendered system prompt state.
*tags:* commands, prompt, register
_extensions/behaviors/inspectors/prompt/commands/prompt.fnl:99_

## <a id="fen-extensions-prompt-state-prompt"></a>fen.extensions.prompt.state.prompt

### <a id="fen-extensions-prompt-state-prompt-visible-q-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27"></a>`fen.extensions.prompt.state.prompt.visible?`
`boolean`
Visibility flag for the persistent /prompt panel that previews assembled system prompt fragments.
*tags:* builtin, commands, state, prompt, panel
_extensions/behaviors/inspectors/prompt/state/prompt.fnl:3_

### <a id="fen-extensions-prompt-state-prompt-cached-rows-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27"></a>`fen.extensions.prompt.state.prompt.cached-rows`
`[PresenterRow]|nil`
Cached rendered /prompt panel rows reused while prompt content and terminal width remain stable.
*tags:* builtin, commands, state, prompt, cache
_extensions/behaviors/inspectors/prompt/state/prompt.fnl:9_

### <a id="fen-extensions-prompt-state-prompt-cached-at-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27"></a>`fen.extensions.prompt.state.prompt.cached-at`
`number`
Timestamp for the /prompt panel cache, used to avoid rebuilding prompt rows on every repaint.
*tags:* builtin, commands, state, prompt, cache
_extensions/behaviors/inspectors/prompt/state/prompt.fnl:15_

### <a id="fen-extensions-prompt-state-prompt-cached-w-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27"></a>`fen.extensions.prompt.state.prompt.cached-w`
`number`
Terminal width associated with cached /prompt rows so resize events rebuild wrapped preview text.
*tags:* builtin, commands, state, prompt, cache
_extensions/behaviors/inspectors/prompt/state/prompt.fnl:21_

## <a id="fen-extensions-provider-anthropic"></a>fen.extensions.provider_anthropic

### <a id="fen-extensions-provider-anthropic-register-extensions-adapters-providers-anthropic-init-fnl-15"></a>`fen.extensions.provider_anthropic.register`
_extensions/adapters/providers/anthropic/init.fnl:15_

## <a id="fen-extensions-provider-anthropic-anthropic-messages"></a>fen.extensions.provider_anthropic.anthropic_messages

### <a id="fen-extensions-provider-anthropic-anthropic-messages-api-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.api`
`string`
Default anthropic-version header sent with Messages API requests.
*tags:* provider, anthropic, metadata
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:580_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-provider-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.provider`
`string`
Default anthropic-version header sent with Messages API requests.
*tags:* provider, anthropic, metadata
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:580_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-default-base-url-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.default-base-url`
`string`
Default anthropic-version header sent with Messages API requests.
*tags:* provider, anthropic, metadata
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:580_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-default-version-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.default-version`
`string`
Default anthropic-version header sent with Messages API requests.
*tags:* provider, anthropic, metadata
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:580_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-convert-messages-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.convert-messages`
`(convert-messages messages _system-prompt) -> [WireMessage]`
Convert canonical messages into Anthropic Messages wire shape, batching consecutive tool results into one user message.
*tags:* provider, anthropic, messages, convert
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:98_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-convert-tools-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.convert-tools`
`(convert-tools tools) -> [WireTool]`
Convert canonical Tool descriptors into Anthropic flat tool specs with input_schema parameters.
*tags:* provider, anthropic, tools, convert
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:136_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-map-stop-reason-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.map-stop-reason`
`(map-stop-reason reason) -> StopReason, error-message|nil`
Map Anthropic stop_reason values onto canonical StopReason values and explanatory error strings.
*tags:* provider, anthropic, stop-reason
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:155_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-parse-response-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.parse-response`
`(parse-response resp model) -> AssistantMessage`
Parse a non-streaming Anthropic Messages response into canonical assistant text, thinking, tool calls, usage, and stop reason.
*tags:* provider, anthropic, parse
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:175_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-process-stream-event-bang-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.process-stream-event!`
`(process-stream-event! state ev emit) -> state`
Fold one decoded Anthropic typed SSE event into stream state, content blocks, usage, and delta callbacks.
*tags:* provider, anthropic, streaming
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:433_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-new-stream-state-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.new-stream-state`
`string`
Default anthropic-version header sent with Messages API requests.
*tags:* provider, anthropic, metadata
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:580_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-finalize-stream-state-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.finalize-stream-state`
`(finalize-stream-state state emit) -> AssistantMessage`
Finalize Anthropic streaming state into a canonical assistant message and emit the terminal done/error event.
*tags:* provider, anthropic, streaming
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:468_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-finalize-stream-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.finalize-stream`
`string`
Default anthropic-version header sent with Messages API requests.
*tags:* provider, anthropic, metadata
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:580_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-build-body-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.build-body`
`(build-body model context max-tokens options) -> table`
Build an Anthropic Messages request body with system prompt/cache markers, tools, parallel-tool policy, and optional thinking budget.
*tags:* provider, anthropic, request, cache
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:242_

### <a id="fen-extensions-provider-anthropic-anthropic-messages-complete-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600"></a>`fen.extensions.provider_anthropic.anthropic_messages.complete`
`(complete model context options ?on-event ?yield-fn) -> AssistantMessage`
Execute one Anthropic provider call, choosing streaming/non-streaming and cooperative/blocking transport from callbacks.
*tags:* provider, anthropic, complete
_extensions/adapters/providers/anthropic/anthropic_messages.fnl:531_

## <a id="fen-extensions-provider-openai"></a>fen.extensions.provider_openai

### <a id="fen-extensions-provider-openai-register-extensions-adapters-providers-openai-init-fnl-39"></a>`fen.extensions.provider_openai.register`
_extensions/adapters/providers/openai/init.fnl:39_

## <a id="fen-extensions-provider-openai-openai-codex-keychain"></a>fen.extensions.provider_openai.openai_codex_keychain

### <a id="fen-extensions-provider-openai-openai-codex-keychain-default-agent-dir-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.default-agent-dir`
`(default-agent-dir) -> string`
Return fen's writable Codex auth directory, honoring FEN_AUTH_DIR before the XDG fen config directory.
*tags:* codex, auth, storage, paths
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:23_

### <a id="fen-extensions-provider-openai-openai-codex-keychain-default-auth-path-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.default-auth-path`
`(default-auth-path) -> string`
Return the fen-owned auth.json path where Codex login, refresh, and logout persist credentials.
*tags:* codex, auth, storage, paths
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:34_

### <a id="fen-extensions-provider-openai-openai-codex-keychain-candidate-read-auth-paths-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.candidate-read-auth-paths`
`(candidate-read-auth-paths) -> [string]`
Return credential read paths in priority order. Currently this is only fen's auth.json path.
*tags:* codex, auth, storage, paths
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:43_

### <a id="fen-extensions-provider-openai-openai-codex-keychain-load-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.load`
`(load ?path) -> table`
Read and decode one auth.json file, returning an empty table for missing, unreadable, or malformed storage.
*tags:* codex, auth, storage, json
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:79_

### <a id="fen-extensions-provider-openai-openai-codex-keychain-get-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.get`
`(get provider-id ?path) -> table|nil`
Return one provider credential record from the explicit path or fen-owned auth.json.
*tags:* codex, auth, storage, lookup
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:99_

### <a id="fen-extensions-provider-openai-openai-codex-keychain-save-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.save`
`(save data ?path) -> nil`
Atomically write the full auth.json table, creating the parent directory and tightening file permissions to 0600.
*tags:* codex, auth, storage, write
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:109_

### <a id="fen-extensions-provider-openai-openai-codex-keychain-set-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151"></a>`fen.extensions.provider_openai.openai_codex_keychain.set`
`(set provider-id record ?path) -> table`
Read-modify-write one provider credential record into auth.json and return the persisted auth table.
*tags:* codex, auth, storage, write
_extensions/adapters/providers/openai/openai_codex_keychain.fnl:138_

## <a id="fen-extensions-provider-openai-openai-codex-login"></a>fen.extensions.provider_openai.openai_codex_login

### <a id="fen-extensions-provider-openai-openai-codex-login-authorize-url-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.AUTHORIZE-URL`
`string`
Originator value sent in the authorization URL to identify fen's simplified Codex login flow.
*tags:* codex, auth, login, metadata
_extensions/adapters/providers/openai/openai_codex_login.fnl:271_

### <a id="fen-extensions-provider-openai-openai-codex-login-redirect-uri-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.REDIRECT-URI`
`string`
Originator value sent in the authorization URL to identify fen's simplified Codex login flow.
*tags:* codex, auth, login, metadata
_extensions/adapters/providers/openai/openai_codex_login.fnl:271_

### <a id="fen-extensions-provider-openai-openai-codex-login-scope-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.SCOPE`
`string`
Originator value sent in the authorization URL to identify fen's simplified Codex login flow.
*tags:* codex, auth, login, metadata
_extensions/adapters/providers/openai/openai_codex_login.fnl:271_

### <a id="fen-extensions-provider-openai-openai-codex-login-originator-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.ORIGINATOR`
`string`
Originator value sent in the authorization URL to identify fen's simplified Codex login flow.
*tags:* codex, auth, login, metadata
_extensions/adapters/providers/openai/openai_codex_login.fnl:271_

### <a id="fen-extensions-provider-openai-openai-codex-login-generate-pkce-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.generate-pkce`
`(generate-pkce) -> {:verifier :challenge}`
Generate a fresh PKCE verifier/challenge pair using platform randomness, SHA-256, and base64url encoding.
*tags:* codex, auth, login, pkce
_extensions/adapters/providers/openai/openai_codex_login.fnl:66_

### <a id="fen-extensions-provider-openai-openai-codex-login-build-authorize-url-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.build-authorize-url`
`(build-authorize-url pkce state) -> string`
Compose the ChatGPT OAuth authorization URL with PKCE challenge, state, scope, redirect URI, and Codex flow flags.
*tags:* codex, auth, login, pkce
_extensions/adapters/providers/openai/openai_codex_login.fnl:80_

### <a id="fen-extensions-provider-openai-openai-codex-login-parse-authorization-input-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.parse-authorization-input`
`(parse-authorization-input input) -> {:code :state}`
Parse pasted Codex authorization input as full callback URL, raw query, code#state shorthand, or bare code.
*tags:* codex, auth, login, parse
_extensions/adapters/providers/openai/openai_codex_login.fnl:123_

### <a id="fen-extensions-provider-openai-openai-codex-login-extract-query-param-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.extract-query-param`
`(extract-query-param query key) -> string|nil`
Extract and URL-decode one parameter from an OAuth callback query string.
*tags:* codex, auth, login, parse
_extensions/adapters/providers/openai/openai_codex_login.fnl:100_

### <a id="fen-extensions-provider-openai-openai-codex-login-exchange-code-bang-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.exchange-code!`
`(exchange-code! code verifier) -> CredentialRecord`
Exchange an authorization code and PKCE verifier for Codex OAuth credentials, validating required token response fields.
*tags:* codex, auth, login, oauth
_extensions/adapters/providers/openai/openai_codex_login.fnl:152_

### <a id="fen-extensions-provider-openai-openai-codex-login-login-bang-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.login!`
`(login! ?path) -> CredentialRecord`
Run the manual PKCE login flow, prompt for the callback code, exchange it, persist credentials, and print account status.
*tags:* codex, auth, login, oauth
_extensions/adapters/providers/openai/openai_codex_login.fnl:217_

### <a id="fen-extensions-provider-openai-openai-codex-login-logout-bang-extensions-adapters-providers-openai-openai-codex-login-fnl-291"></a>`fen.extensions.provider_openai.openai_codex_login.logout!`
`(logout! ?path) -> boolean`
Remove the openai-codex credential record from auth.json and report whether anything was deleted.
*tags:* codex, auth, login, oauth
_extensions/adapters/providers/openai/openai_codex_login.fnl:249_

## <a id="fen-extensions-provider-openai-openai-codex-oauth"></a>fen.extensions.provider_openai.openai_codex_oauth

### <a id="fen-extensions-provider-openai-openai-codex-oauth-provider-id-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.PROVIDER-ID`
`string`
OAuth client id used by the ChatGPT Codex login and refresh flows.
*tags:* codex, auth, oauth, metadata
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:193_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-token-url-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.TOKEN-URL`
`string`
OAuth client id used by the ChatGPT Codex login and refresh flows.
*tags:* codex, auth, oauth, metadata
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:193_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-client-id-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.CLIENT-ID`
`string`
OAuth client id used by the ChatGPT Codex login and refresh flows.
*tags:* codex, auth, oauth, metadata
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:193_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-decode-jwt-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.decode-jwt`
`(decode-jwt token) -> table`
Decode a JWT payload into a Lua table without signature verification for trusted on-disk Codex tokens.
*tags:* codex, auth, oauth, jwt
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:38_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-extract-account-id-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.extract-account-id`
`(extract-account-id access-token) -> string|nil`
Extract chatgpt_account_id from the OpenAI auth claim in a Codex access-token JWT, returning nil on parse failure.
*tags:* codex, auth, oauth, jwt
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:53_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-refresh-bang-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.refresh!`
`(refresh! refresh-token) -> CredentialRecord`
Exchange a refresh token at the OpenAI OAuth token endpoint and return a fresh Codex credential record.
*tags:* codex, auth, oauth, refresh
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:94_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-expiring-soon-q-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.expiring-soon?`
`(expiring-soon? creds) -> boolean`
Return true when stored Codex credentials are missing expiry or expire within the proactive refresh margin.
*tags:* codex, auth, oauth, refresh
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:135_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-configured-q-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.configured?`
`(configured? ?path) -> boolean`
Check whether auth.json contains a structurally usable openai-codex OAuth record without refreshing it.
*tags:* codex, auth, oauth, status
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:162_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-get-fresh-creds-bang-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.get-fresh-creds!`
`(get-fresh-creds! ?path) -> CredentialRecord`
Load Codex credentials, refresh and persist them when near expiry, or raise a friendly login-required error.
*tags:* codex, auth, oauth, refresh
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:176_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-form-encode-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.form-encode`
`(form-encode params) -> string`
Encode OAuth form parameters as an ampersand-joined application/x-www-form-urlencoded body.
*tags:* codex, auth, oauth, form
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:81_

### <a id="fen-extensions-provider-openai-openai-codex-oauth-url-encode-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208"></a>`fen.extensions.provider_openai.openai_codex_oauth.url-encode`
`(url-encode s) -> string`
Percent-encode one OAuth form component using the unreserved character set required by application/x-www-form-urlencoded.
*tags:* codex, auth, oauth, form
_extensions/adapters/providers/openai/openai_codex_oauth.fnl:71_

## <a id="fen-extensions-provider-openai-openai-codex-responses"></a>fen.extensions.provider_openai.openai_codex_responses

### <a id="fen-extensions-provider-openai-openai-codex-responses-api-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.api`
`string`
Default ChatGPT backend API root used by the Codex Responses adapter before appending /codex/responses.
*tags:* codex, provider, responses, metadata
_extensions/adapters/providers/openai/openai_codex_responses.fnl:157_

### <a id="fen-extensions-provider-openai-openai-codex-responses-provider-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.provider`
`string`
Default ChatGPT backend API root used by the Codex Responses adapter before appending /codex/responses.
*tags:* codex, provider, responses, metadata
_extensions/adapters/providers/openai/openai_codex_responses.fnl:157_

### <a id="fen-extensions-provider-openai-openai-codex-responses-default-base-url-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.default-base-url`
`string`
Default ChatGPT backend API root used by the Codex Responses adapter before appending /codex/responses.
*tags:* codex, provider, responses, metadata
_extensions/adapters/providers/openai/openai_codex_responses.fnl:157_

### <a id="fen-extensions-provider-openai-openai-codex-responses-build-url-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.build-url`
`(build-url base-url) -> string`
Normalize a ChatGPT backend base URL into the Codex Responses endpoint while preserving fully-qualified Codex URLs.
*tags:* codex, provider, responses, http
_extensions/adapters/providers/openai/openai_codex_responses.fnl:30_

### <a id="fen-extensions-provider-openai-openai-codex-responses-map-codex-event-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.map-codex-event`
`(map-codex-event ev) -> table`
Normalize Codex response.done and response.incomplete SSE aliases into the shared Responses reducer's response.completed event.
*tags:* codex, provider, responses, streaming
_extensions/adapters/providers/openai/openai_codex_responses.fnl:64_

### <a id="fen-extensions-provider-openai-openai-codex-responses-build-headers-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.build-headers`
`(build-headers creds) -> table`
Build ChatGPT Codex streaming request headers from OAuth credentials, including account id, beta flag, and user agent.
*tags:* codex, provider, responses, http
_extensions/adapters/providers/openai/openai_codex_responses.fnl:50_

### <a id="fen-extensions-provider-openai-openai-codex-responses-merge-options-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.merge-options`
`(merge-options opts) -> table`
Copy provider options and add Codex defaults for encrypted reasoning includes and skipping unsupported max_output_tokens.
*tags:* codex, provider, responses, options
_extensions/adapters/providers/openai/openai_codex_responses.fnl:87_

### <a id="fen-extensions-provider-openai-openai-codex-responses-complete-extensions-adapters-providers-openai-openai-codex-responses-fnl-172"></a>`fen.extensions.provider_openai.openai_codex_responses.complete`
`(complete model context options ?on-event ?yield-fn) -> AssistantMessage`
Execute one ChatGPT Codex Responses call through the shared streaming pipeline with OAuth credentials and Codex event mapping.
*tags:* codex, provider, responses, complete
_extensions/adapters/providers/openai/openai_codex_responses.fnl:110_

## <a id="fen-extensions-provider-openai-openai-completions"></a>fen.extensions.provider_openai.openai_completions

### <a id="fen-extensions-provider-openai-openai-completions-api-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.api`
`string`
Default OpenAI v1 API root used when models.json or provider options do not override the base URL.
*tags:* provider, openai, completions, metadata
_extensions/adapters/providers/openai/openai_completions.fnl:667_

### <a id="fen-extensions-provider-openai-openai-completions-provider-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.provider`
`string`
Default OpenAI v1 API root used when models.json or provider options do not override the base URL.
*tags:* provider, openai, completions, metadata
_extensions/adapters/providers/openai/openai_completions.fnl:667_

### <a id="fen-extensions-provider-openai-openai-completions-default-base-url-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.default-base-url`
`string`
Default OpenAI v1 API root used when models.json or provider options do not override the base URL.
*tags:* provider, openai, completions, metadata
_extensions/adapters/providers/openai/openai_completions.fnl:667_

### <a id="fen-extensions-provider-openai-openai-completions-build-url-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.build-url`
`(build-url base-url) -> string`
Normalize an OpenAI-compatible base URL into a Chat Completions endpoint while preserving fully-qualified legacy endpoints.
*tags:* provider, openai, completions, http
_extensions/adapters/providers/openai/openai_completions.fnl:36_

### <a id="fen-extensions-provider-openai-openai-completions-convert-messages-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.convert-messages`
`(convert-messages messages system-prompt compat) -> [WireMessage]`
Convert canonical messages and optional system prompt into OpenAI Chat Completions wire messages, synthesizing errors for orphaned tool calls.
*tags:* provider, openai, completions, messages
_extensions/adapters/providers/openai/openai_completions.fnl:149_

### <a id="fen-extensions-provider-openai-openai-completions-convert-tools-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.convert-tools`
`(convert-tools tools) -> [WireTool]`
Convert canonical Tool descriptors into OpenAI Chat Completions function-tool declarations.
*tags:* provider, openai, completions, tools
_extensions/adapters/providers/openai/openai_completions.fnl:176_

### <a id="fen-extensions-provider-openai-openai-completions-map-stop-reason-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.map-stop-reason`
`(map-stop-reason reason) -> StopReason, error-message|nil`
Map OpenAI finish_reason values onto canonical StopReason values, returning error text for provider-side stops.
*tags:* provider, openai, completions, stop-reason
_extensions/adapters/providers/openai/openai_completions.fnl:196_

### <a id="fen-extensions-provider-openai-openai-completions-parse-response-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.parse-response`
`(parse-response resp model) -> AssistantMessage`
Parse a non-streaming OpenAI Chat Completions response into canonical assistant content, usage, tool calls, and stop reason.
*tags:* provider, openai, completions, parse
_extensions/adapters/providers/openai/openai_completions.fnl:243_

### <a id="fen-extensions-provider-openai-openai-completions-process-stream-chunk-bang-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.process-stream-chunk!`
`(process-stream-chunk! state chunk emit) -> state`
Fold one decoded streaming ChatCompletionChunk into stream state and emit text, thinking, and tool-call deltas.
*tags:* provider, openai, completions, streaming
_extensions/adapters/providers/openai/openai_completions.fnl:490_

### <a id="fen-extensions-provider-openai-openai-completions-new-stream-state-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.new-stream-state`
`string`
Default OpenAI v1 API root used when models.json or provider options do not override the base URL.
*tags:* provider, openai, completions, metadata
_extensions/adapters/providers/openai/openai_completions.fnl:667_

### <a id="fen-extensions-provider-openai-openai-completions-finalize-stream-state-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.finalize-stream-state`
`(finalize-stream-state state emit) -> AssistantMessage`
Close the streaming content block state, infer tool-use stops, emit the terminal event, and return the canonical assistant message.
*tags:* provider, openai, completions, streaming
_extensions/adapters/providers/openai/openai_completions.fnl:548_

### <a id="fen-extensions-provider-openai-openai-completions-finalize-stream-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.finalize-stream`
`string`
Default OpenAI v1 API root used when models.json or provider options do not override the base URL.
*tags:* provider, openai, completions, metadata
_extensions/adapters/providers/openai/openai_completions.fnl:667_

### <a id="fen-extensions-provider-openai-openai-completions-build-body-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.build-body`
`(build-body model context max-tokens compat options) -> table`
Build the Chat Completions request body, applying models.json compat knobs for max-token fields, thinking formats, and parallel tools.
*tags:* provider, openai, completions, request
_extensions/adapters/providers/openai/openai_completions.fnl:318_

### <a id="fen-extensions-provider-openai-openai-completions-complete-extensions-adapters-providers-openai-openai-completions-fnl-682"></a>`fen.extensions.provider_openai.openai_completions.complete`
`(complete model context options ?on-event ?yield-fn) -> AssistantMessage`
Execute one Chat Completions provider call, choosing streaming/non-streaming and cooperative/blocking transport from callbacks.
*tags:* provider, openai, completions, complete
_extensions/adapters/providers/openai/openai_completions.fnl:619_

## <a id="fen-extensions-provider-openai-openai-responses"></a>fen.extensions.provider_openai.openai_responses

### <a id="fen-extensions-provider-openai-openai-responses-api-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.api`
`string`
Default OpenAI v1 API root used by the Responses adapter before appending /responses.
*tags:* provider, openai, responses, metadata
_extensions/adapters/providers/openai/openai_responses.fnl:209_

### <a id="fen-extensions-provider-openai-openai-responses-provider-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.provider`
`string`
Default OpenAI v1 API root used by the Responses adapter before appending /responses.
*tags:* provider, openai, responses, metadata
_extensions/adapters/providers/openai/openai_responses.fnl:209_

### <a id="fen-extensions-provider-openai-openai-responses-default-base-url-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.default-base-url`
`string`
Default OpenAI v1 API root used by the Responses adapter before appending /responses.
*tags:* provider, openai, responses, metadata
_extensions/adapters/providers/openai/openai_responses.fnl:209_

### <a id="fen-extensions-provider-openai-openai-responses-build-url-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.build-url`
`(build-url base-url) -> string`
Normalize an OpenAI base URL into the /responses endpoint while preserving already-qualified Responses URLs.
*tags:* provider, openai, responses, http
_extensions/adapters/providers/openai/openai_responses.fnl:45_

### <a id="fen-extensions-provider-openai-openai-responses-build-body-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.build-body`
`(build-body model context max-tokens options) -> table`
Build a streaming Responses request body from canonical context, provider options, tools, reasoning settings, and prompt cache keys.
*tags:* provider, openai, responses, request
_extensions/adapters/providers/openai/openai_responses.fnl:53_

### <a id="fen-extensions-provider-openai-openai-responses-build-request-opts-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.build-request-opts`
`(build-request-opts model context options on-chunk ?headers-override ?url-override) -> table`
Assemble fen.util.http options for a streaming Responses POST, allowing Codex to override auth headers and endpoint URL.
*tags:* provider, openai, responses, http
_extensions/adapters/providers/openai/openai_responses.fnl:134_

### <a id="fen-extensions-provider-openai-openai-responses-make-stream-pipeline-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.make-stream-pipeline`
`(make-stream-pipeline model on-event event-mapper) -> state, parser, parser-error`
Create the SSE parser and shared Responses stream reducer state for one streaming request, with optional Codex event mapping.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses.fnl:107_

### <a id="fen-extensions-provider-openai-openai-responses-finalize-stream-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.finalize-stream`
`(finalize-stream state parser parser-error model resp on-event) -> AssistantMessage`
Finish the SSE parser, convert transport/parser/HTTP failures to assistant errors, or finalize shared Responses stream state.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses.fnl:161_

### <a id="fen-extensions-provider-openai-openai-responses-complete-extensions-adapters-providers-openai-openai-responses-fnl-224"></a>`fen.extensions.provider_openai.openai_responses.complete`
`(complete model context options ?on-event ?yield-fn) -> AssistantMessage`
Execute one OpenAI Responses provider call through the streaming SSE pipeline with optional cooperative transport and event forwarding.
*tags:* provider, openai, responses, complete
_extensions/adapters/providers/openai/openai_responses.fnl:172_

## <a id="fen-extensions-provider-openai-openai-responses-shared"></a>fen.extensions.provider_openai.openai_responses_shared

### <a id="fen-extensions-provider-openai-openai-responses-shared-build-url-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.build-url`
`(build-url base-url responses-path) -> string`
Normalize an OpenAI-compatible base URL into a Responses endpoint while preserving already-qualified URLs.
*tags:* provider, openai, responses, http
_extensions/adapters/providers/openai/openai_responses_shared.fnl:960_

### <a id="fen-extensions-provider-openai-openai-responses-shared-build-body-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.build-body`
`(build-body model context max-tokens options ?id) -> table`
Build a streaming Responses request body from canonical context, provider options, tools, reasoning settings, and prompt cache keys.
*tags:* provider, openai, responses, request
_extensions/adapters/providers/openai/openai_responses_shared.fnl:970_

### <a id="fen-extensions-provider-openai-openai-responses-shared-build-request-opts-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.build-request-opts`
`(build-request-opts model context options on-chunk ?headers-override ?url-override default-base-url responses-path ?id) -> table`
Assemble fen.util.http options for a streaming OpenAI-compatible Responses POST.
*tags:* provider, openai, responses, http
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1052_

### <a id="fen-extensions-provider-openai-openai-responses-shared-make-stream-pipeline-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.make-stream-pipeline`
`(make-stream-pipeline model on-event event-mapper) -> state, parser, parser-error`
Create the SSE parser and shared Responses stream reducer state for one streaming request, with optional event mapping.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1021_

### <a id="fen-extensions-provider-openai-openai-responses-shared-finalize-stream-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.finalize-stream`
`(finalize-stream state parser parser-error api provider model resp on-event) -> AssistantMessage`
Finish a Responses SSE stream, preserving the calling provider's canonical API/provider identity.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1077_

### <a id="fen-extensions-provider-openai-openai-responses-shared-convert-messages-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.convert-messages`
`(convert-messages messages ?id) -> [ResponseInputItem]`
Convert canonical transcript messages into Responses input items, repairing persisted shapes that would otherwise 4xx forever (cross-model/cross-backend fc_/rs_ ids, lone reasoning items, orphaned tool outputs, reasoning-less tool-call turns).
*tags:* provider, openai, responses, messages
_extensions/adapters/providers/openai/openai_responses_shared.fnl:395_

### <a id="fen-extensions-provider-openai-openai-responses-shared-convert-tools-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.convert-tools`
`(convert-tools tools) -> [ResponseTool]`
Convert canonical Tool descriptors into Responses function-tool declarations with strict set to JSON null.
*tags:* provider, openai, responses, tools
_extensions/adapters/providers/openai/openai_responses_shared.fnl:487_

### <a id="fen-extensions-provider-openai-openai-responses-shared-map-stop-reason-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.map-stop-reason`
`(map-stop-reason status) -> StopReason, error-message|nil`
Map Responses API response statuses onto canonical StopReason values and provider error messages.
*tags:* provider, openai, responses, stop-reason
_extensions/adapters/providers/openai/openai_responses_shared.fnl:509_

### <a id="fen-extensions-provider-openai-openai-responses-shared-new-stream-state-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.new-stream-state`
`(new-stream-state model) -> table`
Initialize the mutable reducer state used while folding Responses SSE events into canonical assistant content.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:552_

### <a id="fen-extensions-provider-openai-openai-responses-shared-process-event-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.process-event!`
`(process-event! state event emit) -> nil`
Dispatch one decoded Responses SSE event into reducer state, updating content, usage, errors, and delta callbacks.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:860_

### <a id="fen-extensions-provider-openai-openai-responses-shared-finalize-stream-state-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.finalize-stream-state`
`(finalize-stream-state state api provider emit) -> AssistantMessage`
Finalize Responses reducer state into a canonical assistant message and emit the terminal done/error event.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:926_

### <a id="fen-extensions-provider-openai-openai-responses-shared-finish-current-block-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.finish-current-block!`
`(finish-current-block! state emit) -> nil`
Close the active text/thinking/tool-call block, emit the matching end event, and clear current item pointers.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:578_

### <a id="fen-extensions-provider-openai-openai-responses-shared-write-failure-diagnostic-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.write-failure-diagnostic!`
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1154_

### <a id="fen-extensions-provider-openai-openai-responses-shared-failure-diagnostic-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.failure-diagnostic`
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1154_

### <a id="fen-extensions-provider-openai-openai-responses-shared-attach-diagnostic-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.attach-diagnostic!`
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1154_

### <a id="fen-extensions-provider-openai-openai-responses-shared-redact-headers-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.redact-headers`
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1154_

### <a id="fen-extensions-provider-openai-openai-responses-shared-summarize-body-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.summarize-body`
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1154_

### <a id="fen-extensions-provider-openai-openai-responses-shared-clamp-reasoning-effort-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.clamp-reasoning-effort`
`(clamp-reasoning-effort model effort) -> keyword`
Apply Codex/OpenAI per-model reasoning-effort limits so request bodies avoid unsupported effort values.
*tags:* provider, openai, codex, reasoning
_extensions/adapters/providers/openai/openai_responses_shared.fnl:1134_

### <a id="fen-extensions-provider-openai-openai-responses-shared-split-compound-id-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.split-compound-id`
`(split-compound-id id) -> call-id, item-id|nil`
Split Fen's compound Responses tool-call id into call_id and item_id components for wire conversion.
*tags:* provider, openai, responses, tools
_extensions/adapters/providers/openai/openai_responses_shared.fnl:285_

### <a id="fen-extensions-provider-openai-openai-responses-shared-parse-streaming-json-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154"></a>`fen.extensions.provider_openai.openai_responses_shared.parse-streaming-json`
`(parse-streaming-json s) -> table`
Best-effort JSON parser for in-flight streamed tool arguments, returning an empty table until complete JSON is available.
*tags:* provider, openai, responses, streaming
_extensions/adapters/providers/openai/openai_responses_shared.fnl:539_

## <a id="fen-extensions-queue"></a>fen.extensions.queue

### <a id="fen-extensions-queue-register-extensions-behaviors-inspectors-queue-init-fnl-7"></a>`fen.extensions.queue.register`
_extensions/behaviors/inspectors/queue/init.fnl:7_

## <a id="fen-extensions-queue-commands-queue"></a>fen.extensions.queue.commands.queue

### <a id="fen-extensions-queue-commands-queue-register-extensions-behaviors-inspectors-queue-commands-queue-fnl-147"></a>`fen.extensions.queue.commands.queue.register`
`(register api) -> nil`
Register queue management commands and the queue panel for pending steering/follow-up lines.
*tags:* commands, queue, register
_extensions/behaviors/inspectors/queue/commands/queue.fnl:142_

## <a id="fen-extensions-queue-state-queue"></a>fen.extensions.queue.state.queue

### <a id="fen-extensions-queue-state-queue-visible-q-extensions-behaviors-inspectors-queue-state-queue-fnl-27"></a>`fen.extensions.queue.state.queue.visible?`
`boolean`
Visibility flag for the persistent /queue panel showing queued steering and follow-up input.
*tags:* builtin, commands, state, queue, panel
_extensions/behaviors/inspectors/queue/state/queue.fnl:3_

### <a id="fen-extensions-queue-state-queue-cached-rows-extensions-behaviors-inspectors-queue-state-queue-fnl-27"></a>`fen.extensions.queue.state.queue.cached-rows`
`[PresenterRow]|nil`
Cached rendered /queue panel rows reused while queue state and terminal width remain stable.
*tags:* builtin, commands, state, queue, cache
_extensions/behaviors/inspectors/queue/state/queue.fnl:9_

### <a id="fen-extensions-queue-state-queue-cached-at-extensions-behaviors-inspectors-queue-state-queue-fnl-27"></a>`fen.extensions.queue.state.queue.cached-at`
`number`
Timestamp for the /queue panel cache, supporting throttled refreshes during frequent repaints.
*tags:* builtin, commands, state, queue, cache
_extensions/behaviors/inspectors/queue/state/queue.fnl:15_

### <a id="fen-extensions-queue-state-queue-cached-w-extensions-behaviors-inspectors-queue-state-queue-fnl-27"></a>`fen.extensions.queue.state.queue.cached-w`
`number`
Terminal width associated with cached /queue rows so resize events rebuild wrapped queue entries.
*tags:* builtin, commands, state, queue, cache
_extensions/behaviors/inspectors/queue/state/queue.fnl:21_

## <a id="fen-extensions-queue-util"></a>fen.extensions.queue.util

### <a id="fen-extensions-queue-util-approx-tokens-extensions-behaviors-inspectors-queue-util-fnl-12"></a>`fen.extensions.queue.util.approx-tokens`
`(approx-tokens s) -> number`
Estimate token count from text length for status displays when provider-reported usage is unavailable.
*tags:* commands, tokens, status
_extensions/behaviors/inspectors/queue/util.fnl:7_

### <a id="fen-extensions-queue-util-safe-json-extensions-behaviors-inspectors-queue-util-fnl-24"></a>`fen.extensions.queue.util.safe-json`
`(safe-json v) -> string`
JSON-encode a value for token estimation, falling back to tostring when encoding fails.
*tags:* commands, json, tokens
_extensions/behaviors/inspectors/queue/util.fnl:19_

### <a id="fen-extensions-queue-util-content-tokens-extensions-behaviors-inspectors-queue-util-fnl-33"></a>`fen.extensions.queue.util.content-tokens`
`(content-tokens content) -> number`
Estimate tokens for canonical message content, including text, thinking blocks, and tool-call names/arguments.
*tags:* commands, tokens, messages
_extensions/behaviors/inspectors/queue/util.fnl:28_

### <a id="fen-extensions-queue-util-estimated-context-tokens-extensions-behaviors-inspectors-queue-util-fnl-56"></a>`fen.extensions.queue.util.estimated-context-tokens`
`(estimated-context-tokens agent) -> number`
Estimate the current agent context size from system prompt, messages, content blocks, and tool-result names.
*tags:* commands, tokens, agent
_extensions/behaviors/inspectors/queue/util.fnl:51_

### <a id="fen-extensions-queue-util-usage-totals-extensions-behaviors-inspectors-queue-util-fnl-69"></a>`fen.extensions.queue.util.usage-totals`
`(usage-totals messages) -> Usage`
Sum provider usage counters across assistant messages for status and session diagnostics.
*tags:* commands, tokens, usage
_extensions/behaviors/inspectors/queue/util.fnl:64_

### <a id="fen-extensions-queue-util-fmt-tokens-extensions-behaviors-inspectors-queue-util-fnl-88"></a>`fen.extensions.queue.util.fmt-tokens`
`(fmt-tokens n) -> string`
Format a token count compactly with raw, k, or M suffixes for slash-command status output.
*tags:* commands, tokens, format
_extensions/behaviors/inspectors/queue/util.fnl:83_

### <a id="fen-extensions-queue-util-format-token-summary-extensions-behaviors-inspectors-queue-util-fnl-101"></a>`fen.extensions.queue.util.format-token-summary`
`(format-token-summary usage approx) -> string`
Build the one-line input/output/cache/context token summary shown by /status.
*tags:* commands, tokens, status
_extensions/behaviors/inspectors/queue/util.fnl:96_

### <a id="fen-extensions-queue-util-runtime-version-extensions-behaviors-inspectors-queue-util-fnl-114"></a>`fen.extensions.queue.util.runtime-version`
`(runtime-version) -> string`
Return the build-stamped fen version, or unknown when running from source/tests without dist metadata.
*tags:* commands, status, version
_extensions/behaviors/inspectors/queue/util.fnl:109_

### <a id="fen-extensions-queue-util-nth-arg-extensions-behaviors-inspectors-queue-util-fnl-125"></a>`fen.extensions.queue.util.nth-arg`
`(nth-arg args n) -> string|nil`
Extract the nth whitespace-delimited argument from a slash-command argument string.
*tags:* commands, args, parsing
_extensions/behaviors/inspectors/queue/util.fnl:120_

### <a id="fen-extensions-queue-util-first-arg-extensions-behaviors-inspectors-queue-util-fnl-134"></a>`fen.extensions.queue.util.first-arg`
`(first-arg args) -> string|nil`
Extract the first whitespace-delimited argument from a slash-command argument string.
*tags:* commands, args, parsing
_extensions/behaviors/inspectors/queue/util.fnl:129_

## <a id="fen-extensions-session-jsonl"></a>fen.extensions.session_jsonl

### <a id="fen-extensions-session-jsonl-register-extensions-adapters-session-backends-jsonl-init-fnl-7"></a>`fen.extensions.session_jsonl.register`
_extensions/adapters/session-backends/jsonl/init.fnl:7_

## <a id="fen-extensions-session-jsonl-session"></a>fen.extensions.session_jsonl.session

### <a id="fen-extensions-session-jsonl-session-open-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.open`
`(open cwd) -> Session`
Allocate a future append-only JSONL session path for cwd without creating the file until the first appended message.
*tags:* session, jsonl, open
_extensions/adapters/session-backends/jsonl/session.fnl:196_

### <a id="fen-extensions-session-jsonl-session-open-existing-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.open-existing`
`(open-existing p) -> Session|nil`
Open an existing session JSONL for append without writing a duplicate header, preserving header id and cwd.
*tags:* session, jsonl, resume
_extensions/adapters/session-backends/jsonl/session.fnl:461_

### <a id="fen-extensions-session-jsonl-session-append-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.append`
`(append session msg) -> nil`
Lazily open the session file if needed and append one canonical AgentMessage as a JSONL :message entry.
*tags:* session, jsonl, append
_extensions/adapters/session-backends/jsonl/session.fnl:262_

### <a id="fen-extensions-session-jsonl-session-append-entry-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.append-entry`
`(append-entry session entry) -> entry|nil`
Lazily open the session file and append one JSONL entry with stable id, parent-id, and timestamp metadata.
*tags:* session, jsonl, append, entries, ids
_extensions/adapters/session-backends/jsonl/session.fnl:236_

### <a id="fen-extensions-session-jsonl-session-close-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.close`
`(close session) -> nil`
Close an open session file handle and clear it from the mutable session record.
*tags:* session, jsonl, close
_extensions/adapters/session-backends/jsonl/session.fnl:283_

### <a id="fen-extensions-session-jsonl-session-latest-for-cwd-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.latest-for-cwd`
`(latest-for-cwd cwd) -> string|nil`
Return the newest non-empty session JSONL path for cwd by scanning the cwd session directory newest first.
*tags:* session, jsonl, discovery
_extensions/adapters/session-backends/jsonl/session.fnl:374_

### <a id="fen-extensions-session-jsonl-session-list-for-cwd-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.list-for-cwd`
`(list-for-cwd cwd limit) -> [SessionInfo]`
Return recent non-empty session metadata records for cwd in reverse chronological order, capped by limit.
*tags:* session, jsonl, discovery
_extensions/adapters/session-backends/jsonl/session.fnl:444_

### <a id="fen-extensions-session-jsonl-session-header-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.header`
`(header p) -> table|nil`
Read and decode the first JSONL header entry from a session file, returning nil for unreadable or non-session headers.
*tags:* session, jsonl, inspect
_extensions/adapters/session-backends/jsonl/session.fnl:391_

### <a id="fen-extensions-session-jsonl-session-title-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.title`
`(title p) -> string|nil`
Return a human-readable transcript title from the first user text, falling back to the first assistant text.
*tags:* session, jsonl, inspect
_extensions/adapters/session-backends/jsonl/session.fnl:416_

### <a id="fen-extensions-session-jsonl-session-message-count-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.message-count`
`(message-count p) -> number`
Count valid :message entries in a session JSONL file while skipping the header and malformed lines.
*tags:* session, jsonl, inspect
_extensions/adapters/session-backends/jsonl/session.fnl:366_

### <a id="fen-extensions-session-jsonl-session-find-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.find`
`(find cwd target) -> string|nil`
Resolve a resume target as latest, list index, existing path, exact id, or unique id/path prefix within cwd sessions.
*tags:* session, jsonl, resume
_extensions/adapters/session-backends/jsonl/session.fnl:474_

### <a id="fen-extensions-session-jsonl-session-load-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.load`
`(load path) -> [Message]`
Read a session JSONL file and return replayable canonical messages, applying the latest valid compaction entry when present.
*tags:* session, jsonl, replay, compaction
_extensions/adapters/session-backends/jsonl/session.fnl:537_

### <a id="fen-extensions-session-jsonl-session-sessions-root-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.sessions-root`
`(sessions-root cwd) -> string`
Return the state-directory path containing JSONL sessions for a specific cwd.
*tags:* session, jsonl, paths
_extensions/adapters/session-backends/jsonl/session.fnl:50_

### <a id="fen-extensions-session-jsonl-session-cwd-slug-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.cwd-slug`
`(cwd-slug cwd) -> string`
Convert a cwd into the pi-mono-style session directory slug used under the fen sessions root.
*tags:* session, jsonl, paths
_extensions/adapters/session-backends/jsonl/session.fnl:37_

### <a id="fen-extensions-session-jsonl-session-version-extensions-adapters-session-backends-jsonl-session-fnl-567"></a>`fen.extensions.session_jsonl.session.VERSION`
`number`
Current JSONL session format version written into new session headers.
*tags:* session, jsonl, metadata
_extensions/adapters/session-backends/jsonl/session.fnl:562_

## <a id="fen-extensions-session-jsonl-state"></a>fen.extensions.session_jsonl.state

### <a id="fen-extensions-session-jsonl-state-record-cache-extensions-adapters-session-backends-jsonl-state-fnl-7"></a>`fen.extensions.session_jsonl.state.record-cache`
_extensions/adapters/session-backends/jsonl/state.fnl:7_

## <a id="fen-extensions-sessions"></a>fen.extensions.sessions

### <a id="fen-extensions-sessions-register-extensions-behaviors-actions-sessions-init-fnl-7"></a>`fen.extensions.sessions.register`
_extensions/behaviors/actions/sessions/init.fnl:7_

## <a id="fen-extensions-sessions-commands-session"></a>fen.extensions.sessions.commands.session

### <a id="fen-extensions-sessions-commands-session-register-extensions-behaviors-actions-sessions-commands-session-fnl-317"></a>`fen.extensions.sessions.commands.session.register`
`(register api) -> nil`
Register conversation/session lifecycle commands including /new, /reload, /sessions, and /resume aliases.
*tags:* commands, session, register
_extensions/behaviors/actions/sessions/commands/session.fnl:312_

## <a id="fen-extensions-skills"></a>fen.extensions.skills

### <a id="fen-extensions-skills-dir-exists-q-extensions-behaviors-companions-skills-init-fnl-60"></a>`fen.extensions.skills.dir-exists?`
`function`
Filesystem helper alias used by tests to stub directory existence during skill discovery.
*tags:* skills, paths, tests
_extensions/behaviors/companions/skills/init.fnl:55_

### <a id="fen-extensions-skills-file-exists-q-extensions-behaviors-companions-skills-init-fnl-67"></a>`fen.extensions.skills.file-exists?`
`function`
Filesystem helper alias used by tests to stub skill file existence checks.
*tags:* skills, paths, tests
_extensions/behaviors/companions/skills/init.fnl:62_

### <a id="fen-extensions-skills-realpath-extensions-behaviors-companions-skills-init-fnl-74"></a>`fen.extensions.skills.realpath`
`function`
Filesystem helper alias used to canonicalize skill paths for deduplication and tests.
*tags:* skills, paths, tests
_extensions/behaviors/companions/skills/init.fnl:69_

### <a id="fen-extensions-skills-parse-frontmatter-extensions-behaviors-companions-skills-init-fnl-218"></a>`fen.extensions.skills.parse-frontmatter`
`(parse-frontmatter path) -> SkillMeta|nil`
Parse a skill file's YAML frontmatter into invokable metadata using the path-derived fallback name.
*tags:* skills, discovery, frontmatter
_extensions/behaviors/companions/skills/init.fnl:213_

### <a id="fen-extensions-skills-discover-extensions-behaviors-companions-skills-init-fnl-346"></a>`fen.extensions.skills.discover`
`(discover extra-paths?) -> [Skill]`
Scan default and explicit skill roots, respecting ignore files and deduplicating by canonical path and name.
*tags:* skills, discovery, roots
_extensions/behaviors/companions/skills/init.fnl:341_

### <a id="fen-extensions-skills-system-prompt-section-extensions-behaviors-companions-skills-init-fnl-366"></a>`fen.extensions.skills.system-prompt-section`
`(system-prompt-section skills) -> string|nil`
Render discovered model-invokable skills as the XML prompt fragment consumed by the default prompt.
*tags:* skills, prompt, xml
_extensions/behaviors/companions/skills/init.fnl:361_

### <a id="fen-extensions-skills-user-skills-dir-extensions-behaviors-companions-skills-init-fnl-394"></a>`fen.extensions.skills.user-skills-dir`
`(user-skills-dir) -> string`
Return fen's user-level skills directory under the XDG configuration root.
*tags:* skills, paths, user
_extensions/behaviors/companions/skills/init.fnl:389_

### <a id="fen-extensions-skills-project-skills-dir-extensions-behaviors-companions-skills-init-fnl-401"></a>`fen.extensions.skills.project-skills-dir`
`(project-skills-dir) -> string`
Return fen's project-local skills directory path relative to the current workspace.
*tags:* skills, paths, project
_extensions/behaviors/companions/skills/init.fnl:396_

### <a id="fen-extensions-skills-bundled-skills-dir-extensions-behaviors-companions-skills-init-fnl-407"></a>`fen.extensions.skills.bundled-skills-dir`
`(bundled-skills-dir) -> string`
Return the XDG data directory where fen materializes built-in skills.
*tags:* skills, paths, builtin
_extensions/behaviors/companions/skills/init.fnl:402_

### <a id="fen-extensions-skills-discover-from-roots-extensions-behaviors-companions-skills-init-fnl-413"></a>`fen.extensions.skills._discover-from-roots`
`function`
Test helper alias for scanning an explicit root list without loading default skill roots.
*tags:* skills, discovery, tests
_extensions/behaviors/companions/skills/init.fnl:408_

### <a id="fen-extensions-skills-default-roots-extensions-behaviors-companions-skills-init-fnl-420"></a>`fen.extensions.skills._default-roots`
`function`
Test helper alias returning the ordered default user, project, and compatibility skill roots.
*tags:* skills, discovery, tests, roots
_extensions/behaviors/companions/skills/init.fnl:415_

### <a id="fen-extensions-skills-ancestors-extensions-behaviors-companions-skills-init-fnl-427"></a>`fen.extensions.skills._ancestors`
`function`
Test helper alias for the project-ancestor walker used when building default skill roots.
*tags:* skills, discovery, tests, paths
_extensions/behaviors/companions/skills/init.fnl:422_

### <a id="fen-extensions-skills-skills-text-extensions-behaviors-companions-skills-init-fnl-476"></a>`fen.extensions.skills.skills-text`
_extensions/behaviors/companions/skills/init.fnl:476_

### <a id="fen-extensions-skills-skill-detail-lines-extensions-behaviors-companions-skills-init-fnl-536"></a>`fen.extensions.skills.skill-detail-lines`
_extensions/behaviors/companions/skills/init.fnl:536_

### <a id="fen-extensions-skills-register-extensions-behaviors-companions-skills-init-fnl-761"></a>`fen.extensions.skills.register`
`function`
Registration entrypoint alias for installing the available-skills prompt fragment.
*tags:* skills, register, prompt
_extensions/behaviors/companions/skills/init.fnl:756_

### <a id="fen-extensions-skills-register-bang-extensions-behaviors-companions-skills-init-fnl-762"></a>`fen.extensions.skills.register!`
`function`
Registration entrypoint alias for installing the available-skills prompt fragment.
*tags:* skills, register, prompt
_extensions/behaviors/companions/skills/init.fnl:756_

## <a id="fen-extensions-skills-bundled"></a>fen.extensions.skills.bundled

### <a id="fen-extensions-skills-bundled-skills-extensions-behaviors-companions-skills-bundled-fnl-64"></a>`fen.extensions.skills.bundled.skills`
_extensions/behaviors/companions/skills/bundled.fnl:64_

## <a id="fen-extensions-skills-ignore"></a>fen.extensions.skills.ignore

### <a id="fen-extensions-skills-ignore-with-dir-extensions-behaviors-companions-skills-ignore-fnl-80"></a>`fen.extensions.skills.ignore.with-dir`
`(with-dir rules dir) -> [IgnoreRule]`
Return a copied ignore-rule chain extended with .gitignore, .ignore, and .fdignore files from one directory.
*tags:* skills, ignore, rules, discovery
_extensions/behaviors/companions/skills/ignore.fnl:75_

### <a id="fen-extensions-skills-ignore-load-chain-extensions-behaviors-companions-skills-ignore-fnl-91"></a>`fen.extensions.skills.ignore.load-chain`
`(load-chain root) -> [IgnoreRule]`
Collect ignore rules from ancestor directories root-to-leaf for skill discovery traversal.
*tags:* skills, ignore, rules, discovery
_extensions/behaviors/companions/skills/ignore.fnl:86_

### <a id="fen-extensions-skills-ignore-match-q-extensions-behaviors-companions-skills-ignore-fnl-156"></a>`fen.extensions.skills.ignore.match?`
`(match? target is-dir? rules) -> boolean`
Decide whether a path is ignored by the rule chain, with later negated or matching rules taking precedence.
*tags:* skills, ignore, rules, match
_extensions/behaviors/companions/skills/ignore.fnl:151_

## <a id="fen-extensions-skills-state"></a>fen.extensions.skills.state

### <a id="fen-extensions-skills-state-visible-q-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.visible?`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-selected-name-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.selected-name`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-cached-rows-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.cached-rows`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-cached-at-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.cached-at`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-cached-w-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.cached-w`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-cached-selected-name-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.cached-selected-name`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-discover-cache-key-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.discover-cache-key`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-discover-cache-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.discover-cache`
_extensions/behaviors/companions/skills/state.fnl:3_

### <a id="fen-extensions-skills-state-discover-cache-at-extensions-behaviors-companions-skills-state-fnl-3"></a>`fen.extensions.skills.state.discover-cache-at`
_extensions/behaviors/companions/skills/state.fnl:3_

## <a id="fen-extensions-status"></a>fen.extensions.status

### <a id="fen-extensions-status-register-extensions-behaviors-inspectors-status-init-fnl-7"></a>`fen.extensions.status.register`
_extensions/behaviors/inspectors/status/init.fnl:7_

## <a id="fen-extensions-status-commands-status"></a>fen.extensions.status.commands.status

### <a id="fen-extensions-status-commands-status-register-extensions-behaviors-inspectors-status-commands-status-fnl-156"></a>`fen.extensions.status.commands.status.register`
`(register api) -> nil`
Register the /status command and status panel for runtime, model, session, token, and extension diagnostics.
*tags:* commands, status, register
_extensions/behaviors/inspectors/status/commands/status.fnl:151_

## <a id="fen-extensions-status-state-status"></a>fen.extensions.status.state.status

### <a id="fen-extensions-status-state-status-visible-q-extensions-behaviors-inspectors-status-state-status-fnl-27"></a>`fen.extensions.status.state.status.visible?`
`boolean`
Visibility flag for the persistent /status panel showing runtime, model, session, and context details.
*tags:* builtin, commands, state, status, panel
_extensions/behaviors/inspectors/status/state/status.fnl:3_

### <a id="fen-extensions-status-state-status-cached-rows-extensions-behaviors-inspectors-status-state-status-fnl-27"></a>`fen.extensions.status.state.status.cached-rows`
`[PresenterRow]|nil`
Cached rendered /status panel rows reused while status inputs and terminal width remain stable.
*tags:* builtin, commands, state, status, cache
_extensions/behaviors/inspectors/status/state/status.fnl:9_

### <a id="fen-extensions-status-state-status-cached-at-extensions-behaviors-inspectors-status-state-status-fnl-27"></a>`fen.extensions.status.state.status.cached-at`
`number`
Timestamp for the /status panel cache, used to throttle recomputation of derived runtime details.
*tags:* builtin, commands, state, status, cache
_extensions/behaviors/inspectors/status/state/status.fnl:15_

### <a id="fen-extensions-status-state-status-cached-w-extensions-behaviors-inspectors-status-state-status-fnl-27"></a>`fen.extensions.status.state.status.cached-w`
`number`
Terminal width associated with cached /status rows so resize events rebuild aligned panel text.
*tags:* builtin, commands, state, status, cache
_extensions/behaviors/inspectors/status/state/status.fnl:21_

## <a id="fen-extensions-status-util"></a>fen.extensions.status.util

### <a id="fen-extensions-status-util-approx-tokens-extensions-behaviors-inspectors-status-util-fnl-12"></a>`fen.extensions.status.util.approx-tokens`
`(approx-tokens s) -> number`
Estimate token count from text length for status displays when provider-reported usage is unavailable.
*tags:* commands, tokens, status
_extensions/behaviors/inspectors/status/util.fnl:7_

### <a id="fen-extensions-status-util-safe-json-extensions-behaviors-inspectors-status-util-fnl-24"></a>`fen.extensions.status.util.safe-json`
`(safe-json v) -> string`
JSON-encode a value for token estimation, falling back to tostring when encoding fails.
*tags:* commands, json, tokens
_extensions/behaviors/inspectors/status/util.fnl:19_

### <a id="fen-extensions-status-util-content-tokens-extensions-behaviors-inspectors-status-util-fnl-33"></a>`fen.extensions.status.util.content-tokens`
`(content-tokens content) -> number`
Estimate tokens for canonical message content, including text, thinking blocks, and tool-call names/arguments.
*tags:* commands, tokens, messages
_extensions/behaviors/inspectors/status/util.fnl:28_

### <a id="fen-extensions-status-util-estimated-context-tokens-extensions-behaviors-inspectors-status-util-fnl-56"></a>`fen.extensions.status.util.estimated-context-tokens`
`(estimated-context-tokens agent) -> number`
Estimate the current agent context size from system prompt, messages, content blocks, and tool-result names.
*tags:* commands, tokens, agent
_extensions/behaviors/inspectors/status/util.fnl:51_

### <a id="fen-extensions-status-util-usage-totals-extensions-behaviors-inspectors-status-util-fnl-69"></a>`fen.extensions.status.util.usage-totals`
`(usage-totals messages) -> Usage`
Sum provider usage counters across assistant messages for status and session diagnostics.
*tags:* commands, tokens, usage
_extensions/behaviors/inspectors/status/util.fnl:64_

### <a id="fen-extensions-status-util-fmt-tokens-extensions-behaviors-inspectors-status-util-fnl-88"></a>`fen.extensions.status.util.fmt-tokens`
`(fmt-tokens n) -> string`
Format a token count compactly with raw, k, or M suffixes for slash-command status output.
*tags:* commands, tokens, format
_extensions/behaviors/inspectors/status/util.fnl:83_

### <a id="fen-extensions-status-util-format-token-summary-extensions-behaviors-inspectors-status-util-fnl-101"></a>`fen.extensions.status.util.format-token-summary`
`(format-token-summary usage approx) -> string`
Build the one-line input/output/cache/context token summary shown by /status.
*tags:* commands, tokens, status
_extensions/behaviors/inspectors/status/util.fnl:96_

### <a id="fen-extensions-status-util-runtime-version-extensions-behaviors-inspectors-status-util-fnl-114"></a>`fen.extensions.status.util.runtime-version`
`(runtime-version) -> string`
Return the build-stamped fen version, or unknown when running from source/tests without dist metadata.
*tags:* commands, status, version
_extensions/behaviors/inspectors/status/util.fnl:109_

### <a id="fen-extensions-status-util-nth-arg-extensions-behaviors-inspectors-status-util-fnl-134"></a>`fen.extensions.status.util.nth-arg`
`(nth-arg args n) -> string|nil`
Extract the nth whitespace-delimited argument from a slash-command argument string.
*tags:* commands, args, parsing
_extensions/behaviors/inspectors/status/util.fnl:129_

### <a id="fen-extensions-status-util-first-arg-extensions-behaviors-inspectors-status-util-fnl-143"></a>`fen.extensions.status.util.first-arg`
`(first-arg args) -> string|nil`
Extract the first whitespace-delimited argument from a slash-command argument string.
*tags:* commands, args, parsing
_extensions/behaviors/inspectors/status/util.fnl:138_

## <a id="fen-extensions-stdio"></a>fen.extensions.stdio

### <a id="fen-extensions-stdio-render-event-extensions-adapters-presenters-stdio-init-fnl-119"></a>`fen.extensions.stdio.render-event`
`(render-event ev) -> nil`
Render one event to stdio with prefixes, optional ANSI color, streaming delta coalescing, and stderr errors.
*tags:* stdio, presenter, events
_extensions/adapters/presenters/stdio/init.fnl:114_

### <a id="fen-extensions-stdio-stdin-tty-q-extensions-adapters-presenters-stdio-init-fnl-158"></a>`fen.extensions.stdio.stdin-tty?`
`(stdin-tty?) -> boolean`
Return whether stdin is an interactive terminal for prompt-prefix and line-mode behavior.
*tags:* stdio, presenter, tty
_extensions/adapters/presenters/stdio/init.fnl:153_

### <a id="fen-extensions-stdio-drain-turn-extensions-adapters-presenters-stdio-init-fnl-173"></a>`fen.extensions.stdio.drain-turn`
`(drain-turn ctx) -> nil`
Drive cooperative on-tick callbacks until the active agent turn completes in stdio mode.
*tags:* stdio, presenter, loop
_extensions/adapters/presenters/stdio/init.fnl:168_

### <a id="fen-extensions-stdio-submit-line-extensions-adapters-presenters-stdio-init-fnl-188"></a>`fen.extensions.stdio.submit-line`
`(submit-line ctx line interactive?) -> nil`
Echo and submit one user line, then drain the resulting turn or emit a submit error.
*tags:* stdio, presenter, input
_extensions/adapters/presenters/stdio/init.fnl:183_

### <a id="fen-extensions-stdio-run-extensions-adapters-presenters-stdio-init-fnl-202"></a>`fen.extensions.stdio.run`
`(run ctx) -> nil`
Run the line-oriented stdio presenter loop until EOF, prompting interactively when stdin is a TTY.
*tags:* stdio, presenter, run
_extensions/adapters/presenters/stdio/init.fnl:197_

### <a id="fen-extensions-stdio-notify-extensions-adapters-presenters-stdio-init-fnl-221"></a>`fen.extensions.stdio.notify`
`(notify text opts?) -> nil`
Implement the stdio UI notify hook by printing an informational line.
*tags:* stdio, presenter, ui, notify
_extensions/adapters/presenters/stdio/init.fnl:216_

### <a id="fen-extensions-stdio-prompt-extensions-adapters-presenters-stdio-init-fnl-229"></a>`fen.extensions.stdio.prompt`
`(prompt opts) -> string|nil`
Implement the stdio UI prompt hook by printing a label and reading one line from stdin.
*tags:* stdio, presenter, ui, prompt
_extensions/adapters/presenters/stdio/init.fnl:224_

### <a id="fen-extensions-stdio-select-extensions-adapters-presenters-stdio-init-fnl-240"></a>`fen.extensions.stdio.select`
`(select opts) -> Choice|nil`
Implement the stdio UI select hook by listing choices and returning the numbered selection.
*tags:* stdio, presenter, ui, select
_extensions/adapters/presenters/stdio/init.fnl:235_

### <a id="fen-extensions-stdio-register-extensions-adapters-presenters-stdio-init-fnl-261"></a>`fen.extensions.stdio.register`
_extensions/adapters/presenters/stdio/init.fnl:261_

## <a id="fen-extensions-todo"></a>fen.extensions.todo

_Undocumented data/state re-exports omitted from the public API listing:_ `fen.extensions.todo.register`, `fen.extensions.todo.register!`, `fen.extensions.todo.execute`, `fen.extensions.todo.validate-items`, `fen.extensions.todo.copy-items`, `fen.extensions.todo.counts`, `fen.extensions.todo.summary-line`, `fen.extensions.todo.render-text`, `fen.extensions.todo.panel-spec`, `fen.extensions.todo.rebuild-from-messages!`, `fen.extensions.todo._state`, `fen.extensions.todo._test`

## <a id="fen-extensions-todo-state"></a>fen.extensions.todo.state

### <a id="fen-extensions-todo-state-items-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.items`
_extensions/behaviors/companions/todo/state.fnl:3_

### <a id="fen-extensions-todo-state-version-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.version`
_extensions/behaviors/companions/todo/state.fnl:3_

### <a id="fen-extensions-todo-state-visible-q-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.visible?`
_extensions/behaviors/companions/todo/state.fnl:3_

### <a id="fen-extensions-todo-state-cached-rows-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.cached-rows`
_extensions/behaviors/companions/todo/state.fnl:3_

### <a id="fen-extensions-todo-state-cached-w-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.cached-w`
_extensions/behaviors/companions/todo/state.fnl:3_

### <a id="fen-extensions-todo-state-cached-version-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.cached-version`
_extensions/behaviors/companions/todo/state.fnl:3_

### <a id="fen-extensions-todo-state-last-updated-extensions-behaviors-companions-todo-state-fnl-3"></a>`fen.extensions.todo.state.last-updated`
_extensions/behaviors/companions/todo/state.fnl:3_

## <a id="fen-extensions-tui"></a>fen.extensions.tui

### <a id="fen-extensions-tui-init-bang-extensions-adapters-presenters-tui-init-fnl-97"></a>`fen.extensions.tui.init!`
`(init!) -> nil`
Initialize or refresh termbox runtime state, terminal modes, dimensions, and bracketed paste support.
*tags:* tui, lifecycle, termbox, reload
_extensions/adapters/presenters/tui/init.fnl:92_

### <a id="fen-extensions-tui-shutdown-extensions-adapters-presenters-tui-init-fnl-147"></a>`fen.extensions.tui.shutdown`
`(shutdown) -> nil`
Tear down termbox and bracketed paste mode when the TUI presenter exits.
*tags:* tui, lifecycle, termbox
_extensions/adapters/presenters/tui/init.fnl:142_

### <a id="fen-extensions-tui-hard-refresh-bang-extensions-adapters-presenters-tui-init-fnl-163"></a>`fen.extensions.tui.hard-refresh!`
`(hard-refresh!) -> nil`
Recover from external terminal corruption by re-asserting terminal modes and forcing a full repaint.
*tags:* tui, lifecycle, redraw, termbox
_extensions/adapters/presenters/tui/init.fnl:158_

### <a id="fen-extensions-tui-suspend-bang-extensions-adapters-presenters-tui-init-fnl-177"></a>`fen.extensions.tui.suspend!`
`(suspend!) -> nil`
Ctrl-Z job-control suspend: restore the terminal, stop with SIGTSTP, then re-init and repaint on resume.
*tags:* tui, lifecycle, suspend, termbox, signal
_extensions/adapters/presenters/tui/init.fnl:172_

### <a id="fen-extensions-tui-reset-conversation-bang-extensions-adapters-presenters-tui-init-fnl-194"></a>`fen.extensions.tui.reset-conversation!`
`(reset-conversation!) -> nil`
Clear transcript, streaming, input, paste, scroll, and per-turn status state while preserving UI identity.
*tags:* tui, lifecycle, session, reset
_extensions/adapters/presenters/tui/init.fnl:189_

### <a id="fen-extensions-tui-set-status-info-extensions-adapters-presenters-tui-init-fnl-242"></a>`fen.extensions.tui.set-status-info`
`(set-status-info info) -> nil`
Merge provider, model, queue, and context details into the persistent TUI status line state.
*tags:* tui, status, presenter
_extensions/adapters/presenters/tui/init.fnl:237_

### <a id="fen-extensions-tui-input-meta-extensions-adapters-presenters-tui-init-fnl-291"></a>`fen.extensions.tui.input-meta`
_extensions/adapters/presenters/tui/init.fnl:291_

### <a id="fen-extensions-tui-warn-if-stalled-bang-extensions-adapters-presenters-tui-init-fnl-306"></a>`fen.extensions.tui.warn-if-stalled!`
_extensions/adapters/presenters/tui/init.fnl:306_

### <a id="fen-extensions-tui-peek-timeout-ms-extensions-adapters-presenters-tui-init-fnl-338"></a>`fen.extensions.tui.peek-timeout-ms`
`(peek-timeout-ms is-busy?) -> number`
Choose a short or idle termbox poll timeout based on dirty state, Alt resolution, busy work, and animation needs.
*tags:* tui, loop, polling, performance
_extensions/adapters/presenters/tui/init.fnl:333_

### <a id="fen-extensions-tui-interrupted-syscall-q-extensions-adapters-presenters-tui-init-fnl-355"></a>`fen.extensions.tui.interrupted-syscall?`
`(interrupted-syscall? err) -> boolean`
True when a peek_event error string is a transient signal-interrupted syscall (EINTR), which must not be treated as session-fatal.
*tags:* tui, loop, termbox, signal, eintr
_extensions/adapters/presenters/tui/init.fnl:350_

### <a id="fen-extensions-tui-run-extensions-adapters-presenters-tui-init-fnl-379"></a>`fen.extensions.tui.run`
`(run on-submit on-tick on-cancel is-busy? ?get-turn) -> nil`
Run the TUI presenter loop, repainting, polling termbox events, ticking cooperative work, and dispatching input. ?get-turn optionally returns the in-flight agent coroutine for richer stall diagnostics.
*tags:* tui, presenter, loop, termbox
_extensions/adapters/presenters/tui/init.fnl:374_

### <a id="fen-extensions-tui-register-extensions-adapters-presenters-tui-init-fnl-455"></a>`fen.extensions.tui.register`
_extensions/adapters/presenters/tui/init.fnl:455_

## <a id="fen-extensions-tui-draw"></a>fen.extensions.tui.draw

### <a id="fen-extensions-tui-draw-in-bounds-q-extensions-adapters-presenters-tui-draw-fnl-19"></a>`fen.extensions.tui.draw.in-bounds?`
`(in-bounds? x y) -> boolean`
Return whether a zero-based terminal coordinate is inside the current termbox dimensions.
*tags:* tui, draw, bounds, termbox
_extensions/adapters/presenters/tui/draw.fnl:14_

### <a id="fen-extensions-tui-draw-fill-row-extensions-adapters-presenters-tui-draw-fnl-28"></a>`fen.extensions.tui.draw.fill-row`
`(fill-row y x0 x1 ch fg bg) -> nil`
Fill a clipped horizontal row segment with one termbox print call to reduce Lua-to-C overhead.
*tags:* tui, draw, termbox, performance
_extensions/adapters/presenters/tui/draw.fnl:23_

### <a id="fen-extensions-tui-draw-utf8-prefix-cols-extensions-adapters-presenters-tui-draw-fnl-44"></a>`fen.extensions.tui.draw.utf8-prefix-cols`
`(utf8-prefix-cols s cols) -> string`
Return a display-column-limited UTF-8 prefix without cutting multibyte characters in the middle.
*tags:* tui, draw, utf8, clipping
_extensions/adapters/presenters/tui/draw.fnl:39_

### <a id="fen-extensions-tui-draw-put-clipped-extensions-adapters-presenters-tui-draw-fnl-79"></a>`fen.extensions.tui.draw.put-clipped`
`(put-clipped x y fg bg s width-cap) -> nil`
Print clipped text at an in-bounds coordinate while respecting both terminal width and caller cap.
*tags:* tui, draw, termbox, clipping
_extensions/adapters/presenters/tui/draw.fnl:74_

## <a id="fen-extensions-tui-ingest"></a>fen.extensions.tui.ingest

### <a id="fen-extensions-tui-ingest-append-event-extensions-adapters-presenters-tui-ingest-fnl-89"></a>`fen.extensions.tui.ingest.append-event`
`(append-event ev) -> nil`
Ingest a bus event into transcript rows and TUI status side effects, including streaming coalescing and cache invalidation.
*tags:* tui, ingest, events, transcript, status
_extensions/adapters/presenters/tui/ingest.fnl:84_

## <a id="fen-extensions-tui-input"></a>fen.extensions.tui.input

### <a id="fen-extensions-tui-input-ensure-defaults-bang-extensions-adapters-presenters-tui-input-fnl-41"></a>`fen.extensions.tui.input.ensure-defaults!`
`(ensure-defaults!) -> nil`
Backfill persistent input buffer, paste, history, quit, cancel, and Alt state fields after hot reloads.
*tags:* tui, input, state, reload
_extensions/adapters/presenters/tui/input.fnl:36_

### <a id="fen-extensions-tui-input-input-display-rows-extensions-adapters-presenters-tui-input-fnl-63"></a>`fen.extensions.tui.input.input-display-rows`
`(input-display-rows buf width cursor) -> [InputDisplayRow]`
Wrap the input buffer into prompt and continuation rows that preserve byte offsets for cursor placement.
*tags:* tui, input, wrapping, cursor
_extensions/adapters/presenters/tui/input.fnl:58_

### <a id="fen-extensions-tui-input-cursor-display-pos-extensions-adapters-presenters-tui-input-fnl-120"></a>`fen.extensions.tui.input.cursor-display-pos`
`(cursor-display-pos rows cursor) -> row-index col`
Locate the cursor within wrapped input rows using the same byte-offset view that painting uses.
*tags:* tui, input, cursor, wrapping
_extensions/adapters/presenters/tui/input.fnl:115_

### <a id="fen-extensions-tui-input-input-rows-extensions-adapters-presenters-tui-input-fnl-135"></a>`fen.extensions.tui.input.input-rows`
`(input-rows) -> number`
Return the current input region height, capped for multiline editing and terminal layout stability.
*tags:* tui, input, layout
_extensions/adapters/presenters/tui/input.fnl:130_

### <a id="fen-extensions-tui-input-paint-input-extensions-adapters-presenters-tui-input-fnl-148"></a>`fen.extensions.tui.input.paint-input`
`(paint-input layout) -> nil`
Paint the visible wrapped input rows and place or hide the terminal cursor within the input region.
*tags:* tui, input, paint, cursor
_extensions/adapters/presenters/tui/input.fnl:143_

### <a id="fen-extensions-tui-input-handle-key-extensions-adapters-presenters-tui-input-fnl-530"></a>`fen.extensions.tui.input.handle-key`
`(handle-key ev on-submit on-cancel is-busy?) -> boolean|nil`
Dispatch a termbox key event into buffer edits, history movement, submission, cancellation, or quit handling.
*tags:* tui, input, keyboard, events
_extensions/adapters/presenters/tui/input.fnl:525_

### <a id="fen-extensions-tui-input-handle-mouse-extensions-adapters-presenters-tui-input-fnl-718"></a>`fen.extensions.tui.input.handle-mouse`
`(handle-mouse ev) -> nil`
Interpret mouse wheel and click events for transcript scrolling, panel focus, and redraw invalidation.
*tags:* tui, input, mouse, scroll
_extensions/adapters/presenters/tui/input.fnl:713_

### <a id="fen-extensions-tui-input-handle-event-extensions-adapters-presenters-tui-input-fnl-735"></a>`fen.extensions.tui.input.handle-event`
`(handle-event ev on-submit on-cancel is-busy?) -> boolean|nil`
Route termbox keyboard, mouse, resize, paste, and Alt-synthesized events through the TUI input layer.
*tags:* tui, input, events, termbox
_extensions/adapters/presenters/tui/input.fnl:730_

## <a id="fen-extensions-tui-markdown"></a>fen.extensions.tui.markdown

### <a id="fen-extensions-tui-markdown-parse-extensions-adapters-presenters-tui-markdown-fnl-579"></a>`fen.extensions.tui.markdown.parse`
`(parse s) -> [MarkdownBlock]`
Parse Markdown source into the lightweight block records understood by the TUI renderer.
*tags:* tui, markdown, parse, blocks
_extensions/adapters/presenters/tui/markdown.fnl:574_

### <a id="fen-extensions-tui-markdown-parse-inline-extensions-adapters-presenters-tui-markdown-fnl-586"></a>`fen.extensions.tui.markdown.parse-inline`
`(parse-inline s attr?) -> [Segment]`
Parse simple inline Markdown spans into styled text segments for termbox painting.
*tags:* tui, markdown, parse, inline
_extensions/adapters/presenters/tui/markdown.fnl:581_

### <a id="fen-extensions-tui-markdown-render-block-extensions-adapters-presenters-tui-markdown-fnl-593"></a>`fen.extensions.tui.markdown.render-block`
`(render-block block width) -> [PresenterRow]`
Render one parsed Markdown block into wrapped TUI rows for the requested width.
*tags:* tui, markdown, render, blocks
_extensions/adapters/presenters/tui/markdown.fnl:588_

### <a id="fen-extensions-tui-markdown-render-text-extensions-adapters-presenters-tui-markdown-fnl-600"></a>`fen.extensions.tui.markdown.render-text`
`(render-text s width) -> [PresenterRow]`
Parse and render Markdown text into styled TUI rows while preserving readable chat line breaks.
*tags:* tui, markdown, render, text
_extensions/adapters/presenters/tui/markdown.fnl:595_

### <a id="fen-extensions-tui-markdown-render-extensions-adapters-presenters-tui-markdown-fnl-607"></a>`fen.extensions.tui.markdown.render`
`(render s width) -> [PresenterRow]`
Compatibility alias for render-text used by transcript rendering and tests.
*tags:* tui, markdown, render, text
_extensions/adapters/presenters/tui/markdown.fnl:602_

### <a id="fen-extensions-tui-markdown-display-len-extensions-adapters-presenters-tui-markdown-fnl-614"></a>`fen.extensions.tui.markdown.display-len`
`(display-len s) -> number`
Approximate display width by counting UTF-8 codepoints as terminal cells.
*tags:* tui, markdown, width, utf8
_extensions/adapters/presenters/tui/markdown.fnl:609_

## <a id="fen-extensions-tui-paint"></a>fen.extensions.tui.paint

### <a id="fen-extensions-tui-paint-ensure-state-defaults-bang-extensions-adapters-presenters-tui-paint-fnl-51"></a>`fen.extensions.tui.paint.ensure-state-defaults!`
`(ensure-state-defaults!) -> nil`
Backfill persistent paint, transcript, status, errors, spinner, and input defaults after reloads.
*tags:* tui, paint, state, reload
_extensions/adapters/presenters/tui/paint.fnl:46_

### <a id="fen-extensions-tui-paint-max-scroll-extensions-adapters-presenters-tui-paint-fnl-65"></a>`fen.extensions.tui.paint.max-scroll`
`(max-scroll) -> number`
Return the maximum transcript scroll offset after accounting for the current input area height.
*tags:* tui, paint, scroll, transcript
_extensions/adapters/presenters/tui/paint.fnl:60_

### <a id="fen-extensions-tui-paint-layout-extensions-adapters-presenters-tui-paint-fnl-131"></a>`fen.extensions.tui.paint.layout`
`(layout) -> Layout`
Compute status, transcript, input, and registered panel slots for the current terminal dimensions.
*tags:* tui, paint, layout, panels
_extensions/adapters/presenters/tui/paint.fnl:126_

### <a id="fen-extensions-tui-paint-fmt-tokens-extensions-adapters-presenters-tui-paint-fnl-182"></a>`fen.extensions.tui.paint.fmt-tokens`
`function`
Compact token-count formatter alias used by status renderers and tests.
*tags:* tui, paint, status, tokens
_extensions/adapters/presenters/tui/paint.fnl:177_

### <a id="fen-extensions-tui-paint-paint-status-extensions-adapters-presenters-tui-paint-fnl-191"></a>`fen.extensions.tui.paint.paint-status`
`(paint-status layout) -> nil`
Delegate status-line painting to the status panel module while preserving the paint facade entrypoint.
*tags:* tui, paint, status, delegate
_extensions/adapters/presenters/tui/paint.fnl:186_

### <a id="fen-extensions-tui-paint-paint-panels-extensions-adapters-presenters-tui-paint-fnl-252"></a>`fen.extensions.tui.paint.paint-panels`
`(paint-panels layout) -> nil`
Render registered above-input and below-status panels with per-panel error isolation.
*tags:* tui, paint, panels, errors
_extensions/adapters/presenters/tui/paint.fnl:247_

### <a id="fen-extensions-tui-paint-paint-transcript-extensions-adapters-presenters-tui-paint-fnl-268"></a>`fen.extensions.tui.paint.paint-transcript`
`(paint-transcript layout) -> nil`
Paint the visible transcript viewport rows into the reserved transcript region.
*tags:* tui, paint, transcript, viewport
_extensions/adapters/presenters/tui/paint.fnl:263_

### <a id="fen-extensions-tui-paint-paint-input-extensions-adapters-presenters-tui-paint-fnl-285"></a>`fen.extensions.tui.paint.paint-input`
`(paint-input layout) -> nil`
Delegate to the input renderer for the reserved input region.
*tags:* tui, paint, input, delegate
_extensions/adapters/presenters/tui/paint.fnl:280_

### <a id="fen-extensions-tui-paint-invalidate-bang-extensions-adapters-presenters-tui-paint-fnl-295"></a>`fen.extensions.tui.paint.invalidate!`
`(invalidate!) -> nil`
Mark the TUI dirty so the next presenter-loop pass repaints the terminal.
*tags:* tui, paint, redraw, dirty
_extensions/adapters/presenters/tui/paint.fnl:290_

### <a id="fen-extensions-tui-paint-invalidate-full-bang-extensions-adapters-presenters-tui-paint-fnl-304"></a>`fen.extensions.tui.paint.invalidate-full!`
`(invalidate-full!) -> nil`
Request a cache-clearing repaint for resize, reload, and display toggles that invalidate wrapped rows.
*tags:* tui, paint, redraw, cache
_extensions/adapters/presenters/tui/paint.fnl:299_

### <a id="fen-extensions-tui-paint-busy-q-extensions-adapters-presenters-tui-paint-fnl-314"></a>`fen.extensions.tui.paint.busy?`
`(busy?) -> boolean|string|nil`
Report whether thinking or tool-running status should keep the busy animation active.
*tags:* tui, paint, busy, status
_extensions/adapters/presenters/tui/paint.fnl:309_

### <a id="fen-extensions-tui-paint-advance-spinner-if-due-bang-extensions-adapters-presenters-tui-paint-fnl-323"></a>`fen.extensions.tui.paint.advance-spinner-if-due!`
`(advance-spinner-if-due!) -> nil`
Advance the status spinner on a throttled presenter-loop tick cadence and invalidate when it changes.
*tags:* tui, paint, spinner, animation
_extensions/adapters/presenters/tui/paint.fnl:318_

### <a id="fen-extensions-tui-paint-redraw-if-needed-bang-extensions-adapters-presenters-tui-paint-fnl-342"></a>`fen.extensions.tui.paint.redraw-if-needed!`
`(redraw-if-needed!) -> nil`
Repaint only when dirty or forced, clearing caches and terminal geometry before forced redraws.
*tags:* tui, paint, redraw, performance
_extensions/adapters/presenters/tui/paint.fnl:337_

### <a id="fen-extensions-tui-paint-paint-frame-bang-extensions-adapters-presenters-tui-paint-fnl-363"></a>`fen.extensions.tui.paint.paint-frame!`
`(paint-frame!) -> nil`
Paint a complete frame into the termbox back buffer without presenting, allowing overlays to share the underlay.
*tags:* tui, paint, frame, termbox
_extensions/adapters/presenters/tui/paint.fnl:358_

### <a id="fen-extensions-tui-paint-redraw-bang-extensions-adapters-presenters-tui-paint-fnl-385"></a>`fen.extensions.tui.paint.redraw!`
`(redraw!) -> nil`
Paint a complete TUI frame and present termbox's back buffer to the terminal.
*tags:* tui, paint, redraw, termbox
_extensions/adapters/presenters/tui/paint.fnl:380_

### <a id="fen-extensions-tui-paint-clear-render-caches-bang-extensions-adapters-presenters-tui-paint-fnl-395"></a>`fen.extensions.tui.paint.clear-render-caches!`
`(clear-render-caches!) -> nil`
Drop transcript render caches so forced repaints or reloads recompute rows with current renderers.
*tags:* tui, paint, cache, transcript
_extensions/adapters/presenters/tui/paint.fnl:390_

### <a id="fen-extensions-tui-paint-force-redraw-bang-extensions-adapters-presenters-tui-paint-fnl-406"></a>`fen.extensions.tui.paint.force-redraw!`
`(force-redraw!) -> nil`
Blank-present and repaint the full terminal to resynchronize termbox front-buffer assumptions.
*tags:* tui, paint, redraw, termbox
_extensions/adapters/presenters/tui/paint.fnl:401_

## <a id="fen-extensions-tui-panels-busy"></a>fen.extensions.tui.panels.busy

### <a id="fen-extensions-tui-panels-busy-spin-char-extensions-adapters-presenters-tui-panels-busy-fnl-20"></a>`fen.extensions.tui.panels.busy.spin-char`
`(spin-char) -> string`
Return the current busy indicator glyph, respecting the animation toggle and spinner frame counter.
*tags:* tui, panel, busy, spinner
_extensions/adapters/presenters/tui/panels/busy.fnl:15_

### <a id="fen-extensions-tui-panels-busy-turn-elapsed-extensions-adapters-presenters-tui-panels-busy-fnl-33"></a>`fen.extensions.tui.panels.busy.turn-elapsed`
`(turn-elapsed) -> string`
Return elapsed turn time text for the busy panel, or an empty string when no turn is active.
*tags:* tui, panel, busy, timing
_extensions/adapters/presenters/tui/panels/busy.fnl:28_

### <a id="fen-extensions-tui-panels-busy-height-extensions-adapters-presenters-tui-panels-busy-fnl-63"></a>`fen.extensions.tui.panels.busy.height`
`(height ctx) -> number`
Reserve one above-input row only while thinking, retrying, or running a tool.
*tags:* tui, panel, busy, layout
_extensions/adapters/presenters/tui/panels/busy.fnl:58_

### <a id="fen-extensions-tui-panels-busy-render-extensions-adapters-presenters-tui-panels-busy-fnl-71"></a>`fen.extensions.tui.panels.busy.render`
`(render ctx) -> [PresenterRow]`
Render spinner, busy label, retry delay, and elapsed time rows for the active turn.
*tags:* tui, panel, busy, render
_extensions/adapters/presenters/tui/panels/busy.fnl:66_

### <a id="fen-extensions-tui-panels-busy-spec-extensions-adapters-presenters-tui-panels-busy-fnl-84"></a>`fen.extensions.tui.panels.busy.spec`
`(spec) -> PanelSpec`
Return the built-in busy panel contribution that appears above the input while work is active.
*tags:* tui, panel, busy, register
_extensions/adapters/presenters/tui/panels/busy.fnl:79_

## <a id="fen-extensions-tui-panels-errors"></a>fen.extensions.tui.panels.errors

### <a id="fen-extensions-tui-panels-errors-ensure-defaults-bang-extensions-adapters-presenters-tui-panels-errors-fnl-20"></a>`fen.extensions.tui.panels.errors.ensure-defaults!`
`(ensure-defaults!) -> nil`
Backfill persistent error-panel visibility state on live TUI state tables after reloads.
*tags:* tui, panel, errors, state, reload
_extensions/adapters/presenters/tui/panels/errors.fnl:15_

### <a id="fen-extensions-tui-panels-errors-toggle-bang-extensions-adapters-presenters-tui-panels-errors-fnl-68"></a>`fen.extensions.tui.panels.errors.toggle!`
`(toggle! value?) -> boolean`
Toggle or set the TUI error panel visibility and return the new visible state.
*tags:* tui, panel, errors, visibility
_extensions/adapters/presenters/tui/panels/errors.fnl:63_

### <a id="fen-extensions-tui-panels-errors-visible-q-extensions-adapters-presenters-tui-panels-errors-fnl-79"></a>`fen.extensions.tui.panels.errors.visible?`
`(visible?) -> boolean`
Report whether the recent-errors panel should currently reserve below-status space.
*tags:* tui, panel, errors, visibility
_extensions/adapters/presenters/tui/panels/errors.fnl:74_

### <a id="fen-extensions-tui-panels-errors-clear-transcript-errors-bang-extensions-adapters-presenters-tui-panels-errors-fnl-113"></a>`fen.extensions.tui.panels.errors.clear-transcript-errors!`
`(clear-transcript-errors!) -> nil`
Remove error and extension-error events from the transcript and invalidate transcript layout cache.
*tags:* tui, panel, errors, transcript, cache
_extensions/adapters/presenters/tui/panels/errors.fnl:108_

### <a id="fen-extensions-tui-panels-errors-spec-extensions-adapters-presenters-tui-panels-errors-fnl-126"></a>`fen.extensions.tui.panels.errors.spec`
`(spec) -> PanelSpec`
Return the error introspection panel contribution for below-status rendering.
*tags:* tui, panel, errors, register
_extensions/adapters/presenters/tui/panels/errors.fnl:121_

## <a id="fen-extensions-tui-panels-status"></a>fen.extensions.tui.panels.status

### <a id="fen-extensions-tui-panels-status-ensure-defaults-bang-extensions-adapters-presenters-tui-panels-status-fnl-33"></a>`fen.extensions.tui.panels.status.ensure-defaults!`
`(ensure-defaults!) -> nil`
Backfill persistent status-info fields, token counters, retry state, queue counts, and running-label migration.
*tags:* tui, panel, status, state, reload
_extensions/adapters/presenters/tui/panels/status.fnl:28_

### <a id="fen-extensions-tui-panels-status-paint-extensions-adapters-presenters-tui-panels-status-fnl-103"></a>`fen.extensions.tui.panels.status.paint`
`(paint layout) -> nil`
Paint the top status row by composing registered left and right status items with error isolation.
*tags:* tui, panel, status, paint, registry
_extensions/adapters/presenters/tui/panels/status.fnl:98_

## <a id="fen-extensions-tui-panels-transcript"></a>fen.extensions.tui.panels.transcript

### <a id="fen-extensions-tui-panels-transcript-tool-result-preview-bytes-extensions-adapters-presenters-tui-panels-transcript-fnl-24"></a>`fen.extensions.tui.panels.transcript.TOOL-RESULT-PREVIEW-BYTES`
`number`
Maximum inline bytes from a tool result shown in collapsed transcript previews.
*tags:* tui, transcript, tools, defaults
_extensions/adapters/presenters/tui/panels/transcript.fnl:19_

### <a id="fen-extensions-tui-panels-transcript-ensure-defaults-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-31"></a>`fen.extensions.tui.panels.transcript.ensure-defaults!`
`(ensure-defaults!) -> nil`
Backfill persistent transcript, streaming, scroll, Markdown, and tool-result display state after reloads.
*tags:* tui, transcript, state, reload
_extensions/adapters/presenters/tui/panels/transcript.fnl:26_

### <a id="fen-extensions-tui-panels-transcript-args-extensions-adapters-presenters-tui-panels-transcript-fnl-62"></a>`fen.extensions.tui.panels.transcript.args-`
`(args->string args) -> string`
Convert tool-call arguments to compact JSON text for transcript fallback rendering.
*tags:* tui, transcript, tools, json
_extensions/adapters/presenters/tui/panels/transcript.fnl:57_

### <a id="fen-extensions-tui-panels-transcript-content-extensions-adapters-presenters-tui-panels-transcript-fnl-73"></a>`fen.extensions.tui.panels.transcript.content-`
`(content->text content) -> string`
Concatenate text blocks from an AgentToolResult content list for tool-result previews.
*tags:* tui, transcript, tools, results
_extensions/adapters/presenters/tui/panels/transcript.fnl:68_

### <a id="fen-extensions-tui-panels-transcript-truncate-extensions-adapters-presenters-tui-panels-transcript-fnl-87"></a>`fen.extensions.tui.panels.transcript.truncate`
`(truncate s n) -> string`
Return text capped to n bytes with a visible truncation marker for tool-result previews.
*tags:* tui, transcript, truncate, tools
_extensions/adapters/presenters/tui/panels/transcript.fnl:82_

### <a id="fen-extensions-tui-panels-transcript-count-lines-extensions-adapters-presenters-tui-panels-transcript-fnl-96"></a>`fen.extensions.tui.panels.transcript.count-lines`
`(count-lines s) -> number`
Count displayable newline-delimited lines for transcript summaries and tool-result metadata.
*tags:* tui, transcript, lines, tools
_extensions/adapters/presenters/tui/panels/transcript.fnl:91_

### <a id="fen-extensions-tui-panels-transcript-lookup-tool-call-extensions-adapters-presenters-tui-panels-transcript-fnl-145"></a>`fen.extensions.tui.panels.transcript.lookup-tool-call`
`(lookup-tool-call tool-call-id) -> table|nil`
Find the matching prior tool-call event for a tool result by scanning the transcript tail.
*tags:* tui, transcript, tools, lookup
_extensions/adapters/presenters/tui/panels/transcript.fnl:140_

### <a id="fen-extensions-tui-panels-transcript-split-lines-extensions-adapters-presenters-tui-panels-transcript-fnl-182"></a>`fen.extensions.tui.panels.transcript.split-lines`
`function`
Line-splitting helper alias exported for input wrapping and transcript-rendering tests.
*tags:* tui, transcript, lines, tests
_extensions/adapters/presenters/tui/panels/transcript.fnl:177_

### <a id="fen-extensions-tui-panels-transcript-tool-call-short-extensions-adapters-presenters-tui-panels-transcript-fnl-240"></a>`fen.extensions.tui.panels.transcript.tool-call-short`
`(tool-call-short name args) -> string|nil`
Format concise built-in tool call labels for the transcript and busy status row.
*tags:* tui, transcript, tools, format
_extensions/adapters/presenters/tui/panels/transcript.fnl:235_

### <a id="fen-extensions-tui-panels-transcript-event-text-extensions-adapters-presenters-tui-panels-transcript-fnl-288"></a>`fen.extensions.tui.panels.transcript.event-text`
`(event-text ev) -> string`
Materialize streaming text chunks lazily and return the event's display text.
*tags:* tui, transcript, streaming, text
_extensions/adapters/presenters/tui/panels/transcript.fnl:283_

### <a id="fen-extensions-tui-panels-transcript-invalidate-layout-cache-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-486"></a>`fen.extensions.tui.panels.transcript.invalidate-layout-cache!`
`(invalidate-layout-cache!) -> nil`
Drop the transcript-wide row-count cache after event changes or rendering toggles.
*tags:* tui, transcript, cache, layout
_extensions/adapters/presenters/tui/panels/transcript.fnl:481_

### <a id="fen-extensions-tui-panels-transcript-clear-event-render-cache-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-496"></a>`fen.extensions.tui.panels.transcript.clear-event-render-cache!`
`(clear-event-render-cache! ev) -> nil`
Clear one event's Markdown and wrapped-row caches and invalidate transcript layout.
*tags:* tui, transcript, cache, event
_extensions/adapters/presenters/tui/panels/transcript.fnl:491_

### <a id="fen-extensions-tui-panels-transcript-lines-for-event-extensions-adapters-presenters-tui-panels-transcript-fnl-524"></a>`fen.extensions.tui.panels.transcript.lines-for-event`
`function`
Cached event-to-row renderer alias exported for transcript viewport tests and diagnostics.
*tags:* tui, transcript, cache, render, tests
_extensions/adapters/presenters/tui/panels/transcript.fnl:519_

### <a id="fen-extensions-tui-panels-transcript-viewport-lines-extensions-adapters-presenters-tui-panels-transcript-fnl-643"></a>`fen.extensions.tui.panels.transcript.viewport-lines`
`(viewport-lines width region-h) -> [PresenterRow]`
Return visible transcript rows using lazy tail rendering near the end and indexed cache for deep scroll.
*tags:* tui, transcript, viewport, scroll
_extensions/adapters/presenters/tui/panels/transcript.fnl:638_

### <a id="fen-extensions-tui-panels-transcript-max-scroll-extensions-adapters-presenters-tui-panels-transcript-fnl-658"></a>`fen.extensions.tui.panels.transcript.max-scroll`
`(max-scroll input-rows) -> number`
Compute the maximum useful transcript scroll offset for current terminal and input heights.
*tags:* tui, transcript, scroll, layout
_extensions/adapters/presenters/tui/panels/transcript.fnl:653_

### <a id="fen-extensions-tui-panels-transcript-jump-to-user-message-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-677"></a>`fen.extensions.tui.panels.transcript.jump-to-user-message!`
`(jump-to-user-message! input-rows) -> boolean`
Move the transcript viewport to the latest relevant user-authored message, repeating through older messages.
*tags:* tui, transcript, scroll, navigation, keyboard
_extensions/adapters/presenters/tui/panels/transcript.fnl:672_

### <a id="fen-extensions-tui-panels-transcript-clear-render-caches-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-738"></a>`fen.extensions.tui.panels.transcript.clear-render-caches!`
`(clear-render-caches!) -> nil`
Clear cached rows for every transcript event so a forced repaint uses current renderers.
*tags:* tui, transcript, cache, reload
_extensions/adapters/presenters/tui/panels/transcript.fnl:733_

## <a id="fen-extensions-tui-redraw"></a>fen.extensions.tui.redraw

### <a id="fen-extensions-tui-redraw-ensure-defaults-bang-extensions-adapters-presenters-tui-redraw-fnl-16"></a>`fen.extensions.tui.redraw.ensure-defaults!`
`(ensure-defaults!) -> nil`
Backfill persistent redraw and spinner scheduling fields after reloads.
*tags:* tui, redraw, state, reload
_extensions/adapters/presenters/tui/redraw.fnl:11_

### <a id="fen-extensions-tui-redraw-invalidate-bang-extensions-adapters-presenters-tui-redraw-fnl-28"></a>`fen.extensions.tui.redraw.invalidate!`
`(invalidate!) -> nil`
Mark the TUI dirty so the next presenter-loop pass repaints the terminal.
*tags:* tui, redraw, dirty
_extensions/adapters/presenters/tui/redraw.fnl:23_

### <a id="fen-extensions-tui-redraw-invalidate-full-bang-extensions-adapters-presenters-tui-redraw-fnl-38"></a>`fen.extensions.tui.redraw.invalidate-full!`
`(invalidate-full!) -> nil`
Request a cache-clearing repaint for resize, reload, and display toggles that invalidate wrapped rows.
*tags:* tui, redraw, cache
_extensions/adapters/presenters/tui/redraw.fnl:33_

## <a id="fen-extensions-tui-select"></a>fen.extensions.tui.select

### <a id="fen-extensions-tui-select-filtered-extensions-adapters-presenters-tui-select-fnl-51"></a>`fen.extensions.tui.select.filtered`
`(filtered state) -> [Choice]`
Return choices whose label or description match the current selector filter text.
*tags:* tui, select, filter, choices
_extensions/adapters/presenters/tui/select.fnl:46_

### <a id="fen-extensions-tui-select-visible-window-extensions-adapters-presenters-tui-select-fnl-68"></a>`fen.extensions.tui.select.visible-window`
`(visible-window state max-rows) -> first-index item-count total-count`
Compute the visible selector slice so the cursor stays on-screen while moving through long choice lists.
*tags:* tui, select, viewport, scroll, choices
_extensions/adapters/presenters/tui/select.fnl:63_

### <a id="fen-extensions-tui-select-make-state-extensions-adapters-presenters-tui-select-fnl-85"></a>`fen.extensions.tui.select.make-state`
`(make-state opts) -> SelectState`
Create the pure selector state record used by tests and the termbox overlay loop.
*tags:* tui, select, state
_extensions/adapters/presenters/tui/select.fnl:80_

### <a id="fen-extensions-tui-select-step-bang-extensions-adapters-presenters-tui-select-fnl-100"></a>`fen.extensions.tui.select.step!`
`(step! state key) -> SelectState`
Apply one synthetic selector key to filtering, cursor movement, selection, or cancellation state.
*tags:* tui, select, state, keyboard
_extensions/adapters/presenters/tui/select.fnl:95_

### <a id="fen-extensions-tui-select-tui-select-extensions-adapters-presenters-tui-select-fnl-254"></a>`fen.extensions.tui.select.tui-select`
`(tui-select opts) -> Choice|nil`
Run the interactive TUI select overlay when termbox is initialized and return the chosen record.
*tags:* tui, select, overlay, presenter
_extensions/adapters/presenters/tui/select.fnl:249_

## <a id="fen-extensions-tui-state"></a>fen.extensions.tui.state

### <a id="fen-extensions-tui-state-tb-initialized-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.tb-initialized?`
`boolean`
Persistent termbox2 lifecycle flag used to keep TUI init and shutdown idempotent across reloads.
*tags:* tui, state, termbox, reload
_extensions/adapters/presenters/tui/state.fnl:10_

### <a id="fen-extensions-tui-state-tb-init-failed-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.tb-init-failed?`
`boolean`
Flag set when termbox2 initialization failed so startup can print a clean error and avoid unsafe teardown.
*tags:* tui, state, termbox, errors
_extensions/adapters/presenters/tui/state.fnl:16_

### <a id="fen-extensions-tui-state-tb-cols-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.tb-cols`
`number`
Last known terminal column count used by draw/layout code after termbox resize events.
*tags:* tui, state, termbox, layout
_extensions/adapters/presenters/tui/state.fnl:22_

### <a id="fen-extensions-tui-state-tb-rows-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.tb-rows`
`number`
Last known terminal row count used by draw/layout code after termbox resize events.
*tags:* tui, state, termbox, layout
_extensions/adapters/presenters/tui/state.fnl:28_

### <a id="fen-extensions-tui-state-dirty-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.dirty?`
`boolean`
Redraw scheduling flag set when visible TUI state changed and the next presenter loop should repaint.
*tags:* tui, state, redraw
_extensions/adapters/presenters/tui/state.fnl:34_

### <a id="fen-extensions-tui-state-force-redraw-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.force-redraw?`
`boolean`
Strong redraw flag that clears render caches and blanks the presenter before repainting after resize, reload, or display toggles.
*tags:* tui, state, redraw, cache
_extensions/adapters/presenters/tui/state.fnl:40_

### <a id="fen-extensions-tui-state-spinner-ticks-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.spinner-ticks`
`number`
Event-loop tick counter used to pace busy spinner animation without adding another wall-clock dependency.
*tags:* tui, state, animation
_extensions/adapters/presenters/tui/state.fnl:46_

### <a id="fen-extensions-tui-state-spinner-interval-ticks-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.spinner-interval-ticks`
`number`
Number of event-loop ticks between spinner frame advances while the agent is busy.
*tags:* tui, state, animation
_extensions/adapters/presenters/tui/state.fnl:52_

### <a id="fen-extensions-tui-state-animations-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.animations?`
`boolean`
Global animation toggle controlling whether busy indicators use animated spinner frames or static fallback glyphs.
*tags:* tui, state, animation, settings
_extensions/adapters/presenters/tui/state.fnl:58_

### <a id="fen-extensions-tui-state-transcript-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.transcript`
`[PresenterEvent]`
Append-only preprocessed transcript event log used as the source of truth for TUI rendering.
*tags:* tui, state, transcript
_extensions/adapters/presenters/tui/state.fnl:64_

### <a id="fen-extensions-tui-state-streaming-assistant-rows-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.streaming-assistant-rows`
`table`
Lookup table from streaming row keys to transcript rows so delta ingestion can update active assistant output efficiently.
*tags:* tui, state, transcript, streaming
_extensions/adapters/presenters/tui/state.fnl:70_

### <a id="fen-extensions-tui-state-transcript-layout-cache-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.transcript-layout-cache`
`table|nil`
Width/display-keyed wrapped transcript layout cache used for fast viewport and max-scroll calculations.
*tags:* tui, state, transcript, layout
_extensions/adapters/presenters/tui/state.fnl:76_

### <a id="fen-extensions-tui-state-scroll-offset-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.scroll-offset`
`number`
Number of wrapped transcript lines above the tail that anchor the viewport when the user scrolls up.
*tags:* tui, state, scroll, transcript
_extensions/adapters/presenters/tui/state.fnl:82_

### <a id="fen-extensions-tui-state-new-content-below-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.new-content-below?`
`boolean`
Set while the transcript is scroll-locked and newly appended content is available below the viewport.
*tags:* tui, state, scroll, transcript, follow
_extensions/adapters/presenters/tui/state.fnl:88_

### <a id="fen-extensions-tui-state-last-user-jump-index-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.last-user-jump-index`
`number|nil`
Transcript event index targeted by the last user-message jump, used so repeated keypresses walk to previous user messages.
*tags:* tui, state, scroll, transcript, navigation
_extensions/adapters/presenters/tui/state.fnl:94_

### <a id="fen-extensions-tui-state-input-buf-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.input-buf`
`string`
Current multi-line input buffer contents, including literal newlines and paste markers before submit expansion.
*tags:* tui, state, input
_extensions/adapters/presenters/tui/state.fnl:100_

### <a id="fen-extensions-tui-state-input-cursor-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.input-cursor`
`number`
Byte offset cursor position inside input-buf for terminal input editing.
*tags:* tui, state, input
_extensions/adapters/presenters/tui/state.fnl:106_

### <a id="fen-extensions-tui-state-paste-active-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.paste-active?`
`boolean`
Bracketed-paste mode flag indicating incoming bytes should accumulate in paste-buffer instead of editing input directly.
*tags:* tui, state, paste, input
_extensions/adapters/presenters/tui/state.fnl:112_

### <a id="fen-extensions-tui-state-paste-buffer-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.paste-buffer`
`string`
Accumulator for the current bracketed paste before it is compacted into an input marker.
*tags:* tui, state, paste, input
_extensions/adapters/presenters/tui/state.fnl:118_

### <a id="fen-extensions-tui-state-paste-counter-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.paste-counter`
`number`
Monotonic id counter for large pasted payload markers stored in the pastes table.
*tags:* tui, state, paste, input
_extensions/adapters/presenters/tui/state.fnl:124_

### <a id="fen-extensions-tui-state-pastes-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.pastes`
`table`
Table of compact paste marker ids to full pasted text, expanded back into input on submit.
*tags:* tui, state, paste, input
_extensions/adapters/presenters/tui/state.fnl:130_

### <a id="fen-extensions-tui-state-history-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.history`
`[string]`
In-process prompt history ring containing submitted prompts for up/down navigation.
*tags:* tui, state, history, input
_extensions/adapters/presenters/tui/state.fnl:136_

### <a id="fen-extensions-tui-state-history-pos-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.history-pos`
`number`
Prompt history navigation position where zero means the current live draft and positive values index backward from the end.
*tags:* tui, state, history, input
_extensions/adapters/presenters/tui/state.fnl:142_

### <a id="fen-extensions-tui-state-history-draft-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.history-draft`
`string`
Saved live input draft restored when the user navigates back out of history.
*tags:* tui, state, history, input
_extensions/adapters/presenters/tui/state.fnl:148_

### <a id="fen-extensions-tui-state-expand-tool-results-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.expand-tool-results?`
`boolean`
Global /expand toggle controlling whether tool-result transcript events show full truncated bodies or one-line summaries.
*tags:* tui, state, transcript, tools
_extensions/adapters/presenters/tui/state.fnl:154_

### <a id="fen-extensions-tui-state-markdown-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.markdown?`
`boolean`
Global /markdown toggle controlling whether assistant text renders through the terminal markdown renderer or as plain text.
*tags:* tui, state, markdown, settings
_extensions/adapters/presenters/tui/state.fnl:160_

### <a id="fen-extensions-tui-state-hide-thinking-block-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.hide-thinking-block?`
`boolean`
Global /thinking toggle controlling whether assistant reasoning blocks render visibly or collapse to a compact Thinking label.
*tags:* tui, state, thinking, settings
_extensions/adapters/presenters/tui/state.fnl:166_

### <a id="fen-extensions-tui-state-pending-quit-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.pending-quit?`
`boolean`
Two-press ctrl-c confirmation flag for idle quit behavior, cleared by any non-quit key.
*tags:* tui, state, input, quit
_extensions/adapters/presenters/tui/state.fnl:172_

### <a id="fen-extensions-tui-state-alt-pending-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.alt-pending?`
`boolean`
One-tick bare-Esc state used to distinguish dismiss from Alt-key combinations in INPUT_ESC mode.
*tags:* tui, state, input, keyboard
_extensions/adapters/presenters/tui/state.fnl:178_

### <a id="fen-extensions-tui-state-on-tick-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.on-tick`
`function|nil`
Cooperative tick callback published by the run loop so nested selectors can keep agent coroutines and HTTP drains moving.
*tags:* tui, state, cooperative, input
_extensions/adapters/presenters/tui/state.fnl:184_

### <a id="fen-extensions-tui-state-cancel-pressed-q-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.cancel-pressed?`
`boolean`
Busy-turn ctrl-c flag recording that cancellation was requested before the agent loop observes and clears it.
*tags:* tui, state, cancel, input
_extensions/adapters/presenters/tui/state.fnl:190_

### <a id="fen-extensions-tui-state-last-stall-warn-ms-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.last-stall-warn-ms`
_extensions/adapters/presenters/tui/state.fnl:202_

### <a id="fen-extensions-tui-state-status-info-extensions-adapters-presenters-tui-state-fnl-202"></a>`fen.extensions.tui.state.status-info`
`table`
Persistent status-line model, token, queue, retry, thinking, cancellation, elapsed-time, and spinner metadata.
*tags:* tui, state, status
_extensions/adapters/presenters/tui/state.fnl:196_

## <a id="fen-extensions-web"></a>fen.extensions.web

### <a id="fen-extensions-web-init-bang-extensions-adapters-presenters-web-init-fnl-78"></a>`fen.extensions.web.init!`
`(init! ctx) -> nil`
Store the presenter context and initialize the web server listener for browser clients.
*tags:* web, presenter, lifecycle, server
_extensions/adapters/presenters/web/init.fnl:73_

### <a id="fen-extensions-web-shutdown-extensions-adapters-presenters-web-init-fnl-86"></a>`fen.extensions.web.shutdown`
`(shutdown ctx) -> nil`
Clear the web presenter context and close server/client resources during presenter shutdown.
*tags:* web, presenter, lifecycle, server
_extensions/adapters/presenters/web/init.fnl:81_

### <a id="fen-extensions-web-run-extensions-adapters-presenters-web-init-fnl-94"></a>`fen.extensions.web.run`
`(run ctx) -> nil`
Run the web presenter server loop with the current context until the presenter is asked to quit.
*tags:* web, presenter, lifecycle, server
_extensions/adapters/presenters/web/init.fnl:89_

### <a id="fen-extensions-web-register-extensions-adapters-presenters-web-init-fnl-98"></a>`fen.extensions.web.register`
_extensions/adapters/presenters/web/init.fnl:98_

## <a id="fen-extensions-web-ingest"></a>fen.extensions.web.ingest

### <a id="fen-extensions-web-ingest-append-event-extensions-adapters-presenters-web-ingest-fnl-84"></a>`fen.extensions.web.ingest.append-event`
`(append-event ev) -> nil`
Ingest one bus event into web transcript and status state, including streaming assistant deltas and tool summaries.
*tags:* web, ingest, events, transcript, status
_extensions/adapters/presenters/web/ingest.fnl:79_

## <a id="fen-extensions-web-layout"></a>fen.extensions.web.layout

### <a id="fen-extensions-web-layout-snapshot-extensions-adapters-presenters-web-layout-fnl-120"></a>`fen.extensions.web.layout.snapshot`
`(snapshot ctx?) -> table`
Build the JSON-serializable browser layout snapshot from status fragments, panels, transcript rows, select state, and reload sequence.
*tags:* web, layout, snapshot, json
_extensions/adapters/presenters/web/layout.fnl:115_

### <a id="fen-extensions-web-layout-html-snapshot-extensions-adapters-presenters-web-layout-fnl-191"></a>`fen.extensions.web.layout.html-snapshot`
`(html-snapshot ctx?) -> table`
Build a browser layout snapshot with pre-rendered HTML fragments for status, transcript, panels, and select state.
*tags:* web, layout, snapshot, html
_extensions/adapters/presenters/web/layout.fnl:186_

## <a id="fen-extensions-web-page"></a>fen.extensions.web.page

### <a id="fen-extensions-web-page-render-extensions-adapters-presenters-web-page-fnl-71"></a>`fen.extensions.web.page.render`
`function`
Hiccup document renderer alias exported for browser page tests and reuse within web snapshots.
*tags:* web, page, html, render, tests
_extensions/adapters/presenters/web/page.fnl:66_

### <a id="fen-extensions-web-page-render-node-extensions-adapters-presenters-web-page-fnl-78"></a>`fen.extensions.web.page.render-node`
`function`
Single-node HTML renderer alias exported for focused escaping and element-rendering tests.
*tags:* web, page, html, render, tests
_extensions/adapters/presenters/web/page.fnl:73_

### <a id="fen-extensions-web-page-html-extensions-adapters-presenters-web-page-fnl-238"></a>`fen.extensions.web.page.html`
`(html) -> string`
Render the static browser presenter page with embedded CSS and JavaScript for HTTP/SSE interaction.
*tags:* web, page, html, browser
_extensions/adapters/presenters/web/page.fnl:233_

## <a id="fen-extensions-web-server"></a>fen.extensions.web.server

### <a id="fen-extensions-web-server-parse-request-extensions-adapters-presenters-web-server-fnl-73"></a>`fen.extensions.web.server.parse-request`
`(parse-request buf) -> Request|nil`
Parse a buffered HTTP request once headers and the declared body length have arrived.
*tags:* web, server, http, parse
_extensions/adapters/presenters/web/server.fnl:68_

### <a id="fen-extensions-web-server-broadcast-bang-extensions-adapters-presenters-web-server-fnl-252"></a>`fen.extensions.web.server.broadcast!`
`(broadcast! state ctx) -> nil`
Queue a layout SSE frame to connected clients when the rendered browser snapshot changes.
*tags:* web, server, sse, broadcast
_extensions/adapters/presenters/web/server.fnl:247_

### <a id="fen-extensions-web-server-init-extensions-adapters-presenters-web-server-fnl-260"></a>`fen.extensions.web.server.init`
`(init ctx state) -> nil`
Start the nonblocking LuaSocket HTTP server for the web presenter if it is not already listening.
*tags:* web, server, lifecycle, socket
_extensions/adapters/presenters/web/server.fnl:255_

### <a id="fen-extensions-web-server-shutdown-extensions-adapters-presenters-web-server-fnl-276"></a>`fen.extensions.web.server.shutdown`
`(shutdown ctx state) -> nil`
Stop the web server, close HTTP and SSE clients, clear queues, and mark the presenter as quitting.
*tags:* web, server, lifecycle, socket
_extensions/adapters/presenters/web/server.fnl:271_

### <a id="fen-extensions-web-server-tick-extensions-adapters-presenters-web-server-fnl-292"></a>`fen.extensions.web.server.tick`
`(tick socket state ctx) -> nil`
Service accepts, HTTP requests, pending inputs, cooperative ticks, SSE broadcasts, flushes, and pacing sleep once.
*tags:* web, server, loop, sse
_extensions/adapters/presenters/web/server.fnl:287_

### <a id="fen-extensions-web-server-wait-select-extensions-adapters-presenters-web-server-fnl-315"></a>`fen.extensions.web.server.wait-select`
`(wait-select ctx state opts) -> Choice|nil`
Publish an active browser select prompt, service the web loop until a reply arrives, and return the chosen choice.
*tags:* web, server, select, ui
_extensions/adapters/presenters/web/server.fnl:310_

### <a id="fen-extensions-web-server-run-extensions-adapters-presenters-web-server-fnl-339"></a>`fen.extensions.web.server.run`
`(run ctx state) -> nil`
Run the web server loop until shutdown sets the persistent quit flag.
*tags:* web, server, loop, lifecycle
_extensions/adapters/presenters/web/server.fnl:334_

## <a id="fen-extensions-web-state"></a>fen.extensions.web.state

### <a id="fen-extensions-web-state-server-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.server`
`server|nil`
Active web server handle, kept outside reloadable modules so the listening socket can survive behavior reloads.
*tags:* web, state, server, reload
_extensions/adapters/presenters/web/state.fnl:4_

### <a id="fen-extensions-web-state-host-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.host`
`string`
Interface address used by the web presenter when binding its HTTP/SSE server.
*tags:* web, state, server, config
_extensions/adapters/presenters/web/state.fnl:10_

### <a id="fen-extensions-web-state-port-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.port`
`number`
TCP port used by the web presenter server and advertised browser URL.
*tags:* web, state, server, config
_extensions/adapters/presenters/web/state.fnl:16_

### <a id="fen-extensions-web-state-clients-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.clients`
`[client]`
Connected web client records tracked by the presenter server for lifecycle and cleanup.
*tags:* web, state, clients
_extensions/adapters/presenters/web/state.fnl:22_

### <a id="fen-extensions-web-state-sse-clients-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.sse-clients`
`[client]`
Active Server-Sent Events client connections receiving transcript/status snapshots.
*tags:* web, state, clients, sse
_extensions/adapters/presenters/web/state.fnl:28_

### <a id="fen-extensions-web-state-pending-inputs-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.pending-inputs`
`[string]`
User inputs submitted by browser clients and queued for the presenter loop to hand to the agent.
*tags:* web, state, input, queue
_extensions/adapters/presenters/web/state.fnl:34_

### <a id="fen-extensions-web-state-quit-q-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.quit?`
`boolean`
Presenter loop shutdown flag set by web controls when the browser requests session termination.
*tags:* web, state, lifecycle
_extensions/adapters/presenters/web/state.fnl:40_

### <a id="fen-extensions-web-state-last-snapshot-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.last-snapshot`
`string`
Last serialized browser snapshot used to avoid redundant SSE broadcasts when visible state has not changed.
*tags:* web, state, sse, cache
_extensions/adapters/presenters/web/state.fnl:46_

### <a id="fen-extensions-web-state-last-broadcast-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.last-broadcast`
`number`
Timestamp/counter of the last web snapshot broadcast used to pace browser updates.
*tags:* web, state, sse, cache
_extensions/adapters/presenters/web/state.fnl:52_

### <a id="fen-extensions-web-state-client-reload-seq-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.client-reload-seq`
`number`
Monotonic sequence bumped to tell browser clients that frontend assets or presenter behavior should reload.
*tags:* web, state, reload, clients
_extensions/adapters/presenters/web/state.fnl:58_

### <a id="fen-extensions-web-state-select-seq-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.select-seq`
`number`
Monotonic id counter for active web select prompts so browser replies can be matched to the current prompt.
*tags:* web, state, select, input
_extensions/adapters/presenters/web/state.fnl:64_

### <a id="fen-extensions-web-state-active-select-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.active-select`
`table|nil`
Currently active browser select prompt, including choices and response bookkeeping for presenter UI APIs.
*tags:* web, state, select, input
_extensions/adapters/presenters/web/state.fnl:70_

### <a id="fen-extensions-web-state-presenter-ctx-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.presenter-ctx`
`table|nil`
Current web presenter runtime context captured for server handlers that need to submit input or request cancellation.
*tags:* web, state, presenter
_extensions/adapters/presenters/web/state.fnl:76_

### <a id="fen-extensions-web-state-transcript-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.transcript`
`[PresenterEvent]`
Persistent web transcript event log used to build browser snapshots after reloads or client reconnects.
*tags:* web, state, transcript
_extensions/adapters/presenters/web/state.fnl:82_

### <a id="fen-extensions-web-state-status-info-extensions-adapters-presenters-web-state-fnl-94"></a>`fen.extensions.web.state.status-info`
`table`
Web status metadata for provider/model, context estimates, queues, running tool, thinking, cancellation, and turn timing.
*tags:* web, state, status
_extensions/adapters/presenters/web/state.fnl:88_

## <a id="fen-provider-help"></a>fen.provider_help

### <a id="fen-provider-help-render-index-packages-fen-src-fen-provider-help-fnl-123"></a>`fen.provider_help.render-index`
_packages/fen/src/fen/provider_help.fnl:123_

### <a id="fen-provider-help-render-provider-packages-fen-src-fen-provider-help-fnl-150"></a>`fen.provider_help.render-provider`
_packages/fen/src/fen/provider_help.fnl:150_

### <a id="fen-provider-help-known-provider-q-packages-fen-src-fen-provider-help-fnl-157"></a>`fen.provider_help.known-provider?`
_packages/fen/src/fen/provider_help.fnl:157_

### <a id="fen-provider-help-dispatch-packages-fen-src-fen-provider-help-fnl-160"></a>`fen.provider_help.dispatch`
_packages/fen/src/fen/provider_help.fnl:160_

### <a id="fen-provider-help-missing-provider-message-packages-fen-src-fen-provider-help-fnl-173"></a>`fen.provider_help.missing-provider-message`
_packages/fen/src/fen/provider_help.fnl:173_

### <a id="fen-provider-help-unknown-provider-message-packages-fen-src-fen-provider-help-fnl-198"></a>`fen.provider_help.unknown-provider-message`
_packages/fen/src/fen/provider_help.fnl:198_

## <a id="fen-script-runner"></a>fen.script_runner

### <a id="fen-script-runner-usage-packages-fen-src-fen-script-runner-fnl-46"></a>`fen.script_runner.usage`
`(usage) -> string`
Return command-line usage text for fen run.
*tags:* cli, scripts
_packages/fen/src/fen/script_runner.fnl:41_

### <a id="fen-script-runner-eval-usage-packages-fen-src-fen-script-runner-fnl-53"></a>`fen.script_runner.eval-usage`
`(eval-usage) -> string`
Return command-line usage text for fen eval.
*tags:* cli, scripts, eval
_packages/fen/src/fen/script_runner.fnl:48_

### <a id="fen-script-runner-infer-language-packages-fen-src-fen-script-runner-fnl-60"></a>`fen.script_runner.infer-language`
`(infer-language script ?override) -> :lua|:fennel`
Choose the runner language, using an explicit override before script extension inference.
*tags:* cli, scripts
_packages/fen/src/fen/script_runner.fnl:55_

### <a id="fen-script-runner-build-arg-table-packages-fen-src-fen-script-runner-fnl-69"></a>`fen.script_runner.build-arg-table`
`(build-arg-table argv script-index) -> table`
Build a Lua-compatible global arg table for a script selected from fen's original argv.
*tags:* cli, scripts, compatibility
_packages/fen/src/fen/script_runner.fnl:64_

### <a id="fen-script-runner-build-eval-arg-table-packages-fen-src-fen-script-runner-fnl-85"></a>`fen.script_runner.build-eval-arg-table`
`(build-eval-arg-table argv code-index) -> table`
Build a Lua-compatible global arg table for inline eval code.
*tags:* cli, scripts, eval, compatibility
_packages/fen/src/fen/script_runner.fnl:80_

### <a id="fen-script-runner-parse-packages-fen-src-fen-script-runner-fnl-105"></a>`fen.script_runner.parse`
`(parse argv) -> table|nil, err|nil`
Parse fen run arguments without invoking the general agent option parser.
*tags:* cli, scripts
_packages/fen/src/fen/script_runner.fnl:100_

### <a id="fen-script-runner-parse-eval-packages-fen-src-fen-script-runner-fnl-144"></a>`fen.script_runner.parse-eval`
`(parse-eval argv) -> table|nil, err|nil`
Parse fen eval arguments without invoking the general agent option parser.
*tags:* cli, scripts, eval
_packages/fen/src/fen/script_runner.fnl:139_

### <a id="fen-script-runner-run-bang-packages-fen-src-fen-script-runner-fnl-221"></a>`fen.script_runner.run!`
`(run! argv) -> integer`
Run the script selected by fen run and return the process exit code.
*tags:* cli, scripts
_packages/fen/src/fen/script_runner.fnl:216_

### <a id="fen-script-runner-eval-bang-packages-fen-src-fen-script-runner-fnl-245"></a>`fen.script_runner.eval!`
`(eval! argv) -> integer`
Evaluate the code selected by fen eval and return the process exit code.
*tags:* cli, scripts, eval
_packages/fen/src/fen/script_runner.fnl:240_

## <a id="fen-testing"></a>fen.testing

### <a id="fen-testing-shellquote-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.shellquote`
`(shellquote s) -> string`
Quote a string for POSIX shell commands used by test filesystem helpers.
*tags:* testing, shell, paths
_packages/testing/src/fen/testing/init.fnl:5_

### <a id="fen-testing-stub-getenv-bang-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.stub-getenv!`
`(stub-getenv! resolver) -> nil`
Replace os.getenv in tests with a resolver that can delegate to the original environment lookup.
*tags:* testing, env, stubs
_packages/testing/src/fen/testing/init.fnl:23_

### <a id="fen-testing-restore-getenv-bang-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.restore-getenv!`
`(restore-getenv!) -> nil`
Restore the original os.getenv captured before tests installed any environment stubs.
*tags:* testing, env, stubs
_packages/testing/src/fen/testing/init.fnl:34_

### <a id="fen-testing-reload-module-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.reload-module`
`(reload-module name) -> any`
Clear package.loaded for one module and require it again so tests can observe module initialization behavior.
*tags:* testing, reload, modules
_packages/testing/src/fen/testing/init.fnl:42_

### <a id="fen-testing-stub-http-bang-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.stub-http!`
`(stub-http! responder) -> nil`
Replace fen.util.http's backend with a test responder and clear the cached frontend module.
*tags:* testing, http, stubs
_packages/testing/src/fen/testing/init.fnl:51_

### <a id="fen-testing-restore-http-bang-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.restore-http!`
`(restore-http!) -> nil`
Remove the stubbed HTTP backend and cached frontend so later tests reload the normal transport.
*tags:* testing, http, stubs
_packages/testing/src/fen/testing/init.fnl:65_

### <a id="fen-testing-make-tmpdir-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.make-tmpdir`
`(make-tmpdir) -> string`
Create and register ownership of a temporary directory that rmtree is allowed to remove.
*tags:* testing, temp, files
_packages/testing/src/fen/testing/init.fnl:74_

### <a id="fen-testing-rmtree-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.rmtree`
`(rmtree path) -> nil`
Remove an owned temporary directory tree, refusing arbitrary or unsafe paths.
*tags:* testing, temp, files, safety
_packages/testing/src/fen/testing/init.fnl:87_

### <a id="fen-testing-write-file-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.write-file`
`(write-file path content) -> path`
Create parent directories as needed and write content to a test fixture file.
*tags:* testing, files, fixtures
_packages/testing/src/fen/testing/init.fnl:106_

### <a id="fen-testing-append-file-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.append-file`
`(append-file path content) -> path`
Append content to a test fixture file and return the path for fluent setup code.
*tags:* testing, files, fixtures
_packages/testing/src/fen/testing/init.fnl:120_

### <a id="fen-testing-read-file-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.read-file`
`(read-file path) -> string|nil`
Read a file if it exists, returning nil instead of failing for optional fixture paths.
*tags:* testing, files, fixtures
_packages/testing/src/fen/testing/init.fnl:131_

### <a id="fen-testing-read-file-bang-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.read-file!`
`(read-file! path) -> string`
Read a required fixture file and fail the test immediately if it cannot be opened.
*tags:* testing, files, fixtures
_packages/testing/src/fen/testing/init.fnl:143_

### <a id="fen-testing-make-tmpfile-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.make-tmpfile`
`(make-tmpfile content) -> string`
Create an owned temporary file, write initial content, and return its path for the test.
*tags:* testing, temp, files
_packages/testing/src/fen/testing/init.fnl:154_

### <a id="fen-testing-rm-file-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.rm-file`
`(rm-file path) -> nil`
Remove an owned temporary file and refuse paths that were not created by make-tmpfile.
*tags:* testing, temp, files, safety
_packages/testing/src/fen/testing/init.fnl:170_

### <a id="fen-testing-assert-no-leaks-bang-packages-testing-src-fen-testing-init-fnl-195"></a>`fen.testing.assert-no-leaks!`
`(assert-no-leaks!) -> nil`
Assert that all owned temporary roots and files have been cleaned up by the test suite.
*tags:* testing, temp, safety
_packages/testing/src/fen/testing/init.fnl:183_

## <a id="fen-testing-macros"></a>fen.testing.macros

### <a id="fen-testing-macros-with-tmpdir-packages-testing-src-fen-testing-macros-fnl-43"></a>`fen.testing.macros.with-tmpdir`
`(with-tmpdir [name] body...) -> macro-form`
Macro that creates an owned temp directory for a test body and always removes it afterward.
*tags:* testing, macros, temp
_packages/testing/src/fen/testing/macros.fnl:14_

### <a id="fen-testing-macros-with-tmpfile-packages-testing-src-fen-testing-macros-fnl-43"></a>`fen.testing.macros.with-tmpfile`
`(with-tmpfile [name content] body...) -> macro-form`
Macro that creates an owned temp file with content for a test body and always removes it afterward.
*tags:* testing, macros, temp
_packages/testing/src/fen/testing/macros.fnl:28_

## <a id="fen-testing-pty"></a>fen.testing.pty

### <a id="fen-testing-pty-spawn-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.spawn`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-read-until-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.read-until`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-drain-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.drain`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-now-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.now`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-artifact-dir-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.artifact-dir`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-ensure-dir-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.ensure-dir`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-write-file-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.write-file`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-append-file-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.append-file`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-encode-json-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.encode-json`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-cast-start-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.cast-start`
_packages/testing/src/fen/testing/pty.fnl:107_

### <a id="fen-testing-pty-cast-event-packages-testing-src-fen-testing-pty-fnl-107"></a>`fen.testing.pty.cast-event`
_packages/testing/src/fen/testing/pty.fnl:107_

## <a id="fen-testing-tui"></a>fen.testing.tui

### <a id="fen-testing-tui-install-termbox-stub-bang-packages-testing-src-fen-testing-tui-fnl-7"></a>`fen.testing.tui.install-termbox-stub!`
_packages/testing/src/fen/testing/tui.fnl:7_

### <a id="fen-testing-tui-install-markdown-stub-bang-packages-testing-src-fen-testing-tui-fnl-52"></a>`fen.testing.tui.install-markdown-stub!`
_packages/testing/src/fen/testing/tui.fnl:52_

### <a id="fen-testing-tui-reset-state-bang-packages-testing-src-fen-testing-tui-fnl-59"></a>`fen.testing.tui.reset-state!`
_packages/testing/src/fen/testing/tui.fnl:59_

## <a id="fen-turn-lifecycle"></a>fen.turn_lifecycle

### <a id="fen-turn-lifecycle-complete-event-packages-fen-src-fen-turn-lifecycle-fnl-32"></a>`fen.turn_lifecycle.complete-event`
`(complete-event state ok? result-or-error) -> table`
Build an :agent-turn-complete event for a finished agent turn.
*tags:* agent, lifecycle, events
_packages/fen/src/fen/turn_lifecycle.fnl:27_

### <a id="fen-turn-lifecycle-emit-complete-bang-packages-fen-src-fen-turn-lifecycle-fnl-53"></a>`fen.turn_lifecycle.emit-complete!`
`(emit-complete! state ok? result-or-error) -> table`
Emit and return the :agent-turn-complete lifecycle event for a finished agent turn.
*tags:* agent, lifecycle, events
_packages/fen/src/fen/turn_lifecycle.fnl:48_

## <a id="fen-update"></a>fen.update

### <a id="fen-update-run-bang-packages-fen-src-fen-update-fnl-235"></a>`fen.update.run!`
`(run! argv) -> exit-code`
Replace the running release binary with the latest GitHub release; refuses source/dev builds.
*tags:* update, self-update, distribution
_packages/fen/src/fen/update.fnl:230_

_Undocumented data/state re-exports omitted from the public API listing:_ `fen.update.arch-`, `fen.update.expected-hash`

## <a id="fen-util-base64"></a>fen.util.base64

### <a id="fen-util-base64-decode-standard-packages-util-src-fen-util-base64-fnl-120"></a>`fen.util.base64.decode-standard`
`(decode-standard s) -> string`
Decode a standard base64 string with optional padding into its raw byte string for trusted token payloads.
*tags:* util, encoding, base64
_packages/util/src/fen/util/base64.fnl:20_

### <a id="fen-util-base64-decode-url-packages-util-src-fen-util-base64-fnl-120"></a>`fen.util.base64.decode-url`
`(decode-url s) -> string|nil`
Decode an unpadded base64url string by restoring the standard alphabet and padding before decoding.
*tags:* util, encoding, base64
_packages/util/src/fen/util/base64.fnl:50_

### <a id="fen-util-base64-encode-standard-packages-util-src-fen-util-base64-fnl-120"></a>`fen.util.base64.encode-standard`
`(encode-standard bytes) -> string`
Encode a raw byte string as standard base64 with RFC-style `=` padding.
*tags:* util, encoding, base64
_packages/util/src/fen/util/base64.fnl:68_

### <a id="fen-util-base64-encode-url-packages-util-src-fen-util-base64-fnl-120"></a>`fen.util.base64.encode-url`
`(encode-url bytes) -> string|nil`
Encode raw bytes as unpadded base64url for PKCE and token-related wire formats.
*tags:* util, encoding, base64
_packages/util/src/fen/util/base64.fnl:105_

## <a id="fen-util-checksum"></a>fen.util.checksum

### <a id="fen-util-checksum-file-fingerprint-packages-util-src-fen-util-checksum-fnl-80"></a>`fen.util.checksum.file-fingerprint`
`(file-fingerprint path) -> table|nil`
Compute a small non-cryptographic checksum/size fingerprint for a file used by reload-change diagnostics.
*tags:* util, checksum, reload
_packages/util/src/fen/util/checksum.fnl:6_

### <a id="fen-util-checksum-module-path-packages-util-src-fen-util-checksum-fnl-80"></a>`fen.util.checksum.module-path`
`(module-path modname) -> string|nil`
Resolve a module name through package.path or its .fnl dev-path analogue so reload diagnostics can fingerprint the active source file.
*tags:* util, checksum, modules
_packages/util/src/fen/util/checksum.fnl:56_

### <a id="fen-util-checksum-module-fingerprint-packages-util-src-fen-util-checksum-fnl-80"></a>`fen.util.checksum.module-fingerprint`
`(module-fingerprint modname) -> table|nil`
Resolve and fingerprint a Lua module source file, returning nil when the module has no package.path file.
*tags:* util, checksum, modules, reload
_packages/util/src/fen/util/checksum.fnl:70_

## <a id="fen-util-flat-extensions"></a>fen.util.flat_extensions

### <a id="fen-util-flat-extensions-build-map-packages-util-src-fen-util-flat-extensions-fnl-123"></a>`fen.util.flat_extensions.build-map`
`(build-map roots) -> table`
Walk flat extension roots and build the manifest :name to directory map used by the namespace searcher.
*tags:* util, extensions, searcher
_packages/util/src/fen/util/flat_extensions.fnl:118_

### <a id="fen-util-flat-extensions-resolve-fnl-packages-util-src-fen-util-flat-extensions-fnl-142"></a>`fen.util.flat_extensions.resolve-fnl`
`(resolve-fnl map modname) -> string|nil`
Return the flat source path for a fen.extensions module from a manifest-name map.
*tags:* util, extensions, searcher, reload
_packages/util/src/fen/util/flat_extensions.fnl:137_

### <a id="fen-util-flat-extensions-make-searcher-packages-util-src-fen-util-flat-extensions-fnl-163"></a>`fen.util.flat_extensions.make-searcher`
`(make-searcher fennel map) -> searcher-fn`
Build a package.searchers entry that maps fen.extensions.<name> modules back to flat extension source files.
*tags:* util, extensions, searcher
_packages/util/src/fen/util/flat_extensions.fnl:158_

### <a id="fen-util-flat-extensions-install-bang-packages-util-src-fen-util-flat-extensions-fnl-180"></a>`fen.util.flat_extensions.install!`
`(install! opts) -> searcher-fn`
Build and insert the flat-extension searcher into package.searchers at the requested position.
*tags:* util, extensions, searcher
_packages/util/src/fen/util/flat_extensions.fnl:175_

## <a id="fen-util-http"></a>fen.util.http

### <a id="fen-util-http-request-packages-util-src-fen-util-http-init-fnl-59"></a>`fen.util.http.request`
`(request opts) -> {:status :body :headers}|{:error}`
Perform an HTTP request through the selected backend, supporting streaming chunks and cooperative yielding.
*tags:* util, http, providers
_packages/util/src/fen/util/http/init.fnl:14_

## <a id="fen-util-http-backends-native"></a>fen.util.http.backends.native

### <a id="fen-util-http-backends-native-request-packages-util-src-fen-util-http-backends-native-fnl-48"></a>`fen.util.http.backends.native.request`
`(request opts) -> {:status :body :headers}|{:error :curl-code?}`
Translate kebab-case HTTP options/results and dispatch to the project-owned fen_http libcurl binding.
*tags:* util, http, native
_packages/util/src/fen/util/http/backends/native.fnl:36_

## <a id="fen-util-id"></a>fen.util.id

### <a id="fen-util-id-random-hex-packages-util-src-fen-util-id-fnl-20"></a>`fen.util.id.random-hex`
_packages/util/src/fen/util/id.fnl:20_

### <a id="fen-util-id-uuidv7-packages-util-src-fen-util-id-fnl-38"></a>`fen.util.id.uuidv7`
_packages/util/src/fen/util/id.fnl:38_

## <a id="fen-util-json"></a>fen.util.json

### <a id="fen-util-json-encode-packages-util-src-fen-util-json-fnl-29"></a>`fen.util.json.encode`
`cjson.empty_array`
Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.
*tags:* util, json
_packages/util/src/fen/util/json.fnl:9_

### <a id="fen-util-json-decode-packages-util-src-fen-util-json-fnl-29"></a>`fen.util.json.decode`
`cjson.empty_array`
Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.
*tags:* util, json
_packages/util/src/fen/util/json.fnl:9_

### <a id="fen-util-json-null-packages-util-src-fen-util-json-fnl-29"></a>`fen.util.json.null`
`cjson.empty_array`
Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.
*tags:* util, json
_packages/util/src/fen/util/json.fnl:9_

### <a id="fen-util-json-empty-array-packages-util-src-fen-util-json-fnl-29"></a>`fen.util.json.empty-array`
`cjson.empty_array`
Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.
*tags:* util, json
_packages/util/src/fen/util/json.fnl:9_

## <a id="fen-util-log"></a>fen.util.log

### <a id="fen-util-log-debug-packages-util-src-fen-util-log-fnl-50"></a>`fen.util.log.debug`
`(timestamp) -> string`
Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.
*tags:* util, logging, time
_packages/util/src/fen/util/log.fnl:25_

### <a id="fen-util-log-info-packages-util-src-fen-util-log-fnl-50"></a>`fen.util.log.info`
`(timestamp) -> string`
Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.
*tags:* util, logging, time
_packages/util/src/fen/util/log.fnl:25_

### <a id="fen-util-log-warn-packages-util-src-fen-util-log-fnl-50"></a>`fen.util.log.warn`
`(timestamp) -> string`
Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.
*tags:* util, logging, time
_packages/util/src/fen/util/log.fnl:25_

### <a id="fen-util-log-error-packages-util-src-fen-util-log-fnl-50"></a>`fen.util.log.error`
`(timestamp) -> string`
Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.
*tags:* util, logging, time
_packages/util/src/fen/util/log.fnl:25_

### <a id="fen-util-log-timestamp-packages-util-src-fen-util-log-fnl-50"></a>`fen.util.log.timestamp`
`(timestamp) -> string`
Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.
*tags:* util, logging, time
_packages/util/src/fen/util/log.fnl:25_

## <a id="fen-util-log-sink"></a>fen.util.log_sink

### <a id="fen-util-log-sink-open-bang-packages-util-src-fen-util-log-sink-fnl-23"></a>`fen.util.log_sink.open!`
`(open! path) -> boolean,?string`
Open path in append mode as the active log sink, closing any prior handle. Returns ok?, err.
*tags:* util, logging, sink
_packages/util/src/fen/util/log_sink.fnl:18_

### <a id="fen-util-log-sink-close-bang-packages-util-src-fen-util-log-sink-fnl-36"></a>`fen.util.log_sink.close!`
`(close!) -> nil`
Close and clear the active log sink handle, returning log routing to stderr.
*tags:* util, logging, sink
_packages/util/src/fen/util/log_sink.fnl:31_

### <a id="fen-util-log-sink-active-q-packages-util-src-fen-util-log-sink-fnl-46"></a>`fen.util.log_sink.active?`
`(active?) -> boolean`
True when a file sink is currently open and write-line will land in the file.
*tags:* util, logging, sink
_packages/util/src/fen/util/log_sink.fnl:41_

### <a id="fen-util-log-sink-write-line-packages-util-src-fen-util-log-sink-fnl-68"></a>`fen.util.log_sink.write-line`
`(write-line s) -> boolean,?string`
Append s plus a newline to the active sink and flush. Returns true on success; on write failure clears the handle (so callers can fall back to stderr) and returns false plus the error. No-op true when the sink is inactive.
*tags:* util, logging, sink
_packages/util/src/fen/util/log_sink.fnl:49_

_Undocumented data/state re-exports omitted from the public API listing:_ `fen.util.log_sink.handle`

## <a id="fen-util-path"></a>fen.util.path

### <a id="fen-util-path-home-packages-util-src-fen-util-path-fnl-21"></a>`fen.util.path.home`
`(home) -> string`
Return HOME with a /tmp fallback so path helpers remain usable in stripped-down test or daemon environments.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:16_

### <a id="fen-util-path-config-home-packages-util-src-fen-util-path-fnl-29"></a>`fen.util.path.config-home`
`(config-home) -> string`
Return XDG_CONFIG_HOME or the conventional ~/.config directory under the resolved home path.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:24_

### <a id="fen-util-path-config-dir-packages-util-src-fen-util-path-fnl-40"></a>`fen.util.path.config-dir`
`(config-dir app) -> string`
Return the per-application configuration directory under the XDG config home.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:35_

### <a id="fen-util-path-state-home-packages-util-src-fen-util-path-fnl-48"></a>`fen.util.path.state-home`
`(state-home) -> string`
Return XDG_STATE_HOME or the conventional ~/.local/state directory under the resolved home path.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:43_

### <a id="fen-util-path-state-dir-packages-util-src-fen-util-path-fnl-59"></a>`fen.util.path.state-dir`
`(state-dir app) -> string`
Return the per-application state directory under the XDG state home.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:54_

### <a id="fen-util-path-data-home-packages-util-src-fen-util-path-fnl-67"></a>`fen.util.path.data-home`
`(data-home) -> string`
Return XDG_DATA_HOME or the conventional ~/.local/share directory under the resolved home path.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:62_

### <a id="fen-util-path-data-dir-packages-util-src-fen-util-path-fnl-78"></a>`fen.util.path.data-dir`
`(data-dir app) -> string`
Return the per-application data directory under the XDG data home.
*tags:* util, paths, xdg
_packages/util/src/fen/util/path.fnl:73_

### <a id="fen-util-path-ensure-dir-bang-packages-util-src-fen-util-path-fnl-86"></a>`fen.util.path.ensure-dir!`
`(ensure-dir! dir) -> nil`
Create dir (and missing parents) with POSIX mkdir -p, swallowing failures so callers can attempt their write and surface a clearer error.
*tags:* util, paths, filesystem
_packages/util/src/fen/util/path.fnl:81_

### <a id="fen-util-path-shell-quote-packages-util-src-fen-util-path-fnl-94"></a>`fen.util.path.shell-quote`
`(shell-quote s) -> string`
Quote a value as one POSIX shell word for helper functions that must invoke system tools safely.
*tags:* util, paths, shell
_packages/util/src/fen/util/path.fnl:89_

### <a id="fen-util-path-dirname-packages-util-src-fen-util-path-fnl-102"></a>`fen.util.path.dirname`
`(dirname path) -> string`
Return the directory portion of a path, using . for bare names and / for root-level paths.
*tags:* util, paths
_packages/util/src/fen/util/path.fnl:97_

### <a id="fen-util-path-basename-packages-util-src-fen-util-path-fnl-113"></a>`fen.util.path.basename`
`(basename path) -> string`
Return the final path component while tolerating a trailing slash.
*tags:* util, paths
_packages/util/src/fen/util/path.fnl:108_

### <a id="fen-util-path-pwd-physical-packages-util-src-fen-util-path-fnl-121"></a>`fen.util.path.pwd-physical`
`(pwd-physical dir) -> string|nil`
Resolve a directory through `pwd -P`, returning its physical path or nil if the shell probe fails.
*tags:* util, paths, shell
_packages/util/src/fen/util/path.fnl:116_

### <a id="fen-util-path-cwd-packages-util-src-fen-util-path-fnl-134"></a>`fen.util.path.cwd`
`(cwd) -> string`
Return the user's current directory spelling from PWD, falling back to a physical pwd probe and then . .
*tags:* util, paths, cwd
_packages/util/src/fen/util/path.fnl:129_

### <a id="fen-util-path-realpath-packages-util-src-fen-util-path-fnl-142"></a>`fen.util.path.realpath`
`(realpath path) -> string`
Resolve the directory portion of a path physically while preserving the original basename.
*tags:* util, paths
_packages/util/src/fen/util/path.fnl:137_

### <a id="fen-util-path-file-exists-q-packages-util-src-fen-util-path-fnl-179"></a>`fen.util.path.file-exists?`
`(file-exists? path) -> boolean`
Return true only for regular files, preferring LuaFileSystem and falling back to POSIX test -f.
*tags:* util, paths, filesystem
_packages/util/src/fen/util/path.fnl:174_

### <a id="fen-util-path-dir-exists-q-packages-util-src-fen-util-path-fnl-191"></a>`fen.util.path.dir-exists?`
`(dir-exists? path) -> boolean`
Return true only for directories, preferring LuaFileSystem and falling back to POSIX test -d.
*tags:* util, paths, filesystem
_packages/util/src/fen/util/path.fnl:186_

### <a id="fen-util-path-ancestors-root-to-leaf-packages-util-src-fen-util-path-fnl-200"></a>`fen.util.path.ancestors-root-to-leaf`
`(ancestors-root-to-leaf start) -> [string]`
Return a physical ancestor chain from / to start for deterministic project-context discovery.
*tags:* util, paths, discovery
_packages/util/src/fen/util/path.fnl:195_

## <a id="fen-util-process"></a>fen.util.process

### <a id="fen-util-process-read-pipe-coop-packages-util-src-fen-util-process-fnl-367"></a>`fen.util.process.read-pipe-coop`
`(read-pipe-coop pipe yield-fn) -> string`
Drain a popen pipe in nonblocking chunks, yielding on EAGAIN so cooperative tool execution keeps the UI responsive.
*tags:* util, process, cooperative
_packages/util/src/fen/util/process.fnl:27_

### <a id="fen-util-process-read-pipe-close-packages-util-src-fen-util-process-fnl-367"></a>`fen.util.process.read-pipe-close`
`(read-pipe-close pipe yield-fn?) -> string`
Drain and close a popen pipe, guaranteeing close runs even when cooperative cancellation raises through yield-fn.
*tags:* util, process, cooperative, popen
_packages/util/src/fen/util/process.fnl:62_

### <a id="fen-util-process-run-captured-packages-util-src-fen-util-process-fnl-367"></a>`fen.util.process.run-captured`
`(run-captured opts yield-fn?) -> table`
Run a shell command with cooperative output capture, timeout/cancel cleanup, bounded inline output, and optional full-output spill file.
*tags:* util, process, subprocess, timeout, cooperative
_packages/util/src/fen/util/process.fnl:147_

### <a id="fen-util-process-monotonic-ms-packages-util-src-fen-util-process-fnl-367"></a>`fen.util.process.monotonic-ms`
_packages/util/src/fen/util/process.fnl:367_

### <a id="fen-util-process-sleep-ms-packages-util-src-fen-util-process-fnl-367"></a>`fen.util.process.sleep-ms`
_packages/util/src/fen/util/process.fnl:367_

## <a id="fen-util-random"></a>fen.util.random

### <a id="fen-util-random-bytes-packages-util-src-fen-util-random-fnl-21"></a>`fen.util.random.bytes`
`(bytes n) -> string`
Return n cryptographically random raw bytes from the platform RNG through the fen_random native binding.
*tags:* util, random, crypto
_packages/util/src/fen/util/random.fnl:11_

## <a id="fen-util-search-bitap"></a>fen.util.search.bitap

### <a id="fen-util-search-bitap-compile-packages-util-src-fen-util-search-bitap-fnl-20"></a>`fen.util.search.bitap.compile`
_packages/util/src/fen/util/search/bitap.fnl:20_

### <a id="fen-util-search-bitap-match-packages-util-src-fen-util-search-bitap-fnl-109"></a>`fen.util.search.bitap.match`
_packages/util/src/fen/util/search/bitap.fnl:109_

### <a id="fen-util-search-bitap-score-packages-util-src-fen-util-search-bitap-fnl-118"></a>`fen.util.search.bitap.score`
_packages/util/src/fen/util/search/bitap.fnl:118_

## <a id="fen-util-sha256"></a>fen.util.sha256

### <a id="fen-util-sha256-digest-packages-util-src-fen-util-sha256-fnl-130"></a>`fen.util.sha256.digest`
`(digest bytes) -> string`
Compute SHA-256 for a Lua string and return the 32-byte raw digest used by PKCE challenge construction.
*tags:* util, crypto, sha256
_packages/util/src/fen/util/sha256.fnl:98_

### <a id="fen-util-sha256-hex-digest-packages-util-src-fen-util-sha256-fnl-130"></a>`fen.util.sha256.hex-digest`
`(hex-digest bytes) -> string`
Compute SHA-256 for a Lua string and return the lowercase 64-character hexadecimal digest.
*tags:* util, crypto, sha256
_packages/util/src/fen/util/sha256.fnl:117_

## <a id="fen-util-sse"></a>fen.util.sse

### <a id="fen-util-sse-new-parser-packages-util-src-fen-util-sse-fnl-125"></a>`fen.util.sse.new-parser`
`(new-parser on-event) -> parser`
Create an incremental Server-Sent Events parser that accepts arbitrary chunks and dispatches complete event tables.
*tags:* util, sse, streaming
_packages/util/src/fen/util/sse.fnl:28_

### <a id="fen-util-sse-parse-packages-util-src-fen-util-sse-fnl-125"></a>`fen.util.sse.parse`
`(parse raw) -> [SseEvent]`
Parse a complete Server-Sent Events payload into event tables, flushing any final unterminated line.
*tags:* util, sse, streaming
_packages/util/src/fen/util/sse.fnl:99_

### <a id="fen-util-sse-json-events-packages-util-src-fen-util-sse-fnl-125"></a>`fen.util.sse.json-events`
`(json-events raw) -> [table]`
Parse an SSE payload and JSON-decode every non-empty, non-[DONE] data field for provider tests and adapters.
*tags:* util, sse, json
_packages/util/src/fen/util/sse.fnl:112_

## <a id="fen-util-text"></a>fen.util.text

### <a id="fen-util-text-default-tool-result-max-bytes-packages-util-src-fen-util-text-fnl-227"></a>`fen.util.text.default-tool-result-max-bytes`
_packages/util/src/fen/util/text.fnl:227_

### <a id="fen-util-text-trim-packages-util-src-fen-util-text-fnl-227"></a>`fen.util.text.trim`
`(trim s) -> string`
Strip leading and trailing ASCII whitespace; nil becomes "".
*tags:* util, text
_packages/util/src/fen/util/text.fnl:11_

### <a id="fen-util-text-first-line-packages-util-src-fen-util-text-fnl-227"></a>`fen.util.text.first-line`
`(first-line s) -> string`
Return the substring up to the first newline; nil becomes "".
*tags:* util, text
_packages/util/src/fen/util/text.fnl:19_

### <a id="fen-util-text-sanitize-packages-util-src-fen-util-text-fnl-227"></a>`fen.util.text.sanitize`
`(sanitize s) -> {:text :changed? :unsafe-count :invalid-count :input-bytes}`
Escape unsafe control bytes and invalid UTF-8 while preserving valid text and \n/\r/\t.
*tags:* util, text, tools, sessions, providers
_packages/util/src/fen/util/text.fnl:97_

### <a id="fen-util-text-scrub-tool-text-packages-util-src-fen-util-text-fnl-227"></a>`fen.util.text.scrub-tool-text`
`(scrub-tool-text s ?opts) -> {:text :changed? :note :unsafe-count :invalid-count :truncated? :input-bytes :sanitized-bytes :kept-bytes :max-bytes}`
Sanitize and cap provider-visible tool output text, appending an explicit marker when changed.
*tags:* util, text, tools, sessions, providers
_packages/util/src/fen/util/text.fnl:174_

_Undocumented data/state re-exports omitted from the public API listing:_ `fen.util.text.DEFAULT-MAX-TOOL-RESULT-BYTES`, `fen.util.text.MAX-SCAN-BYTES`

## <a id="fen-version"></a>fen.version

### <a id="fen-version-info-packages-fen-src-fen-version-fnl-51"></a>`fen.version.info`
`(info) -> VersionInfo`
Return source-checkout version metadata; Nix builds replace this module with a stamped table.
*tags:* version, build, metadata
_packages/fen/src/fen/version.fnl:46_

### <a id="fen-version-version-packages-fen-src-fen-version-fnl-59"></a>`fen.version.version`
`(version) -> string`
Return the short source version string used by CLI/status displays.
*tags:* version, build, metadata
_packages/fen/src/fen/version.fnl:54_

### <a id="fen-version-format-packages-fen-src-fen-version-fnl-67"></a>`fen.version.format`
`(format ?info) -> string`
Format version metadata as the single-line `fen --version` display.
*tags:* version, build, metadata
_packages/fen/src/fen/version.fnl:62_
