{"href":"api.html#fen-extensions-print-run-extensions-adapters-presenters-print-init-fnl-18","id":"fen.extensions.print.run","kind":"function","line":13,"path":"extensions/adapters/presenters/print/init.fnl","signature":"(run ctx) -> nil","summary":"Execute the one-shot print presenter by stepping the agent with the supplied prompt and printing the final text.","tags":["print","presenter","run"]}
{"href":"api.html#fen-extensions-print-register-extensions-adapters-presenters-print-init-fnl-29","id":"fen.extensions.print.register","kind":"function","line":29,"path":"extensions/adapters/presenters/print/init.fnl"}
{"href":"api.html#fen-extensions-stdio-render-event-extensions-adapters-presenters-stdio-init-fnl-119","id":"fen.extensions.stdio.render-event","kind":"function","line":114,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(render-event ev) -> nil","summary":"Render one event to stdio with prefixes, optional ANSI color, streaming delta coalescing, and stderr errors.","tags":["stdio","presenter","events"]}
{"href":"api.html#fen-extensions-stdio-stdin-tty-q-extensions-adapters-presenters-stdio-init-fnl-158","id":"fen.extensions.stdio.stdin-tty?","kind":"function","line":153,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(stdin-tty?) -> boolean","summary":"Return whether stdin is an interactive terminal for prompt-prefix and line-mode behavior.","tags":["stdio","presenter","tty"]}
{"href":"api.html#fen-extensions-stdio-drain-turn-extensions-adapters-presenters-stdio-init-fnl-173","id":"fen.extensions.stdio.drain-turn","kind":"function","line":168,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(drain-turn ctx) -> nil","summary":"Drive cooperative on-tick callbacks until the active agent turn completes in stdio mode.","tags":["stdio","presenter","loop"]}
{"href":"api.html#fen-extensions-stdio-submit-line-extensions-adapters-presenters-stdio-init-fnl-188","id":"fen.extensions.stdio.submit-line","kind":"function","line":183,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(submit-line ctx line interactive?) -> nil","summary":"Echo and submit one user line, then drain the resulting turn or emit a submit error.","tags":["stdio","presenter","input"]}
{"href":"api.html#fen-extensions-stdio-run-extensions-adapters-presenters-stdio-init-fnl-202","id":"fen.extensions.stdio.run","kind":"function","line":197,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(run ctx) -> nil","summary":"Run the line-oriented stdio presenter loop until EOF, prompting interactively when stdin is a TTY.","tags":["stdio","presenter","run"]}
{"href":"api.html#fen-extensions-stdio-notify-extensions-adapters-presenters-stdio-init-fnl-221","id":"fen.extensions.stdio.notify","kind":"function","line":216,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(notify text opts?) -> nil","summary":"Implement the stdio UI notify hook by printing an informational line.","tags":["stdio","presenter","ui","notify"]}
{"href":"api.html#fen-extensions-stdio-prompt-extensions-adapters-presenters-stdio-init-fnl-229","id":"fen.extensions.stdio.prompt","kind":"function","line":224,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(prompt opts) -> string|nil","summary":"Implement the stdio UI prompt hook by printing a label and reading one line from stdin.","tags":["stdio","presenter","ui","prompt"]}
{"href":"api.html#fen-extensions-stdio-select-extensions-adapters-presenters-stdio-init-fnl-240","id":"fen.extensions.stdio.select","kind":"function","line":235,"path":"extensions/adapters/presenters/stdio/init.fnl","signature":"(select opts) -> Choice|nil","summary":"Implement the stdio UI select hook by listing choices and returning the numbered selection.","tags":["stdio","presenter","ui","select"]}
{"href":"api.html#fen-extensions-stdio-register-extensions-adapters-presenters-stdio-init-fnl-261","id":"fen.extensions.stdio.register","kind":"function","line":261,"path":"extensions/adapters/presenters/stdio/init.fnl"}
{"href":"api.html#fen-extensions-tui-draw-in-bounds-q-extensions-adapters-presenters-tui-draw-fnl-19","id":"fen.extensions.tui.draw.in-bounds?","kind":"function","line":14,"path":"extensions/adapters/presenters/tui/draw.fnl","signature":"(in-bounds? x y) -> boolean","summary":"Return whether a zero-based terminal coordinate is inside the current termbox dimensions.","tags":["tui","draw","bounds","termbox"]}
{"href":"api.html#fen-extensions-tui-draw-fill-row-extensions-adapters-presenters-tui-draw-fnl-28","id":"fen.extensions.tui.draw.fill-row","kind":"function","line":23,"path":"extensions/adapters/presenters/tui/draw.fnl","signature":"(fill-row y x0 x1 ch fg bg) -> nil","summary":"Fill a clipped horizontal row segment with one termbox print call to reduce Lua-to-C overhead.","tags":["tui","draw","termbox","performance"]}
{"href":"api.html#fen-extensions-tui-draw-utf8-prefix-cols-extensions-adapters-presenters-tui-draw-fnl-44","id":"fen.extensions.tui.draw.utf8-prefix-cols","kind":"function","line":39,"path":"extensions/adapters/presenters/tui/draw.fnl","signature":"(utf8-prefix-cols s cols) -> string","summary":"Return a display-column-limited UTF-8 prefix without cutting multibyte characters in the middle.","tags":["tui","draw","utf8","clipping"]}
{"href":"api.html#fen-extensions-tui-draw-put-clipped-extensions-adapters-presenters-tui-draw-fnl-79","id":"fen.extensions.tui.draw.put-clipped","kind":"function","line":74,"path":"extensions/adapters/presenters/tui/draw.fnl","signature":"(put-clipped x y fg bg s width-cap) -> nil","summary":"Print clipped text at an in-bounds coordinate while respecting both terminal width and caller cap.","tags":["tui","draw","termbox","clipping"]}
{"href":"api.html#fen-extensions-tui-ingest-append-event-extensions-adapters-presenters-tui-ingest-fnl-89","id":"fen.extensions.tui.ingest.append-event","kind":"function","line":84,"path":"extensions/adapters/presenters/tui/ingest.fnl","signature":"(append-event ev) -> nil","summary":"Ingest a bus event into transcript rows and TUI status side effects, including streaming coalescing and cache invalidation.","tags":["tui","ingest","events","transcript","status"]}
{"href":"api.html#fen-extensions-tui-init-bang-extensions-adapters-presenters-tui-init-fnl-97","id":"fen.extensions.tui.init!","kind":"function","line":92,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(init!) -> nil","summary":"Initialize or refresh termbox runtime state, terminal modes, dimensions, and bracketed paste support.","tags":["tui","lifecycle","termbox","reload"]}
{"href":"api.html#fen-extensions-tui-shutdown-extensions-adapters-presenters-tui-init-fnl-147","id":"fen.extensions.tui.shutdown","kind":"function","line":142,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(shutdown) -> nil","summary":"Tear down termbox and bracketed paste mode when the TUI presenter exits.","tags":["tui","lifecycle","termbox"]}
{"href":"api.html#fen-extensions-tui-hard-refresh-bang-extensions-adapters-presenters-tui-init-fnl-163","id":"fen.extensions.tui.hard-refresh!","kind":"function","line":158,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(hard-refresh!) -> nil","summary":"Recover from external terminal corruption by re-asserting terminal modes and forcing a full repaint.","tags":["tui","lifecycle","redraw","termbox"]}
{"href":"api.html#fen-extensions-tui-suspend-bang-extensions-adapters-presenters-tui-init-fnl-177","id":"fen.extensions.tui.suspend!","kind":"function","line":172,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(suspend!) -> nil","summary":"Ctrl-Z job-control suspend: restore the terminal, stop with SIGTSTP, then re-init and repaint on resume.","tags":["tui","lifecycle","suspend","termbox","signal"]}
{"href":"api.html#fen-extensions-tui-reset-conversation-bang-extensions-adapters-presenters-tui-init-fnl-194","id":"fen.extensions.tui.reset-conversation!","kind":"function","line":189,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(reset-conversation!) -> nil","summary":"Clear transcript, streaming, input, paste, scroll, and per-turn status state while preserving UI identity.","tags":["tui","lifecycle","session","reset"]}
{"href":"api.html#fen-extensions-tui-set-status-info-extensions-adapters-presenters-tui-init-fnl-242","id":"fen.extensions.tui.set-status-info","kind":"function","line":237,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(set-status-info info) -> nil","summary":"Merge provider, model, queue, and context details into the persistent TUI status line state.","tags":["tui","status","presenter"]}
{"href":"api.html#fen-extensions-tui-input-meta-extensions-adapters-presenters-tui-init-fnl-291","id":"fen.extensions.tui.input-meta","kind":"function","line":291,"path":"extensions/adapters/presenters/tui/init.fnl"}
{"href":"api.html#fen-extensions-tui-warn-if-stalled-bang-extensions-adapters-presenters-tui-init-fnl-306","id":"fen.extensions.tui.warn-if-stalled!","kind":"function","line":306,"path":"extensions/adapters/presenters/tui/init.fnl"}
{"href":"api.html#fen-extensions-tui-peek-timeout-ms-extensions-adapters-presenters-tui-init-fnl-338","id":"fen.extensions.tui.peek-timeout-ms","kind":"function","line":333,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(peek-timeout-ms is-busy?) -> number","summary":"Choose a short or idle termbox poll timeout based on dirty state, Alt resolution, busy work, and animation needs.","tags":["tui","loop","polling","performance"]}
{"href":"api.html#fen-extensions-tui-interrupted-syscall-q-extensions-adapters-presenters-tui-init-fnl-355","id":"fen.extensions.tui.interrupted-syscall?","kind":"function","line":350,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(interrupted-syscall? err) -> boolean","summary":"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"]}
{"href":"api.html#fen-extensions-tui-run-extensions-adapters-presenters-tui-init-fnl-379","id":"fen.extensions.tui.run","kind":"function","line":374,"path":"extensions/adapters/presenters/tui/init.fnl","signature":"(run on-submit on-tick on-cancel is-busy? ?get-turn) -> nil","summary":"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"]}
{"href":"api.html#fen-extensions-tui-register-extensions-adapters-presenters-tui-init-fnl-455","id":"fen.extensions.tui.register","kind":"function","line":455,"path":"extensions/adapters/presenters/tui/init.fnl"}
{"href":"api.html#fen-extensions-tui-input-ensure-defaults-bang-extensions-adapters-presenters-tui-input-fnl-41","id":"fen.extensions.tui.input.ensure-defaults!","kind":"function","line":36,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(ensure-defaults!) -> nil","summary":"Backfill persistent input buffer, paste, history, quit, cancel, and Alt state fields after hot reloads.","tags":["tui","input","state","reload"]}
{"href":"api.html#fen-extensions-tui-input-input-display-rows-extensions-adapters-presenters-tui-input-fnl-63","id":"fen.extensions.tui.input.input-display-rows","kind":"function","line":58,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(input-display-rows buf width cursor) -> [InputDisplayRow]","summary":"Wrap the input buffer into prompt and continuation rows that preserve byte offsets for cursor placement.","tags":["tui","input","wrapping","cursor"]}
{"href":"api.html#fen-extensions-tui-input-cursor-display-pos-extensions-adapters-presenters-tui-input-fnl-120","id":"fen.extensions.tui.input.cursor-display-pos","kind":"function","line":115,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(cursor-display-pos rows cursor) -> row-index col","summary":"Locate the cursor within wrapped input rows using the same byte-offset view that painting uses.","tags":["tui","input","cursor","wrapping"]}
{"href":"api.html#fen-extensions-tui-input-input-rows-extensions-adapters-presenters-tui-input-fnl-135","id":"fen.extensions.tui.input.input-rows","kind":"function","line":130,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(input-rows) -> number","summary":"Return the current input region height, capped for multiline editing and terminal layout stability.","tags":["tui","input","layout"]}
{"href":"api.html#fen-extensions-tui-input-paint-input-extensions-adapters-presenters-tui-input-fnl-148","id":"fen.extensions.tui.input.paint-input","kind":"function","line":143,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(paint-input layout) -> nil","summary":"Paint the visible wrapped input rows and place or hide the terminal cursor within the input region.","tags":["tui","input","paint","cursor"]}
{"href":"api.html#fen-extensions-tui-input-handle-key-extensions-adapters-presenters-tui-input-fnl-530","id":"fen.extensions.tui.input.handle-key","kind":"function","line":525,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(handle-key ev on-submit on-cancel is-busy?) -> boolean|nil","summary":"Dispatch a termbox key event into buffer edits, history movement, submission, cancellation, or quit handling.","tags":["tui","input","keyboard","events"]}
{"href":"api.html#fen-extensions-tui-input-handle-mouse-extensions-adapters-presenters-tui-input-fnl-718","id":"fen.extensions.tui.input.handle-mouse","kind":"function","line":713,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(handle-mouse ev) -> nil","summary":"Interpret mouse wheel and click events for transcript scrolling, panel focus, and redraw invalidation.","tags":["tui","input","mouse","scroll"]}
{"href":"api.html#fen-extensions-tui-input-handle-event-extensions-adapters-presenters-tui-input-fnl-735","id":"fen.extensions.tui.input.handle-event","kind":"function","line":730,"path":"extensions/adapters/presenters/tui/input.fnl","signature":"(handle-event ev on-submit on-cancel is-busy?) -> boolean|nil","summary":"Route termbox keyboard, mouse, resize, paste, and Alt-synthesized events through the TUI input layer.","tags":["tui","input","events","termbox"]}
{"href":"api.html#fen-extensions-tui-markdown-parse-extensions-adapters-presenters-tui-markdown-fnl-579","id":"fen.extensions.tui.markdown.parse","kind":"function","line":574,"path":"extensions/adapters/presenters/tui/markdown.fnl","signature":"(parse s) -> [MarkdownBlock]","summary":"Parse Markdown source into the lightweight block records understood by the TUI renderer.","tags":["tui","markdown","parse","blocks"]}
{"href":"api.html#fen-extensions-tui-markdown-parse-inline-extensions-adapters-presenters-tui-markdown-fnl-586","id":"fen.extensions.tui.markdown.parse-inline","kind":"function","line":581,"path":"extensions/adapters/presenters/tui/markdown.fnl","signature":"(parse-inline s attr?) -> [Segment]","summary":"Parse simple inline Markdown spans into styled text segments for termbox painting.","tags":["tui","markdown","parse","inline"]}
{"href":"api.html#fen-extensions-tui-markdown-render-block-extensions-adapters-presenters-tui-markdown-fnl-593","id":"fen.extensions.tui.markdown.render-block","kind":"function","line":588,"path":"extensions/adapters/presenters/tui/markdown.fnl","signature":"(render-block block width) -> [PresenterRow]","summary":"Render one parsed Markdown block into wrapped TUI rows for the requested width.","tags":["tui","markdown","render","blocks"]}
{"href":"api.html#fen-extensions-tui-markdown-render-text-extensions-adapters-presenters-tui-markdown-fnl-600","id":"fen.extensions.tui.markdown.render-text","kind":"function","line":595,"path":"extensions/adapters/presenters/tui/markdown.fnl","signature":"(render-text s width) -> [PresenterRow]","summary":"Parse and render Markdown text into styled TUI rows while preserving readable chat line breaks.","tags":["tui","markdown","render","text"]}
{"href":"api.html#fen-extensions-tui-markdown-render-extensions-adapters-presenters-tui-markdown-fnl-607","id":"fen.extensions.tui.markdown.render","kind":"function","line":602,"path":"extensions/adapters/presenters/tui/markdown.fnl","signature":"(render s width) -> [PresenterRow]","summary":"Compatibility alias for render-text used by transcript rendering and tests.","tags":["tui","markdown","render","text"]}
{"href":"api.html#fen-extensions-tui-markdown-display-len-extensions-adapters-presenters-tui-markdown-fnl-614","id":"fen.extensions.tui.markdown.display-len","kind":"function","line":609,"path":"extensions/adapters/presenters/tui/markdown.fnl","signature":"(display-len s) -> number","summary":"Approximate display width by counting UTF-8 codepoints as terminal cells.","tags":["tui","markdown","width","utf8"]}
{"href":"api.html#fen-extensions-tui-paint-ensure-state-defaults-bang-extensions-adapters-presenters-tui-paint-fnl-51","id":"fen.extensions.tui.paint.ensure-state-defaults!","kind":"function","line":46,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(ensure-state-defaults!) -> nil","summary":"Backfill persistent paint, transcript, status, errors, spinner, and input defaults after reloads.","tags":["tui","paint","state","reload"]}
{"href":"api.html#fen-extensions-tui-paint-max-scroll-extensions-adapters-presenters-tui-paint-fnl-65","id":"fen.extensions.tui.paint.max-scroll","kind":"function","line":60,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(max-scroll) -> number","summary":"Return the maximum transcript scroll offset after accounting for the current input area height.","tags":["tui","paint","scroll","transcript"]}
{"href":"api.html#fen-extensions-tui-paint-layout-extensions-adapters-presenters-tui-paint-fnl-131","id":"fen.extensions.tui.paint.layout","kind":"function","line":126,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(layout) -> Layout","summary":"Compute status, transcript, input, and registered panel slots for the current terminal dimensions.","tags":["tui","paint","layout","panels"]}
{"href":"api.html#fen-extensions-tui-paint-fmt-tokens-extensions-adapters-presenters-tui-paint-fnl-182","id":"fen.extensions.tui.paint.fmt-tokens","kind":"data","line":177,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"function","summary":"Compact token-count formatter alias used by status renderers and tests.","tags":["tui","paint","status","tokens"]}
{"href":"api.html#fen-extensions-tui-paint-paint-status-extensions-adapters-presenters-tui-paint-fnl-191","id":"fen.extensions.tui.paint.paint-status","kind":"function","line":186,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(paint-status layout) -> nil","summary":"Delegate status-line painting to the status panel module while preserving the paint facade entrypoint.","tags":["tui","paint","status","delegate"]}
{"href":"api.html#fen-extensions-tui-paint-paint-panels-extensions-adapters-presenters-tui-paint-fnl-252","id":"fen.extensions.tui.paint.paint-panels","kind":"function","line":247,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(paint-panels layout) -> nil","summary":"Render registered above-input and below-status panels with per-panel error isolation.","tags":["tui","paint","panels","errors"]}
{"href":"api.html#fen-extensions-tui-paint-paint-transcript-extensions-adapters-presenters-tui-paint-fnl-268","id":"fen.extensions.tui.paint.paint-transcript","kind":"function","line":263,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(paint-transcript layout) -> nil","summary":"Paint the visible transcript viewport rows into the reserved transcript region.","tags":["tui","paint","transcript","viewport"]}
{"href":"api.html#fen-extensions-tui-paint-paint-input-extensions-adapters-presenters-tui-paint-fnl-285","id":"fen.extensions.tui.paint.paint-input","kind":"function","line":280,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(paint-input layout) -> nil","summary":"Delegate to the input renderer for the reserved input region.","tags":["tui","paint","input","delegate"]}
{"href":"api.html#fen-extensions-tui-paint-invalidate-bang-extensions-adapters-presenters-tui-paint-fnl-295","id":"fen.extensions.tui.paint.invalidate!","kind":"function","line":290,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(invalidate!) -> nil","summary":"Mark the TUI dirty so the next presenter-loop pass repaints the terminal.","tags":["tui","paint","redraw","dirty"]}
{"href":"api.html#fen-extensions-tui-paint-invalidate-full-bang-extensions-adapters-presenters-tui-paint-fnl-304","id":"fen.extensions.tui.paint.invalidate-full!","kind":"function","line":299,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(invalidate-full!) -> nil","summary":"Request a cache-clearing repaint for resize, reload, and display toggles that invalidate wrapped rows.","tags":["tui","paint","redraw","cache"]}
{"href":"api.html#fen-extensions-tui-paint-busy-q-extensions-adapters-presenters-tui-paint-fnl-314","id":"fen.extensions.tui.paint.busy?","kind":"function","line":309,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(busy?) -> boolean|string|nil","summary":"Report whether thinking or tool-running status should keep the busy animation active.","tags":["tui","paint","busy","status"]}
{"href":"api.html#fen-extensions-tui-paint-advance-spinner-if-due-bang-extensions-adapters-presenters-tui-paint-fnl-323","id":"fen.extensions.tui.paint.advance-spinner-if-due!","kind":"function","line":318,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(advance-spinner-if-due!) -> nil","summary":"Advance the status spinner on a throttled presenter-loop tick cadence and invalidate when it changes.","tags":["tui","paint","spinner","animation"]}
{"href":"api.html#fen-extensions-tui-paint-redraw-if-needed-bang-extensions-adapters-presenters-tui-paint-fnl-342","id":"fen.extensions.tui.paint.redraw-if-needed!","kind":"function","line":337,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(redraw-if-needed!) -> nil","summary":"Repaint only when dirty or forced, clearing caches and terminal geometry before forced redraws.","tags":["tui","paint","redraw","performance"]}
{"href":"api.html#fen-extensions-tui-paint-paint-frame-bang-extensions-adapters-presenters-tui-paint-fnl-363","id":"fen.extensions.tui.paint.paint-frame!","kind":"function","line":358,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(paint-frame!) -> nil","summary":"Paint a complete frame into the termbox back buffer without presenting, allowing overlays to share the underlay.","tags":["tui","paint","frame","termbox"]}
{"href":"api.html#fen-extensions-tui-paint-redraw-bang-extensions-adapters-presenters-tui-paint-fnl-385","id":"fen.extensions.tui.paint.redraw!","kind":"function","line":380,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(redraw!) -> nil","summary":"Paint a complete TUI frame and present termbox's back buffer to the terminal.","tags":["tui","paint","redraw","termbox"]}
{"href":"api.html#fen-extensions-tui-paint-clear-render-caches-bang-extensions-adapters-presenters-tui-paint-fnl-395","id":"fen.extensions.tui.paint.clear-render-caches!","kind":"function","line":390,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(clear-render-caches!) -> nil","summary":"Drop transcript render caches so forced repaints or reloads recompute rows with current renderers.","tags":["tui","paint","cache","transcript"]}
{"href":"api.html#fen-extensions-tui-paint-force-redraw-bang-extensions-adapters-presenters-tui-paint-fnl-406","id":"fen.extensions.tui.paint.force-redraw!","kind":"function","line":401,"path":"extensions/adapters/presenters/tui/paint.fnl","signature":"(force-redraw!) -> nil","summary":"Blank-present and repaint the full terminal to resynchronize termbox front-buffer assumptions.","tags":["tui","paint","redraw","termbox"]}
{"href":"api.html#fen-extensions-tui-panels-busy-spin-char-extensions-adapters-presenters-tui-panels-busy-fnl-20","id":"fen.extensions.tui.panels.busy.spin-char","kind":"function","line":15,"path":"extensions/adapters/presenters/tui/panels/busy.fnl","signature":"(spin-char) -> string","summary":"Return the current busy indicator glyph, respecting the animation toggle and spinner frame counter.","tags":["tui","panel","busy","spinner"]}
{"href":"api.html#fen-extensions-tui-panels-busy-turn-elapsed-extensions-adapters-presenters-tui-panels-busy-fnl-33","id":"fen.extensions.tui.panels.busy.turn-elapsed","kind":"function","line":28,"path":"extensions/adapters/presenters/tui/panels/busy.fnl","signature":"(turn-elapsed) -> string","summary":"Return elapsed turn time text for the busy panel, or an empty string when no turn is active.","tags":["tui","panel","busy","timing"]}
{"href":"api.html#fen-extensions-tui-panels-busy-height-extensions-adapters-presenters-tui-panels-busy-fnl-63","id":"fen.extensions.tui.panels.busy.height","kind":"function","line":58,"path":"extensions/adapters/presenters/tui/panels/busy.fnl","signature":"(height ctx) -> number","summary":"Reserve one above-input row only while thinking, retrying, or running a tool.","tags":["tui","panel","busy","layout"]}
{"href":"api.html#fen-extensions-tui-panels-busy-render-extensions-adapters-presenters-tui-panels-busy-fnl-71","id":"fen.extensions.tui.panels.busy.render","kind":"function","line":66,"path":"extensions/adapters/presenters/tui/panels/busy.fnl","signature":"(render ctx) -> [PresenterRow]","summary":"Render spinner, busy label, retry delay, and elapsed time rows for the active turn.","tags":["tui","panel","busy","render"]}
{"href":"api.html#fen-extensions-tui-panels-busy-spec-extensions-adapters-presenters-tui-panels-busy-fnl-84","id":"fen.extensions.tui.panels.busy.spec","kind":"function","line":79,"path":"extensions/adapters/presenters/tui/panels/busy.fnl","signature":"(spec) -> PanelSpec","summary":"Return the built-in busy panel contribution that appears above the input while work is active.","tags":["tui","panel","busy","register"]}
{"href":"api.html#fen-extensions-tui-panels-errors-ensure-defaults-bang-extensions-adapters-presenters-tui-panels-errors-fnl-20","id":"fen.extensions.tui.panels.errors.ensure-defaults!","kind":"function","line":15,"path":"extensions/adapters/presenters/tui/panels/errors.fnl","signature":"(ensure-defaults!) -> nil","summary":"Backfill persistent error-panel visibility state on live TUI state tables after reloads.","tags":["tui","panel","errors","state","reload"]}
{"href":"api.html#fen-extensions-tui-panels-errors-toggle-bang-extensions-adapters-presenters-tui-panels-errors-fnl-68","id":"fen.extensions.tui.panels.errors.toggle!","kind":"function","line":63,"path":"extensions/adapters/presenters/tui/panels/errors.fnl","signature":"(toggle! value?) -> boolean","summary":"Toggle or set the TUI error panel visibility and return the new visible state.","tags":["tui","panel","errors","visibility"]}
{"href":"api.html#fen-extensions-tui-panels-errors-visible-q-extensions-adapters-presenters-tui-panels-errors-fnl-79","id":"fen.extensions.tui.panels.errors.visible?","kind":"function","line":74,"path":"extensions/adapters/presenters/tui/panels/errors.fnl","signature":"(visible?) -> boolean","summary":"Report whether the recent-errors panel should currently reserve below-status space.","tags":["tui","panel","errors","visibility"]}
{"href":"api.html#fen-extensions-tui-panels-errors-clear-transcript-errors-bang-extensions-adapters-presenters-tui-panels-errors-fnl-113","id":"fen.extensions.tui.panels.errors.clear-transcript-errors!","kind":"function","line":108,"path":"extensions/adapters/presenters/tui/panels/errors.fnl","signature":"(clear-transcript-errors!) -> nil","summary":"Remove error and extension-error events from the transcript and invalidate transcript layout cache.","tags":["tui","panel","errors","transcript","cache"]}
{"href":"api.html#fen-extensions-tui-panels-errors-spec-extensions-adapters-presenters-tui-panels-errors-fnl-126","id":"fen.extensions.tui.panels.errors.spec","kind":"function","line":121,"path":"extensions/adapters/presenters/tui/panels/errors.fnl","signature":"(spec) -> PanelSpec","summary":"Return the error introspection panel contribution for below-status rendering.","tags":["tui","panel","errors","register"]}
{"href":"api.html#fen-extensions-tui-panels-status-ensure-defaults-bang-extensions-adapters-presenters-tui-panels-status-fnl-33","id":"fen.extensions.tui.panels.status.ensure-defaults!","kind":"function","line":28,"path":"extensions/adapters/presenters/tui/panels/status.fnl","signature":"(ensure-defaults!) -> nil","summary":"Backfill persistent status-info fields, token counters, retry state, queue counts, and running-label migration.","tags":["tui","panel","status","state","reload"]}
{"href":"api.html#fen-extensions-tui-panels-status-paint-extensions-adapters-presenters-tui-panels-status-fnl-103","id":"fen.extensions.tui.panels.status.paint","kind":"function","line":98,"path":"extensions/adapters/presenters/tui/panels/status.fnl","signature":"(paint layout) -> nil","summary":"Paint the top status row by composing registered left and right status items with error isolation.","tags":["tui","panel","status","paint","registry"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-tool-result-preview-bytes-extensions-adapters-presenters-tui-panels-transcript-fnl-24","id":"fen.extensions.tui.panels.transcript.TOOL-RESULT-PREVIEW-BYTES","kind":"data","line":19,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"number","summary":"Maximum inline bytes from a tool result shown in collapsed transcript previews.","tags":["tui","transcript","tools","defaults"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-ensure-defaults-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-31","id":"fen.extensions.tui.panels.transcript.ensure-defaults!","kind":"function","line":26,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(ensure-defaults!) -> nil","summary":"Backfill persistent transcript, streaming, scroll, Markdown, and tool-result display state after reloads.","tags":["tui","transcript","state","reload"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-args-extensions-adapters-presenters-tui-panels-transcript-fnl-62","id":"fen.extensions.tui.panels.transcript.args-","kind":"function","line":57,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(args->string args) -> string","summary":"Convert tool-call arguments to compact JSON text for transcript fallback rendering.","tags":["tui","transcript","tools","json"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-content-extensions-adapters-presenters-tui-panels-transcript-fnl-73","id":"fen.extensions.tui.panels.transcript.content-","kind":"function","line":68,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(content->text content) -> string","summary":"Concatenate text blocks from an AgentToolResult content list for tool-result previews.","tags":["tui","transcript","tools","results"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-truncate-extensions-adapters-presenters-tui-panels-transcript-fnl-87","id":"fen.extensions.tui.panels.transcript.truncate","kind":"function","line":82,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(truncate s n) -> string","summary":"Return text capped to n bytes with a visible truncation marker for tool-result previews.","tags":["tui","transcript","truncate","tools"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-count-lines-extensions-adapters-presenters-tui-panels-transcript-fnl-96","id":"fen.extensions.tui.panels.transcript.count-lines","kind":"function","line":91,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(count-lines s) -> number","summary":"Count displayable newline-delimited lines for transcript summaries and tool-result metadata.","tags":["tui","transcript","lines","tools"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-lookup-tool-call-extensions-adapters-presenters-tui-panels-transcript-fnl-145","id":"fen.extensions.tui.panels.transcript.lookup-tool-call","kind":"function","line":140,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(lookup-tool-call tool-call-id) -> table|nil","summary":"Find the matching prior tool-call event for a tool result by scanning the transcript tail.","tags":["tui","transcript","tools","lookup"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-split-lines-extensions-adapters-presenters-tui-panels-transcript-fnl-182","id":"fen.extensions.tui.panels.transcript.split-lines","kind":"data","line":177,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"function","summary":"Line-splitting helper alias exported for input wrapping and transcript-rendering tests.","tags":["tui","transcript","lines","tests"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-tool-call-short-extensions-adapters-presenters-tui-panels-transcript-fnl-240","id":"fen.extensions.tui.panels.transcript.tool-call-short","kind":"function","line":235,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(tool-call-short name args) -> string|nil","summary":"Format concise built-in tool call labels for the transcript and busy status row.","tags":["tui","transcript","tools","format"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-event-text-extensions-adapters-presenters-tui-panels-transcript-fnl-288","id":"fen.extensions.tui.panels.transcript.event-text","kind":"function","line":283,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(event-text ev) -> string","summary":"Materialize streaming text chunks lazily and return the event's display text.","tags":["tui","transcript","streaming","text"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-invalidate-layout-cache-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-486","id":"fen.extensions.tui.panels.transcript.invalidate-layout-cache!","kind":"function","line":481,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(invalidate-layout-cache!) -> nil","summary":"Drop the transcript-wide row-count cache after event changes or rendering toggles.","tags":["tui","transcript","cache","layout"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-clear-event-render-cache-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-496","id":"fen.extensions.tui.panels.transcript.clear-event-render-cache!","kind":"function","line":491,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(clear-event-render-cache! ev) -> nil","summary":"Clear one event's Markdown and wrapped-row caches and invalidate transcript layout.","tags":["tui","transcript","cache","event"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-lines-for-event-extensions-adapters-presenters-tui-panels-transcript-fnl-524","id":"fen.extensions.tui.panels.transcript.lines-for-event","kind":"data","line":519,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"function","summary":"Cached event-to-row renderer alias exported for transcript viewport tests and diagnostics.","tags":["tui","transcript","cache","render","tests"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-viewport-lines-extensions-adapters-presenters-tui-panels-transcript-fnl-643","id":"fen.extensions.tui.panels.transcript.viewport-lines","kind":"function","line":638,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(viewport-lines width region-h) -> [PresenterRow]","summary":"Return visible transcript rows using lazy tail rendering near the end and indexed cache for deep scroll.","tags":["tui","transcript","viewport","scroll"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-max-scroll-extensions-adapters-presenters-tui-panels-transcript-fnl-658","id":"fen.extensions.tui.panels.transcript.max-scroll","kind":"function","line":653,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(max-scroll input-rows) -> number","summary":"Compute the maximum useful transcript scroll offset for current terminal and input heights.","tags":["tui","transcript","scroll","layout"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-jump-to-user-message-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-677","id":"fen.extensions.tui.panels.transcript.jump-to-user-message!","kind":"function","line":672,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(jump-to-user-message! input-rows) -> boolean","summary":"Move the transcript viewport to the latest relevant user-authored message, repeating through older messages.","tags":["tui","transcript","scroll","navigation","keyboard"]}
{"href":"api.html#fen-extensions-tui-panels-transcript-clear-render-caches-bang-extensions-adapters-presenters-tui-panels-transcript-fnl-738","id":"fen.extensions.tui.panels.transcript.clear-render-caches!","kind":"function","line":733,"path":"extensions/adapters/presenters/tui/panels/transcript.fnl","signature":"(clear-render-caches!) -> nil","summary":"Clear cached rows for every transcript event so a forced repaint uses current renderers.","tags":["tui","transcript","cache","reload"]}
{"href":"api.html#fen-extensions-tui-redraw-ensure-defaults-bang-extensions-adapters-presenters-tui-redraw-fnl-16","id":"fen.extensions.tui.redraw.ensure-defaults!","kind":"function","line":11,"path":"extensions/adapters/presenters/tui/redraw.fnl","signature":"(ensure-defaults!) -> nil","summary":"Backfill persistent redraw and spinner scheduling fields after reloads.","tags":["tui","redraw","state","reload"]}
{"href":"api.html#fen-extensions-tui-redraw-invalidate-bang-extensions-adapters-presenters-tui-redraw-fnl-28","id":"fen.extensions.tui.redraw.invalidate!","kind":"function","line":23,"path":"extensions/adapters/presenters/tui/redraw.fnl","signature":"(invalidate!) -> nil","summary":"Mark the TUI dirty so the next presenter-loop pass repaints the terminal.","tags":["tui","redraw","dirty"]}
{"href":"api.html#fen-extensions-tui-redraw-invalidate-full-bang-extensions-adapters-presenters-tui-redraw-fnl-38","id":"fen.extensions.tui.redraw.invalidate-full!","kind":"function","line":33,"path":"extensions/adapters/presenters/tui/redraw.fnl","signature":"(invalidate-full!) -> nil","summary":"Request a cache-clearing repaint for resize, reload, and display toggles that invalidate wrapped rows.","tags":["tui","redraw","cache"]}
{"href":"api.html#fen-extensions-tui-select-filtered-extensions-adapters-presenters-tui-select-fnl-51","id":"fen.extensions.tui.select.filtered","kind":"function","line":46,"path":"extensions/adapters/presenters/tui/select.fnl","signature":"(filtered state) -> [Choice]","summary":"Return choices whose label or description match the current selector filter text.","tags":["tui","select","filter","choices"]}
{"href":"api.html#fen-extensions-tui-select-visible-window-extensions-adapters-presenters-tui-select-fnl-68","id":"fen.extensions.tui.select.visible-window","kind":"function","line":63,"path":"extensions/adapters/presenters/tui/select.fnl","signature":"(visible-window state max-rows) -> first-index item-count total-count","summary":"Compute the visible selector slice so the cursor stays on-screen while moving through long choice lists.","tags":["tui","select","viewport","scroll","choices"]}
{"href":"api.html#fen-extensions-tui-select-make-state-extensions-adapters-presenters-tui-select-fnl-85","id":"fen.extensions.tui.select.make-state","kind":"function","line":80,"path":"extensions/adapters/presenters/tui/select.fnl","signature":"(make-state opts) -> SelectState","summary":"Create the pure selector state record used by tests and the termbox overlay loop.","tags":["tui","select","state"]}
{"href":"api.html#fen-extensions-tui-select-step-bang-extensions-adapters-presenters-tui-select-fnl-100","id":"fen.extensions.tui.select.step!","kind":"function","line":95,"path":"extensions/adapters/presenters/tui/select.fnl","signature":"(step! state key) -> SelectState","summary":"Apply one synthetic selector key to filtering, cursor movement, selection, or cancellation state.","tags":["tui","select","state","keyboard"]}
{"href":"api.html#fen-extensions-tui-select-tui-select-extensions-adapters-presenters-tui-select-fnl-254","id":"fen.extensions.tui.select.tui-select","kind":"function","line":249,"path":"extensions/adapters/presenters/tui/select.fnl","signature":"(tui-select opts) -> Choice|nil","summary":"Run the interactive TUI select overlay when termbox is initialized and return the chosen record.","tags":["tui","select","overlay","presenter"]}
{"href":"api.html#fen-extensions-tui-state-tb-initialized-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.tb-initialized?","kind":"data","line":10,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Persistent termbox2 lifecycle flag used to keep TUI init and shutdown idempotent across reloads.","tags":["tui","state","termbox","reload"]}
{"href":"api.html#fen-extensions-tui-state-tb-init-failed-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.tb-init-failed?","kind":"data","line":16,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Flag set when termbox2 initialization failed so startup can print a clean error and avoid unsafe teardown.","tags":["tui","state","termbox","errors"]}
{"href":"api.html#fen-extensions-tui-state-tb-cols-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.tb-cols","kind":"data","line":22,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Last known terminal column count used by draw/layout code after termbox resize events.","tags":["tui","state","termbox","layout"]}
{"href":"api.html#fen-extensions-tui-state-tb-rows-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.tb-rows","kind":"data","line":28,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Last known terminal row count used by draw/layout code after termbox resize events.","tags":["tui","state","termbox","layout"]}
{"href":"api.html#fen-extensions-tui-state-dirty-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.dirty?","kind":"data","line":34,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Redraw scheduling flag set when visible TUI state changed and the next presenter loop should repaint.","tags":["tui","state","redraw"]}
{"href":"api.html#fen-extensions-tui-state-force-redraw-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.force-redraw?","kind":"data","line":40,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Strong redraw flag that clears render caches and blanks the presenter before repainting after resize, reload, or display toggles.","tags":["tui","state","redraw","cache"]}
{"href":"api.html#fen-extensions-tui-state-spinner-ticks-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.spinner-ticks","kind":"data","line":46,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Event-loop tick counter used to pace busy spinner animation without adding another wall-clock dependency.","tags":["tui","state","animation"]}
{"href":"api.html#fen-extensions-tui-state-spinner-interval-ticks-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.spinner-interval-ticks","kind":"data","line":52,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Number of event-loop ticks between spinner frame advances while the agent is busy.","tags":["tui","state","animation"]}
{"href":"api.html#fen-extensions-tui-state-animations-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.animations?","kind":"data","line":58,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Global animation toggle controlling whether busy indicators use animated spinner frames or static fallback glyphs.","tags":["tui","state","animation","settings"]}
{"href":"api.html#fen-extensions-tui-state-transcript-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.transcript","kind":"data","line":64,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"[PresenterEvent]","summary":"Append-only preprocessed transcript event log used as the source of truth for TUI rendering.","tags":["tui","state","transcript"]}
{"href":"api.html#fen-extensions-tui-state-streaming-assistant-rows-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.streaming-assistant-rows","kind":"data","line":70,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"table","summary":"Lookup table from streaming row keys to transcript rows so delta ingestion can update active assistant output efficiently.","tags":["tui","state","transcript","streaming"]}
{"href":"api.html#fen-extensions-tui-state-transcript-layout-cache-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.transcript-layout-cache","kind":"data","line":76,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"table|nil","summary":"Width/display-keyed wrapped transcript layout cache used for fast viewport and max-scroll calculations.","tags":["tui","state","transcript","layout"]}
{"href":"api.html#fen-extensions-tui-state-scroll-offset-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.scroll-offset","kind":"data","line":82,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Number of wrapped transcript lines above the tail that anchor the viewport when the user scrolls up.","tags":["tui","state","scroll","transcript"]}
{"href":"api.html#fen-extensions-tui-state-new-content-below-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.new-content-below?","kind":"data","line":88,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Set while the transcript is scroll-locked and newly appended content is available below the viewport.","tags":["tui","state","scroll","transcript","follow"]}
{"href":"api.html#fen-extensions-tui-state-last-user-jump-index-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.last-user-jump-index","kind":"data","line":94,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number|nil","summary":"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"]}
{"href":"api.html#fen-extensions-tui-state-input-buf-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.input-buf","kind":"data","line":100,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"string","summary":"Current multi-line input buffer contents, including literal newlines and paste markers before submit expansion.","tags":["tui","state","input"]}
{"href":"api.html#fen-extensions-tui-state-input-cursor-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.input-cursor","kind":"data","line":106,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Byte offset cursor position inside input-buf for terminal input editing.","tags":["tui","state","input"]}
{"href":"api.html#fen-extensions-tui-state-paste-active-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.paste-active?","kind":"data","line":112,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Bracketed-paste mode flag indicating incoming bytes should accumulate in paste-buffer instead of editing input directly.","tags":["tui","state","paste","input"]}
{"href":"api.html#fen-extensions-tui-state-paste-buffer-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.paste-buffer","kind":"data","line":118,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"string","summary":"Accumulator for the current bracketed paste before it is compacted into an input marker.","tags":["tui","state","paste","input"]}
{"href":"api.html#fen-extensions-tui-state-paste-counter-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.paste-counter","kind":"data","line":124,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Monotonic id counter for large pasted payload markers stored in the pastes table.","tags":["tui","state","paste","input"]}
{"href":"api.html#fen-extensions-tui-state-pastes-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.pastes","kind":"data","line":130,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"table","summary":"Table of compact paste marker ids to full pasted text, expanded back into input on submit.","tags":["tui","state","paste","input"]}
{"href":"api.html#fen-extensions-tui-state-history-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.history","kind":"data","line":136,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"[string]","summary":"In-process prompt history ring containing submitted prompts for up/down navigation.","tags":["tui","state","history","input"]}
{"href":"api.html#fen-extensions-tui-state-history-pos-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.history-pos","kind":"data","line":142,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"number","summary":"Prompt history navigation position where zero means the current live draft and positive values index backward from the end.","tags":["tui","state","history","input"]}
{"href":"api.html#fen-extensions-tui-state-history-draft-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.history-draft","kind":"data","line":148,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"string","summary":"Saved live input draft restored when the user navigates back out of history.","tags":["tui","state","history","input"]}
{"href":"api.html#fen-extensions-tui-state-expand-tool-results-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.expand-tool-results?","kind":"data","line":154,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Global /expand toggle controlling whether tool-result transcript events show full truncated bodies or one-line summaries.","tags":["tui","state","transcript","tools"]}
{"href":"api.html#fen-extensions-tui-state-markdown-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.markdown?","kind":"data","line":160,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Global /markdown toggle controlling whether assistant text renders through the terminal markdown renderer or as plain text.","tags":["tui","state","markdown","settings"]}
{"href":"api.html#fen-extensions-tui-state-hide-thinking-block-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.hide-thinking-block?","kind":"data","line":166,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Global /thinking toggle controlling whether assistant reasoning blocks render visibly or collapse to a compact Thinking label.","tags":["tui","state","thinking","settings"]}
{"href":"api.html#fen-extensions-tui-state-pending-quit-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.pending-quit?","kind":"data","line":172,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Two-press ctrl-c confirmation flag for idle quit behavior, cleared by any non-quit key.","tags":["tui","state","input","quit"]}
{"href":"api.html#fen-extensions-tui-state-alt-pending-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.alt-pending?","kind":"data","line":178,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"One-tick bare-Esc state used to distinguish dismiss from Alt-key combinations in INPUT_ESC mode.","tags":["tui","state","input","keyboard"]}
{"href":"api.html#fen-extensions-tui-state-on-tick-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.on-tick","kind":"data","line":184,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"function|nil","summary":"Cooperative tick callback published by the run loop so nested selectors can keep agent coroutines and HTTP drains moving.","tags":["tui","state","cooperative","input"]}
{"href":"api.html#fen-extensions-tui-state-cancel-pressed-q-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.cancel-pressed?","kind":"data","line":190,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"boolean","summary":"Busy-turn ctrl-c flag recording that cancellation was requested before the agent loop observes and clears it.","tags":["tui","state","cancel","input"]}
{"href":"api.html#fen-extensions-tui-state-last-stall-warn-ms-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.last-stall-warn-ms","kind":"function","line":202,"path":"extensions/adapters/presenters/tui/state.fnl"}
{"href":"api.html#fen-extensions-tui-state-status-info-extensions-adapters-presenters-tui-state-fnl-202","id":"fen.extensions.tui.state.status-info","kind":"data","line":196,"path":"extensions/adapters/presenters/tui/state.fnl","signature":"table","summary":"Persistent status-line model, token, queue, retry, thinking, cancellation, elapsed-time, and spinner metadata.","tags":["tui","state","status"]}
{"href":"api.html#fen-extensions-web-ingest-append-event-extensions-adapters-presenters-web-ingest-fnl-84","id":"fen.extensions.web.ingest.append-event","kind":"function","line":79,"path":"extensions/adapters/presenters/web/ingest.fnl","signature":"(append-event ev) -> nil","summary":"Ingest one bus event into web transcript and status state, including streaming assistant deltas and tool summaries.","tags":["web","ingest","events","transcript","status"]}
{"href":"api.html#fen-extensions-web-init-bang-extensions-adapters-presenters-web-init-fnl-78","id":"fen.extensions.web.init!","kind":"function","line":73,"path":"extensions/adapters/presenters/web/init.fnl","signature":"(init! ctx) -> nil","summary":"Store the presenter context and initialize the web server listener for browser clients.","tags":["web","presenter","lifecycle","server"]}
{"href":"api.html#fen-extensions-web-shutdown-extensions-adapters-presenters-web-init-fnl-86","id":"fen.extensions.web.shutdown","kind":"function","line":81,"path":"extensions/adapters/presenters/web/init.fnl","signature":"(shutdown ctx) -> nil","summary":"Clear the web presenter context and close server/client resources during presenter shutdown.","tags":["web","presenter","lifecycle","server"]}
{"href":"api.html#fen-extensions-web-run-extensions-adapters-presenters-web-init-fnl-94","id":"fen.extensions.web.run","kind":"function","line":89,"path":"extensions/adapters/presenters/web/init.fnl","signature":"(run ctx) -> nil","summary":"Run the web presenter server loop with the current context until the presenter is asked to quit.","tags":["web","presenter","lifecycle","server"]}
{"href":"api.html#fen-extensions-web-register-extensions-adapters-presenters-web-init-fnl-98","id":"fen.extensions.web.register","kind":"function","line":98,"path":"extensions/adapters/presenters/web/init.fnl"}
{"href":"api.html#fen-extensions-web-layout-snapshot-extensions-adapters-presenters-web-layout-fnl-120","id":"fen.extensions.web.layout.snapshot","kind":"function","line":115,"path":"extensions/adapters/presenters/web/layout.fnl","signature":"(snapshot ctx?) -> table","summary":"Build the JSON-serializable browser layout snapshot from status fragments, panels, transcript rows, select state, and reload sequence.","tags":["web","layout","snapshot","json"]}
{"href":"api.html#fen-extensions-web-layout-html-snapshot-extensions-adapters-presenters-web-layout-fnl-191","id":"fen.extensions.web.layout.html-snapshot","kind":"function","line":186,"path":"extensions/adapters/presenters/web/layout.fnl","signature":"(html-snapshot ctx?) -> table","summary":"Build a browser layout snapshot with pre-rendered HTML fragments for status, transcript, panels, and select state.","tags":["web","layout","snapshot","html"]}
{"href":"api.html#fen-extensions-web-page-render-extensions-adapters-presenters-web-page-fnl-71","id":"fen.extensions.web.page.render","kind":"data","line":66,"path":"extensions/adapters/presenters/web/page.fnl","signature":"function","summary":"Hiccup document renderer alias exported for browser page tests and reuse within web snapshots.","tags":["web","page","html","render","tests"]}
{"href":"api.html#fen-extensions-web-page-render-node-extensions-adapters-presenters-web-page-fnl-78","id":"fen.extensions.web.page.render-node","kind":"data","line":73,"path":"extensions/adapters/presenters/web/page.fnl","signature":"function","summary":"Single-node HTML renderer alias exported for focused escaping and element-rendering tests.","tags":["web","page","html","render","tests"]}
{"href":"api.html#fen-extensions-web-page-html-extensions-adapters-presenters-web-page-fnl-238","id":"fen.extensions.web.page.html","kind":"function","line":233,"path":"extensions/adapters/presenters/web/page.fnl","signature":"(html) -> string","summary":"Render the static browser presenter page with embedded CSS and JavaScript for HTTP/SSE interaction.","tags":["web","page","html","browser"]}
{"href":"api.html#fen-extensions-web-server-parse-request-extensions-adapters-presenters-web-server-fnl-73","id":"fen.extensions.web.server.parse-request","kind":"function","line":68,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(parse-request buf) -> Request|nil","summary":"Parse a buffered HTTP request once headers and the declared body length have arrived.","tags":["web","server","http","parse"]}
{"href":"api.html#fen-extensions-web-server-broadcast-bang-extensions-adapters-presenters-web-server-fnl-252","id":"fen.extensions.web.server.broadcast!","kind":"function","line":247,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(broadcast! state ctx) -> nil","summary":"Queue a layout SSE frame to connected clients when the rendered browser snapshot changes.","tags":["web","server","sse","broadcast"]}
{"href":"api.html#fen-extensions-web-server-init-extensions-adapters-presenters-web-server-fnl-260","id":"fen.extensions.web.server.init","kind":"function","line":255,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(init ctx state) -> nil","summary":"Start the nonblocking LuaSocket HTTP server for the web presenter if it is not already listening.","tags":["web","server","lifecycle","socket"]}
{"href":"api.html#fen-extensions-web-server-shutdown-extensions-adapters-presenters-web-server-fnl-276","id":"fen.extensions.web.server.shutdown","kind":"function","line":271,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(shutdown ctx state) -> nil","summary":"Stop the web server, close HTTP and SSE clients, clear queues, and mark the presenter as quitting.","tags":["web","server","lifecycle","socket"]}
{"href":"api.html#fen-extensions-web-server-tick-extensions-adapters-presenters-web-server-fnl-292","id":"fen.extensions.web.server.tick","kind":"function","line":287,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(tick socket state ctx) -> nil","summary":"Service accepts, HTTP requests, pending inputs, cooperative ticks, SSE broadcasts, flushes, and pacing sleep once.","tags":["web","server","loop","sse"]}
{"href":"api.html#fen-extensions-web-server-wait-select-extensions-adapters-presenters-web-server-fnl-315","id":"fen.extensions.web.server.wait-select","kind":"function","line":310,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(wait-select ctx state opts) -> Choice|nil","summary":"Publish an active browser select prompt, service the web loop until a reply arrives, and return the chosen choice.","tags":["web","server","select","ui"]}
{"href":"api.html#fen-extensions-web-server-run-extensions-adapters-presenters-web-server-fnl-339","id":"fen.extensions.web.server.run","kind":"function","line":334,"path":"extensions/adapters/presenters/web/server.fnl","signature":"(run ctx state) -> nil","summary":"Run the web server loop until shutdown sets the persistent quit flag.","tags":["web","server","loop","lifecycle"]}
{"href":"api.html#fen-extensions-web-state-server-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.server","kind":"data","line":4,"path":"extensions/adapters/presenters/web/state.fnl","signature":"server|nil","summary":"Active web server handle, kept outside reloadable modules so the listening socket can survive behavior reloads.","tags":["web","state","server","reload"]}
{"href":"api.html#fen-extensions-web-state-host-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.host","kind":"data","line":10,"path":"extensions/adapters/presenters/web/state.fnl","signature":"string","summary":"Interface address used by the web presenter when binding its HTTP/SSE server.","tags":["web","state","server","config"]}
{"href":"api.html#fen-extensions-web-state-port-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.port","kind":"data","line":16,"path":"extensions/adapters/presenters/web/state.fnl","signature":"number","summary":"TCP port used by the web presenter server and advertised browser URL.","tags":["web","state","server","config"]}
{"href":"api.html#fen-extensions-web-state-clients-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.clients","kind":"data","line":22,"path":"extensions/adapters/presenters/web/state.fnl","signature":"[client]","summary":"Connected web client records tracked by the presenter server for lifecycle and cleanup.","tags":["web","state","clients"]}
{"href":"api.html#fen-extensions-web-state-sse-clients-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.sse-clients","kind":"data","line":28,"path":"extensions/adapters/presenters/web/state.fnl","signature":"[client]","summary":"Active Server-Sent Events client connections receiving transcript/status snapshots.","tags":["web","state","clients","sse"]}
{"href":"api.html#fen-extensions-web-state-pending-inputs-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.pending-inputs","kind":"data","line":34,"path":"extensions/adapters/presenters/web/state.fnl","signature":"[string]","summary":"User inputs submitted by browser clients and queued for the presenter loop to hand to the agent.","tags":["web","state","input","queue"]}
{"href":"api.html#fen-extensions-web-state-quit-q-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.quit?","kind":"data","line":40,"path":"extensions/adapters/presenters/web/state.fnl","signature":"boolean","summary":"Presenter loop shutdown flag set by web controls when the browser requests session termination.","tags":["web","state","lifecycle"]}
{"href":"api.html#fen-extensions-web-state-last-snapshot-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.last-snapshot","kind":"data","line":46,"path":"extensions/adapters/presenters/web/state.fnl","signature":"string","summary":"Last serialized browser snapshot used to avoid redundant SSE broadcasts when visible state has not changed.","tags":["web","state","sse","cache"]}
{"href":"api.html#fen-extensions-web-state-last-broadcast-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.last-broadcast","kind":"data","line":52,"path":"extensions/adapters/presenters/web/state.fnl","signature":"number","summary":"Timestamp/counter of the last web snapshot broadcast used to pace browser updates.","tags":["web","state","sse","cache"]}
{"href":"api.html#fen-extensions-web-state-client-reload-seq-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.client-reload-seq","kind":"data","line":58,"path":"extensions/adapters/presenters/web/state.fnl","signature":"number","summary":"Monotonic sequence bumped to tell browser clients that frontend assets or presenter behavior should reload.","tags":["web","state","reload","clients"]}
{"href":"api.html#fen-extensions-web-state-select-seq-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.select-seq","kind":"data","line":64,"path":"extensions/adapters/presenters/web/state.fnl","signature":"number","summary":"Monotonic id counter for active web select prompts so browser replies can be matched to the current prompt.","tags":["web","state","select","input"]}
{"href":"api.html#fen-extensions-web-state-active-select-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.active-select","kind":"data","line":70,"path":"extensions/adapters/presenters/web/state.fnl","signature":"table|nil","summary":"Currently active browser select prompt, including choices and response bookkeeping for presenter UI APIs.","tags":["web","state","select","input"]}
{"href":"api.html#fen-extensions-web-state-presenter-ctx-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.presenter-ctx","kind":"data","line":76,"path":"extensions/adapters/presenters/web/state.fnl","signature":"table|nil","summary":"Current web presenter runtime context captured for server handlers that need to submit input or request cancellation.","tags":["web","state","presenter"]}
{"href":"api.html#fen-extensions-web-state-transcript-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.transcript","kind":"data","line":82,"path":"extensions/adapters/presenters/web/state.fnl","signature":"[PresenterEvent]","summary":"Persistent web transcript event log used to build browser snapshots after reloads or client reconnects.","tags":["web","state","transcript"]}
{"href":"api.html#fen-extensions-web-state-status-info-extensions-adapters-presenters-web-state-fnl-94","id":"fen.extensions.web.state.status-info","kind":"data","line":88,"path":"extensions/adapters/presenters/web/state.fnl","signature":"table","summary":"Web status metadata for provider/model, context estimates, queues, running tool, thinking, cancellation, and turn timing.","tags":["web","state","status"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-api-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.api","kind":"data","line":580,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"string","summary":"Default anthropic-version header sent with Messages API requests.","tags":["provider","anthropic","metadata"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-provider-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.provider","kind":"data","line":580,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"string","summary":"Default anthropic-version header sent with Messages API requests.","tags":["provider","anthropic","metadata"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-default-base-url-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.default-base-url","kind":"data","line":580,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"string","summary":"Default anthropic-version header sent with Messages API requests.","tags":["provider","anthropic","metadata"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-default-version-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.default-version","kind":"data","line":580,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"string","summary":"Default anthropic-version header sent with Messages API requests.","tags":["provider","anthropic","metadata"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-convert-messages-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.convert-messages","kind":"function","line":98,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(convert-messages messages _system-prompt) -> [WireMessage]","summary":"Convert canonical messages into Anthropic Messages wire shape, batching consecutive tool results into one user message.","tags":["provider","anthropic","messages","convert"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-convert-tools-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.convert-tools","kind":"function","line":136,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(convert-tools tools) -> [WireTool]","summary":"Convert canonical Tool descriptors into Anthropic flat tool specs with input_schema parameters.","tags":["provider","anthropic","tools","convert"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-map-stop-reason-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.map-stop-reason","kind":"function","line":155,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(map-stop-reason reason) -> StopReason, error-message|nil","summary":"Map Anthropic stop_reason values onto canonical StopReason values and explanatory error strings.","tags":["provider","anthropic","stop-reason"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-parse-response-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.parse-response","kind":"function","line":175,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(parse-response resp model) -> AssistantMessage","summary":"Parse a non-streaming Anthropic Messages response into canonical assistant text, thinking, tool calls, usage, and stop reason.","tags":["provider","anthropic","parse"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-process-stream-event-bang-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.process-stream-event!","kind":"function","line":433,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(process-stream-event! state ev emit) -> state","summary":"Fold one decoded Anthropic typed SSE event into stream state, content blocks, usage, and delta callbacks.","tags":["provider","anthropic","streaming"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-new-stream-state-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.new-stream-state","kind":"data","line":580,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"string","summary":"Default anthropic-version header sent with Messages API requests.","tags":["provider","anthropic","metadata"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-finalize-stream-state-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.finalize-stream-state","kind":"function","line":468,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(finalize-stream-state state emit) -> AssistantMessage","summary":"Finalize Anthropic streaming state into a canonical assistant message and emit the terminal done/error event.","tags":["provider","anthropic","streaming"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-finalize-stream-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.finalize-stream","kind":"data","line":580,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"string","summary":"Default anthropic-version header sent with Messages API requests.","tags":["provider","anthropic","metadata"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-build-body-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.build-body","kind":"function","line":242,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(build-body model context max-tokens options) -> table","summary":"Build an Anthropic Messages request body with system prompt/cache markers, tools, parallel-tool policy, and optional thinking budget.","tags":["provider","anthropic","request","cache"]}
{"href":"api.html#fen-extensions-provider-anthropic-anthropic-messages-complete-extensions-adapters-providers-anthropic-anthropic-messages-fnl-600","id":"fen.extensions.provider_anthropic.anthropic_messages.complete","kind":"function","line":531,"path":"extensions/adapters/providers/anthropic/anthropic_messages.fnl","signature":"(complete model context options ?on-event ?yield-fn) -> AssistantMessage","summary":"Execute one Anthropic provider call, choosing streaming/non-streaming and cooperative/blocking transport from callbacks.","tags":["provider","anthropic","complete"]}
{"href":"api.html#fen-extensions-provider-anthropic-register-extensions-adapters-providers-anthropic-init-fnl-15","id":"fen.extensions.provider_anthropic.register","kind":"function","line":15,"path":"extensions/adapters/providers/anthropic/init.fnl"}
{"href":"api.html#fen-extensions-provider-openai-register-extensions-adapters-providers-openai-init-fnl-39","id":"fen.extensions.provider_openai.register","kind":"function","line":39,"path":"extensions/adapters/providers/openai/init.fnl"}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-default-agent-dir-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.default-agent-dir","kind":"function","line":23,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(default-agent-dir) -> string","summary":"Return fen's writable Codex auth directory, honoring FEN_AUTH_DIR before the XDG fen config directory.","tags":["codex","auth","storage","paths"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-default-auth-path-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.default-auth-path","kind":"function","line":34,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(default-auth-path) -> string","summary":"Return the fen-owned auth.json path where Codex login, refresh, and logout persist credentials.","tags":["codex","auth","storage","paths"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-candidate-read-auth-paths-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.candidate-read-auth-paths","kind":"function","line":43,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(candidate-read-auth-paths) -> [string]","summary":"Return credential read paths in priority order. Currently this is only fen's auth.json path.","tags":["codex","auth","storage","paths"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-load-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.load","kind":"function","line":79,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(load ?path) -> table","summary":"Read and decode one auth.json file, returning an empty table for missing, unreadable, or malformed storage.","tags":["codex","auth","storage","json"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-get-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.get","kind":"function","line":99,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(get provider-id ?path) -> table|nil","summary":"Return one provider credential record from the explicit path or fen-owned auth.json.","tags":["codex","auth","storage","lookup"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-save-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.save","kind":"function","line":109,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(save data ?path) -> nil","summary":"Atomically write the full auth.json table, creating the parent directory and tightening file permissions to 0600.","tags":["codex","auth","storage","write"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-keychain-set-extensions-adapters-providers-openai-openai-codex-keychain-fnl-151","id":"fen.extensions.provider_openai.openai_codex_keychain.set","kind":"function","line":138,"path":"extensions/adapters/providers/openai/openai_codex_keychain.fnl","signature":"(set provider-id record ?path) -> table","summary":"Read-modify-write one provider credential record into auth.json and return the persisted auth table.","tags":["codex","auth","storage","write"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-authorize-url-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.AUTHORIZE-URL","kind":"data","line":271,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"string","summary":"Originator value sent in the authorization URL to identify fen's simplified Codex login flow.","tags":["codex","auth","login","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-redirect-uri-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.REDIRECT-URI","kind":"data","line":271,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"string","summary":"Originator value sent in the authorization URL to identify fen's simplified Codex login flow.","tags":["codex","auth","login","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-scope-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.SCOPE","kind":"data","line":271,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"string","summary":"Originator value sent in the authorization URL to identify fen's simplified Codex login flow.","tags":["codex","auth","login","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-originator-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.ORIGINATOR","kind":"data","line":271,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"string","summary":"Originator value sent in the authorization URL to identify fen's simplified Codex login flow.","tags":["codex","auth","login","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-generate-pkce-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.generate-pkce","kind":"function","line":66,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(generate-pkce) -> {:verifier :challenge}","summary":"Generate a fresh PKCE verifier/challenge pair using platform randomness, SHA-256, and base64url encoding.","tags":["codex","auth","login","pkce"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-build-authorize-url-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.build-authorize-url","kind":"function","line":80,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(build-authorize-url pkce state) -> string","summary":"Compose the ChatGPT OAuth authorization URL with PKCE challenge, state, scope, redirect URI, and Codex flow flags.","tags":["codex","auth","login","pkce"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-parse-authorization-input-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.parse-authorization-input","kind":"function","line":123,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(parse-authorization-input input) -> {:code :state}","summary":"Parse pasted Codex authorization input as full callback URL, raw query, code#state shorthand, or bare code.","tags":["codex","auth","login","parse"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-extract-query-param-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.extract-query-param","kind":"function","line":100,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(extract-query-param query key) -> string|nil","summary":"Extract and URL-decode one parameter from an OAuth callback query string.","tags":["codex","auth","login","parse"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-exchange-code-bang-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.exchange-code!","kind":"function","line":152,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(exchange-code! code verifier) -> CredentialRecord","summary":"Exchange an authorization code and PKCE verifier for Codex OAuth credentials, validating required token response fields.","tags":["codex","auth","login","oauth"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-login-bang-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.login!","kind":"function","line":217,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(login! ?path) -> CredentialRecord","summary":"Run the manual PKCE login flow, prompt for the callback code, exchange it, persist credentials, and print account status.","tags":["codex","auth","login","oauth"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-login-logout-bang-extensions-adapters-providers-openai-openai-codex-login-fnl-291","id":"fen.extensions.provider_openai.openai_codex_login.logout!","kind":"function","line":249,"path":"extensions/adapters/providers/openai/openai_codex_login.fnl","signature":"(logout! ?path) -> boolean","summary":"Remove the openai-codex credential record from auth.json and report whether anything was deleted.","tags":["codex","auth","login","oauth"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-provider-id-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.PROVIDER-ID","kind":"data","line":193,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"string","summary":"OAuth client id used by the ChatGPT Codex login and refresh flows.","tags":["codex","auth","oauth","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-token-url-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.TOKEN-URL","kind":"data","line":193,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"string","summary":"OAuth client id used by the ChatGPT Codex login and refresh flows.","tags":["codex","auth","oauth","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-client-id-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.CLIENT-ID","kind":"data","line":193,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"string","summary":"OAuth client id used by the ChatGPT Codex login and refresh flows.","tags":["codex","auth","oauth","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-decode-jwt-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.decode-jwt","kind":"function","line":38,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(decode-jwt token) -> table","summary":"Decode a JWT payload into a Lua table without signature verification for trusted on-disk Codex tokens.","tags":["codex","auth","oauth","jwt"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-extract-account-id-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.extract-account-id","kind":"function","line":53,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(extract-account-id access-token) -> string|nil","summary":"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"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-refresh-bang-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.refresh!","kind":"function","line":94,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(refresh! refresh-token) -> CredentialRecord","summary":"Exchange a refresh token at the OpenAI OAuth token endpoint and return a fresh Codex credential record.","tags":["codex","auth","oauth","refresh"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-expiring-soon-q-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.expiring-soon?","kind":"function","line":135,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(expiring-soon? creds) -> boolean","summary":"Return true when stored Codex credentials are missing expiry or expire within the proactive refresh margin.","tags":["codex","auth","oauth","refresh"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-configured-q-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.configured?","kind":"function","line":162,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(configured? ?path) -> boolean","summary":"Check whether auth.json contains a structurally usable openai-codex OAuth record without refreshing it.","tags":["codex","auth","oauth","status"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-get-fresh-creds-bang-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.get-fresh-creds!","kind":"function","line":176,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(get-fresh-creds! ?path) -> CredentialRecord","summary":"Load Codex credentials, refresh and persist them when near expiry, or raise a friendly login-required error.","tags":["codex","auth","oauth","refresh"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-form-encode-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.form-encode","kind":"function","line":81,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(form-encode params) -> string","summary":"Encode OAuth form parameters as an ampersand-joined application/x-www-form-urlencoded body.","tags":["codex","auth","oauth","form"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-oauth-url-encode-extensions-adapters-providers-openai-openai-codex-oauth-fnl-208","id":"fen.extensions.provider_openai.openai_codex_oauth.url-encode","kind":"function","line":71,"path":"extensions/adapters/providers/openai/openai_codex_oauth.fnl","signature":"(url-encode s) -> string","summary":"Percent-encode one OAuth form component using the unreserved character set required by application/x-www-form-urlencoded.","tags":["codex","auth","oauth","form"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-api-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.api","kind":"data","line":157,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"string","summary":"Default ChatGPT backend API root used by the Codex Responses adapter before appending /codex/responses.","tags":["codex","provider","responses","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-provider-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.provider","kind":"data","line":157,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"string","summary":"Default ChatGPT backend API root used by the Codex Responses adapter before appending /codex/responses.","tags":["codex","provider","responses","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-default-base-url-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.default-base-url","kind":"data","line":157,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"string","summary":"Default ChatGPT backend API root used by the Codex Responses adapter before appending /codex/responses.","tags":["codex","provider","responses","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-build-url-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.build-url","kind":"function","line":30,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"(build-url base-url) -> string","summary":"Normalize a ChatGPT backend base URL into the Codex Responses endpoint while preserving fully-qualified Codex URLs.","tags":["codex","provider","responses","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-map-codex-event-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.map-codex-event","kind":"function","line":64,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"(map-codex-event ev) -> table","summary":"Normalize Codex response.done and response.incomplete SSE aliases into the shared Responses reducer's response.completed event.","tags":["codex","provider","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-build-headers-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.build-headers","kind":"function","line":50,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"(build-headers creds) -> table","summary":"Build ChatGPT Codex streaming request headers from OAuth credentials, including account id, beta flag, and user agent.","tags":["codex","provider","responses","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-merge-options-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.merge-options","kind":"function","line":87,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"(merge-options opts) -> table","summary":"Copy provider options and add Codex defaults for encrypted reasoning includes and skipping unsupported max_output_tokens.","tags":["codex","provider","responses","options"]}
{"href":"api.html#fen-extensions-provider-openai-openai-codex-responses-complete-extensions-adapters-providers-openai-openai-codex-responses-fnl-172","id":"fen.extensions.provider_openai.openai_codex_responses.complete","kind":"function","line":110,"path":"extensions/adapters/providers/openai/openai_codex_responses.fnl","signature":"(complete model context options ?on-event ?yield-fn) -> AssistantMessage","summary":"Execute one ChatGPT Codex Responses call through the shared streaming pipeline with OAuth credentials and Codex event mapping.","tags":["codex","provider","responses","complete"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-api-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.api","kind":"data","line":667,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"string","summary":"Default OpenAI v1 API root used when models.json or provider options do not override the base URL.","tags":["provider","openai","completions","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-provider-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.provider","kind":"data","line":667,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"string","summary":"Default OpenAI v1 API root used when models.json or provider options do not override the base URL.","tags":["provider","openai","completions","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-default-base-url-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.default-base-url","kind":"data","line":667,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"string","summary":"Default OpenAI v1 API root used when models.json or provider options do not override the base URL.","tags":["provider","openai","completions","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-build-url-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.build-url","kind":"function","line":36,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(build-url base-url) -> string","summary":"Normalize an OpenAI-compatible base URL into a Chat Completions endpoint while preserving fully-qualified legacy endpoints.","tags":["provider","openai","completions","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-convert-messages-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.convert-messages","kind":"function","line":149,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(convert-messages messages system-prompt compat) -> [WireMessage]","summary":"Convert canonical messages and optional system prompt into OpenAI Chat Completions wire messages, synthesizing errors for orphaned tool calls.","tags":["provider","openai","completions","messages"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-convert-tools-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.convert-tools","kind":"function","line":176,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(convert-tools tools) -> [WireTool]","summary":"Convert canonical Tool descriptors into OpenAI Chat Completions function-tool declarations.","tags":["provider","openai","completions","tools"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-map-stop-reason-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.map-stop-reason","kind":"function","line":196,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(map-stop-reason reason) -> StopReason, error-message|nil","summary":"Map OpenAI finish_reason values onto canonical StopReason values, returning error text for provider-side stops.","tags":["provider","openai","completions","stop-reason"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-parse-response-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.parse-response","kind":"function","line":243,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(parse-response resp model) -> AssistantMessage","summary":"Parse a non-streaming OpenAI Chat Completions response into canonical assistant content, usage, tool calls, and stop reason.","tags":["provider","openai","completions","parse"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-process-stream-chunk-bang-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.process-stream-chunk!","kind":"function","line":490,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(process-stream-chunk! state chunk emit) -> state","summary":"Fold one decoded streaming ChatCompletionChunk into stream state and emit text, thinking, and tool-call deltas.","tags":["provider","openai","completions","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-new-stream-state-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.new-stream-state","kind":"data","line":667,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"string","summary":"Default OpenAI v1 API root used when models.json or provider options do not override the base URL.","tags":["provider","openai","completions","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-finalize-stream-state-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.finalize-stream-state","kind":"function","line":548,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(finalize-stream-state state emit) -> AssistantMessage","summary":"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"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-finalize-stream-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.finalize-stream","kind":"data","line":667,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"string","summary":"Default OpenAI v1 API root used when models.json or provider options do not override the base URL.","tags":["provider","openai","completions","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-build-body-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.build-body","kind":"function","line":318,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(build-body model context max-tokens compat options) -> table","summary":"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"]}
{"href":"api.html#fen-extensions-provider-openai-openai-completions-complete-extensions-adapters-providers-openai-openai-completions-fnl-682","id":"fen.extensions.provider_openai.openai_completions.complete","kind":"function","line":619,"path":"extensions/adapters/providers/openai/openai_completions.fnl","signature":"(complete model context options ?on-event ?yield-fn) -> AssistantMessage","summary":"Execute one Chat Completions provider call, choosing streaming/non-streaming and cooperative/blocking transport from callbacks.","tags":["provider","openai","completions","complete"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-api-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.api","kind":"data","line":209,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"string","summary":"Default OpenAI v1 API root used by the Responses adapter before appending /responses.","tags":["provider","openai","responses","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-provider-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.provider","kind":"data","line":209,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"string","summary":"Default OpenAI v1 API root used by the Responses adapter before appending /responses.","tags":["provider","openai","responses","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-default-base-url-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.default-base-url","kind":"data","line":209,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"string","summary":"Default OpenAI v1 API root used by the Responses adapter before appending /responses.","tags":["provider","openai","responses","metadata"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-build-url-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.build-url","kind":"function","line":45,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"(build-url base-url) -> string","summary":"Normalize an OpenAI base URL into the /responses endpoint while preserving already-qualified Responses URLs.","tags":["provider","openai","responses","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-build-body-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.build-body","kind":"function","line":53,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"(build-body model context max-tokens options) -> table","summary":"Build a streaming Responses request body from canonical context, provider options, tools, reasoning settings, and prompt cache keys.","tags":["provider","openai","responses","request"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-build-request-opts-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.build-request-opts","kind":"function","line":134,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"(build-request-opts model context options on-chunk ?headers-override ?url-override) -> table","summary":"Assemble fen.util.http options for a streaming Responses POST, allowing Codex to override auth headers and endpoint URL.","tags":["provider","openai","responses","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-make-stream-pipeline-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.make-stream-pipeline","kind":"function","line":107,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"(make-stream-pipeline model on-event event-mapper) -> state, parser, parser-error","summary":"Create the SSE parser and shared Responses stream reducer state for one streaming request, with optional Codex event mapping.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-finalize-stream-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.finalize-stream","kind":"function","line":161,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"(finalize-stream state parser parser-error model resp on-event) -> AssistantMessage","summary":"Finish the SSE parser, convert transport/parser/HTTP failures to assistant errors, or finalize shared Responses stream state.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-complete-extensions-adapters-providers-openai-openai-responses-fnl-224","id":"fen.extensions.provider_openai.openai_responses.complete","kind":"function","line":172,"path":"extensions/adapters/providers/openai/openai_responses.fnl","signature":"(complete model context options ?on-event ?yield-fn) -> AssistantMessage","summary":"Execute one OpenAI Responses provider call through the streaming SSE pipeline with optional cooperative transport and event forwarding.","tags":["provider","openai","responses","complete"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-build-url-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.build-url","kind":"function","line":960,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(build-url base-url responses-path) -> string","summary":"Normalize an OpenAI-compatible base URL into a Responses endpoint while preserving already-qualified URLs.","tags":["provider","openai","responses","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-build-body-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.build-body","kind":"function","line":970,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(build-body model context max-tokens options ?id) -> table","summary":"Build a streaming Responses request body from canonical context, provider options, tools, reasoning settings, and prompt cache keys.","tags":["provider","openai","responses","request"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-build-request-opts-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.build-request-opts","kind":"function","line":1052,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(build-request-opts model context options on-chunk ?headers-override ?url-override default-base-url responses-path ?id) -> table","summary":"Assemble fen.util.http options for a streaming OpenAI-compatible Responses POST.","tags":["provider","openai","responses","http"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-make-stream-pipeline-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.make-stream-pipeline","kind":"function","line":1021,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(make-stream-pipeline model on-event event-mapper) -> state, parser, parser-error","summary":"Create the SSE parser and shared Responses stream reducer state for one streaming request, with optional event mapping.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-finalize-stream-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.finalize-stream","kind":"function","line":1077,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(finalize-stream state parser parser-error api provider model resp on-event) -> AssistantMessage","summary":"Finish a Responses SSE stream, preserving the calling provider's canonical API/provider identity.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-convert-messages-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.convert-messages","kind":"function","line":395,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(convert-messages messages ?id) -> [ResponseInputItem]","summary":"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"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-convert-tools-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.convert-tools","kind":"function","line":487,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(convert-tools tools) -> [ResponseTool]","summary":"Convert canonical Tool descriptors into Responses function-tool declarations with strict set to JSON null.","tags":["provider","openai","responses","tools"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-map-stop-reason-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.map-stop-reason","kind":"function","line":509,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(map-stop-reason status) -> StopReason, error-message|nil","summary":"Map Responses API response statuses onto canonical StopReason values and provider error messages.","tags":["provider","openai","responses","stop-reason"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-new-stream-state-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.new-stream-state","kind":"function","line":552,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(new-stream-state model) -> table","summary":"Initialize the mutable reducer state used while folding Responses SSE events into canonical assistant content.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-process-event-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.process-event!","kind":"function","line":860,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(process-event! state event emit) -> nil","summary":"Dispatch one decoded Responses SSE event into reducer state, updating content, usage, errors, and delta callbacks.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-finalize-stream-state-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.finalize-stream-state","kind":"function","line":926,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(finalize-stream-state state api provider emit) -> AssistantMessage","summary":"Finalize Responses reducer state into a canonical assistant message and emit the terminal done/error event.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-finish-current-block-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.finish-current-block!","kind":"function","line":578,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(finish-current-block! state emit) -> nil","summary":"Close the active text/thinking/tool-call block, emit the matching end event, and clear current item pointers.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-write-failure-diagnostic-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.write-failure-diagnostic!","kind":"function","line":1154,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl"}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-failure-diagnostic-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.failure-diagnostic","kind":"function","line":1154,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl"}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-attach-diagnostic-bang-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.attach-diagnostic!","kind":"function","line":1154,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl"}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-redact-headers-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.redact-headers","kind":"function","line":1154,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl"}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-summarize-body-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.summarize-body","kind":"function","line":1154,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl"}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-clamp-reasoning-effort-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.clamp-reasoning-effort","kind":"function","line":1134,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(clamp-reasoning-effort model effort) -> keyword","summary":"Apply Codex/OpenAI per-model reasoning-effort limits so request bodies avoid unsupported effort values.","tags":["provider","openai","codex","reasoning"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-split-compound-id-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.split-compound-id","kind":"function","line":285,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(split-compound-id id) -> call-id, item-id|nil","summary":"Split Fen's compound Responses tool-call id into call_id and item_id components for wire conversion.","tags":["provider","openai","responses","tools"]}
{"href":"api.html#fen-extensions-provider-openai-openai-responses-shared-parse-streaming-json-extensions-adapters-providers-openai-openai-responses-shared-fnl-1154","id":"fen.extensions.provider_openai.openai_responses_shared.parse-streaming-json","kind":"function","line":539,"path":"extensions/adapters/providers/openai/openai_responses_shared.fnl","signature":"(parse-streaming-json s) -> table","summary":"Best-effort JSON parser for in-flight streamed tool arguments, returning an empty table until complete JSON is available.","tags":["provider","openai","responses","streaming"]}
{"href":"api.html#fen-extensions-session-jsonl-register-extensions-adapters-session-backends-jsonl-init-fnl-7","id":"fen.extensions.session_jsonl.register","kind":"function","line":7,"path":"extensions/adapters/session-backends/jsonl/init.fnl"}
{"href":"api.html#fen-extensions-session-jsonl-session-open-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.open","kind":"function","line":196,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(open cwd) -> Session","summary":"Allocate a future append-only JSONL session path for cwd without creating the file until the first appended message.","tags":["session","jsonl","open"]}
{"href":"api.html#fen-extensions-session-jsonl-session-open-existing-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.open-existing","kind":"function","line":461,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(open-existing p) -> Session|nil","summary":"Open an existing session JSONL for append without writing a duplicate header, preserving header id and cwd.","tags":["session","jsonl","resume"]}
{"href":"api.html#fen-extensions-session-jsonl-session-append-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.append","kind":"function","line":262,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(append session msg) -> nil","summary":"Lazily open the session file if needed and append one canonical AgentMessage as a JSONL :message entry.","tags":["session","jsonl","append"]}
{"href":"api.html#fen-extensions-session-jsonl-session-append-entry-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.append-entry","kind":"function","line":236,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(append-entry session entry) -> entry|nil","summary":"Lazily open the session file and append one JSONL entry with stable id, parent-id, and timestamp metadata.","tags":["session","jsonl","append","entries","ids"]}
{"href":"api.html#fen-extensions-session-jsonl-session-close-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.close","kind":"function","line":283,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(close session) -> nil","summary":"Close an open session file handle and clear it from the mutable session record.","tags":["session","jsonl","close"]}
{"href":"api.html#fen-extensions-session-jsonl-session-latest-for-cwd-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.latest-for-cwd","kind":"function","line":374,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(latest-for-cwd cwd) -> string|nil","summary":"Return the newest non-empty session JSONL path for cwd by scanning the cwd session directory newest first.","tags":["session","jsonl","discovery"]}
{"href":"api.html#fen-extensions-session-jsonl-session-list-for-cwd-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.list-for-cwd","kind":"function","line":444,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(list-for-cwd cwd limit) -> [SessionInfo]","summary":"Return recent non-empty session metadata records for cwd in reverse chronological order, capped by limit.","tags":["session","jsonl","discovery"]}
{"href":"api.html#fen-extensions-session-jsonl-session-header-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.header","kind":"function","line":391,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(header p) -> table|nil","summary":"Read and decode the first JSONL header entry from a session file, returning nil for unreadable or non-session headers.","tags":["session","jsonl","inspect"]}
{"href":"api.html#fen-extensions-session-jsonl-session-title-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.title","kind":"function","line":416,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(title p) -> string|nil","summary":"Return a human-readable transcript title from the first user text, falling back to the first assistant text.","tags":["session","jsonl","inspect"]}
{"href":"api.html#fen-extensions-session-jsonl-session-message-count-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.message-count","kind":"function","line":366,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(message-count p) -> number","summary":"Count valid :message entries in a session JSONL file while skipping the header and malformed lines.","tags":["session","jsonl","inspect"]}
{"href":"api.html#fen-extensions-session-jsonl-session-find-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.find","kind":"function","line":474,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(find cwd target) -> string|nil","summary":"Resolve a resume target as latest, list index, existing path, exact id, or unique id/path prefix within cwd sessions.","tags":["session","jsonl","resume"]}
{"href":"api.html#fen-extensions-session-jsonl-session-load-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.load","kind":"function","line":537,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(load path) -> [Message]","summary":"Read a session JSONL file and return replayable canonical messages, applying the latest valid compaction entry when present.","tags":["session","jsonl","replay","compaction"]}
{"href":"api.html#fen-extensions-session-jsonl-session-sessions-root-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.sessions-root","kind":"function","line":50,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(sessions-root cwd) -> string","summary":"Return the state-directory path containing JSONL sessions for a specific cwd.","tags":["session","jsonl","paths"]}
{"href":"api.html#fen-extensions-session-jsonl-session-cwd-slug-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.cwd-slug","kind":"function","line":37,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"(cwd-slug cwd) -> string","summary":"Convert a cwd into the pi-mono-style session directory slug used under the fen sessions root.","tags":["session","jsonl","paths"]}
{"href":"api.html#fen-extensions-session-jsonl-session-version-extensions-adapters-session-backends-jsonl-session-fnl-567","id":"fen.extensions.session_jsonl.session.VERSION","kind":"data","line":562,"path":"extensions/adapters/session-backends/jsonl/session.fnl","signature":"number","summary":"Current JSONL session format version written into new session headers.","tags":["session","jsonl","metadata"]}
{"href":"api.html#fen-extensions-session-jsonl-state-record-cache-extensions-adapters-session-backends-jsonl-state-fnl-7","id":"fen.extensions.session_jsonl.state.record-cache","kind":"function","line":7,"path":"extensions/adapters/session-backends/jsonl/state.fnl"}
{"href":"api.html#fen-extensions-sessions-commands-session-register-extensions-behaviors-actions-sessions-commands-session-fnl-317","id":"fen.extensions.sessions.commands.session.register","kind":"function","line":312,"path":"extensions/behaviors/actions/sessions/commands/session.fnl","signature":"(register api) -> nil","summary":"Register conversation/session lifecycle commands including /new, /reload, /sessions, and /resume aliases.","tags":["commands","session","register"]}
{"href":"api.html#fen-extensions-sessions-register-extensions-behaviors-actions-sessions-init-fnl-7","id":"fen.extensions.sessions.register","kind":"function","line":7,"path":"extensions/behaviors/actions/sessions/init.fnl"}
{"href":"api.html#fen-extensions-agent-state-register-extensions-behaviors-companions-agent-state-init-fnl-12","id":"fen.extensions.agent_state.register","kind":"function","line":12,"path":"extensions/behaviors/companions/agent-state/init.fnl"}
{"href":"api.html#fen-extensions-agent-state-tool-execute-extensions-behaviors-companions-agent-state-tool-fnl-558","id":"fen.extensions.agent_state.tool.execute","kind":"function","line":531,"path":"extensions/behaviors/companions/agent-state/tool.fnl","signature":"(execute args ctx ?api ?yield-fn) -> AgentToolResult","summary":"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"]}
{"href":"api.html#fen-extensions-agent-state-tool-parse-query-extensions-behaviors-companions-agent-state-tool-fnl-558","id":"fen.extensions.agent_state.tool.parse-query","kind":"function","line":146,"path":"extensions/behaviors/companions/agent-state/tool.fnl","signature":"(parse-query s) -> expr|nil, err|nil","summary":"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"]}
{"href":"api.html#fen-extensions-agent-state-tool-eval-query-extensions-behaviors-companions-agent-state-tool-fnl-558","id":"fen.extensions.agent_state.tool.eval-query","kind":"function","line":503,"path":"extensions/behaviors/companions/agent-state/tool.fnl","signature":"(eval-query expr state) -> any","summary":"Evaluate the parsed agent_state query operators against the sanitized snapshot without exposing general code execution.","tags":["tool","agent-state","query","eval"]}
{"href":"api.html#fen-extensions-agent-state-tool-sanitized-state-extensions-behaviors-companions-agent-state-tool-fnl-558","id":"fen.extensions.agent_state.tool.sanitized-state","kind":"function","line":389,"path":"extensions/behaviors/companions/agent-state/tool.fnl","signature":"(sanitized-state agent api ?ctx) -> table","summary":"Build the redacted agent-state snapshot exposed to the agent_state tool without leaking raw mutable agent internals.","tags":["tool","agent-state","introspection"]}
{"href":"api.html#fen-extensions-compact-register-extensions-behaviors-companions-compact-init-fnl-242","id":"fen.extensions.compact.register","kind":"function","line":242,"path":"extensions/behaviors/companions/compact/init.fnl"}
{"href":"api.html#fen-extensions-compact-register-bang-extensions-behaviors-companions-compact-init-fnl-242","id":"fen.extensions.compact.register!","kind":"function","line":242,"path":"extensions/behaviors/companions/compact/init.fnl"}
{"href":"api.html#fen-extensions-compact-test-extensions-behaviors-companions-compact-init-fnl-242","id":"fen.extensions.compact._test","kind":"function","line":242,"path":"extensions/behaviors/companions/compact/init.fnl"}
{"href":"api.html#fen-extensions-handoff-register-extensions-behaviors-companions-handoff-init-fnl-153","id":"fen.extensions.handoff.register","kind":"function","line":153,"path":"extensions/behaviors/companions/handoff/init.fnl"}
{"href":"api.html#fen-extensions-handoff-register-bang-extensions-behaviors-companions-handoff-init-fnl-153","id":"fen.extensions.handoff.register!","kind":"function","line":135,"path":"extensions/behaviors/companions/handoff/init.fnl","signature":"(register!) -> true","summary":"Register the /handoff command that summarizes the current session and seeds a fresh session with the result.","tags":["handoff","command","session"]}
{"href":"api.html#fen-extensions-mem-report-rows-extensions-behaviors-companions-mem-init-fnl-135","id":"fen.extensions.mem.report-rows","kind":"function","line":130,"path":"extensions/behaviors/companions/mem/init.fnl","signature":"(report-rows run-state opts?) -> [PresenterRow]","summary":"Build memory diagnostics rows for the /mem panel, including optional GC before/after output, app state, registries, and history.","tags":["mem","panel","diagnostics","rows"]}
{"href":"api.html#fen-extensions-mem-panel-spec-extensions-behaviors-companions-mem-init-fnl-203","id":"fen.extensions.mem.panel-spec","kind":"function","line":198,"path":"extensions/behaviors/companions/mem/init.fnl","signature":"(panel-spec) -> PanelSpec","summary":"Return the /mem panel contribution that sizes and renders the cached memory diagnostics above the input.","tags":["mem","panel","register"]}
{"href":"api.html#fen-extensions-mem-register-extensions-behaviors-companions-mem-init-fnl-297","id":"fen.extensions.mem.register","kind":"data","line":292,"path":"extensions/behaviors/companions/mem/init.fnl","signature":"function","summary":"Registration entrypoint alias for installing the /mem command, panel, sampling hook, and dismiss handler.","tags":["mem","register","command","panel"]}
{"href":"api.html#fen-extensions-mem-register-bang-extensions-behaviors-companions-mem-init-fnl-298","id":"fen.extensions.mem.register!","kind":"data","line":292,"path":"extensions/behaviors/companions/mem/init.fnl","signature":"function","summary":"Registration entrypoint alias for installing the /mem command, panel, sampling hook, and dismiss handler.","tags":["mem","register","command","panel"]}
{"href":"api.html#fen-extensions-mem-state-extensions-behaviors-companions-mem-init-fnl-305","id":"fen.extensions.mem._state","kind":"data","line":300,"path":"extensions/behaviors/companions/mem/init.fnl","signature":"table","summary":"Test and diagnostics alias for the persistent memory diagnostics state table.","tags":["mem","state","tests"]}
{"href":"api.html#fen-extensions-mem-state-samples-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.samples","kind":"data","line":3,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"[number]","summary":"Rolling Lua heap samples used by the memory diagnostics panel to render its history sparkline.","tags":["mem","state","samples","panel"]}
{"href":"api.html#fen-extensions-mem-state-max-samples-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.max-samples","kind":"data","line":9,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"number","summary":"Maximum number of memory samples retained for the diagnostics panel history window.","tags":["mem","state","samples","config"]}
{"href":"api.html#fen-extensions-mem-state-peak-kb-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.peak-kb","kind":"data","line":15,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"number","summary":"Largest observed Lua heap size in kilobytes, used for peak reporting and sparkline scaling.","tags":["mem","state","samples","peak"]}
{"href":"api.html#fen-extensions-mem-state-visible-q-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.visible?","kind":"data","line":21,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"boolean","summary":"Visibility flag for the persistent memory diagnostics panel toggled by the /mem command.","tags":["mem","state","panel"]}
{"href":"api.html#fen-extensions-mem-state-run-state-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.run-state","kind":"data","line":27,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"table|nil","summary":"Last presenter run-state snapshot used by the memory panel to display agent and session details.","tags":["mem","state","runtime","panel"]}
{"href":"api.html#fen-extensions-mem-state-cached-rows-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.cached-rows","kind":"data","line":33,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"[PresenterRow]|nil","summary":"Cached rendered memory panel rows reused between paints to avoid noisy heap recomputation.","tags":["mem","state","cache","panel"]}
{"href":"api.html#fen-extensions-mem-state-cached-at-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.cached-at","kind":"data","line":39,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"number","summary":"Timestamp for the memory panel cache, supporting its one-hertz refresh throttle.","tags":["mem","state","cache","panel"]}
{"href":"api.html#fen-extensions-mem-state-cached-w-extensions-behaviors-companions-mem-state-fnl-51","id":"fen.extensions.mem.state.cached-w","kind":"data","line":45,"path":"extensions/behaviors/companions/mem/state.fnl","signature":"number","summary":"Terminal width associated with cached memory rows so resize events rebuild the bordered panel.","tags":["mem","state","cache","panel"]}
{"href":"api.html#fen-extensions-skills-bundled-skills-extensions-behaviors-companions-skills-bundled-fnl-64","id":"fen.extensions.skills.bundled.skills","kind":"function","line":64,"path":"extensions/behaviors/companions/skills/bundled.fnl"}
{"href":"api.html#fen-extensions-skills-ignore-with-dir-extensions-behaviors-companions-skills-ignore-fnl-80","id":"fen.extensions.skills.ignore.with-dir","kind":"function","line":75,"path":"extensions/behaviors/companions/skills/ignore.fnl","signature":"(with-dir rules dir) -> [IgnoreRule]","summary":"Return a copied ignore-rule chain extended with .gitignore, .ignore, and .fdignore files from one directory.","tags":["skills","ignore","rules","discovery"]}
{"href":"api.html#fen-extensions-skills-ignore-load-chain-extensions-behaviors-companions-skills-ignore-fnl-91","id":"fen.extensions.skills.ignore.load-chain","kind":"function","line":86,"path":"extensions/behaviors/companions/skills/ignore.fnl","signature":"(load-chain root) -> [IgnoreRule]","summary":"Collect ignore rules from ancestor directories root-to-leaf for skill discovery traversal.","tags":["skills","ignore","rules","discovery"]}
{"href":"api.html#fen-extensions-skills-ignore-match-q-extensions-behaviors-companions-skills-ignore-fnl-156","id":"fen.extensions.skills.ignore.match?","kind":"function","line":151,"path":"extensions/behaviors/companions/skills/ignore.fnl","signature":"(match? target is-dir? rules) -> boolean","summary":"Decide whether a path is ignored by the rule chain, with later negated or matching rules taking precedence.","tags":["skills","ignore","rules","match"]}
{"href":"api.html#fen-extensions-skills-dir-exists-q-extensions-behaviors-companions-skills-init-fnl-60","id":"fen.extensions.skills.dir-exists?","kind":"data","line":55,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Filesystem helper alias used by tests to stub directory existence during skill discovery.","tags":["skills","paths","tests"]}
{"href":"api.html#fen-extensions-skills-file-exists-q-extensions-behaviors-companions-skills-init-fnl-67","id":"fen.extensions.skills.file-exists?","kind":"data","line":62,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Filesystem helper alias used by tests to stub skill file existence checks.","tags":["skills","paths","tests"]}
{"href":"api.html#fen-extensions-skills-realpath-extensions-behaviors-companions-skills-init-fnl-74","id":"fen.extensions.skills.realpath","kind":"data","line":69,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Filesystem helper alias used to canonicalize skill paths for deduplication and tests.","tags":["skills","paths","tests"]}
{"href":"api.html#fen-extensions-skills-parse-frontmatter-extensions-behaviors-companions-skills-init-fnl-218","id":"fen.extensions.skills.parse-frontmatter","kind":"function","line":213,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"(parse-frontmatter path) -> SkillMeta|nil","summary":"Parse a skill file's YAML frontmatter into invokable metadata using the path-derived fallback name.","tags":["skills","discovery","frontmatter"]}
{"href":"api.html#fen-extensions-skills-discover-extensions-behaviors-companions-skills-init-fnl-346","id":"fen.extensions.skills.discover","kind":"function","line":341,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"(discover extra-paths?) -> [Skill]","summary":"Scan default and explicit skill roots, respecting ignore files and deduplicating by canonical path and name.","tags":["skills","discovery","roots"]}
{"href":"api.html#fen-extensions-skills-system-prompt-section-extensions-behaviors-companions-skills-init-fnl-366","id":"fen.extensions.skills.system-prompt-section","kind":"function","line":361,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"(system-prompt-section skills) -> string|nil","summary":"Render discovered model-invokable skills as the XML prompt fragment consumed by the default prompt.","tags":["skills","prompt","xml"]}
{"href":"api.html#fen-extensions-skills-user-skills-dir-extensions-behaviors-companions-skills-init-fnl-394","id":"fen.extensions.skills.user-skills-dir","kind":"function","line":389,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"(user-skills-dir) -> string","summary":"Return fen's user-level skills directory under the XDG configuration root.","tags":["skills","paths","user"]}
{"href":"api.html#fen-extensions-skills-project-skills-dir-extensions-behaviors-companions-skills-init-fnl-401","id":"fen.extensions.skills.project-skills-dir","kind":"function","line":396,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"(project-skills-dir) -> string","summary":"Return fen's project-local skills directory path relative to the current workspace.","tags":["skills","paths","project"]}
{"href":"api.html#fen-extensions-skills-bundled-skills-dir-extensions-behaviors-companions-skills-init-fnl-407","id":"fen.extensions.skills.bundled-skills-dir","kind":"function","line":402,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"(bundled-skills-dir) -> string","summary":"Return the XDG data directory where fen materializes built-in skills.","tags":["skills","paths","builtin"]}
{"href":"api.html#fen-extensions-skills-discover-from-roots-extensions-behaviors-companions-skills-init-fnl-413","id":"fen.extensions.skills._discover-from-roots","kind":"data","line":408,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Test helper alias for scanning an explicit root list without loading default skill roots.","tags":["skills","discovery","tests"]}
{"href":"api.html#fen-extensions-skills-default-roots-extensions-behaviors-companions-skills-init-fnl-420","id":"fen.extensions.skills._default-roots","kind":"data","line":415,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Test helper alias returning the ordered default user, project, and compatibility skill roots.","tags":["skills","discovery","tests","roots"]}
{"href":"api.html#fen-extensions-skills-ancestors-extensions-behaviors-companions-skills-init-fnl-427","id":"fen.extensions.skills._ancestors","kind":"data","line":422,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Test helper alias for the project-ancestor walker used when building default skill roots.","tags":["skills","discovery","tests","paths"]}
{"href":"api.html#fen-extensions-skills-skills-text-extensions-behaviors-companions-skills-init-fnl-476","id":"fen.extensions.skills.skills-text","kind":"function","line":476,"path":"extensions/behaviors/companions/skills/init.fnl"}
{"href":"api.html#fen-extensions-skills-skill-detail-lines-extensions-behaviors-companions-skills-init-fnl-536","id":"fen.extensions.skills.skill-detail-lines","kind":"function","line":536,"path":"extensions/behaviors/companions/skills/init.fnl"}
{"href":"api.html#fen-extensions-skills-register-extensions-behaviors-companions-skills-init-fnl-761","id":"fen.extensions.skills.register","kind":"data","line":756,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Registration entrypoint alias for installing the available-skills prompt fragment.","tags":["skills","register","prompt"]}
{"href":"api.html#fen-extensions-skills-register-bang-extensions-behaviors-companions-skills-init-fnl-762","id":"fen.extensions.skills.register!","kind":"data","line":756,"path":"extensions/behaviors/companions/skills/init.fnl","signature":"function","summary":"Registration entrypoint alias for installing the available-skills prompt fragment.","tags":["skills","register","prompt"]}
{"href":"api.html#fen-extensions-skills-state-visible-q-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.visible?","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-selected-name-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.selected-name","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-cached-rows-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.cached-rows","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-cached-at-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.cached-at","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-cached-w-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.cached-w","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-cached-selected-name-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.cached-selected-name","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-discover-cache-key-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.discover-cache-key","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-discover-cache-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.discover-cache","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-skills-state-discover-cache-at-extensions-behaviors-companions-skills-state-fnl-3","id":"fen.extensions.skills.state.discover-cache-at","kind":"function","line":3,"path":"extensions/behaviors/companions/skills/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-items-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.items","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-version-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.version","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-visible-q-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.visible?","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-cached-rows-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.cached-rows","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-cached-w-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.cached-w","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-cached-version-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.cached-version","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-todo-state-last-updated-extensions-behaviors-companions-todo-state-fnl-3","id":"fen.extensions.todo.state.last-updated","kind":"function","line":3,"path":"extensions/behaviors/companions/todo/state.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-commands-extension-register-extensions-behaviors-inspectors-extensions-commands-extension-fnl-463","id":"fen.extensions.extensions_inspector.commands.extension.register","kind":"function","line":458,"path":"extensions/behaviors/inspectors/extensions/commands/extension.fnl","signature":"(register api) -> nil","summary":"Register extension management commands plus the extension picker/detail panel and dismiss handler.","tags":["commands","extensions","register"]}
{"href":"api.html#fen-extensions-extensions-inspector-register-extensions-behaviors-inspectors-extensions-init-fnl-7","id":"fen.extensions.extensions_inspector.register","kind":"function","line":7,"path":"extensions/behaviors/inspectors/extensions/init.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-visible-q-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.visible?","kind":"data","line":3,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl","signature":"boolean","summary":"Visibility flag for the persistent /extensions panel, kept across hot reloads until dismissed or toggled.","tags":["builtin","commands","state","extensions","panel"]}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-view-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.view","kind":"function","line":39,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-extensions-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.extensions","kind":"function","line":39,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-selected-name-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.selected-name","kind":"data","line":9,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl","signature":"string|nil","summary":"Currently selected extension name used by the /extensions panel to keep focus stable while rows refresh.","tags":["builtin","commands","state","extensions","selection"]}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-registry-kind-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.registry-kind","kind":"function","line":39,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-cached-rows-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.cached-rows","kind":"data","line":15,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl","signature":"[PresenterRow]|nil","summary":"Cached rendered /extensions panel rows reused between paints when width and selection have not changed.","tags":["builtin","commands","state","extensions","cache"]}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-cached-at-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.cached-at","kind":"data","line":21,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl","signature":"number","summary":"Timestamp for the /extensions panel row cache, allowing throttled refreshes of registry-derived content.","tags":["builtin","commands","state","extensions","cache"]}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-cached-w-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.cached-w","kind":"data","line":27,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl","signature":"number","summary":"Terminal width associated with cached /extensions rows so resizes invalidate wrapped panel content.","tags":["builtin","commands","state","extensions","cache"]}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-cached-selected-name-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.cached-selected-name","kind":"data","line":33,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl","signature":"string|nil","summary":"Extension selection value associated with cached rows so focus changes trigger a panel rerender.","tags":["builtin","commands","state","extensions","cache","selection"]}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-cached-view-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.cached-view","kind":"function","line":39,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-state-extensions-cached-registry-kind-extensions-behaviors-inspectors-extensions-state-extensions-fnl-39","id":"fen.extensions.extensions_inspector.state.extensions.cached-registry-kind","kind":"function","line":39,"path":"extensions/behaviors/inspectors/extensions/state/extensions.fnl"}
{"href":"api.html#fen-extensions-extensions-inspector-util-approx-tokens-extensions-behaviors-inspectors-extensions-util-fnl-12","id":"fen.extensions.extensions_inspector.util.approx-tokens","kind":"function","line":7,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(approx-tokens s) -> number","summary":"Estimate token count from text length for status displays when provider-reported usage is unavailable.","tags":["commands","tokens","status"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-safe-json-extensions-behaviors-inspectors-extensions-util-fnl-24","id":"fen.extensions.extensions_inspector.util.safe-json","kind":"function","line":19,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(safe-json v) -> string","summary":"JSON-encode a value for token estimation, falling back to tostring when encoding fails.","tags":["commands","json","tokens"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-content-tokens-extensions-behaviors-inspectors-extensions-util-fnl-33","id":"fen.extensions.extensions_inspector.util.content-tokens","kind":"function","line":28,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(content-tokens content) -> number","summary":"Estimate tokens for canonical message content, including text, thinking blocks, and tool-call names/arguments.","tags":["commands","tokens","messages"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-estimated-context-tokens-extensions-behaviors-inspectors-extensions-util-fnl-56","id":"fen.extensions.extensions_inspector.util.estimated-context-tokens","kind":"function","line":51,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(estimated-context-tokens agent) -> number","summary":"Estimate the current agent context size from system prompt, messages, content blocks, and tool-result names.","tags":["commands","tokens","agent"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-usage-totals-extensions-behaviors-inspectors-extensions-util-fnl-69","id":"fen.extensions.extensions_inspector.util.usage-totals","kind":"function","line":64,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(usage-totals messages) -> Usage","summary":"Sum provider usage counters across assistant messages for status and session diagnostics.","tags":["commands","tokens","usage"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-fmt-tokens-extensions-behaviors-inspectors-extensions-util-fnl-88","id":"fen.extensions.extensions_inspector.util.fmt-tokens","kind":"function","line":83,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(fmt-tokens n) -> string","summary":"Format a token count compactly with raw, k, or M suffixes for slash-command status output.","tags":["commands","tokens","format"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-format-token-summary-extensions-behaviors-inspectors-extensions-util-fnl-101","id":"fen.extensions.extensions_inspector.util.format-token-summary","kind":"function","line":96,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(format-token-summary usage approx) -> string","summary":"Build the one-line input/output/cache/context token summary shown by /status.","tags":["commands","tokens","status"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-runtime-version-extensions-behaviors-inspectors-extensions-util-fnl-114","id":"fen.extensions.extensions_inspector.util.runtime-version","kind":"function","line":109,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(runtime-version) -> string","summary":"Return the build-stamped fen version, or unknown when running from source/tests without dist metadata.","tags":["commands","status","version"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-nth-arg-extensions-behaviors-inspectors-extensions-util-fnl-125","id":"fen.extensions.extensions_inspector.util.nth-arg","kind":"function","line":120,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(nth-arg args n) -> string|nil","summary":"Extract the nth whitespace-delimited argument from a slash-command argument string.","tags":["commands","args","parsing"]}
{"href":"api.html#fen-extensions-extensions-inspector-util-first-arg-extensions-behaviors-inspectors-extensions-util-fnl-134","id":"fen.extensions.extensions_inspector.util.first-arg","kind":"function","line":129,"path":"extensions/behaviors/inspectors/extensions/util.fnl","signature":"(first-arg args) -> string|nil","summary":"Extract the first whitespace-delimited argument from a slash-command argument string.","tags":["commands","args","parsing"]}
{"href":"api.html#fen-extensions-prompt-commands-prompt-register-extensions-behaviors-inspectors-prompt-commands-prompt-fnl-104","id":"fen.extensions.prompt.commands.prompt.register","kind":"function","line":99,"path":"extensions/behaviors/inspectors/prompt/commands/prompt.fnl","signature":"(register api) -> nil","summary":"Register the /prompt command and prompt-fragment panel for inspecting rendered system prompt state.","tags":["commands","prompt","register"]}
{"href":"api.html#fen-extensions-prompt-register-extensions-behaviors-inspectors-prompt-init-fnl-7","id":"fen.extensions.prompt.register","kind":"function","line":7,"path":"extensions/behaviors/inspectors/prompt/init.fnl"}
{"href":"api.html#fen-extensions-prompt-state-prompt-visible-q-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27","id":"fen.extensions.prompt.state.prompt.visible?","kind":"data","line":3,"path":"extensions/behaviors/inspectors/prompt/state/prompt.fnl","signature":"boolean","summary":"Visibility flag for the persistent /prompt panel that previews assembled system prompt fragments.","tags":["builtin","commands","state","prompt","panel"]}
{"href":"api.html#fen-extensions-prompt-state-prompt-cached-rows-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27","id":"fen.extensions.prompt.state.prompt.cached-rows","kind":"data","line":9,"path":"extensions/behaviors/inspectors/prompt/state/prompt.fnl","signature":"[PresenterRow]|nil","summary":"Cached rendered /prompt panel rows reused while prompt content and terminal width remain stable.","tags":["builtin","commands","state","prompt","cache"]}
{"href":"api.html#fen-extensions-prompt-state-prompt-cached-at-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27","id":"fen.extensions.prompt.state.prompt.cached-at","kind":"data","line":15,"path":"extensions/behaviors/inspectors/prompt/state/prompt.fnl","signature":"number","summary":"Timestamp for the /prompt panel cache, used to avoid rebuilding prompt rows on every repaint.","tags":["builtin","commands","state","prompt","cache"]}
{"href":"api.html#fen-extensions-prompt-state-prompt-cached-w-extensions-behaviors-inspectors-prompt-state-prompt-fnl-27","id":"fen.extensions.prompt.state.prompt.cached-w","kind":"data","line":21,"path":"extensions/behaviors/inspectors/prompt/state/prompt.fnl","signature":"number","summary":"Terminal width associated with cached /prompt rows so resize events rebuild wrapped preview text.","tags":["builtin","commands","state","prompt","cache"]}
{"href":"api.html#fen-extensions-queue-commands-queue-register-extensions-behaviors-inspectors-queue-commands-queue-fnl-147","id":"fen.extensions.queue.commands.queue.register","kind":"function","line":142,"path":"extensions/behaviors/inspectors/queue/commands/queue.fnl","signature":"(register api) -> nil","summary":"Register queue management commands and the queue panel for pending steering/follow-up lines.","tags":["commands","queue","register"]}
{"href":"api.html#fen-extensions-queue-register-extensions-behaviors-inspectors-queue-init-fnl-7","id":"fen.extensions.queue.register","kind":"function","line":7,"path":"extensions/behaviors/inspectors/queue/init.fnl"}
{"href":"api.html#fen-extensions-queue-state-queue-visible-q-extensions-behaviors-inspectors-queue-state-queue-fnl-27","id":"fen.extensions.queue.state.queue.visible?","kind":"data","line":3,"path":"extensions/behaviors/inspectors/queue/state/queue.fnl","signature":"boolean","summary":"Visibility flag for the persistent /queue panel showing queued steering and follow-up input.","tags":["builtin","commands","state","queue","panel"]}
{"href":"api.html#fen-extensions-queue-state-queue-cached-rows-extensions-behaviors-inspectors-queue-state-queue-fnl-27","id":"fen.extensions.queue.state.queue.cached-rows","kind":"data","line":9,"path":"extensions/behaviors/inspectors/queue/state/queue.fnl","signature":"[PresenterRow]|nil","summary":"Cached rendered /queue panel rows reused while queue state and terminal width remain stable.","tags":["builtin","commands","state","queue","cache"]}
{"href":"api.html#fen-extensions-queue-state-queue-cached-at-extensions-behaviors-inspectors-queue-state-queue-fnl-27","id":"fen.extensions.queue.state.queue.cached-at","kind":"data","line":15,"path":"extensions/behaviors/inspectors/queue/state/queue.fnl","signature":"number","summary":"Timestamp for the /queue panel cache, supporting throttled refreshes during frequent repaints.","tags":["builtin","commands","state","queue","cache"]}
{"href":"api.html#fen-extensions-queue-state-queue-cached-w-extensions-behaviors-inspectors-queue-state-queue-fnl-27","id":"fen.extensions.queue.state.queue.cached-w","kind":"data","line":21,"path":"extensions/behaviors/inspectors/queue/state/queue.fnl","signature":"number","summary":"Terminal width associated with cached /queue rows so resize events rebuild wrapped queue entries.","tags":["builtin","commands","state","queue","cache"]}
{"href":"api.html#fen-extensions-queue-util-approx-tokens-extensions-behaviors-inspectors-queue-util-fnl-12","id":"fen.extensions.queue.util.approx-tokens","kind":"function","line":7,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(approx-tokens s) -> number","summary":"Estimate token count from text length for status displays when provider-reported usage is unavailable.","tags":["commands","tokens","status"]}
{"href":"api.html#fen-extensions-queue-util-safe-json-extensions-behaviors-inspectors-queue-util-fnl-24","id":"fen.extensions.queue.util.safe-json","kind":"function","line":19,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(safe-json v) -> string","summary":"JSON-encode a value for token estimation, falling back to tostring when encoding fails.","tags":["commands","json","tokens"]}
{"href":"api.html#fen-extensions-queue-util-content-tokens-extensions-behaviors-inspectors-queue-util-fnl-33","id":"fen.extensions.queue.util.content-tokens","kind":"function","line":28,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(content-tokens content) -> number","summary":"Estimate tokens for canonical message content, including text, thinking blocks, and tool-call names/arguments.","tags":["commands","tokens","messages"]}
{"href":"api.html#fen-extensions-queue-util-estimated-context-tokens-extensions-behaviors-inspectors-queue-util-fnl-56","id":"fen.extensions.queue.util.estimated-context-tokens","kind":"function","line":51,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(estimated-context-tokens agent) -> number","summary":"Estimate the current agent context size from system prompt, messages, content blocks, and tool-result names.","tags":["commands","tokens","agent"]}
{"href":"api.html#fen-extensions-queue-util-usage-totals-extensions-behaviors-inspectors-queue-util-fnl-69","id":"fen.extensions.queue.util.usage-totals","kind":"function","line":64,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(usage-totals messages) -> Usage","summary":"Sum provider usage counters across assistant messages for status and session diagnostics.","tags":["commands","tokens","usage"]}
{"href":"api.html#fen-extensions-queue-util-fmt-tokens-extensions-behaviors-inspectors-queue-util-fnl-88","id":"fen.extensions.queue.util.fmt-tokens","kind":"function","line":83,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(fmt-tokens n) -> string","summary":"Format a token count compactly with raw, k, or M suffixes for slash-command status output.","tags":["commands","tokens","format"]}
{"href":"api.html#fen-extensions-queue-util-format-token-summary-extensions-behaviors-inspectors-queue-util-fnl-101","id":"fen.extensions.queue.util.format-token-summary","kind":"function","line":96,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(format-token-summary usage approx) -> string","summary":"Build the one-line input/output/cache/context token summary shown by /status.","tags":["commands","tokens","status"]}
{"href":"api.html#fen-extensions-queue-util-runtime-version-extensions-behaviors-inspectors-queue-util-fnl-114","id":"fen.extensions.queue.util.runtime-version","kind":"function","line":109,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(runtime-version) -> string","summary":"Return the build-stamped fen version, or unknown when running from source/tests without dist metadata.","tags":["commands","status","version"]}
{"href":"api.html#fen-extensions-queue-util-nth-arg-extensions-behaviors-inspectors-queue-util-fnl-125","id":"fen.extensions.queue.util.nth-arg","kind":"function","line":120,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(nth-arg args n) -> string|nil","summary":"Extract the nth whitespace-delimited argument from a slash-command argument string.","tags":["commands","args","parsing"]}
{"href":"api.html#fen-extensions-queue-util-first-arg-extensions-behaviors-inspectors-queue-util-fnl-134","id":"fen.extensions.queue.util.first-arg","kind":"function","line":129,"path":"extensions/behaviors/inspectors/queue/util.fnl","signature":"(first-arg args) -> string|nil","summary":"Extract the first whitespace-delimited argument from a slash-command argument string.","tags":["commands","args","parsing"]}
{"href":"api.html#fen-extensions-status-commands-status-register-extensions-behaviors-inspectors-status-commands-status-fnl-156","id":"fen.extensions.status.commands.status.register","kind":"function","line":151,"path":"extensions/behaviors/inspectors/status/commands/status.fnl","signature":"(register api) -> nil","summary":"Register the /status command and status panel for runtime, model, session, token, and extension diagnostics.","tags":["commands","status","register"]}
{"href":"api.html#fen-extensions-status-register-extensions-behaviors-inspectors-status-init-fnl-7","id":"fen.extensions.status.register","kind":"function","line":7,"path":"extensions/behaviors/inspectors/status/init.fnl"}
{"href":"api.html#fen-extensions-status-state-status-visible-q-extensions-behaviors-inspectors-status-state-status-fnl-27","id":"fen.extensions.status.state.status.visible?","kind":"data","line":3,"path":"extensions/behaviors/inspectors/status/state/status.fnl","signature":"boolean","summary":"Visibility flag for the persistent /status panel showing runtime, model, session, and context details.","tags":["builtin","commands","state","status","panel"]}
{"href":"api.html#fen-extensions-status-state-status-cached-rows-extensions-behaviors-inspectors-status-state-status-fnl-27","id":"fen.extensions.status.state.status.cached-rows","kind":"data","line":9,"path":"extensions/behaviors/inspectors/status/state/status.fnl","signature":"[PresenterRow]|nil","summary":"Cached rendered /status panel rows reused while status inputs and terminal width remain stable.","tags":["builtin","commands","state","status","cache"]}
{"href":"api.html#fen-extensions-status-state-status-cached-at-extensions-behaviors-inspectors-status-state-status-fnl-27","id":"fen.extensions.status.state.status.cached-at","kind":"data","line":15,"path":"extensions/behaviors/inspectors/status/state/status.fnl","signature":"number","summary":"Timestamp for the /status panel cache, used to throttle recomputation of derived runtime details.","tags":["builtin","commands","state","status","cache"]}
{"href":"api.html#fen-extensions-status-state-status-cached-w-extensions-behaviors-inspectors-status-state-status-fnl-27","id":"fen.extensions.status.state.status.cached-w","kind":"data","line":21,"path":"extensions/behaviors/inspectors/status/state/status.fnl","signature":"number","summary":"Terminal width associated with cached /status rows so resize events rebuild aligned panel text.","tags":["builtin","commands","state","status","cache"]}
{"href":"api.html#fen-extensions-status-util-approx-tokens-extensions-behaviors-inspectors-status-util-fnl-12","id":"fen.extensions.status.util.approx-tokens","kind":"function","line":7,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(approx-tokens s) -> number","summary":"Estimate token count from text length for status displays when provider-reported usage is unavailable.","tags":["commands","tokens","status"]}
{"href":"api.html#fen-extensions-status-util-safe-json-extensions-behaviors-inspectors-status-util-fnl-24","id":"fen.extensions.status.util.safe-json","kind":"function","line":19,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(safe-json v) -> string","summary":"JSON-encode a value for token estimation, falling back to tostring when encoding fails.","tags":["commands","json","tokens"]}
{"href":"api.html#fen-extensions-status-util-content-tokens-extensions-behaviors-inspectors-status-util-fnl-33","id":"fen.extensions.status.util.content-tokens","kind":"function","line":28,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(content-tokens content) -> number","summary":"Estimate tokens for canonical message content, including text, thinking blocks, and tool-call names/arguments.","tags":["commands","tokens","messages"]}
{"href":"api.html#fen-extensions-status-util-estimated-context-tokens-extensions-behaviors-inspectors-status-util-fnl-56","id":"fen.extensions.status.util.estimated-context-tokens","kind":"function","line":51,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(estimated-context-tokens agent) -> number","summary":"Estimate the current agent context size from system prompt, messages, content blocks, and tool-result names.","tags":["commands","tokens","agent"]}
{"href":"api.html#fen-extensions-status-util-usage-totals-extensions-behaviors-inspectors-status-util-fnl-69","id":"fen.extensions.status.util.usage-totals","kind":"function","line":64,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(usage-totals messages) -> Usage","summary":"Sum provider usage counters across assistant messages for status and session diagnostics.","tags":["commands","tokens","usage"]}
{"href":"api.html#fen-extensions-status-util-fmt-tokens-extensions-behaviors-inspectors-status-util-fnl-88","id":"fen.extensions.status.util.fmt-tokens","kind":"function","line":83,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(fmt-tokens n) -> string","summary":"Format a token count compactly with raw, k, or M suffixes for slash-command status output.","tags":["commands","tokens","format"]}
{"href":"api.html#fen-extensions-status-util-format-token-summary-extensions-behaviors-inspectors-status-util-fnl-101","id":"fen.extensions.status.util.format-token-summary","kind":"function","line":96,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(format-token-summary usage approx) -> string","summary":"Build the one-line input/output/cache/context token summary shown by /status.","tags":["commands","tokens","status"]}
{"href":"api.html#fen-extensions-status-util-runtime-version-extensions-behaviors-inspectors-status-util-fnl-114","id":"fen.extensions.status.util.runtime-version","kind":"function","line":109,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(runtime-version) -> string","summary":"Return the build-stamped fen version, or unknown when running from source/tests without dist metadata.","tags":["commands","status","version"]}
{"href":"api.html#fen-extensions-status-util-nth-arg-extensions-behaviors-inspectors-status-util-fnl-134","id":"fen.extensions.status.util.nth-arg","kind":"function","line":129,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(nth-arg args n) -> string|nil","summary":"Extract the nth whitespace-delimited argument from a slash-command argument string.","tags":["commands","args","parsing"]}
{"href":"api.html#fen-extensions-status-util-first-arg-extensions-behaviors-inspectors-status-util-fnl-143","id":"fen.extensions.status.util.first-arg","kind":"function","line":138,"path":"extensions/behaviors/inspectors/status/util.fnl","signature":"(first-arg args) -> string|nil","summary":"Extract the first whitespace-delimited argument from a slash-command argument string.","tags":["commands","args","parsing"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-name-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.name","kind":"data","line":3,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"keyword","summary":"Registry name for the built-in Bash tool descriptor advertised to providers and slash-command docs.","tags":["builtin","tools","bash","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-bash-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.bash","kind":"data","line":9,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"AgentToolSpec","summary":"Complete Bash tool specification exported by the module for registration in the built-in tool registry.","tags":["builtin","tools","bash","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-label-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.label","kind":"data","line":15,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated tool listings before shell commands.","tags":["builtin","tools","bash","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-snippet-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.snippet","kind":"data","line":21,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"string","summary":"Short Bash tool teaser used by generated docs and compact tool summaries before the full description.","tags":["builtin","tools","bash","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-description-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.description","kind":"data","line":27,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"string","summary":"Provider-facing Bash tool description documenting merged stdout/stderr and tail-truncation behavior.","tags":["builtin","tools","bash","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-parameters-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.parameters","kind":"data","line":33,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"JSONSchema","summary":"JSON schema for Bash tool arguments, including command text, optional timeout, and checked working directory.","tags":["builtin","tools","bash","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-bash-execute-extensions-behaviors-kernel-builtin-tools-bash-fnl-110","id":"fen.extensions.builtin_tools.bash.execute","kind":"function","line":39,"path":"extensions/behaviors/kernel/builtin-tools/bash.fnl","signature":"(execute args ctx yield-fn?) -> AgentToolResult","summary":"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"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-name-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.name","kind":"data","line":5,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"keyword","summary":"Registry name for the built-in exact-replacement edit tool descriptor.","tags":["builtin","tools","edit","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-edit-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.edit","kind":"data","line":11,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"AgentToolSpec","summary":"Complete edit tool specification exported for registration with batch and single-file replacement modes.","tags":["builtin","tools","edit","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-label-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.label","kind":"data","line":17,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated listings for exact text edits.","tags":["builtin","tools","edit","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-snippet-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.snippet","kind":"data","line":23,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"string","summary":"Short edit tool teaser describing precise replacements for compact generated docs.","tags":["builtin","tools","edit","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-description-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.description","kind":"data","line":29,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"string","summary":"Provider-facing edit tool description covering uniqueness, snapshot application, and all-or-nothing batch validation.","tags":["builtin","tools","edit","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-parameters-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.parameters","kind":"data","line":35,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"JSONSchema","summary":"JSON schema for single-file and batch edit payloads, including exact old and replacement strings.","tags":["builtin","tools","edit","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-edit-execute-extensions-behaviors-kernel-builtin-tools-edit-fnl-203","id":"fen.extensions.builtin_tools.edit.execute","kind":"function","line":41,"path":"extensions/behaviors/kernel/builtin-tools/edit.fnl","signature":"(execute args ctx? yield-fn?) -> AgentToolResult","summary":"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"]}
{"href":"api.html#fen-extensions-builtin-tools-find-name-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.name","kind":"data","line":5,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"keyword","summary":"Registry name for the built-in recursive file find tool descriptor.","tags":["builtin","tools","find","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-find-find-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.find","kind":"data","line":11,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"AgentToolSpec","summary":"Complete find tool specification exported for name-glob file discovery through the built-in registry.","tags":["builtin","tools","find","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-find-label-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.label","kind":"data","line":17,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated listings for file discovery.","tags":["builtin","tools","find","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-find-snippet-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.snippet","kind":"data","line":23,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"string","summary":"Short find tool teaser used by generated docs and compact tool summaries.","tags":["builtin","tools","find","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-find-description-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.description","kind":"data","line":29,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"string","summary":"Provider-facing find tool description for recursive filename-glob searches.","tags":["builtin","tools","find","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-find-parameters-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.parameters","kind":"data","line":35,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"JSONSchema","summary":"JSON schema for find arguments, including required name glob, optional root path, and result limit.","tags":["builtin","tools","find","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-find-execute-extensions-behaviors-kernel-builtin-tools-find-fnl-64","id":"fen.extensions.builtin_tools.find.execute","kind":"function","line":41,"path":"extensions/behaviors/kernel/builtin-tools/find.fnl","signature":"(execute args ctx? yield-fn?) -> AgentToolResult","summary":"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"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-name-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.name","kind":"data","line":5,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"keyword","summary":"Registry name for the built-in recursive grep tool descriptor.","tags":["builtin","tools","grep","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-grep-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.grep","kind":"data","line":11,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"AgentToolSpec","summary":"Complete grep tool specification exported for content search through the built-in registry.","tags":["builtin","tools","grep","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-label-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.label","kind":"data","line":17,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated listings for text searches.","tags":["builtin","tools","grep","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-snippet-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.snippet","kind":"data","line":23,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"string","summary":"Short grep tool teaser used by generated docs before the full search option contract.","tags":["builtin","tools","grep","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-description-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.description","kind":"data","line":29,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"string","summary":"Provider-facing grep tool description covering recursive regex search behavior.","tags":["builtin","tools","grep","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-parameters-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.parameters","kind":"data","line":35,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"JSONSchema","summary":"JSON schema for grep arguments, including pattern, path, glob, literal, case, context, and limit controls.","tags":["builtin","tools","grep","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-grep-execute-extensions-behaviors-kernel-builtin-tools-grep-fnl-72","id":"fen.extensions.builtin_tools.grep.execute","kind":"function","line":41,"path":"extensions/behaviors/kernel/builtin-tools/grep.fnl","signature":"(execute args ctx? yield-fn?) -> AgentToolResult","summary":"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"]}
{"href":"api.html#fen-extensions-builtin-tools-register-extensions-behaviors-kernel-builtin-tools-init-fnl-11","id":"fen.extensions.builtin_tools.register","kind":"function","line":11,"path":"extensions/behaviors/kernel/builtin-tools/init.fnl"}
{"href":"api.html#fen-extensions-builtin-tools-ls-name-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.name","kind":"data","line":7,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"keyword","summary":"Registry name for the built-in directory listing tool descriptor.","tags":["builtin","tools","ls","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-ls-ls-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.ls","kind":"data","line":13,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"AgentToolSpec","summary":"Complete ls tool specification exported for listing directory entries through the built-in registry.","tags":["builtin","tools","ls","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-ls-label-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.label","kind":"data","line":19,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated listings for directory scans.","tags":["builtin","tools","ls","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-ls-snippet-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.snippet","kind":"data","line":25,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"string","summary":"Short ls tool teaser used by generated docs and compact tool summaries.","tags":["builtin","tools","ls","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-ls-description-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.description","kind":"data","line":31,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"string","summary":"Provider-facing ls tool description for shallow directory entry listings.","tags":["builtin","tools","ls","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-ls-parameters-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.parameters","kind":"data","line":37,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"JSONSchema","summary":"JSON schema for ls arguments, including optional target directory and output line limit.","tags":["builtin","tools","ls","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-ls-execute-extensions-behaviors-kernel-builtin-tools-ls-fnl-72","id":"fen.extensions.builtin_tools.ls.execute","kind":"function","line":43,"path":"extensions/behaviors/kernel/builtin-tools/ls.fnl","signature":"(execute args ctx? yield-fn?) -> AgentToolResult","summary":"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"]}
{"href":"api.html#fen-extensions-builtin-tools-read-name-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.name","kind":"data","line":7,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"keyword","summary":"Registry name for the built-in file read tool descriptor.","tags":["builtin","tools","read","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-read-read-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.read","kind":"data","line":13,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"AgentToolSpec","summary":"Complete read tool specification exported for single-file and batched file inspection.","tags":["builtin","tools","read","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-read-label-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.label","kind":"data","line":19,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated listings for file reads.","tags":["builtin","tools","read","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-read-snippet-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.snippet","kind":"data","line":25,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"string","summary":"Short read tool teaser used by generated docs before the full paging and truncation contract.","tags":["builtin","tools","read","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-read-description-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.description","kind":"data","line":31,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"string","summary":"Provider-facing read tool description covering full slurps, offset/limit paging, batched reads, and truncation tags.","tags":["builtin","tools","read","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-read-parameters-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.parameters","kind":"data","line":37,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"JSONSchema","summary":"JSON schema for read arguments, including path, batched paths, and optional line window controls.","tags":["builtin","tools","read","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-read-execute-extensions-behaviors-kernel-builtin-tools-read-fnl-120","id":"fen.extensions.builtin_tools.read.execute","kind":"function","line":43,"path":"extensions/behaviors/kernel/builtin-tools/read.fnl","signature":"(execute args ctx? yield-fn?) -> AgentToolResult","summary":"Read tool executor that dispatches single or batch reads, yielding during large file and batch work when cooperative.","tags":["builtin","tools","read","execution"]}
{"href":"api.html#fen-extensions-builtin-tools-registry-registry-extensions-behaviors-kernel-builtin-tools-registry-fnl-17","id":"fen.extensions.builtin_tools.registry.registry","kind":"data","line":3,"path":"extensions/behaviors/kernel/builtin-tools/registry.fnl","signature":"[AgentToolSpec]","summary":"Ordered list of built-in tool specifications registered by the builtin-tools extension and reused by tests.","tags":["builtin","tools","registry"]}
{"href":"api.html#fen-extensions-builtin-tools-truncate-default-max-lines-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181","id":"fen.extensions.builtin_tools.truncate.DEFAULT-MAX-LINES","kind":"data","line":3,"path":"extensions/behaviors/kernel/builtin-tools/truncate.fnl","signature":"number","summary":"Default maximum number of tool-output lines kept inline before truncation spills the full output.","tags":["builtin","tools","truncate","defaults"]}
{"href":"api.html#fen-extensions-builtin-tools-truncate-default-max-bytes-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181","id":"fen.extensions.builtin_tools.truncate.DEFAULT-MAX-BYTES","kind":"data","line":10,"path":"extensions/behaviors/kernel/builtin-tools/truncate.fnl","signature":"number","summary":"Default maximum number of tool-output bytes kept inline before truncation writes a spill file.","tags":["builtin","tools","truncate","defaults"]}
{"href":"api.html#fen-extensions-builtin-tools-truncate-truncate-head-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181","id":"fen.extensions.builtin_tools.truncate.truncate-head","kind":"function","line":96,"path":"extensions/behaviors/kernel/builtin-tools/truncate.fnl","signature":"(truncate-head s opts? yield-fn?) -> string, truncated?","summary":"Keep the beginning of tool output within max-lines/max-bytes, yielding during scans and full-output spills when cooperative.","tags":["tools","output","truncate"]}
{"href":"api.html#fen-extensions-builtin-tools-truncate-truncate-tail-extensions-behaviors-kernel-builtin-tools-truncate-fnl-181","id":"fen.extensions.builtin_tools.truncate.truncate-tail","kind":"function","line":133,"path":"extensions/behaviors/kernel/builtin-tools/truncate.fnl","signature":"(truncate-tail s opts? yield-fn?) -> string, truncated?","summary":"Keep the end of tool output within max-lines/max-bytes, yielding during scans and full-output spills when cooperative.","tags":["tools","output","truncate"]}
{"href":"api.html#fen-extensions-builtin-tools-util-agent-result-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.agent-result","kind":"function","line":3,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(agent-result content is-error? details) -> AgentToolResult","summary":"Build the common AgentToolResult shape used by built-in tools, preserving optional presenter details.","tags":["tools","results","util"]}
{"href":"api.html#fen-extensions-builtin-tools-util-ok-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.ok","kind":"function","line":13,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(ok text) -> AgentToolResult","summary":"Wrap successful plain text output as a canonical non-error AgentToolResult.","tags":["tools","results","util"]}
{"href":"api.html#fen-extensions-builtin-tools-util-err-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.err","kind":"function","line":21,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(err message) -> AgentToolResult","summary":"Wrap an error message as a canonical AgentToolResult whose text is prefixed with error:.","tags":["tools","results","util"]}
{"href":"api.html#fen-extensions-builtin-tools-util-shellquote-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.shellquote","kind":"function","line":29,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(shellquote s) -> string","summary":"Quote a built-in tool path or argument as one POSIX shell word for system probes.","tags":["tools","shell","util"]}
{"href":"api.html#fen-extensions-builtin-tools-util-int-arg-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.int-arg","kind":"function","line":37,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(int-arg v default) -> number","summary":"Normalize numeric tool arguments by converting to an integer or returning the provided default.","tags":["tools","args","util"]}
{"href":"api.html#fen-extensions-builtin-tools-util-result-text-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.result-text","kind":"function","line":47,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(result-text r) -> string","summary":"Extract the first text block from an AgentToolResult for tests and composed tool helpers.","tags":["tools","results","util"]}
{"href":"api.html#fen-extensions-builtin-tools-util-dir-exists-q-extensions-behaviors-kernel-builtin-tools-util-fnl-69","id":"fen.extensions.builtin_tools.util.dir-exists?","kind":"function","line":56,"path":"extensions/behaviors/kernel/builtin-tools/util.fnl","signature":"(dir-exists? path) -> boolean","summary":"Check whether a path is a directory using a shell-quoted POSIX test probe.","tags":["tools","filesystem","util"]}
{"href":"api.html#fen-extensions-builtin-tools-write-name-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.name","kind":"data","line":5,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"keyword","summary":"Registry name for the built-in file write tool descriptor.","tags":["builtin","tools","write","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-write-write-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.write","kind":"data","line":11,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"AgentToolSpec","summary":"Complete write tool specification exported for creating or overwriting files.","tags":["builtin","tools","write","descriptor"]}
{"href":"api.html#fen-extensions-builtin-tools-write-label-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.label","kind":"data","line":17,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"string","summary":"Human-readable label shown in tool-running status and generated listings for file writes.","tags":["builtin","tools","write","ui"]}
{"href":"api.html#fen-extensions-builtin-tools-write-snippet-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.snippet","kind":"data","line":23,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"string","summary":"Short write tool teaser used by generated docs and compact tool summaries.","tags":["builtin","tools","write","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-write-description-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.description","kind":"data","line":29,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"string","summary":"Provider-facing write tool description documenting overwrite semantics and parent-directory creation.","tags":["builtin","tools","write","docs"]}
{"href":"api.html#fen-extensions-builtin-tools-write-parameters-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.parameters","kind":"data","line":35,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"JSONSchema","summary":"JSON schema for write arguments containing the destination path and complete file content.","tags":["builtin","tools","write","schema"]}
{"href":"api.html#fen-extensions-builtin-tools-write-execute-extensions-behaviors-kernel-builtin-tools-write-fnl-84","id":"fen.extensions.builtin_tools.write.execute","kind":"function","line":41,"path":"extensions/behaviors/kernel/builtin-tools/write.fnl","signature":"(execute args ctx? yield-fn?) -> AgentToolResult","summary":"Write tool executor that creates missing parent directories, yields during large content writes, and reports byte counts.","tags":["builtin","tools","write","execution"]}
{"href":"api.html#fen-extensions-default-prompt-tool-list-section-extensions-behaviors-kernel-default-prompt-init-fnl-35","id":"fen.extensions.default_prompt.tool-list-section","kind":"function","line":30,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"(tool-list-section tools) -> string|nil","summary":"Render the available-tools prompt section from registered tool snippets, omitting the section when none are present.","tags":["prompt","default","tools"]}
{"href":"api.html#fen-extensions-default-prompt-guidelines-section-extensions-behaviors-kernel-default-prompt-init-fnl-49","id":"fen.extensions.default_prompt.guidelines-section","kind":"function","line":44,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"(guidelines-section tools) -> string","summary":"Render built-in model guidance tailored to the currently available file, bash, read/edit, and agent_state tools.","tags":["prompt","default","guidelines","tools"]}
{"href":"api.html#fen-extensions-default-prompt-context-section-extensions-behaviors-kernel-default-prompt-init-fnl-73","id":"fen.extensions.default_prompt.context-section","kind":"function","line":68,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"(context-section context-files) -> string|nil","summary":"Render loaded project context files as titled prompt sections for the default system prompt.","tags":["prompt","default","context"]}
{"href":"api.html#fen-extensions-default-prompt-default-prompt-extensions-behaviors-kernel-default-prompt-init-fnl-144","id":"fen.extensions.default_prompt.default-prompt","kind":"data","line":139,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"string","summary":"Built-in fallback system prompt used when no SYSTEM.md or CLI system override is available.","tags":["prompt","default","data"]}
{"href":"api.html#fen-extensions-default-prompt-register-extensions-behaviors-kernel-default-prompt-init-fnl-151","id":"fen.extensions.default_prompt.register","kind":"data","line":146,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"function","summary":"Registration entrypoint alias for installing the default prompt fragments into the extension registry.","tags":["prompt","default","register"]}
{"href":"api.html#fen-extensions-default-prompt-register-bang-extensions-behaviors-kernel-default-prompt-init-fnl-152","id":"fen.extensions.default_prompt.register!","kind":"data","line":146,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"function","summary":"Registration entrypoint alias for installing the default prompt fragments into the extension registry.","tags":["prompt","default","register"]}
{"href":"api.html#fen-extensions-default-prompt-current-loader-extensions-behaviors-kernel-default-prompt-init-fnl-159","id":"fen.extensions.default_prompt.current-loader","kind":"data","line":154,"path":"extensions/behaviors/kernel/default-prompt/init.fnl","signature":"function","summary":"Loader accessor alias returning the cached default-prompt resource loader, creating it on first use.","tags":["prompt","default","resources"]}
{"href":"api.html#fen-extensions-default-prompt-resources-make-extensions-behaviors-kernel-default-prompt-resources-fnl-78","id":"fen.extensions.default_prompt.resources.make","kind":"function","line":73,"path":"extensions/behaviors/kernel/default-prompt/resources.fnl","signature":"(make opts) -> ResourceLoader","summary":"Create and immediately load a reloadable resource snapshot for SYSTEM overlays and project context files.","tags":["prompt","resources","context","reload"]}
{"href":"api.html#fen-extensions-default-prompt-resources-cwd-extensions-behaviors-kernel-default-prompt-resources-fnl-92","id":"fen.extensions.default_prompt.resources.cwd","kind":"data","line":87,"path":"extensions/behaviors/kernel/default-prompt/resources.fnl","signature":"function","summary":"Path helper alias returning the current logical working directory for resource scans.","tags":["prompt","resources","paths"]}
{"href":"api.html#fen-extensions-default-prompt-resources-config-dir-extensions-behaviors-kernel-default-prompt-resources-fnl-99","id":"fen.extensions.default_prompt.resources.config-dir","kind":"data","line":94,"path":"extensions/behaviors/kernel/default-prompt/resources.fnl","signature":"function","summary":"Helper alias returning fen's XDG configuration directory for prompt overlays and global context.","tags":["prompt","resources","paths"]}
{"href":"api.html#fen-extensions-default-prompt-resources-load-project-context-files-extensions-behaviors-kernel-default-prompt-resources-fnl-106","id":"fen.extensions.default_prompt.resources.load-project-context-files","kind":"data","line":101,"path":"extensions/behaviors/kernel/default-prompt/resources.fnl","signature":"function","summary":"Helper alias loading global and ancestor AGENTS.md or CLAUDE.md context files in prompt order.","tags":["prompt","resources","context"]}
{"href":"api.html#fen-extensions-default-prompt-resources-load-system-file-extensions-behaviors-kernel-default-prompt-resources-fnl-113","id":"fen.extensions.default_prompt.resources.load-system-file","kind":"data","line":108,"path":"extensions/behaviors/kernel/default-prompt/resources.fnl","signature":"function","summary":"Helper alias resolving the effective SYSTEM.md or APPEND_SYSTEM.md overlay for the current project.","tags":["prompt","resources","system"]}
{"href":"api.html#fen-extensions-default-prompt-resources-ancestors-root-to-leaf-extensions-behaviors-kernel-default-prompt-resources-fnl-120","id":"fen.extensions.default_prompt.resources._ancestors-root-to-leaf","kind":"data","line":115,"path":"extensions/behaviors/kernel/default-prompt/resources.fnl","signature":"function","summary":"Test helper alias exposing the root-to-leaf ancestor walker used by prompt resource discovery.","tags":["prompt","resources","tests","paths"]}
{"href":"api.html#fen-extensions-docs-register-extensions-behaviors-kernel-docs-init-fnl-482","id":"fen.extensions.docs.register","kind":"function","line":477,"path":"extensions/behaviors/kernel/docs/init.fnl","signature":"(register api?) -> true","summary":"Register the /docs command, fen_docs tool, docs panel, and dismiss handler against the extension API.","tags":["docs","register","command","tool","panel"]}
{"href":"api.html#fen-extensions-docs-state-visible-q-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.visible?","kind":"data","line":3,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"boolean","summary":"Visibility flag for the persistent /docs panel that lists generated API and contract entries.","tags":["docs","state","panel"]}
{"href":"api.html#fen-extensions-docs-state-selected-topic-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.selected-topic","kind":"data","line":9,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"string|nil","summary":"Current /docs topic selection used to keep the active group stable across row refreshes.","tags":["docs","state","selection"]}
{"href":"api.html#fen-extensions-docs-state-selected-name-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.selected-name","kind":"data","line":15,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"string|nil","summary":"Current /docs entry selection within the active topic for keyboard focus and detail rendering.","tags":["docs","state","selection"]}
{"href":"api.html#fen-extensions-docs-state-cached-rows-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.cached-rows","kind":"data","line":21,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"[PresenterRow]|nil","summary":"Cached rendered /docs panel rows reused while topic, selection, and terminal width are unchanged.","tags":["docs","state","cache"]}
{"href":"api.html#fen-extensions-docs-state-cached-at-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.cached-at","kind":"data","line":27,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"number","summary":"Timestamp for the /docs panel cache, allowing registry documentation to be refreshed predictably.","tags":["docs","state","cache"]}
{"href":"api.html#fen-extensions-docs-state-cached-w-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.cached-w","kind":"data","line":33,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"number","summary":"Terminal width associated with cached /docs rows so resize events rebuild wrapped documentation text.","tags":["docs","state","cache"]}
{"href":"api.html#fen-extensions-docs-state-cached-selected-topic-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.cached-selected-topic","kind":"data","line":39,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"string|nil","summary":"Topic selection value associated with cached /docs rows so topic changes invalidate the panel cache.","tags":["docs","state","cache","selection"]}
{"href":"api.html#fen-extensions-docs-state-cached-selected-name-extensions-behaviors-kernel-docs-state-fnl-51","id":"fen.extensions.docs.state.cached-selected-name","kind":"data","line":45,"path":"extensions/behaviors/kernel/docs/state.fnl","signature":"string|nil","summary":"Entry selection value associated with cached /docs rows so focus changes invalidate detail rendering.","tags":["docs","state","cache","selection"]}
{"href":"api.html#fen-extensions-essentials-commands-help-register-extensions-behaviors-kernel-essentials-commands-help-fnl-93","id":"fen.extensions.essentials.commands.help.register","kind":"function","line":88,"path":"extensions/behaviors/kernel/essentials/commands/help.fnl","signature":"(register api) -> nil","summary":"Register the /help command that lists available slash commands and controls grouped by extension owner.","tags":["commands","help","register"]}
{"href":"api.html#fen-extensions-essentials-commands-model-register-extensions-behaviors-kernel-essentials-commands-model-fnl-120","id":"fen.extensions.essentials.commands.model.register","kind":"function","line":115,"path":"extensions/behaviors/kernel/essentials/commands/model.fnl","signature":"(register api) -> nil","summary":"Register the /model command for selecting configured models by overlay, index, exact id, or substring query.","tags":["commands","model","register"]}
{"href":"api.html#fen-extensions-essentials-commands-thinking-register-extensions-behaviors-kernel-essentials-commands-thinking-fnl-114","id":"fen.extensions.essentials.commands.thinking.register","kind":"function","line":109,"path":"extensions/behaviors/kernel/essentials/commands/thinking.fnl","signature":"(register api) -> nil","summary":"Register the /thinking command for inspecting and setting provider-neutral thinking effort.","tags":["commands","thinking","register"]}
{"href":"api.html#fen-extensions-essentials-register-extensions-behaviors-kernel-essentials-init-fnl-9","id":"fen.extensions.essentials.register","kind":"function","line":9,"path":"extensions/behaviors/kernel/essentials/init.fnl"}
{"href":"api.html#fen-core-agent-make-agent-packages-core-src-fen-core-agent-fnl-494","id":"fen.core.agent.make-agent","kind":"function","line":47,"path":"packages/core/src/fen/core/agent.fnl","signature":"(make-agent {:provider-name :model :system :tools :api-key :on-event :max-tokens :convert-to-llm :provider-options}) -> Agent","summary":"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"]}
{"href":"api.html#fen-core-agent-step-packages-core-src-fen-core-agent-fnl-494","id":"fen.core.agent.step","kind":"function","line":454,"path":"packages/core/src/fen/core/agent.fnl","signature":"(step agent user-msg ?cancel-fn) -> string","summary":"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"]}
{"href":"api.html#fen-core-agent-safety-cap-packages-core-src-fen-core-agent-fnl-494","id":"fen.core.agent.SAFETY-CAP","kind":"constant","line":15,"path":"packages/core/src/fen/core/agent.fnl","signature":"number","summary":"Hard ceiling on tool-call iterations per step. Bump if a real workflow needs more, don't remove.","tags":["agent","loop","limits"]}
{"href":"api.html#fen-core-agent-complete-messages-packages-core-src-fen-core-agent-fnl-494","id":"fen.core.agent.complete-messages","kind":"function","line":376,"path":"packages/core/src/fen/core/agent.fnl","signature":"(complete-messages agent messages ?model ?opts ?on-event ?yield-fn) -> AssistantMessage","summary":"Run one provider completion using an agent's provider configuration, explicit canonical messages, and no tools.","tags":["agent","llm","extensions"]}
{"href":"api.html#fen-core-diagnostics-set-runtime-info-bang-packages-core-src-fen-core-diagnostics-fnl-39","id":"fen.core.diagnostics.set-runtime-info!","kind":"function","line":34,"path":"packages/core/src/fen/core/diagnostics.fnl","signature":"(set-runtime-info! info) -> table|nil","summary":"Store sanitized runtime/build metadata for durable error/provider diagnostics.","tags":["diagnostics","version","runtime"]}
{"href":"api.html#fen-core-diagnostics-runtime-info-packages-core-src-fen-core-diagnostics-fnl-49","id":"fen.core.diagnostics.runtime-info","kind":"function","line":44,"path":"packages/core/src/fen/core/diagnostics.fnl","signature":"(runtime-info) -> table|nil","summary":"Return runtime/build metadata previously injected by fen.main, if available.","tags":["diagnostics","version","runtime"]}
{"href":"api.html#fen-core-docs-contracts-types-packages-core-src-fen-core-docs-contracts-fnl-20","id":"fen.core.docs.contracts.types","kind":"data","line":15,"path":"packages/core/src/fen/core/docs/contracts.fnl","signature":"table","summary":"Canonical message, content, tool, usage, and agent-context type contracts shared by providers, tools, sessions, and docs.","tags":["docs","contracts","types"]}
{"href":"api.html#fen-core-docs-contracts-register-kinds-packages-core-src-fen-core-docs-contracts-fnl-20","id":"fen.core.docs.contracts.register-kinds","kind":"data","line":158,"path":"packages/core/src/fen/core/docs/contracts.fnl","signature":"table","summary":"Extension registration kind contracts describing required fields for tools, commands, providers, presenters, panels, hooks, and prompt fragments.","tags":["docs","contracts","extensions","register"]}
{"href":"api.html#fen-core-docs-contracts-events-packages-core-src-fen-core-docs-contracts-fnl-20","id":"fen.core.docs.contracts.events","kind":"data","line":295,"path":"packages/core/src/fen/core/docs/contracts.fnl","signature":"table","summary":"Event bus contract table documenting emitted runtime event shapes and fields consumed by presenters and extensions.","tags":["docs","contracts","events","bus"]}
{"href":"api.html#fen-core-docs-contracts-interfaces-packages-core-src-fen-core-docs-contracts-fnl-20","id":"fen.core.docs.contracts.interfaces","kind":"data","line":614,"path":"packages/core/src/fen/core/docs/contracts.fnl","signature":"table","summary":"Interface contract table for provider, auth backend, session backend, and presenter records.","tags":["docs","contracts","interfaces","providers","sessions"]}
{"href":"api.html#fen-core-extensions-events-error-log-path-packages-core-src-fen-core-extensions-events-fnl-50","id":"fen.core.extensions.events.error-log-path","kind":"function","line":45,"path":"packages/core/src/fen/core/extensions/events.fnl","signature":"(error-log-path) -> string","summary":"Lazily compute and return the JSONL file path where extension event-bus failures are persisted.","tags":["extensions","events","diagnostics"]}
{"href":"api.html#fen-core-extensions-events-list-errors-packages-core-src-fen-core-extensions-events-fnl-101","id":"fen.core.extensions.events.list-errors","kind":"function","line":96,"path":"packages/core/src/fen/core/extensions/events.fnl","signature":"(list-errors) -> [ExtensionError]","summary":"Return the bounded in-memory list of sanitized extension error records captured by the event bus.","tags":["extensions","events","diagnostics"]}
{"href":"api.html#fen-core-extensions-events-emit-packages-core-src-fen-core-extensions-events-fnl-134","id":"fen.core.extensions.events.emit","kind":"function","line":129,"path":"packages/core/src/fen/core/extensions/events.fnl","signature":"(emit ev) -> nil","summary":"Record error events, dispatch ev to handlers for ev.type, and then dispatch to wildcard `:*` subscribers.","tags":["extensions","events","bus"]}
{"href":"api.html#fen-core-extensions-events-on-packages-core-src-fen-core-extensions-events-fnl-147","id":"fen.core.extensions.events.on","kind":"function","line":142,"path":"packages/core/src/fen/core/extensions/events.fnl","signature":"(on event-name handler ?owner) -> unsubscribe-fn","summary":"Subscribe a handler to one event name with optional owner tagging and return a closure that removes that exact handler.","tags":["extensions","events","subscribe"]}
{"href":"api.html#fen-core-extensions-events-unregister-by-owner-packages-core-src-fen-core-extensions-events-fnl-158","id":"fen.core.extensions.events.unregister-by-owner","kind":"function","line":153,"path":"packages/core/src/fen/core/extensions/events.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove every event handler tagged with owner from all event buckets during extension reload or teardown.","tags":["extensions","events","reload"]}
{"href":"api.html#fen-core-extensions-events-list-packages-core-src-fen-core-extensions-events-fnl-167","id":"fen.core.extensions.events.list","kind":"function","line":162,"path":"packages/core/src/fen/core/extensions/events.fnl","signature":"(list) -> table","summary":"Return a safe introspection table of subscribed event names and handler owners without exposing handler functions.","tags":["extensions","events","introspection"]}
{"href":"api.html#fen-core-extensions-loader-discover-first-party-roots-packages-core-src-fen-core-extensions-loader-discover-fnl-121","id":"fen.core.extensions.loader.discover.first-party-roots","kind":"function","line":116,"path":"packages/core/src/fen/core/extensions/loader/discover.fnl","signature":"(first-party-roots) -> [string]","summary":"Return trusted flat first-party overlay roots supplied by the single-file launcher.","tags":["extensions","loader","discovery"]}
{"href":"api.html#fen-core-extensions-loader-discover-project-roots-packages-core-src-fen-core-extensions-loader-discover-fnl-136","id":"fen.core.extensions.loader.discover.project-roots","kind":"function","line":131,"path":"packages/core/src/fen/core/extensions/loader/discover.fnl","signature":"(project-roots) -> [string]","summary":"Return .fen/extensions roots from cwd upward to the worktree boundary, nearest first for project-local override priority.","tags":["extensions","loader","discovery"]}
{"href":"api.html#fen-core-extensions-loader-discover-user-roots-packages-core-src-fen-core-extensions-loader-discover-fnl-161","id":"fen.core.extensions.loader.discover.user-roots","kind":"function","line":156,"path":"packages/core/src/fen/core/extensions/loader/discover.fnl","signature":"(user-roots) -> [string]","summary":"Return user extension roots from FEN_EXTENSIONS_PATH plus the XDG fen/extensions directory.","tags":["extensions","loader","discovery"]}
{"href":"api.html#fen-core-extensions-loader-discover-discover-packages-core-src-fen-core-extensions-loader-discover-fnl-301","id":"fen.core.extensions.loader.discover.discover","kind":"function","line":296,"path":"packages/core/src/fen/core/extensions/loader/discover.fnl","signature":"(discover explicit-paths) -> [ExtensionSpec]","summary":"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"]}
{"href":"api.html#fen-core-extensions-loader-load-sibling-packages-core-src-fen-core-extensions-loader-init-fnl-224","id":"fen.core.extensions.loader.load-sibling","kind":"function","line":219,"path":"packages/core/src/fen/core/extensions/loader/init.fnl","signature":"(load-sibling spec sibling) -> any","summary":"Load a sibling .fnl/.lua file for a path-shaped extension's api.load helper without requiring a global namespace.","tags":["extensions","loader","files"]}
{"href":"api.html#fen-core-extensions-loader-load-bang-packages-core-src-fen-core-extensions-loader-init-fnl-257","id":"fen.core.extensions.loader.load!","kind":"function","line":240,"path":"packages/core/src/fen/core/extensions/loader/init.fnl","signature":"(load! opts ?mode) -> ExtensionLoadSummary","summary":"Discover, gate, and load admissible extensions, failing fast only after collecting first-party load failures.","tags":["extensions","loader","lifecycle"]}
{"href":"api.html#fen-core-extensions-loader-summarize-packages-core-src-fen-core-extensions-loader-init-fnl-291","id":"fen.core.extensions.loader.summarize","kind":"function","line":286,"path":"packages/core/src/fen/core/extensions/loader/init.fnl","signature":"(summarize items) -> ExtensionLoadSummary","summary":"Fold per-extension load entries into aggregate loaded/changed/failed counters plus the original extension list.","tags":["extensions","loader","diagnostics"]}
{"href":"api.html#fen-core-extensions-loader-reload-extension-bang-packages-core-src-fen-core-extensions-loader-init-fnl-308","id":"fen.core.extensions.loader.reload-extension!","kind":"function","line":303,"path":"packages/core/src/fen/core/extensions/loader/init.fnl","signature":"(reload-extension! name) -> ok?, err","summary":"Reload a previously loaded extension by name using its retained spec and interactive TUI reload mode.","tags":["extensions","loader","reload"]}
{"href":"api.html#fen-core-extensions-loader-manifest-strip-ext-packages-core-src-fen-core-extensions-loader-manifest-fnl-25","id":"fen.core.extensions.loader.manifest.strip-ext","kind":"function","line":25,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-load-file-packages-core-src-fen-core-extensions-loader-manifest-fnl-42","id":"fen.core.extensions.loader.manifest.load-file","kind":"function","line":42,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-manifest-path-packages-core-src-fen-core-extensions-loader-manifest-fnl-48","id":"fen.core.extensions.loader.manifest.manifest-path","kind":"function","line":48,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-entry-path-for-dir-packages-core-src-fen-core-extensions-loader-manifest-fnl-55","id":"fen.core.extensions.loader.manifest.entry-path-for-dir","kind":"function","line":55,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-read-manifest-packages-core-src-fen-core-extensions-loader-manifest-fnl-62","id":"fen.core.extensions.loader.manifest.read-manifest","kind":"function","line":62,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-entry-module-of-packages-core-src-fen-core-extensions-loader-manifest-fnl-68","id":"fen.core.extensions.loader.manifest.entry-module-of","kind":"function","line":68,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-entry-of-packages-core-src-fen-core-extensions-loader-manifest-fnl-72","id":"fen.core.extensions.loader.manifest.entry-of","kind":"function","line":72,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-interactive-only-q-packages-core-src-fen-core-extensions-loader-manifest-fnl-76","id":"fen.core.extensions.loader.manifest.interactive-only?","kind":"function","line":76,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-presenter-of-packages-core-src-fen-core-extensions-loader-manifest-fnl-81","id":"fen.core.extensions.loader.manifest.presenter-of","kind":"function","line":81,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-first-party-q-packages-core-src-fen-core-extensions-loader-manifest-fnl-84","id":"fen.core.extensions.loader.manifest.first-party?","kind":"function","line":84,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-reload-modules-packages-core-src-fen-core-extensions-loader-manifest-fnl-89","id":"fen.core.extensions.loader.manifest.reload-modules","kind":"function","line":89,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-reload-exclude-packages-core-src-fen-core-extensions-loader-manifest-fnl-95","id":"fen.core.extensions.loader.manifest.reload-exclude","kind":"function","line":95,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-enabled-q-packages-core-src-fen-core-extensions-loader-manifest-fnl-100","id":"fen.core.extensions.loader.manifest.enabled?","kind":"function","line":100,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-entry-register-packages-core-src-fen-core-extensions-loader-manifest-fnl-106","id":"fen.core.extensions.loader.manifest.entry-register","kind":"function","line":106,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-requires-modules-packages-core-src-fen-core-extensions-loader-manifest-fnl-126","id":"fen.core.extensions.loader.manifest.requires-modules","kind":"function","line":126,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-requires-shared-libs-packages-core-src-fen-core-extensions-loader-manifest-fnl-132","id":"fen.core.extensions.loader.manifest.requires-shared-libs","kind":"function","line":132,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-missing-requires-modules-packages-core-src-fen-core-extensions-loader-manifest-fnl-137","id":"fen.core.extensions.loader.manifest.missing-requires-modules","kind":"function","line":137,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-manifest-missing-deps-packages-core-src-fen-core-extensions-loader-manifest-fnl-146","id":"fen.core.extensions.loader.manifest.missing-deps","kind":"function","line":146,"path":"packages/core/src/fen/core/extensions/loader/manifest.fnl"}
{"href":"api.html#fen-core-extensions-loader-reload-file-changed-q-bang-packages-core-src-fen-core-extensions-loader-reload-fnl-47","id":"fen.core.extensions.loader.reload.file-changed?!","kind":"function","line":42,"path":"packages/core/src/fen/core/extensions/loader/reload.fnl","signature":"(file-changed?! file-path) -> boolean","summary":"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"]}
{"href":"api.html#fen-core-extensions-loader-reload-change-summary-packages-core-src-fen-core-extensions-loader-reload-fnl-56","id":"fen.core.extensions.loader.reload.change-summary","kind":"function","line":51,"path":"packages/core/src/fen/core/extensions/loader/reload.fnl","signature":"(change-summary mods) -> ReloadChangeSummary","summary":"Probe module fingerprints, update the reload cache, and return checked/changed counts plus changed module names.","tags":["extensions","loader","reload","fingerprint"]}
{"href":"api.html#fen-core-extensions-loader-reload-clear-reload-modules-bang-packages-core-src-fen-core-extensions-loader-reload-fnl-88","id":"fen.core.extensions.loader.reload.clear-reload-modules!","kind":"function","line":83,"path":"packages/core/src/fen/core/extensions/loader/reload.fnl","signature":"(clear-reload-modules! manifest fallback) -> ReloadChangeSummary","summary":"Re-require manifest reload modules in place, respecting reload-exclude, and return one summary for user-facing reload diagnostics.","tags":["extensions","loader","reload"]}
{"href":"api.html#fen-core-extensions-register-auth-backend-register-packages-core-src-fen-core-extensions-register-auth-backend-fnl-11","id":"fen.core.extensions.register.auth_backend.register","kind":"function","line":6,"path":"packages/core/src/fen/core/extensions/register/auth_backend.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and install a singleton auth-backend contribution keyed by :name for provider credential lookup.","tags":["extensions","register","auth"]}
{"href":"api.html#fen-core-extensions-register-auth-backend-unregister-by-owner-packages-core-src-fen-core-extensions-register-auth-backend-fnl-22","id":"fen.core.extensions.register.auth_backend.unregister-by-owner","kind":"function","line":17,"path":"packages/core/src/fen/core/extensions/register/auth_backend.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove every auth backend installed by owner without disturbing backends registered by other extensions.","tags":["extensions","register","auth","reload"]}
{"href":"api.html#fen-core-extensions-register-auth-backend-find-packages-core-src-fen-core-extensions-register-auth-backend-fnl-32","id":"fen.core.extensions.register.auth_backend.find","kind":"function","line":27,"path":"packages/core/src/fen/core/extensions/register/auth_backend.fnl","signature":"(find name) -> AuthBackend|nil","summary":"Return the registered auth backend for name, or nil when no matching backend is installed.","tags":["extensions","register","auth"]}
{"href":"api.html#fen-core-extensions-register-auth-backend-list-packages-core-src-fen-core-extensions-register-auth-backend-fnl-40","id":"fen.core.extensions.register.auth_backend.list","kind":"function","line":35,"path":"packages/core/src/fen/core/extensions/register/auth_backend.fnl","signature":"(list) -> [AuthBackendInfo]","summary":"Return auth backend metadata for introspection, including owner and optional credential capability flags.","tags":["extensions","register","auth","introspection"]}
{"href":"api.html#fen-core-extensions-register-command-register-packages-core-src-fen-core-extensions-register-command-fnl-12","id":"fen.core.extensions.register.command.register","kind":"function","line":7,"path":"packages/core/src/fen/core/extensions/register/command.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and install a slash-command contribution keyed by :name with its handler and command metadata.","tags":["extensions","register","commands"]}
{"href":"api.html#fen-core-extensions-register-command-unregister-by-owner-packages-core-src-fen-core-extensions-register-command-fnl-26","id":"fen.core.extensions.register.command.unregister-by-owner","kind":"function","line":21,"path":"packages/core/src/fen/core/extensions/register/command.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove all slash commands installed by owner so extension reloads replace commands without stale aliases.","tags":["extensions","register","commands","reload"]}
{"href":"api.html#fen-core-extensions-register-command-dispatch-packages-core-src-fen-core-extensions-register-command-fnl-49","id":"fen.core.extensions.register.command.dispatch","kind":"function","line":44,"path":"packages/core/src/fen/core/extensions/register/command.fnl","signature":"(dispatch line caller-state) -> nil","summary":"Parse a slash command line, enforce idle-only guards, pcall-isolate the handler, and emit user-facing errors.","tags":["extensions","commands","events"]}
{"href":"api.html#fen-core-extensions-register-command-list-packages-core-src-fen-core-extensions-register-command-fnl-74","id":"fen.core.extensions.register.command.list","kind":"function","line":69,"path":"packages/core/src/fen/core/extensions/register/command.fnl","signature":"(list) -> [CommandInfo]","summary":"Return command metadata used by help, docs, and diagnostics without exposing handler functions.","tags":["extensions","commands","introspection"]}
{"href":"api.html#fen-core-extensions-register-control-register-packages-core-src-fen-core-extensions-register-control-fnl-11","id":"fen.core.extensions.register.control.register","kind":"function","line":6,"path":"packages/core/src/fen/core/extensions/register/control.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and append a presenter-neutral control contribution with owner tagging for reload cleanup.","tags":["extensions","register","controls"]}
{"href":"api.html#fen-core-extensions-register-control-unregister-by-owner-packages-core-src-fen-core-extensions-register-control-fnl-22","id":"fen.core.extensions.register.control.unregister-by-owner","kind":"function","line":17,"path":"packages/core/src/fen/core/extensions/register/control.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove all control contributions installed by owner from the ordered controls registry.","tags":["extensions","register","controls","reload"]}
{"href":"api.html#fen-core-extensions-register-control-list-packages-core-src-fen-core-extensions-register-control-fnl-31","id":"fen.core.extensions.register.control.list","kind":"function","line":26,"path":"packages/core/src/fen/core/extensions/register/control.fnl","signature":"(list) -> [ControlInfo]","summary":"Return control metadata for presenters and docs, including keys/order while hiding mutable registry records.","tags":["extensions","controls","introspection"]}
{"href":"api.html#fen-core-extensions-register-hook-register-packages-core-src-fen-core-extensions-register-hook-fnl-11","id":"fen.core.extensions.register.hook.register","kind":"function","line":6,"path":"packages/core/src/fen/core/extensions/register/hook.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and append a before-tool hook contribution that can inspect or veto pending tool execution.","tags":["extensions","register","hooks","tools"]}
{"href":"api.html#fen-core-extensions-register-hook-unregister-by-owner-packages-core-src-fen-core-extensions-register-hook-fnl-24","id":"fen.core.extensions.register.hook.unregister-by-owner","kind":"function","line":19,"path":"packages/core/src/fen/core/extensions/register/hook.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove all before-tool hooks installed by owner during extension reload or teardown.","tags":["extensions","hooks","reload"]}
{"href":"api.html#fen-core-extensions-register-hook-list-packages-core-src-fen-core-extensions-register-hook-fnl-33","id":"fen.core.extensions.register.hook.list","kind":"function","line":28,"path":"packages/core/src/fen/core/extensions/register/hook.fnl","signature":"(list) -> [HookInfo]","summary":"Return hook contributions without exposing hook functions.","tags":["extensions","hooks","introspection"]}
{"href":"api.html#fen-core-extensions-register-hook-run-before-tool-packages-core-src-fen-core-extensions-register-hook-fnl-44","id":"fen.core.extensions.register.hook.run-before-tool","kind":"function","line":39,"path":"packages/core/src/fen/core/extensions/register/hook.fnl","signature":"(run-before-tool tool-name args ctx) -> {:block? boolean :reason string|nil}","summary":"Run registered before-tool hooks in order and return the first veto decision, or an explicit non-blocking decision.","tags":["extensions","hooks","tools"]}
{"href":"api.html#fen-core-extensions-register-register-packages-core-src-fen-core-extensions-register-init-fnl-43","id":"fen.core.extensions.register.register","kind":"function","line":38,"path":"packages/core/src/fen/core/extensions/register/init.fnl","signature":"(register kind spec owner) -> register-result","summary":"Dispatch one extension contribution to the per-kind registry module and return its owner-tagged unregister handle.","tags":["extensions","register","dispatcher"]}
{"href":"api.html#fen-core-extensions-register-unregister-by-owner-packages-core-src-fen-core-extensions-register-init-fnl-62","id":"fen.core.extensions.register.unregister-by-owner","kind":"function","line":57,"path":"packages/core/src/fen/core/extensions/register/init.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Sweep every registry kind and event-handler bucket, removing contributions tagged with owner during reload or teardown.","tags":["extensions","register","reload"]}
{"href":"api.html#fen-core-extensions-register-list-packages-core-src-fen-core-extensions-register-init-fnl-112","id":"fen.core.extensions.register.list","kind":"function","line":107,"path":"packages/core/src/fen/core/extensions/register/init.fnl","signature":"(list kind) -> frozen-table","summary":"Return a frozen introspection list for the requested registry kind, including extensions, hooks, event handlers, and prompt fragments.","tags":["extensions","register","introspection"]}
{"href":"api.html#fen-core-extensions-register-collect-introspection-packages-core-src-fen-core-extensions-register-init-fnl-135","id":"fen.core.extensions.register.collect-introspection","kind":"function","line":130,"path":"packages/core/src/fen/core/extensions/register/init.fnl","signature":"(collect-introspection ?owner ?ctx) -> table","summary":"Evaluate registered introspection snapshots through the centralized pcall-isolated collector.","tags":["extensions","register","introspection","snapshots"]}
{"href":"api.html#fen-core-extensions-register-introspect-register-packages-core-src-fen-core-extensions-register-introspect-fnl-17","id":"fen.core.extensions.register.introspect.register","kind":"function","line":17,"path":"packages/core/src/fen/core/extensions/register/introspect.fnl"}
{"href":"api.html#fen-core-extensions-register-introspect-unregister-by-owner-packages-core-src-fen-core-extensions-register-introspect-fnl-26","id":"fen.core.extensions.register.introspect.unregister-by-owner","kind":"function","line":26,"path":"packages/core/src/fen/core/extensions/register/introspect.fnl"}
{"href":"api.html#fen-core-extensions-register-introspect-list-packages-core-src-fen-core-extensions-register-introspect-fnl-38","id":"fen.core.extensions.register.introspect.list","kind":"function","line":38,"path":"packages/core/src/fen/core/extensions/register/introspect.fnl"}
{"href":"api.html#fen-core-extensions-register-introspect-collect-packages-core-src-fen-core-extensions-register-introspect-fnl-83","id":"fen.core.extensions.register.introspect.collect","kind":"function","line":83,"path":"packages/core/src/fen/core/extensions/register/introspect.fnl"}
{"href":"api.html#fen-core-extensions-register-panel-register-packages-core-src-fen-core-extensions-register-panel-fnl-32","id":"fen.core.extensions.register.panel.register","kind":"function","line":27,"path":"packages/core/src/fen/core/extensions/register/panel.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate a panel contribution, fill default placement/order fields, and append it to the presenter panel registry.","tags":["extensions","register","panels","ui"]}
{"href":"api.html#fen-core-extensions-register-panel-unregister-by-owner-packages-core-src-fen-core-extensions-register-panel-fnl-52","id":"fen.core.extensions.register.panel.unregister-by-owner","kind":"function","line":47,"path":"packages/core/src/fen/core/extensions/register/panel.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove all panel contributions installed by owner while preserving the shared panel registry table identity.","tags":["extensions","panels","reload"]}
{"href":"api.html#fen-core-extensions-register-panel-list-packages-core-src-fen-core-extensions-register-panel-fnl-69","id":"fen.core.extensions.register.panel.list","kind":"function","line":64,"path":"packages/core/src/fen/core/extensions/register/panel.fnl","signature":"(list) -> [Panel]","summary":"Return panel contributions sorted by order, owner, and name for deterministic presenter layout.","tags":["extensions","panels","introspection"]}
{"href":"api.html#fen-core-extensions-register-presenter-promote-ui-slot-bang-packages-core-src-fen-core-extensions-register-presenter-fnl-15","id":"fen.core.extensions.register.presenter.promote-ui-slot!","kind":"function","line":10,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(promote-ui-slot!) -> nil","summary":"Recompute the shared UI slot from the first active presenter that supplies one after unregister or reload.","tags":["extensions","presenter","ui","reload"]}
{"href":"api.html#fen-core-extensions-register-presenter-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-27","id":"fen.core.extensions.register.presenter.active-presenter","kind":"function","line":22,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(active-presenter) -> Presenter|nil","summary":"Return the first registered presenter marked active, or nil when no presenter has claimed the run.","tags":["extensions","presenter","ui"]}
{"href":"api.html#fen-core-extensions-register-presenter-register-packages-core-src-fen-core-extensions-register-presenter-fnl-40","id":"fen.core.extensions.register.presenter.register","kind":"function","line":35,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and append a presenter contribution, promoting its UI slot immediately when it is active.","tags":["extensions","register","presenter","ui"]}
{"href":"api.html#fen-core-extensions-register-presenter-unregister-by-owner-packages-core-src-fen-core-extensions-register-presenter-fnl-57","id":"fen.core.extensions.register.presenter.unregister-by-owner","kind":"function","line":52,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove presenters installed by owner and promote the next active UI slot so extension APIs keep working after reload.","tags":["extensions","presenter","reload"]}
{"href":"api.html#fen-core-extensions-register-presenter-init-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-80","id":"fen.core.extensions.register.presenter.init-active-presenter","kind":"function","line":75,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(init-active-presenter ctx) -> ok?, result","summary":"Call the active presenter's optional :init lifecycle method through a pcall-style result pair.","tags":["extensions","presenter","lifecycle"]}
{"href":"api.html#fen-core-extensions-register-presenter-shutdown-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-88","id":"fen.core.extensions.register.presenter.shutdown-active-presenter","kind":"function","line":83,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(shutdown-active-presenter ctx) -> ok?, result","summary":"Call the active presenter's optional :shutdown lifecycle method during process teardown.","tags":["extensions","presenter","lifecycle"]}
{"href":"api.html#fen-core-extensions-register-presenter-run-active-presenter-packages-core-src-fen-core-extensions-register-presenter-fnl-96","id":"fen.core.extensions.register.presenter.run-active-presenter","kind":"function","line":91,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(run-active-presenter ctx) -> ok?, result","summary":"Call the active presenter's required :run lifecycle method and report an error pair when no runnable presenter exists.","tags":["extensions","presenter","lifecycle"]}
{"href":"api.html#fen-core-extensions-register-presenter-build-ui-slot-packages-core-src-fen-core-extensions-register-presenter-fnl-129","id":"fen.core.extensions.register.presenter.build-ui-slot","kind":"function","line":124,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(build-ui-slot) -> table","summary":"Build the stable extension-facing UI facade whose methods dispatch to the active presenter or lightweight fallbacks.","tags":["extensions","presenter","ui","api"]}
{"href":"api.html#fen-core-extensions-register-presenter-list-packages-core-src-fen-core-extensions-register-presenter-fnl-140","id":"fen.core.extensions.register.presenter.list","kind":"function","line":135,"path":"packages/core/src/fen/core/extensions/register/presenter.fnl","signature":"(list) -> [PresenterInfo]","summary":"Return presenter metadata and lifecycle capability flags for diagnostics and runtime docs.","tags":["extensions","presenter","introspection"]}
{"href":"api.html#fen-core-extensions-register-prompt-contribute-packages-core-src-fen-core-extensions-register-prompt-fnl-21","id":"fen.core.extensions.register.prompt.contribute","kind":"function","line":16,"path":"packages/core/src/fen/core/extensions/register/prompt.fnl","signature":"(contribute text-or-fn ?opts owner handle-result) -> register-result","summary":"Append an ordered system-prompt fragment from api.prompt, tagging owner metadata and returning an unregister handle.","tags":["extensions","prompt","register"]}
{"href":"api.html#fen-core-extensions-register-prompt-unregister-by-owner-packages-core-src-fen-core-extensions-register-prompt-fnl-40","id":"fen.core.extensions.register.prompt.unregister-by-owner","kind":"function","line":35,"path":"packages/core/src/fen/core/extensions/register/prompt.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove all system-prompt fragments contributed by owner during reload or extension teardown.","tags":["extensions","prompt","reload"]}
{"href":"api.html#fen-core-extensions-register-prompt-render-packages-core-src-fen-core-extensions-register-prompt-fnl-73","id":"fen.core.extensions.register.prompt.render","kind":"function","line":68,"path":"packages/core/src/fen/core/extensions/register/prompt.fnl","signature":"(render ?ctx) -> string|nil","summary":"Render registered prompt fragments in final order, omitting nil/empty fragments and isolating fragment function errors.","tags":["extensions","prompt","render"]}
{"href":"api.html#fen-core-extensions-register-prompt-list-packages-core-src-fen-core-extensions-register-prompt-fnl-99","id":"fen.core.extensions.register.prompt.list","kind":"function","line":94,"path":"packages/core/src/fen/core/extensions/register/prompt.fnl","signature":"(list) -> [PromptFragmentInfo]","summary":"Return prompt-fragment metadata in final render order without exposing raw fragment text content.","tags":["extensions","prompt","introspection"]}
{"href":"api.html#fen-core-extensions-register-provider-register-packages-core-src-fen-core-extensions-register-provider-fnl-11","id":"fen.core.extensions.register.provider.register","kind":"function","line":6,"path":"packages/core/src/fen/core/extensions/register/provider.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and install a singleton provider contribution keyed by name, defaulting name from api when omitted.","tags":["extensions","register","providers"]}
{"href":"api.html#fen-core-extensions-register-provider-unregister-by-owner-packages-core-src-fen-core-extensions-register-provider-fnl-27","id":"fen.core.extensions.register.provider.unregister-by-owner","kind":"function","line":22,"path":"packages/core/src/fen/core/extensions/register/provider.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove every provider installed by owner without clobbering same-name providers registered later by other owners.","tags":["extensions","providers","reload"]}
{"href":"api.html#fen-core-extensions-register-provider-find-packages-core-src-fen-core-extensions-register-provider-fnl-37","id":"fen.core.extensions.register.provider.find","kind":"function","line":32,"path":"packages/core/src/fen/core/extensions/register/provider.fnl","signature":"(find name) -> Provider|nil","summary":"Find a provider by its unique registry name; provider :api is protocol metadata, not the deterministic dispatch key.","tags":["extensions","providers","lookup"]}
{"href":"api.html#fen-core-extensions-register-provider-list-by-api-packages-core-src-fen-core-extensions-register-provider-fnl-47","id":"fen.core.extensions.register.provider.list-by-api","kind":"function","line":42,"path":"packages/core/src/fen/core/extensions/register/provider.fnl","signature":"(list-by-api api) -> [Provider]","summary":"Return all providers whose protocol/family metadata matches api for introspection and delegation.","tags":["extensions","providers","lookup"]}
{"href":"api.html#fen-core-extensions-register-provider-find-by-api-packages-core-src-fen-core-extensions-register-provider-fnl-62","id":"fen.core.extensions.register.provider.find-by-api","kind":"function","line":57,"path":"packages/core/src/fen/core/extensions/register/provider.fnl","signature":"(find-by-api api) -> Provider|nil","summary":"Return the first provider matching an api family for legacy/introspection callers that cannot require unique provider names.","tags":["extensions","providers","lookup"]}
{"href":"api.html#fen-core-extensions-register-provider-list-packages-core-src-fen-core-extensions-register-provider-fnl-73","id":"fen.core.extensions.register.provider.list","kind":"function","line":68,"path":"packages/core/src/fen/core/extensions/register/provider.fnl","signature":"(list) -> [ProviderInfo]","summary":"Return provider metadata for model selection, docs, and diagnostics while preserving provider implementation records internally.","tags":["extensions","providers","introspection"]}
{"href":"api.html#fen-core-extensions-register-session-backend-register-packages-core-src-fen-core-extensions-register-session-backend-fnl-18","id":"fen.core.extensions.register.session_backend.register","kind":"function","line":13,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate required session backend methods and install the backend by name for session persistence selection.","tags":["extensions","register","session"]}
{"href":"api.html#fen-core-extensions-register-session-backend-unregister-by-owner-packages-core-src-fen-core-extensions-register-session-backend-fnl-33","id":"fen.core.extensions.register.session_backend.unregister-by-owner","kind":"function","line":28,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove session backends installed by owner and clear active session state if the active backend is removed.","tags":["extensions","session","reload"]}
{"href":"api.html#fen-core-extensions-register-session-backend-find-packages-core-src-fen-core-extensions-register-session-backend-fnl-46","id":"fen.core.extensions.register.session_backend.find","kind":"function","line":41,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(find name) -> SessionBackend|nil","summary":"Return the registered session backend for name, or nil when no backend is installed under that name.","tags":["extensions","session","lookup"]}
{"href":"api.html#fen-core-extensions-register-session-backend-set-active-bang-packages-core-src-fen-core-extensions-register-session-backend-fnl-54","id":"fen.core.extensions.register.session_backend.set-active!","kind":"function","line":49,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(set-active! name) -> SessionBackend|nil","summary":"Record the active session backend name, resolve it immediately, and return the selected backend if present.","tags":["extensions","session","state"]}
{"href":"api.html#fen-core-extensions-register-session-backend-active-packages-core-src-fen-core-extensions-register-session-backend-fnl-64","id":"fen.core.extensions.register.session_backend.active","kind":"function","line":59,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(active) -> SessionBackend|nil","summary":"Return the cached active backend or resolve the active backend name after reload restored the registry.","tags":["extensions","session","state"]}
{"href":"api.html#fen-core-extensions-register-session-backend-set-info-bang-packages-core-src-fen-core-extensions-register-session-backend-fnl-73","id":"fen.core.extensions.register.session_backend.set-info!","kind":"function","line":68,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(set-info! info) -> info","summary":"Store the active session info record for later runtime inspection by commands, tools, and docs.","tags":["extensions","session","introspection"]}
{"href":"api.html#fen-core-extensions-register-session-backend-info-packages-core-src-fen-core-extensions-register-session-backend-fnl-82","id":"fen.core.extensions.register.session_backend.info","kind":"function","line":77,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(info) -> SessionInfo|nil","summary":"Return the cached active session info record without touching backend storage.","tags":["extensions","session","introspection"]}
{"href":"api.html#fen-core-extensions-register-session-backend-list-packages-core-src-fen-core-extensions-register-session-backend-fnl-89","id":"fen.core.extensions.register.session_backend.list","kind":"function","line":84,"path":"packages/core/src/fen/core/extensions/register/session_backend.fnl","signature":"(list) -> [SessionBackendInfo]","summary":"Return session backend names and owners for diagnostics and generated runtime documentation.","tags":["extensions","session","introspection"]}
{"href":"api.html#fen-core-extensions-register-status-register-packages-core-src-fen-core-extensions-register-status-fnl-17","id":"fen.core.extensions.register.status.register","kind":"function","line":12,"path":"packages/core/src/fen/core/extensions/register/status.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate a status-line contributor, fill default side/order fields, and append it to the status registry.","tags":["extensions","register","status"]}
{"href":"api.html#fen-core-extensions-register-status-unregister-by-owner-packages-core-src-fen-core-extensions-register-status-fnl-35","id":"fen.core.extensions.register.status.unregister-by-owner","kind":"function","line":30,"path":"packages/core/src/fen/core/extensions/register/status.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove all status contributors installed by owner while preserving contributors from other extensions.","tags":["extensions","register","status","reload"]}
{"href":"api.html#fen-core-extensions-register-status-list-packages-core-src-fen-core-extensions-register-status-fnl-52","id":"fen.core.extensions.register.status.list","kind":"function","line":47,"path":"packages/core/src/fen/core/extensions/register/status.fnl","signature":"(list) -> [StatusItem]","summary":"Return status contributors sorted by order, owner, and name for deterministic presenter rendering.","tags":["extensions","status","introspection"]}
{"href":"api.html#fen-core-extensions-register-tool-register-packages-core-src-fen-core-extensions-register-tool-fnl-11","id":"fen.core.extensions.register.tool.register","kind":"function","line":6,"path":"packages/core/src/fen/core/extensions/register/tool.fnl","signature":"(register spec owner handle-result) -> register-result","summary":"Validate and append an AgentTool contribution so the agent can expose it to providers and execute ToolCalls by name.","tags":["extensions","register","tools"]}
{"href":"api.html#fen-core-extensions-register-tool-unregister-by-owner-packages-core-src-fen-core-extensions-register-tool-fnl-22","id":"fen.core.extensions.register.tool.unregister-by-owner","kind":"function","line":17,"path":"packages/core/src/fen/core/extensions/register/tool.fnl","signature":"(unregister-by-owner owner) -> nil","summary":"Remove every tool contribution installed by owner from the extension tool registry.","tags":["extensions","register","tools","reload"]}
{"href":"api.html#fen-core-extensions-register-tool-merged-packages-core-src-fen-core-extensions-register-tool-fnl-31","id":"fen.core.extensions.register.tool.merged","kind":"function","line":26,"path":"packages/core/src/fen/core/extensions/register/tool.fnl","signature":"(merged base) -> [AgentTool]","summary":"Return base tools followed by extension-contributed tools in registry order for agent-step tool exposure.","tags":["extensions","tools","agent"]}
{"href":"api.html#fen-core-extensions-register-tool-list-packages-core-src-fen-core-extensions-register-tool-fnl-43","id":"fen.core.extensions.register.tool.list","kind":"function","line":38,"path":"packages/core/src/fen/core/extensions/register/tool.fnl","signature":"(list) -> [ToolInfo]","summary":"Return lightweight tool metadata for docs and diagnostics without exposing execute functions.","tags":["extensions","tools","introspection"]}
{"href":"api.html#fen-core-extensions-rocks-default-tree-packages-core-src-fen-core-extensions-rocks-fnl-17","id":"fen.core.extensions.rocks.default-tree","kind":"function","line":12,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(default-tree) -> string","summary":"Return the fen-managed LuaRocks tree, honoring FEN_ROCKS_TREE before falling back to the user data directory.","tags":["extensions","rocks","paths"]}
{"href":"api.html#fen-core-extensions-rocks-lua-path-fragment-packages-core-src-fen-core-extensions-rocks-fnl-28","id":"fen.core.extensions.rocks.lua-path-fragment","kind":"function","line":23,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(lua-path-fragment tree) -> string","summary":"Build the package.path fragment that exposes pure-Lua modules installed in a fen rocks tree.","tags":["extensions","rocks","paths"]}
{"href":"api.html#fen-core-extensions-rocks-lua-cpath-fragment-packages-core-src-fen-core-extensions-rocks-fnl-37","id":"fen.core.extensions.rocks.lua-cpath-fragment","kind":"function","line":32,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(lua-cpath-fragment tree) -> string","summary":"Build the package.cpath fragment that exposes native Lua 5.4 modules installed in a fen rocks tree.","tags":["extensions","rocks","paths"]}
{"href":"api.html#fen-core-extensions-rocks-prepend-tree-bang-packages-core-src-fen-core-extensions-rocks-fnl-50","id":"fen.core.extensions.rocks.prepend-tree!","kind":"function","line":45,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(prepend-tree! ?tree) -> true|nil","summary":"Prepend an existing fen rocks tree to package.path and package.cpath so extension dependencies can be required.","tags":["extensions","rocks","paths"]}
{"href":"api.html#fen-core-extensions-rocks-rockspecs-packages-core-src-fen-core-extensions-rocks-fnl-72","id":"fen.core.extensions.rocks.rockspecs","kind":"function","line":67,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(rockspecs dir) -> [string]","summary":"List top-level .rockspec files in an extension directory for build and missing-dependency diagnostics.","tags":["extensions","rocks","build"]}
{"href":"api.html#fen-core-extensions-rocks-rockspec-present-q-packages-core-src-fen-core-extensions-rocks-fnl-82","id":"fen.core.extensions.rocks.rockspec-present?","kind":"function","line":77,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(rockspec-present? dir) -> boolean","summary":"Return true when an extension directory contains at least one rockspec for fen ext build guidance.","tags":["extensions","rocks","build"]}
{"href":"api.html#fen-core-extensions-rocks-single-rockspec-packages-core-src-fen-core-extensions-rocks-fnl-90","id":"fen.core.extensions.rocks.single-rockspec","kind":"function","line":85,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(single-rockspec dir) -> rockspec|nil, err|nil","summary":"Require exactly one rockspec in an extension directory and return a user-facing error when zero or multiple are present.","tags":["extensions","rocks","build"]}
{"href":"api.html#fen-core-extensions-rocks-parse-missing-module-packages-core-src-fen-core-extensions-rocks-fnl-104","id":"fen.core.extensions.rocks.parse-missing-module","kind":"function","line":99,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(parse-missing-module err) -> string|nil","summary":"Extract the missing module name from Lua's standard require error so loader failures can suggest installation actions.","tags":["extensions","rocks","diagnostics"]}
{"href":"api.html#fen-core-extensions-rocks-manual-install-command-packages-core-src-fen-core-extensions-rocks-fnl-115","id":"fen.core.extensions.rocks.manual-install-command","kind":"function","line":110,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(manual-install-command module-name ?tree) -> string","summary":"Format the LuaRocks install command users can run to install a missing dependency into the fen rocks tree.","tags":["extensions","rocks","diagnostics"]}
{"href":"api.html#fen-core-extensions-rocks-build-command-packages-core-src-fen-core-extensions-rocks-fnl-124","id":"fen.core.extensions.rocks.build-command","kind":"function","line":119,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(build-command dir) -> string","summary":"Format the fen ext build command for an extension directory that declares a rockspec.","tags":["extensions","rocks","build"]}
{"href":"api.html#fen-core-extensions-rocks-missing-module-message-packages-core-src-fen-core-extensions-rocks-fnl-141","id":"fen.core.extensions.rocks.missing-module-message","kind":"function","line":136,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(missing-module-message spec module-name) -> string","summary":"Build an actionable loader error for one missing Lua module, preferring fen ext build when the extension has a rockspec.","tags":["extensions","rocks","diagnostics"]}
{"href":"api.html#fen-core-extensions-rocks-missing-modules-message-packages-core-src-fen-core-extensions-rocks-fnl-156","id":"fen.core.extensions.rocks.missing-modules-message","kind":"function","line":151,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(missing-modules-message spec modules) -> string","summary":"Build an actionable loader error for declared missing modules, including shared-library hints from the manifest.","tags":["extensions","rocks","diagnostics"]}
{"href":"api.html#fen-core-extensions-rocks-build-bang-packages-core-src-fen-core-extensions-rocks-fnl-212","id":"fen.core.extensions.rocks.build!","kind":"function","line":207,"path":"packages/core/src/fen/core/extensions/rocks.fnl","signature":"(build! dir) -> exit-code","summary":"Build an extension rockspec into the fen rocks tree using bundled LuaRocks when available, returning process-style exit codes.","tags":["extensions","rocks","build"]}
{"href":"api.html#fen-core-extensions-state-version-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.version","kind":"data","line":3,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"number","summary":"Schema/version marker for the persistent extension state table shared across reloadable extension modules.","tags":["extensions","state","reload"]}
{"href":"api.html#fen-core-extensions-state-handlers-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.handlers","kind":"data","line":9,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Event-bus handler buckets keyed by event name, preserving subscriptions across reloadable event-module updates.","tags":["extensions","state","events"]}
{"href":"api.html#fen-core-extensions-state-tools-extra-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.tools-extra","kind":"data","line":15,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[AgentTool]","summary":"Array registry of extension-contributed tools appended to the agent's base tool set each step.","tags":["extensions","state","tools"]}
{"href":"api.html#fen-core-extensions-state-commands-extra-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.commands-extra","kind":"data","line":21,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Singleton registry of slash-command contributions keyed by command name for dispatch and help introspection.","tags":["extensions","state","commands"]}
{"href":"api.html#fen-core-extensions-state-controls-extra-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.controls-extra","kind":"data","line":27,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[Control]","summary":"Array registry of presenter-neutral keyboard/control contributions exposed to active presenters.","tags":["extensions","state","controls"]}
{"href":"api.html#fen-core-extensions-state-status-extra-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.status-extra","kind":"data","line":33,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[StatusItem]","summary":"Array registry of status-line contributors sorted by presenters into left/right status regions.","tags":["extensions","state","status"]}
{"href":"api.html#fen-core-extensions-state-panel-extra-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.panel-extra","kind":"data","line":39,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[Panel]","summary":"Array registry of non-modal panel contributions rendered by presenters that support panel regions.","tags":["extensions","state","panels"]}
{"href":"api.html#fen-core-extensions-state-presenters-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.presenters","kind":"data","line":45,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[Presenter]","summary":"Array registry of presenter contributions, including lifecycle callbacks and optional UI slot implementations.","tags":["extensions","state","presenter"]}
{"href":"api.html#fen-core-extensions-state-introspectors-extra-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.introspectors-extra","kind":"data","line":51,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[Introspector]","summary":"Array registry of extension-owned read-only snapshot providers exposed through agent_state, /extensions, and runtime diagnostics.","tags":["extensions","state","introspection"]}
{"href":"api.html#fen-core-extensions-state-providers-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.providers","kind":"data","line":57,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Singleton registry of LLM provider contributions keyed by provider name for deterministic model dispatch.","tags":["extensions","state","providers"]}
{"href":"api.html#fen-core-extensions-state-auth-backends-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.auth-backends","kind":"data","line":63,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Singleton registry of auth backend contributions keyed by name for provider credential resolution.","tags":["extensions","state","auth"]}
{"href":"api.html#fen-core-extensions-state-session-backends-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.session-backends","kind":"data","line":69,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Singleton registry of session persistence backend contributions keyed by backend name.","tags":["extensions","state","session"]}
{"href":"api.html#fen-core-extensions-state-session-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.session","kind":"data","line":75,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Active session backend selection and cached SessionInfo shared by session commands, tools, and backends.","tags":["extensions","state","session"]}
{"href":"api.html#fen-core-extensions-state-hooks-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.hooks","kind":"data","line":81,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Lifecycle hook registries, currently the before-tool hook array consulted before tool execution.","tags":["extensions","state","hooks"]}
{"href":"api.html#fen-core-extensions-state-prompt-fragments-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.prompt-fragments","kind":"data","line":87,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[PromptFragment]","summary":"Ordered system-prompt fragment registry rendered into the agent context before provider calls.","tags":["extensions","state","prompt"]}
{"href":"api.html#fen-core-extensions-state-prompt-next-seq-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.prompt-next-seq","kind":"data","line":93,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"number","summary":"Monotonic sequence counter used to keep prompt-fragment ordering stable when fragments share the same order.","tags":["extensions","state","prompt"]}
{"href":"api.html#fen-core-extensions-state-extensions-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.extensions","kind":"data","line":99,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Loader status records keyed by extension name for runtime docs, diagnostics, and extension-listing commands.","tags":["extensions","state","loader"]}
{"href":"api.html#fen-core-extensions-state-reload-fingerprints-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.reload-fingerprints","kind":"data","line":105,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Cached file/module fingerprints that let extension reload report checked and changed modules across reloads.","tags":["extensions","state","reload"]}
{"href":"api.html#fen-core-extensions-state-runtime-info-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.runtime-info","kind":"data","line":111,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table|nil","summary":"Sanitized runtime/build metadata injected by fen.main and attached to durable diagnostics.","tags":["extensions","state","diagnostics"]}
{"href":"api.html#fen-core-extensions-state-errors-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.errors","kind":"data","line":117,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"[ExtensionError]","summary":"Bounded in-memory list of sanitized extension/event-bus errors for diagnostics and user-facing commands.","tags":["extensions","state","diagnostics"]}
{"href":"api.html#fen-core-extensions-state-error-log-path-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.error-log-path","kind":"data","line":123,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"string|nil","summary":"Lazily initialized JSONL path where extension and event-bus errors are mirrored for postmortem inspection.","tags":["extensions","state","diagnostics"]}
{"href":"api.html#fen-core-extensions-state-ui-packages-core-src-fen-core-extensions-state-fnl-135","id":"fen.core.extensions.state.ui","kind":"data","line":129,"path":"packages/core/src/fen/core/extensions/state.fnl","signature":"table","summary":"Persistent presenter UI slot wrapper whose identity survives reload while active presenter behavior changes underneath.","tags":["extensions","state","ui","reload"]}
{"href":"api.html#fen-core-extensions-test-api-reset-bang-packages-core-src-fen-core-extensions-test-api-fnl-41","id":"fen.core.extensions.test_api.reset!","kind":"function","line":36,"path":"packages/core/src/fen/core/extensions/test_api.fnl","signature":"(reset!) -> nil","summary":"Wipe all extension registries in place for tests without requiring the broad runtime facade.","tags":["extensions","testing","reset"]}
{"href":"api.html#fen-core-extensions-test-api-make-runtime-api-packages-core-src-fen-core-extensions-test-api-fnl-74","id":"fen.core.extensions.test_api.make-runtime-api","kind":"function","line":74,"path":"packages/core/src/fen/core/extensions/test_api.fnl"}
{"href":"api.html#fen-core-extensions-test-api-make-packages-core-src-fen-core-extensions-test-api-fnl-86","id":"fen.core.extensions.test_api.make","kind":"function","line":81,"path":"packages/core/src/fen/core/extensions/test_api.fnl","signature":"(make ?owner ?manifest) -> ExtensionApi","summary":"Build a captured extension API for tests, resetting global extension state and recording registrations, prompts, and events.","tags":["extensions","testing","api"]}
{"href":"api.html#fen-core-extensions-util-deep-copy-packages-core-src-fen-core-extensions-util-fnl-8","id":"fen.core.extensions.util.deep-copy","kind":"function","line":3,"path":"packages/core/src/fen/core/extensions/util.fnl","signature":"(deep-copy v) -> any","summary":"Recursively copy Lua tables so extension registry records cannot mutate caller-owned contribution specs.","tags":["extensions","registry","util"]}
{"href":"api.html#fen-core-extensions-util-freeze-packages-core-src-fen-core-extensions-util-fnl-21","id":"fen.core.extensions.util.freeze","kind":"function","line":16,"path":"packages/core/src/fen/core/extensions/util.fnl","signature":"(freeze t) -> table","summary":"Return a recursive read-only proxy around a copied table for safe extension-facing introspection lists.","tags":["extensions","registry","introspection"]}
{"href":"api.html#fen-core-extensions-util-remove-where-packages-core-src-fen-core-extensions-util-fnl-46","id":"fen.core.extensions.util.remove-where","kind":"function","line":41,"path":"packages/core/src/fen/core/extensions/util.fnl","signature":"(remove-where t pred) -> nil","summary":"Mutate an array-like table in place, removing entries whose predicate returns true while iterating from the end.","tags":["extensions","registry","util"]}
{"href":"api.html#fen-core-extensions-util-clear-table-packages-core-src-fen-core-extensions-util-fnl-57","id":"fen.core.extensions.util.clear-table","kind":"function","line":52,"path":"packages/core/src/fen/core/extensions/util.fnl","signature":"(clear-table t) -> nil","summary":"Delete every key from an existing table so long-lived state table identity survives reloads and resets.","tags":["extensions","reload","state"]}
{"href":"api.html#fen-core-extensions-util-add-tagged-bang-packages-core-src-fen-core-extensions-util-fnl-65","id":"fen.core.extensions.util.add-tagged!","kind":"function","line":60,"path":"packages/core/src/fen/core/extensions/util.fnl","signature":"(add-tagged! list spec owner) -> record, unregister-fn","summary":"Append a deep-copied owner-tagged contribution to an array registry and return the record plus identity-based unregister closure.","tags":["extensions","registry","owner"]}
{"href":"api.html#fen-core-extensions-util-set-tagged-bang-packages-core-src-fen-core-extensions-util-fnl-81","id":"fen.core.extensions.util.set-tagged!","kind":"function","line":76,"path":"packages/core/src/fen/core/extensions/util.fnl","signature":"(set-tagged! dict name spec owner) -> record, unregister-fn","summary":"Install a deep-copied owner-tagged singleton registry entry and return a stale-safe unregister closure.","tags":["extensions","registry","owner"]}
{"href":"api.html#fen-core-llm-event-stream-new-stream-packages-core-src-fen-core-llm-event-stream-fnl-65","id":"fen.core.llm.event_stream.new-stream","kind":"function","line":30,"path":"packages/core/src/fen/core/llm/event_stream.fnl","signature":"(new-stream on-event) -> AssistantEventStream","summary":"Create a synchronous assistant-event sink that records events, forwards them to an observer, and captures the final result.","tags":["llm","events","stream"]}
{"href":"api.html#fen-core-llm-event-stream-terminal-event-q-packages-core-src-fen-core-llm-event-stream-fnl-65","id":"fen.core.llm.event_stream.terminal-event?","kind":"function","line":9,"path":"packages/core/src/fen/core/llm/event_stream.fnl","signature":"(terminal-event? ev) -> boolean","summary":"Return true when an assistant stream event terminates the stream with either :done or :error.","tags":["llm","events","stream"]}
{"href":"api.html#fen-core-llm-event-stream-event-result-packages-core-src-fen-core-llm-event-stream-fnl-65","id":"fen.core.llm.event_stream.event-result","kind":"function","line":18,"path":"packages/core/src/fen/core/llm/event_stream.fnl","signature":"(event-result ev) -> AssistantMessage|string|nil","summary":"Extract the final AssistantMessage or error payload carried by a terminal assistant stream event.","tags":["llm","events","stream"]}
{"href":"api.html#fen-core-llm-register-packages-core-src-fen-core-llm-init-fnl-78","id":"fen.core.llm.register","kind":"function","line":11,"path":"packages/core/src/fen/core/llm/init.fnl","signature":"(register provider) -> provider","summary":"Compatibility helper for in-process callers/tests. Prefer (extensions.register :provider provider owner) in extensions.","tags":["provider","llm"]}
{"href":"api.html#fen-core-llm-get-provider-packages-core-src-fen-core-llm-init-fnl-78","id":"fen.core.llm.get-provider","kind":"function","line":22,"path":"packages/core/src/fen/core/llm/init.fnl","signature":"(get-provider provider-name) -> provider","summary":"Resolve a provider by registered :name. Errors if the name is unknown.","tags":["provider","llm"]}
{"href":"api.html#fen-core-llm-complete-packages-core-src-fen-core-llm-init-fnl-78","id":"fen.core.llm.complete","kind":"function","line":67,"path":"packages/core/src/fen/core/llm/init.fnl","signature":"(complete provider-name model context options ?on-event ?yield-fn) -> AssistantMessage","summary":"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"]}
{"href":"api.html#fen-core-llm-emit-block-events-packages-core-src-fen-core-llm-init-fnl-78","id":"fen.core.llm.emit-block-events","kind":"function","line":31,"path":"packages/core/src/fen/core/llm/init.fnl","signature":"(emit-block-events asst emit) -> nil","summary":"Synthesize streaming block events from a complete AssistantMessage. Compatibility bridge for providers that do not implement :complete-stream natively.","tags":["provider","llm","streaming"]}
{"href":"api.html#fen-core-llm-models-config-dir-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.config-dir","kind":"function","line":16,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(config-dir) -> string","summary":"Return fen's user configuration directory, honoring XDG_CONFIG_HOME through the shared path helper.","tags":["models","config","paths"]}
{"href":"api.html#fen-core-llm-models-config-path-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.config-path","kind":"function","line":24,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(config-path) -> string","summary":"Return the models.json path used for custom provider and model registry configuration.","tags":["models","config","paths"]}
{"href":"api.html#fen-core-llm-models-load-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.load","kind":"function","line":94,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(load) -> table","summary":"Load and cache the raw providers map from models.json, returning an empty table for missing or malformed config.","tags":["models","config","providers"]}
{"href":"api.html#fen-core-llm-models-get-provider-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.get-provider","kind":"function","line":120,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(get-provider name) -> ModelsProvider|nil","summary":"Return the normalized models.json provider record for name, including api, base-url, api-key, compat, and models.","tags":["models","config","providers"]}
{"href":"api.html#fen-core-llm-models-register-providers-bang-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.register-providers!","kind":"function","line":173,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(register-providers!) -> number","summary":"Register every valid models.json provider into the extension registry under owner :models_json and return the count installed.","tags":["models","providers","extensions"]}
{"href":"api.html#fen-core-llm-models-resolve-api-key-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.resolve-api-key","kind":"function","line":58,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(resolve-api-key value) -> string|nil","summary":"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"]}
{"href":"api.html#fen-core-llm-models-looks-like-env-var-q-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.looks-like-env-var?","kind":"function","line":41,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(looks-like-env-var? s) -> boolean","summary":"Return true when an apiKey string looks like an environment variable name rather than a literal credential.","tags":["models","config","auth"]}
{"href":"api.html#fen-core-llm-models-first-model-id-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.first-model-id","kind":"function","line":130,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(first-model-id provider) -> string|nil","summary":"Pick the first declared model id from a normalized provider record for default-model selection.","tags":["models","providers","defaults"]}
{"href":"api.html#fen-core-llm-models-available-models-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.available-models","kind":"function","line":256,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(available-models opts) -> [ModelRef]","summary":"Return selectable model refs from registered providers, filtering credential-gated built-ins until auth is configured.","tags":["models","providers","resolve"]}
{"href":"api.html#fen-core-llm-models-canonical-model-id-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.canonical-model-id","kind":"function","line":208,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(canonical-model-id model-ref) -> string","summary":"Format a model reference as the canonical provider/id string accepted by model resolution and displayed by commands.","tags":["models","resolve"]}
{"href":"api.html#fen-core-llm-models-resolve-model-exact-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.resolve-model-exact","kind":"function","line":290,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(resolve-model-exact query models) -> {:status :model :candidates}","summary":"Resolve an exact model query by canonical provider/id first and then by unique bare model id.","tags":["models","resolve"]}
{"href":"api.html#fen-core-llm-models-resolve-model-packages-core-src-fen-core-llm-models-fnl-325","id":"fen.core.llm.models.resolve-model","kind":"function","line":305,"path":"packages/core/src/fen/core/llm/models.fnl","signature":"(resolve-model query models) -> {:status :model :candidates}","summary":"Resolve a model query by exact provider/id or bare id first, then by unique substring over provider/id or id.","tags":["models","resolve"]}
{"href":"api.html#fen-core-llm-retry-default-max-attempts-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.DEFAULT-MAX-ATTEMPTS","kind":"data","line":9,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"number","summary":"Default maximum number of provider HTTP attempts, including the initial try and transient retries.","tags":["llm","retry","defaults"]}
{"href":"api.html#fen-core-llm-retry-default-base-delay-ms-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.DEFAULT-BASE-DELAY-MS","kind":"data","line":16,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"number","summary":"Default base delay in milliseconds used as the first exponential-backoff jitter cap.","tags":["llm","retry","defaults"]}
{"href":"api.html#fen-core-llm-retry-default-max-delay-ms-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.DEFAULT-MAX-DELAY-MS","kind":"data","line":23,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"number","summary":"Default maximum jitter cap in milliseconds for provider retry backoff delays.","tags":["llm","retry","defaults"]}
{"href":"api.html#fen-core-llm-retry-transient-q-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.transient?","kind":"function","line":53,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"(transient? status err-message ?curl-code) -> boolean","summary":"Return true for provider HTTP status or curl code that is safe to retry below the agent message layer.","tags":["llm","http","retry"]}
{"href":"api.html#fen-core-llm-retry-mark-incomplete-stream-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.mark-incomplete-stream","kind":"function","line":237,"path":"packages/core/src/fen/core/llm/retry.fnl"}
{"href":"api.html#fen-core-llm-retry-options-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.options","kind":"function","line":175,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"(options provider ?opts ?on-event) -> table","summary":"Build with-retry options from provider request opts, honoring AGENT_FENNEL_RETRY=0 and emitting tagged :provider-retry events.","tags":["llm","http","retry"]}
{"href":"api.html#fen-core-llm-retry-parse-retry-after-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.parse-retry-after","kind":"function","line":97,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"(parse-retry-after headers) -> number|nil","summary":"Parse Retry-After or retry-after-ms response headers into a millisecond delay for provider backoff.","tags":["llm","http","retry"]}
{"href":"api.html#fen-core-llm-retry-backoff-delay-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.backoff-delay","kind":"function","line":116,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"(backoff-delay attempt base-ms max-ms) -> number","summary":"Compute a full-jitter exponential backoff delay in milliseconds for the given failed attempt number.","tags":["llm","http","retry"]}
{"href":"api.html#fen-core-llm-retry-with-retry-packages-core-src-fen-core-llm-retry-fnl-237","id":"fen.core.llm.retry.with-retry","kind":"function","line":202,"path":"packages/core/src/fen/core/llm/retry.fnl","signature":"(with-retry opts make-request ?yield!) -> response","summary":"Run a provider request with bounded retry, Retry-After support, jittered backoff, and cooperative cancellation yields.","tags":["llm","http","retry"]}
{"href":"api.html#fen-core-prompt-build-context-packages-core-src-fen-core-prompt-fnl-16","id":"fen.core.prompt.build-context","kind":"function","line":11,"path":"packages/core/src/fen/core/prompt.fnl","signature":"(build-context opts tools) -> table","summary":"Build the minimal context table passed to registered system-prompt fragment renderers.","tags":["prompt","extensions","context"]}
{"href":"api.html#fen-core-prompt-build-packages-core-src-fen-core-prompt-fnl-25","id":"fen.core.prompt.build","kind":"function","line":20,"path":"packages/core/src/fen/core/prompt.fnl","signature":"(build opts tools) -> string","summary":"Render all extension-contributed system-prompt fragments for opts/tools and return an empty string when none render.","tags":["prompt","extensions"]}
{"href":"api.html#fen-core-settings-config-dir-packages-core-src-fen-core-settings-fnl-20","id":"fen.core.settings.config-dir","kind":"function","line":15,"path":"packages/core/src/fen/core/settings.fnl","signature":"(config-dir) -> string","summary":"Return fen's user configuration directory, honoring XDG_CONFIG_HOME through the shared path helper.","tags":["settings","config","paths"]}
{"href":"api.html#fen-core-settings-config-path-packages-core-src-fen-core-settings-fnl-28","id":"fen.core.settings.config-path","kind":"function","line":23,"path":"packages/core/src/fen/core/settings.fnl","signature":"(config-path) -> string","summary":"Return the settings.json path used for mutable user preferences such as the default provider and model.","tags":["settings","config","paths"]}
{"href":"api.html#fen-core-settings-load-packages-core-src-fen-core-settings-fnl-65","id":"fen.core.settings.load","kind":"function","line":60,"path":"packages/core/src/fen/core/settings.fnl","signature":"(load ?p) -> Settings","summary":"Load normalized user settings from settings.json, returning an empty record for missing or malformed files.","tags":["settings","config"]}
{"href":"api.html#fen-core-settings-save-bang-packages-core-src-fen-core-settings-fnl-92","id":"fen.core.settings.save!","kind":"function","line":87,"path":"packages/core/src/fen/core/settings.fnl","signature":"(save! settings ?p) -> Settings","summary":"Atomically write normalized default-provider/default-model settings while preserving unknown top-level keys already on disk.","tags":["settings","config","write"]}
{"href":"api.html#fen-core-settings-set-defaults-bang-packages-core-src-fen-core-settings-fnl-111","id":"fen.core.settings.set-defaults!","kind":"function","line":106,"path":"packages/core/src/fen/core/settings.fnl","signature":"(set-defaults! provider model ?p) -> Settings","summary":"Persist the default provider and model selected by commands, then return the normalized settings record.","tags":["settings","config","models"]}
{"href":"api.html#fen-core-settings-set-thinking-default-bang-packages-core-src-fen-core-settings-fnl-120","id":"fen.core.settings.set-thinking-default!","kind":"function","line":115,"path":"packages/core/src/fen/core/settings.fnl","signature":"(set-thinking-default! level ?p) -> Settings","summary":"Persist the default provider-neutral thinking level and return the normalized settings record.","tags":["settings","config","thinking"]}
{"href":"api.html#fen-core-thinking-normalize-level-packages-core-src-fen-core-thinking-fnl-61","id":"fen.core.thinking.normalize-level","kind":"function","line":61,"path":"packages/core/src/fen/core/thinking.fnl"}
{"href":"api.html#fen-core-thinking-valid-level-q-packages-core-src-fen-core-thinking-fnl-61","id":"fen.core.thinking.valid-level?","kind":"function","line":61,"path":"packages/core/src/fen/core/thinking.fnl"}
{"href":"api.html#fen-core-thinking-levels-packages-core-src-fen-core-thinking-fnl-61","id":"fen.core.thinking.levels","kind":"function","line":61,"path":"packages/core/src/fen/core/thinking.fnl"}
{"href":"api.html#fen-core-thinking-level-list-packages-core-src-fen-core-thinking-fnl-61","id":"fen.core.thinking.level-list","kind":"function","line":61,"path":"packages/core/src/fen/core/thinking.fnl"}
{"href":"api.html#fen-core-thinking-level-packages-core-src-fen-core-thinking-fnl-61","id":"fen.core.thinking.level-","kind":"function","line":61,"path":"packages/core/src/fen/core/thinking.fnl"}
{"href":"api.html#fen-core-tools-descriptors-packages-core-src-fen-core-tools-fnl-124","id":"fen.core.tools.descriptors","kind":"function","line":22,"path":"packages/core/src/fen/core/tools.fnl","signature":"(descriptors reg) -> [Tool]","summary":"Strip executable AgentTool records down to canonical Tool descriptors passed to providers.","tags":["tools","providers"]}
{"href":"api.html#fen-core-tools-execute-call-packages-core-src-fen-core-tools-fnl-124","id":"fen.core.tools.execute-call","kind":"function","line":101,"path":"packages/core/src/fen/core/tools.fnl","signature":"(execute-call reg tool-call ctx ?yield-fn) -> {:message :result :duration-seconds :tool-call}","summary":"Execute one canonical ToolCall against the registered tools and wrap the result as a ToolResultMessage plus diagnostics.","tags":["tools","agent"]}
{"href":"api.html#fen-core-types-now-ms-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.now-ms","kind":"function","line":101,"path":"packages/core/src/fen/core/types.fnl","signature":"(now-ms) -> number","summary":"Current epoch in milliseconds. Used as the :timestamp field on canonical messages.","tags":["types","time"]}
{"href":"api.html#fen-core-types-text-block-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.text-block","kind":"function","line":108,"path":"packages/core/src/fen/core/types.fnl","see-also":["type:TextContent"],"signature":"(text-block s) -> TextContent","summary":"Build a {:type :text :text s} block. The visible-text content kind.","tags":["types","content-block"]}
{"href":"api.html#fen-core-types-thinking-block-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.thinking-block","kind":"function","line":116,"path":"packages/core/src/fen/core/types.fnl","see-also":["type:ThinkingContent"],"signature":"(thinking-block {: thinking : thinking-signature : redacted}) -> ThinkingContent","summary":"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"]}
{"href":"api.html#fen-core-types-tool-call-block-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.tool-call-block","kind":"function","line":128,"path":"packages/core/src/fen/core/types.fnl","see-also":["type:ToolCall"],"signature":"(tool-call-block id name args) -> ToolCall","summary":"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"]}
{"href":"api.html#fen-core-types-user-message-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.user-message","kind":"function","line":137,"path":"packages/core/src/fen/core/types.fnl","see-also":["type:UserMessage"],"signature":"(user-message content) -> UserMessage","summary":"Build a {:role :user :content :timestamp} message. content is a string or [TextContent].","tags":["types","message"]}
{"href":"api.html#fen-core-types-assistant-message-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.assistant-message","kind":"function","line":148,"path":"packages/core/src/fen/core/types.fnl","see-also":["type:AssistantMessage"],"signature":"(assistant-message {: content : api : provider : model : usage : stop-reason : error-message}) -> AssistantMessage","summary":"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"]}
{"href":"api.html#fen-core-types-tool-result-message-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.tool-result-message","kind":"function","line":166,"path":"packages/core/src/fen/core/types.fnl","see-also":["type:ToolResultMessage"],"signature":"(tool-result-message {: tool-call-id : tool-name : content : details : is-error?}) -> ToolResultMessage","summary":"Build a canonical ToolResultMessage. content is always an array; details is opaque presenter payload.","tags":["types","message","tool-result"]}
{"href":"api.html#fen-core-types-assistant-error-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.assistant-error","kind":"function","line":182,"path":"packages/core/src/fen/core/types.fnl","signature":"(assistant-error api provider model error-message) -> AssistantMessage","summary":"Build an AssistantMessage representing a transport/HTTP failure. Sets stop-reason :error and inserts a synthetic \"[error] ...\" text block.","tags":["types","message","error"]}
{"href":"api.html#fen-core-types-incomplete-stream-msg-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.INCOMPLETE-STREAM-MSG","kind":"data","line":195,"path":"packages/core/src/fen/core/types.fnl","signature":"string","summary":"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"]}
{"href":"api.html#fen-core-types-assistant-text-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.assistant-text","kind":"function","line":202,"path":"packages/core/src/fen/core/types.fnl","signature":"(assistant-text msg) -> string","summary":"Concatenate every TextContent block in msg.content. Returns \"\" if there are no text blocks.","tags":["types","message","accessor"]}
{"href":"api.html#fen-core-types-assistant-tool-calls-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.assistant-tool-calls","kind":"function","line":222,"path":"packages/core/src/fen/core/types.fnl","signature":"(assistant-tool-calls msg) -> [ToolCall]","summary":"Return every :tool-call block in msg.content, in source order.","tags":["types","message","accessor","tool-call"]}
{"href":"api.html#fen-core-types-assistant-thinking-packages-core-src-fen-core-types-fnl-236","id":"fen.core.types.assistant-thinking","kind":"function","line":229,"path":"packages/core/src/fen/core/types.fnl","signature":"(assistant-thinking msg) -> [ThinkingContent]","summary":"Return every :thinking block in msg.content, in source order.","tags":["types","message","accessor","thinking"]}
{"href":"api.html#fen-provider-help-render-index-packages-fen-src-fen-provider-help-fnl-123","id":"fen.provider_help.render-index","kind":"function","line":123,"path":"packages/fen/src/fen/provider_help.fnl"}
{"href":"api.html#fen-provider-help-render-provider-packages-fen-src-fen-provider-help-fnl-150","id":"fen.provider_help.render-provider","kind":"function","line":150,"path":"packages/fen/src/fen/provider_help.fnl"}
{"href":"api.html#fen-provider-help-known-provider-q-packages-fen-src-fen-provider-help-fnl-157","id":"fen.provider_help.known-provider?","kind":"function","line":157,"path":"packages/fen/src/fen/provider_help.fnl"}
{"href":"api.html#fen-provider-help-dispatch-packages-fen-src-fen-provider-help-fnl-160","id":"fen.provider_help.dispatch","kind":"function","line":160,"path":"packages/fen/src/fen/provider_help.fnl"}
{"href":"api.html#fen-provider-help-missing-provider-message-packages-fen-src-fen-provider-help-fnl-173","id":"fen.provider_help.missing-provider-message","kind":"function","line":173,"path":"packages/fen/src/fen/provider_help.fnl"}
{"href":"api.html#fen-provider-help-unknown-provider-message-packages-fen-src-fen-provider-help-fnl-198","id":"fen.provider_help.unknown-provider-message","kind":"function","line":198,"path":"packages/fen/src/fen/provider_help.fnl"}
{"href":"api.html#fen-script-runner-usage-packages-fen-src-fen-script-runner-fnl-46","id":"fen.script_runner.usage","kind":"function","line":41,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(usage) -> string","summary":"Return command-line usage text for fen run.","tags":["cli","scripts"]}
{"href":"api.html#fen-script-runner-eval-usage-packages-fen-src-fen-script-runner-fnl-53","id":"fen.script_runner.eval-usage","kind":"function","line":48,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(eval-usage) -> string","summary":"Return command-line usage text for fen eval.","tags":["cli","scripts","eval"]}
{"href":"api.html#fen-script-runner-infer-language-packages-fen-src-fen-script-runner-fnl-60","id":"fen.script_runner.infer-language","kind":"function","line":55,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(infer-language script ?override) -> :lua|:fennel","summary":"Choose the runner language, using an explicit override before script extension inference.","tags":["cli","scripts"]}
{"href":"api.html#fen-script-runner-build-arg-table-packages-fen-src-fen-script-runner-fnl-69","id":"fen.script_runner.build-arg-table","kind":"function","line":64,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(build-arg-table argv script-index) -> table","summary":"Build a Lua-compatible global arg table for a script selected from fen's original argv.","tags":["cli","scripts","compatibility"]}
{"href":"api.html#fen-script-runner-build-eval-arg-table-packages-fen-src-fen-script-runner-fnl-85","id":"fen.script_runner.build-eval-arg-table","kind":"function","line":80,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(build-eval-arg-table argv code-index) -> table","summary":"Build a Lua-compatible global arg table for inline eval code.","tags":["cli","scripts","eval","compatibility"]}
{"href":"api.html#fen-script-runner-parse-packages-fen-src-fen-script-runner-fnl-105","id":"fen.script_runner.parse","kind":"function","line":100,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(parse argv) -> table|nil, err|nil","summary":"Parse fen run arguments without invoking the general agent option parser.","tags":["cli","scripts"]}
{"href":"api.html#fen-script-runner-parse-eval-packages-fen-src-fen-script-runner-fnl-144","id":"fen.script_runner.parse-eval","kind":"function","line":139,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(parse-eval argv) -> table|nil, err|nil","summary":"Parse fen eval arguments without invoking the general agent option parser.","tags":["cli","scripts","eval"]}
{"href":"api.html#fen-script-runner-run-bang-packages-fen-src-fen-script-runner-fnl-221","id":"fen.script_runner.run!","kind":"function","line":216,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(run! argv) -> integer","summary":"Run the script selected by fen run and return the process exit code.","tags":["cli","scripts"]}
{"href":"api.html#fen-script-runner-eval-bang-packages-fen-src-fen-script-runner-fnl-245","id":"fen.script_runner.eval!","kind":"function","line":240,"path":"packages/fen/src/fen/script_runner.fnl","signature":"(eval! argv) -> integer","summary":"Evaluate the code selected by fen eval and return the process exit code.","tags":["cli","scripts","eval"]}
{"href":"api.html#fen-turn-lifecycle-complete-event-packages-fen-src-fen-turn-lifecycle-fnl-32","id":"fen.turn_lifecycle.complete-event","kind":"function","line":27,"path":"packages/fen/src/fen/turn_lifecycle.fnl","signature":"(complete-event state ok? result-or-error) -> table","summary":"Build an :agent-turn-complete event for a finished agent turn.","tags":["agent","lifecycle","events"]}
{"href":"api.html#fen-turn-lifecycle-emit-complete-bang-packages-fen-src-fen-turn-lifecycle-fnl-53","id":"fen.turn_lifecycle.emit-complete!","kind":"function","line":48,"path":"packages/fen/src/fen/turn_lifecycle.fnl","signature":"(emit-complete! state ok? result-or-error) -> table","summary":"Emit and return the :agent-turn-complete lifecycle event for a finished agent turn.","tags":["agent","lifecycle","events"]}
{"href":"api.html#fen-update-run-bang-packages-fen-src-fen-update-fnl-235","id":"fen.update.run!","kind":"function","line":230,"path":"packages/fen/src/fen/update.fnl","signature":"(run! argv) -> exit-code","summary":"Replace the running release binary with the latest GitHub release; refuses source/dev builds.","tags":["update","self-update","distribution"]}
{"href":"api.html#fen-version-info-packages-fen-src-fen-version-fnl-51","id":"fen.version.info","kind":"function","line":46,"path":"packages/fen/src/fen/version.fnl","signature":"(info) -> VersionInfo","summary":"Return source-checkout version metadata; Nix builds replace this module with a stamped table.","tags":["version","build","metadata"]}
{"href":"api.html#fen-version-version-packages-fen-src-fen-version-fnl-59","id":"fen.version.version","kind":"function","line":54,"path":"packages/fen/src/fen/version.fnl","signature":"(version) -> string","summary":"Return the short source version string used by CLI/status displays.","tags":["version","build","metadata"]}
{"href":"api.html#fen-version-format-packages-fen-src-fen-version-fnl-67","id":"fen.version.format","kind":"function","line":62,"path":"packages/fen/src/fen/version.fnl","signature":"(format ?info) -> string","summary":"Format version metadata as the single-line `fen --version` display.","tags":["version","build","metadata"]}
{"href":"api.html#fen-testing-shellquote-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.shellquote","kind":"function","line":5,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(shellquote s) -> string","summary":"Quote a string for POSIX shell commands used by test filesystem helpers.","tags":["testing","shell","paths"]}
{"href":"api.html#fen-testing-stub-getenv-bang-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.stub-getenv!","kind":"function","line":23,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(stub-getenv! resolver) -> nil","summary":"Replace os.getenv in tests with a resolver that can delegate to the original environment lookup.","tags":["testing","env","stubs"]}
{"href":"api.html#fen-testing-restore-getenv-bang-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.restore-getenv!","kind":"function","line":34,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(restore-getenv!) -> nil","summary":"Restore the original os.getenv captured before tests installed any environment stubs.","tags":["testing","env","stubs"]}
{"href":"api.html#fen-testing-reload-module-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.reload-module","kind":"function","line":42,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(reload-module name) -> any","summary":"Clear package.loaded for one module and require it again so tests can observe module initialization behavior.","tags":["testing","reload","modules"]}
{"href":"api.html#fen-testing-stub-http-bang-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.stub-http!","kind":"function","line":51,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(stub-http! responder) -> nil","summary":"Replace fen.util.http's backend with a test responder and clear the cached frontend module.","tags":["testing","http","stubs"]}
{"href":"api.html#fen-testing-restore-http-bang-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.restore-http!","kind":"function","line":65,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(restore-http!) -> nil","summary":"Remove the stubbed HTTP backend and cached frontend so later tests reload the normal transport.","tags":["testing","http","stubs"]}
{"href":"api.html#fen-testing-make-tmpdir-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.make-tmpdir","kind":"function","line":74,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(make-tmpdir) -> string","summary":"Create and register ownership of a temporary directory that rmtree is allowed to remove.","tags":["testing","temp","files"]}
{"href":"api.html#fen-testing-rmtree-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.rmtree","kind":"function","line":87,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(rmtree path) -> nil","summary":"Remove an owned temporary directory tree, refusing arbitrary or unsafe paths.","tags":["testing","temp","files","safety"]}
{"href":"api.html#fen-testing-write-file-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.write-file","kind":"function","line":106,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(write-file path content) -> path","summary":"Create parent directories as needed and write content to a test fixture file.","tags":["testing","files","fixtures"]}
{"href":"api.html#fen-testing-append-file-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.append-file","kind":"function","line":120,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(append-file path content) -> path","summary":"Append content to a test fixture file and return the path for fluent setup code.","tags":["testing","files","fixtures"]}
{"href":"api.html#fen-testing-read-file-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.read-file","kind":"function","line":131,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(read-file path) -> string|nil","summary":"Read a file if it exists, returning nil instead of failing for optional fixture paths.","tags":["testing","files","fixtures"]}
{"href":"api.html#fen-testing-read-file-bang-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.read-file!","kind":"function","line":143,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(read-file! path) -> string","summary":"Read a required fixture file and fail the test immediately if it cannot be opened.","tags":["testing","files","fixtures"]}
{"href":"api.html#fen-testing-make-tmpfile-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.make-tmpfile","kind":"function","line":154,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(make-tmpfile content) -> string","summary":"Create an owned temporary file, write initial content, and return its path for the test.","tags":["testing","temp","files"]}
{"href":"api.html#fen-testing-rm-file-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.rm-file","kind":"function","line":170,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(rm-file path) -> nil","summary":"Remove an owned temporary file and refuse paths that were not created by make-tmpfile.","tags":["testing","temp","files","safety"]}
{"href":"api.html#fen-testing-assert-no-leaks-bang-packages-testing-src-fen-testing-init-fnl-195","id":"fen.testing.assert-no-leaks!","kind":"function","line":183,"path":"packages/testing/src/fen/testing/init.fnl","signature":"(assert-no-leaks!) -> nil","summary":"Assert that all owned temporary roots and files have been cleaned up by the test suite.","tags":["testing","temp","safety"]}
{"href":"api.html#fen-testing-macros-with-tmpdir-packages-testing-src-fen-testing-macros-fnl-43","id":"fen.testing.macros.with-tmpdir","kind":"function","line":14,"path":"packages/testing/src/fen/testing/macros.fnl","signature":"(with-tmpdir [name] body...) -> macro-form","summary":"Macro that creates an owned temp directory for a test body and always removes it afterward.","tags":["testing","macros","temp"]}
{"href":"api.html#fen-testing-macros-with-tmpfile-packages-testing-src-fen-testing-macros-fnl-43","id":"fen.testing.macros.with-tmpfile","kind":"function","line":28,"path":"packages/testing/src/fen/testing/macros.fnl","signature":"(with-tmpfile [name content] body...) -> macro-form","summary":"Macro that creates an owned temp file with content for a test body and always removes it afterward.","tags":["testing","macros","temp"]}
{"href":"api.html#fen-testing-pty-spawn-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.spawn","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-read-until-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.read-until","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-drain-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.drain","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-now-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.now","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-artifact-dir-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.artifact-dir","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-ensure-dir-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.ensure-dir","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-write-file-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.write-file","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-append-file-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.append-file","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-encode-json-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.encode-json","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-cast-start-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.cast-start","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-pty-cast-event-packages-testing-src-fen-testing-pty-fnl-107","id":"fen.testing.pty.cast-event","kind":"function","line":107,"path":"packages/testing/src/fen/testing/pty.fnl"}
{"href":"api.html#fen-testing-tui-install-termbox-stub-bang-packages-testing-src-fen-testing-tui-fnl-7","id":"fen.testing.tui.install-termbox-stub!","kind":"function","line":7,"path":"packages/testing/src/fen/testing/tui.fnl"}
{"href":"api.html#fen-testing-tui-install-markdown-stub-bang-packages-testing-src-fen-testing-tui-fnl-52","id":"fen.testing.tui.install-markdown-stub!","kind":"function","line":52,"path":"packages/testing/src/fen/testing/tui.fnl"}
{"href":"api.html#fen-testing-tui-reset-state-bang-packages-testing-src-fen-testing-tui-fnl-59","id":"fen.testing.tui.reset-state!","kind":"function","line":59,"path":"packages/testing/src/fen/testing/tui.fnl"}
{"href":"api.html#fen-util-base64-decode-standard-packages-util-src-fen-util-base64-fnl-120","id":"fen.util.base64.decode-standard","kind":"function","line":20,"path":"packages/util/src/fen/util/base64.fnl","signature":"(decode-standard s) -> string","summary":"Decode a standard base64 string with optional padding into its raw byte string for trusted token payloads.","tags":["util","encoding","base64"]}
{"href":"api.html#fen-util-base64-decode-url-packages-util-src-fen-util-base64-fnl-120","id":"fen.util.base64.decode-url","kind":"function","line":50,"path":"packages/util/src/fen/util/base64.fnl","signature":"(decode-url s) -> string|nil","summary":"Decode an unpadded base64url string by restoring the standard alphabet and padding before decoding.","tags":["util","encoding","base64"]}
{"href":"api.html#fen-util-base64-encode-standard-packages-util-src-fen-util-base64-fnl-120","id":"fen.util.base64.encode-standard","kind":"function","line":68,"path":"packages/util/src/fen/util/base64.fnl","signature":"(encode-standard bytes) -> string","summary":"Encode a raw byte string as standard base64 with RFC-style `=` padding.","tags":["util","encoding","base64"]}
{"href":"api.html#fen-util-base64-encode-url-packages-util-src-fen-util-base64-fnl-120","id":"fen.util.base64.encode-url","kind":"function","line":105,"path":"packages/util/src/fen/util/base64.fnl","signature":"(encode-url bytes) -> string|nil","summary":"Encode raw bytes as unpadded base64url for PKCE and token-related wire formats.","tags":["util","encoding","base64"]}
{"href":"api.html#fen-util-checksum-file-fingerprint-packages-util-src-fen-util-checksum-fnl-80","id":"fen.util.checksum.file-fingerprint","kind":"function","line":6,"path":"packages/util/src/fen/util/checksum.fnl","signature":"(file-fingerprint path) -> table|nil","summary":"Compute a small non-cryptographic checksum/size fingerprint for a file used by reload-change diagnostics.","tags":["util","checksum","reload"]}
{"href":"api.html#fen-util-checksum-module-path-packages-util-src-fen-util-checksum-fnl-80","id":"fen.util.checksum.module-path","kind":"function","line":56,"path":"packages/util/src/fen/util/checksum.fnl","signature":"(module-path modname) -> string|nil","summary":"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"]}
{"href":"api.html#fen-util-checksum-module-fingerprint-packages-util-src-fen-util-checksum-fnl-80","id":"fen.util.checksum.module-fingerprint","kind":"function","line":70,"path":"packages/util/src/fen/util/checksum.fnl","signature":"(module-fingerprint modname) -> table|nil","summary":"Resolve and fingerprint a Lua module source file, returning nil when the module has no package.path file.","tags":["util","checksum","modules","reload"]}
{"href":"api.html#fen-util-flat-extensions-build-map-packages-util-src-fen-util-flat-extensions-fnl-123","id":"fen.util.flat_extensions.build-map","kind":"function","line":118,"path":"packages/util/src/fen/util/flat_extensions.fnl","signature":"(build-map roots) -> table","summary":"Walk flat extension roots and build the manifest :name to directory map used by the namespace searcher.","tags":["util","extensions","searcher"]}
{"href":"api.html#fen-util-flat-extensions-resolve-fnl-packages-util-src-fen-util-flat-extensions-fnl-142","id":"fen.util.flat_extensions.resolve-fnl","kind":"function","line":137,"path":"packages/util/src/fen/util/flat_extensions.fnl","signature":"(resolve-fnl map modname) -> string|nil","summary":"Return the flat source path for a fen.extensions module from a manifest-name map.","tags":["util","extensions","searcher","reload"]}
{"href":"api.html#fen-util-flat-extensions-make-searcher-packages-util-src-fen-util-flat-extensions-fnl-163","id":"fen.util.flat_extensions.make-searcher","kind":"function","line":158,"path":"packages/util/src/fen/util/flat_extensions.fnl","signature":"(make-searcher fennel map) -> searcher-fn","summary":"Build a package.searchers entry that maps fen.extensions.<name> modules back to flat extension source files.","tags":["util","extensions","searcher"]}
{"href":"api.html#fen-util-flat-extensions-install-bang-packages-util-src-fen-util-flat-extensions-fnl-180","id":"fen.util.flat_extensions.install!","kind":"function","line":175,"path":"packages/util/src/fen/util/flat_extensions.fnl","signature":"(install! opts) -> searcher-fn","summary":"Build and insert the flat-extension searcher into package.searchers at the requested position.","tags":["util","extensions","searcher"]}
{"href":"api.html#fen-util-http-backends-native-request-packages-util-src-fen-util-http-backends-native-fnl-48","id":"fen.util.http.backends.native.request","kind":"function","line":36,"path":"packages/util/src/fen/util/http/backends/native.fnl","signature":"(request opts) -> {:status :body :headers}|{:error :curl-code?}","summary":"Translate kebab-case HTTP options/results and dispatch to the project-owned fen_http libcurl binding.","tags":["util","http","native"]}
{"href":"api.html#fen-util-http-request-packages-util-src-fen-util-http-init-fnl-59","id":"fen.util.http.request","kind":"function","line":14,"path":"packages/util/src/fen/util/http/init.fnl","signature":"(request opts) -> {:status :body :headers}|{:error}","summary":"Perform an HTTP request through the selected backend, supporting streaming chunks and cooperative yielding.","tags":["util","http","providers"]}
{"href":"api.html#fen-util-id-random-hex-packages-util-src-fen-util-id-fnl-20","id":"fen.util.id.random-hex","kind":"function","line":20,"path":"packages/util/src/fen/util/id.fnl"}
{"href":"api.html#fen-util-id-uuidv7-packages-util-src-fen-util-id-fnl-38","id":"fen.util.id.uuidv7","kind":"function","line":38,"path":"packages/util/src/fen/util/id.fnl"}
{"href":"api.html#fen-util-json-encode-packages-util-src-fen-util-json-fnl-29","id":"fen.util.json.encode","kind":"data","line":9,"path":"packages/util/src/fen/util/json.fnl","signature":"cjson.empty_array","summary":"Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.","tags":["util","json"]}
{"href":"api.html#fen-util-json-decode-packages-util-src-fen-util-json-fnl-29","id":"fen.util.json.decode","kind":"data","line":9,"path":"packages/util/src/fen/util/json.fnl","signature":"cjson.empty_array","summary":"Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.","tags":["util","json"]}
{"href":"api.html#fen-util-json-null-packages-util-src-fen-util-json-fnl-29","id":"fen.util.json.null","kind":"data","line":9,"path":"packages/util/src/fen/util/json.fnl","signature":"cjson.empty_array","summary":"Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.","tags":["util","json"]}
{"href":"api.html#fen-util-json-empty-array-packages-util-src-fen-util-json-fnl-29","id":"fen.util.json.empty-array","kind":"data","line":9,"path":"packages/util/src/fen/util/json.fnl","signature":"cjson.empty_array","summary":"Sentinel table that serializes as [] instead of {}, used when provider wire payloads require literal empty arrays.","tags":["util","json"]}
{"href":"api.html#fen-util-log-debug-packages-util-src-fen-util-log-fnl-50","id":"fen.util.log.debug","kind":"function","line":25,"path":"packages/util/src/fen/util/log.fnl","signature":"(timestamp) -> string","summary":"Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.","tags":["util","logging","time"]}
{"href":"api.html#fen-util-log-info-packages-util-src-fen-util-log-fnl-50","id":"fen.util.log.info","kind":"function","line":25,"path":"packages/util/src/fen/util/log.fnl","signature":"(timestamp) -> string","summary":"Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.","tags":["util","logging","time"]}
{"href":"api.html#fen-util-log-warn-packages-util-src-fen-util-log-fnl-50","id":"fen.util.log.warn","kind":"function","line":25,"path":"packages/util/src/fen/util/log.fnl","signature":"(timestamp) -> string","summary":"Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.","tags":["util","logging","time"]}
{"href":"api.html#fen-util-log-error-packages-util-src-fen-util-log-fnl-50","id":"fen.util.log.error","kind":"function","line":25,"path":"packages/util/src/fen/util/log.fnl","signature":"(timestamp) -> string","summary":"Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.","tags":["util","logging","time"]}
{"href":"api.html#fen-util-log-timestamp-packages-util-src-fen-util-log-fnl-50","id":"fen.util.log.timestamp","kind":"function","line":25,"path":"packages/util/src/fen/util/log.fnl","signature":"(timestamp) -> string","summary":"Return the current UTC time formatted as RFC3339/ISO8601 for diagnostic file output.","tags":["util","logging","time"]}
{"href":"api.html#fen-util-log-sink-open-bang-packages-util-src-fen-util-log-sink-fnl-23","id":"fen.util.log_sink.open!","kind":"function","line":18,"path":"packages/util/src/fen/util/log_sink.fnl","signature":"(open! path) -> boolean,?string","summary":"Open path in append mode as the active log sink, closing any prior handle. Returns ok?, err.","tags":["util","logging","sink"]}
{"href":"api.html#fen-util-log-sink-close-bang-packages-util-src-fen-util-log-sink-fnl-36","id":"fen.util.log_sink.close!","kind":"function","line":31,"path":"packages/util/src/fen/util/log_sink.fnl","signature":"(close!) -> nil","summary":"Close and clear the active log sink handle, returning log routing to stderr.","tags":["util","logging","sink"]}
{"href":"api.html#fen-util-log-sink-active-q-packages-util-src-fen-util-log-sink-fnl-46","id":"fen.util.log_sink.active?","kind":"function","line":41,"path":"packages/util/src/fen/util/log_sink.fnl","signature":"(active?) -> boolean","summary":"True when a file sink is currently open and write-line will land in the file.","tags":["util","logging","sink"]}
{"href":"api.html#fen-util-log-sink-write-line-packages-util-src-fen-util-log-sink-fnl-68","id":"fen.util.log_sink.write-line","kind":"function","line":49,"path":"packages/util/src/fen/util/log_sink.fnl","signature":"(write-line s) -> boolean,?string","summary":"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"]}
{"href":"api.html#fen-util-path-home-packages-util-src-fen-util-path-fnl-21","id":"fen.util.path.home","kind":"function","line":16,"path":"packages/util/src/fen/util/path.fnl","signature":"(home) -> string","summary":"Return HOME with a /tmp fallback so path helpers remain usable in stripped-down test or daemon environments.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-config-home-packages-util-src-fen-util-path-fnl-29","id":"fen.util.path.config-home","kind":"function","line":24,"path":"packages/util/src/fen/util/path.fnl","signature":"(config-home) -> string","summary":"Return XDG_CONFIG_HOME or the conventional ~/.config directory under the resolved home path.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-config-dir-packages-util-src-fen-util-path-fnl-40","id":"fen.util.path.config-dir","kind":"function","line":35,"path":"packages/util/src/fen/util/path.fnl","signature":"(config-dir app) -> string","summary":"Return the per-application configuration directory under the XDG config home.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-state-home-packages-util-src-fen-util-path-fnl-48","id":"fen.util.path.state-home","kind":"function","line":43,"path":"packages/util/src/fen/util/path.fnl","signature":"(state-home) -> string","summary":"Return XDG_STATE_HOME or the conventional ~/.local/state directory under the resolved home path.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-state-dir-packages-util-src-fen-util-path-fnl-59","id":"fen.util.path.state-dir","kind":"function","line":54,"path":"packages/util/src/fen/util/path.fnl","signature":"(state-dir app) -> string","summary":"Return the per-application state directory under the XDG state home.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-data-home-packages-util-src-fen-util-path-fnl-67","id":"fen.util.path.data-home","kind":"function","line":62,"path":"packages/util/src/fen/util/path.fnl","signature":"(data-home) -> string","summary":"Return XDG_DATA_HOME or the conventional ~/.local/share directory under the resolved home path.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-data-dir-packages-util-src-fen-util-path-fnl-78","id":"fen.util.path.data-dir","kind":"function","line":73,"path":"packages/util/src/fen/util/path.fnl","signature":"(data-dir app) -> string","summary":"Return the per-application data directory under the XDG data home.","tags":["util","paths","xdg"]}
{"href":"api.html#fen-util-path-ensure-dir-bang-packages-util-src-fen-util-path-fnl-86","id":"fen.util.path.ensure-dir!","kind":"function","line":81,"path":"packages/util/src/fen/util/path.fnl","signature":"(ensure-dir! dir) -> nil","summary":"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"]}
{"href":"api.html#fen-util-path-shell-quote-packages-util-src-fen-util-path-fnl-94","id":"fen.util.path.shell-quote","kind":"function","line":89,"path":"packages/util/src/fen/util/path.fnl","signature":"(shell-quote s) -> string","summary":"Quote a value as one POSIX shell word for helper functions that must invoke system tools safely.","tags":["util","paths","shell"]}
{"href":"api.html#fen-util-path-dirname-packages-util-src-fen-util-path-fnl-102","id":"fen.util.path.dirname","kind":"function","line":97,"path":"packages/util/src/fen/util/path.fnl","signature":"(dirname path) -> string","summary":"Return the directory portion of a path, using . for bare names and / for root-level paths.","tags":["util","paths"]}
{"href":"api.html#fen-util-path-basename-packages-util-src-fen-util-path-fnl-113","id":"fen.util.path.basename","kind":"function","line":108,"path":"packages/util/src/fen/util/path.fnl","signature":"(basename path) -> string","summary":"Return the final path component while tolerating a trailing slash.","tags":["util","paths"]}
{"href":"api.html#fen-util-path-pwd-physical-packages-util-src-fen-util-path-fnl-121","id":"fen.util.path.pwd-physical","kind":"function","line":116,"path":"packages/util/src/fen/util/path.fnl","signature":"(pwd-physical dir) -> string|nil","summary":"Resolve a directory through `pwd -P`, returning its physical path or nil if the shell probe fails.","tags":["util","paths","shell"]}
{"href":"api.html#fen-util-path-cwd-packages-util-src-fen-util-path-fnl-134","id":"fen.util.path.cwd","kind":"function","line":129,"path":"packages/util/src/fen/util/path.fnl","signature":"(cwd) -> string","summary":"Return the user's current directory spelling from PWD, falling back to a physical pwd probe and then . .","tags":["util","paths","cwd"]}
{"href":"api.html#fen-util-path-realpath-packages-util-src-fen-util-path-fnl-142","id":"fen.util.path.realpath","kind":"function","line":137,"path":"packages/util/src/fen/util/path.fnl","signature":"(realpath path) -> string","summary":"Resolve the directory portion of a path physically while preserving the original basename.","tags":["util","paths"]}
{"href":"api.html#fen-util-path-file-exists-q-packages-util-src-fen-util-path-fnl-179","id":"fen.util.path.file-exists?","kind":"function","line":174,"path":"packages/util/src/fen/util/path.fnl","signature":"(file-exists? path) -> boolean","summary":"Return true only for regular files, preferring LuaFileSystem and falling back to POSIX test -f.","tags":["util","paths","filesystem"]}
{"href":"api.html#fen-util-path-dir-exists-q-packages-util-src-fen-util-path-fnl-191","id":"fen.util.path.dir-exists?","kind":"function","line":186,"path":"packages/util/src/fen/util/path.fnl","signature":"(dir-exists? path) -> boolean","summary":"Return true only for directories, preferring LuaFileSystem and falling back to POSIX test -d.","tags":["util","paths","filesystem"]}
{"href":"api.html#fen-util-path-ancestors-root-to-leaf-packages-util-src-fen-util-path-fnl-200","id":"fen.util.path.ancestors-root-to-leaf","kind":"function","line":195,"path":"packages/util/src/fen/util/path.fnl","signature":"(ancestors-root-to-leaf start) -> [string]","summary":"Return a physical ancestor chain from / to start for deterministic project-context discovery.","tags":["util","paths","discovery"]}
{"href":"api.html#fen-util-process-read-pipe-coop-packages-util-src-fen-util-process-fnl-367","id":"fen.util.process.read-pipe-coop","kind":"function","line":27,"path":"packages/util/src/fen/util/process.fnl","signature":"(read-pipe-coop pipe yield-fn) -> string","summary":"Drain a popen pipe in nonblocking chunks, yielding on EAGAIN so cooperative tool execution keeps the UI responsive.","tags":["util","process","cooperative"]}
{"href":"api.html#fen-util-process-read-pipe-close-packages-util-src-fen-util-process-fnl-367","id":"fen.util.process.read-pipe-close","kind":"function","line":62,"path":"packages/util/src/fen/util/process.fnl","signature":"(read-pipe-close pipe yield-fn?) -> string","summary":"Drain and close a popen pipe, guaranteeing close runs even when cooperative cancellation raises through yield-fn.","tags":["util","process","cooperative","popen"]}
{"href":"api.html#fen-util-process-run-captured-packages-util-src-fen-util-process-fnl-367","id":"fen.util.process.run-captured","kind":"function","line":147,"path":"packages/util/src/fen/util/process.fnl","signature":"(run-captured opts yield-fn?) -> table","summary":"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"]}
{"href":"api.html#fen-util-process-monotonic-ms-packages-util-src-fen-util-process-fnl-367","id":"fen.util.process.monotonic-ms","kind":"function","line":367,"path":"packages/util/src/fen/util/process.fnl"}
{"href":"api.html#fen-util-process-sleep-ms-packages-util-src-fen-util-process-fnl-367","id":"fen.util.process.sleep-ms","kind":"function","line":367,"path":"packages/util/src/fen/util/process.fnl"}
{"href":"api.html#fen-util-random-bytes-packages-util-src-fen-util-random-fnl-21","id":"fen.util.random.bytes","kind":"function","line":11,"path":"packages/util/src/fen/util/random.fnl","signature":"(bytes n) -> string","summary":"Return n cryptographically random raw bytes from the platform RNG through the fen_random native binding.","tags":["util","random","crypto"]}
{"href":"api.html#fen-util-search-bitap-compile-packages-util-src-fen-util-search-bitap-fnl-20","id":"fen.util.search.bitap.compile","kind":"function","line":20,"path":"packages/util/src/fen/util/search/bitap.fnl"}
{"href":"api.html#fen-util-search-bitap-match-packages-util-src-fen-util-search-bitap-fnl-109","id":"fen.util.search.bitap.match","kind":"function","line":109,"path":"packages/util/src/fen/util/search/bitap.fnl"}
{"href":"api.html#fen-util-search-bitap-score-packages-util-src-fen-util-search-bitap-fnl-118","id":"fen.util.search.bitap.score","kind":"function","line":118,"path":"packages/util/src/fen/util/search/bitap.fnl"}
{"href":"api.html#fen-util-sha256-digest-packages-util-src-fen-util-sha256-fnl-130","id":"fen.util.sha256.digest","kind":"function","line":98,"path":"packages/util/src/fen/util/sha256.fnl","signature":"(digest bytes) -> string","summary":"Compute SHA-256 for a Lua string and return the 32-byte raw digest used by PKCE challenge construction.","tags":["util","crypto","sha256"]}
{"href":"api.html#fen-util-sha256-hex-digest-packages-util-src-fen-util-sha256-fnl-130","id":"fen.util.sha256.hex-digest","kind":"function","line":117,"path":"packages/util/src/fen/util/sha256.fnl","signature":"(hex-digest bytes) -> string","summary":"Compute SHA-256 for a Lua string and return the lowercase 64-character hexadecimal digest.","tags":["util","crypto","sha256"]}
{"href":"api.html#fen-util-sse-new-parser-packages-util-src-fen-util-sse-fnl-125","id":"fen.util.sse.new-parser","kind":"function","line":28,"path":"packages/util/src/fen/util/sse.fnl","signature":"(new-parser on-event) -> parser","summary":"Create an incremental Server-Sent Events parser that accepts arbitrary chunks and dispatches complete event tables.","tags":["util","sse","streaming"]}
{"href":"api.html#fen-util-sse-parse-packages-util-src-fen-util-sse-fnl-125","id":"fen.util.sse.parse","kind":"function","line":99,"path":"packages/util/src/fen/util/sse.fnl","signature":"(parse raw) -> [SseEvent]","summary":"Parse a complete Server-Sent Events payload into event tables, flushing any final unterminated line.","tags":["util","sse","streaming"]}
{"href":"api.html#fen-util-sse-json-events-packages-util-src-fen-util-sse-fnl-125","id":"fen.util.sse.json-events","kind":"function","line":112,"path":"packages/util/src/fen/util/sse.fnl","signature":"(json-events raw) -> [table]","summary":"Parse an SSE payload and JSON-decode every non-empty, non-[DONE] data field for provider tests and adapters.","tags":["util","sse","json"]}
{"href":"api.html#fen-util-text-default-tool-result-max-bytes-packages-util-src-fen-util-text-fnl-227","id":"fen.util.text.default-tool-result-max-bytes","kind":"function","line":227,"path":"packages/util/src/fen/util/text.fnl"}
{"href":"api.html#fen-util-text-trim-packages-util-src-fen-util-text-fnl-227","id":"fen.util.text.trim","kind":"function","line":11,"path":"packages/util/src/fen/util/text.fnl","signature":"(trim s) -> string","summary":"Strip leading and trailing ASCII whitespace; nil becomes \"\".","tags":["util","text"]}
{"href":"api.html#fen-util-text-first-line-packages-util-src-fen-util-text-fnl-227","id":"fen.util.text.first-line","kind":"function","line":19,"path":"packages/util/src/fen/util/text.fnl","signature":"(first-line s) -> string","summary":"Return the substring up to the first newline; nil becomes \"\".","tags":["util","text"]}
{"href":"api.html#fen-util-text-sanitize-packages-util-src-fen-util-text-fnl-227","id":"fen.util.text.sanitize","kind":"function","line":97,"path":"packages/util/src/fen/util/text.fnl","signature":"(sanitize s) -> {:text :changed? :unsafe-count :invalid-count :input-bytes}","summary":"Escape unsafe control bytes and invalid UTF-8 while preserving valid text and \\n/\\r/\\t.","tags":["util","text","tools","sessions","providers"]}
{"href":"api.html#fen-util-text-scrub-tool-text-packages-util-src-fen-util-text-fnl-227","id":"fen.util.text.scrub-tool-text","kind":"function","line":174,"path":"packages/util/src/fen/util/text.fnl","signature":"(scrub-tool-text s ?opts) -> {:text :changed? :note :unsafe-count :invalid-count :truncated? :input-bytes :sanitized-bytes :kept-bytes :max-bytes}","summary":"Sanitize and cap provider-visible tool output text, appending an explicit marker when changed.","tags":["util","text","tools","sessions","providers"]}
{"field":":api-key","href":"register-kinds.html#contract-field-register-kind-auth-backend-api-key","id":"register-kind:auth-backend.api-key","kind":"contract-field","parent":"register-kind:auth-backend","signature":":api-key () -> string|nil","summary":"Return the current bearer/API key, refreshing or loading secrets as needed.","tags":["contracts","register-kind","field","auth-backend","api-key","-","string","nil"]}
{"field":":login!","href":"register-kinds.html#contract-field-register-kind-auth-backend-login","id":"register-kind:auth-backend.login!","kind":"contract-field","parent":"register-kind:auth-backend","signature":":login! (opts) -> any","summary":"Optional. Drives `fen --login <name>`.","tags":["contracts","register-kind","field","auth-backend","login","opts","-","any"]}
{"field":":logout!","href":"register-kinds.html#contract-field-register-kind-auth-backend-logout","id":"register-kind:auth-backend.logout!","kind":"contract-field","parent":"register-kind:auth-backend","signature":":logout! () -> any","summary":"Optional. Drives `fen --logout <name>`.","tags":["contracts","register-kind","field","auth-backend","logout","-","any"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-auth-backend-name","id":"register-kind:auth-backend.name","kind":"contract-field","parent":"register-kind:auth-backend","signature":":name keyword|string","summary":"Auth backend name selected by provider configuration or CLI login/logout flags.","tags":["contracts","register-kind","field","auth-backend","name","keyword","string"]}
{"fields":["api-key","login!","logout!","name"],"href":"register-kinds.html#contract-entry-register-kind-auth-backend","id":"register-kind:auth-backend","kind":"register-kind","summary":"Auth credential backend. Resolves an api-key or rotates an OAuth token for one or more providers.","tags":["contracts","register-kind","auth-backend"]}
{"field":":description","href":"register-kinds.html#contract-field-register-kind-command-description","id":"register-kind:command.description","kind":"contract-field","parent":"register-kind:command","signature":":description string","summary":"Human-readable command help shown in command listings and docs.","tags":["contracts","register-kind","field","command","description","string"]}
{"field":":handler","href":"register-kinds.html#contract-field-register-kind-command-handler","id":"register-kind:command.handler","kind":"contract-field","parent":"register-kind:command","signature":":handler (args caller-state) -> any","summary":"Callback invoked with raw command arguments and the caller's runtime state.","tags":["contracts","register-kind","field","command","handler","args","caller-state","-","any"]}
{"field":":idle-only?","href":"register-kinds.html#contract-field-register-kind-command-idle-only","id":"register-kind:command.idle-only?","kind":"contract-field","parent":"register-kind:command","signature":":idle-only? boolean","summary":"Refuse the command while the agent is busy.","tags":["contracts","register-kind","field","command","idle-only","boolean"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-command-name","id":"register-kind:command.name","kind":"contract-field","parent":"register-kind:command","signature":":name keyword|string","summary":"Command name without the leading slash.","tags":["contracts","register-kind","field","command","name","keyword","string"]}
{"field":":order","href":"register-kinds.html#contract-field-register-kind-command-order","id":"register-kind:command.order","kind":"contract-field","parent":"register-kind:command","signature":":order number","summary":"Sort hint for `/help`.","tags":["contracts","register-kind","field","command","order","number"]}
{"fields":["description","handler","idle-only?","name","order"],"href":"register-kinds.html#contract-entry-register-kind-command","id":"register-kind:command","kind":"register-kind","summary":"Slash command contribution. Looked up by name when the user submits `/<name> <args>` from a presenter.","tags":["contracts","register-kind","command"]}
{"field":":description","href":"register-kinds.html#contract-field-register-kind-control-description","id":"register-kind:control.description","kind":"contract-field","parent":"register-kind:control","signature":":description string","summary":"Human-readable explanation of the control's UI effect.","tags":["contracts","register-kind","field","control","description","string"]}
{"field":":handler","href":"register-kinds.html#contract-field-register-kind-control-handler","id":"register-kind:control.handler","kind":"contract-field","parent":"register-kind:control","signature":":handler (ctx) -> any","summary":"Callback invoked by the presenter when the control is activated.","tags":["contracts","register-kind","field","control","handler","ctx","-","any"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-control-name","id":"register-kind:control.name","kind":"contract-field","parent":"register-kind:control","signature":":name keyword|string","summary":"Stable control name exposed to presenter help and docs.","tags":["contracts","register-kind","field","control","name","keyword","string"]}
{"fields":["description","handler","name"],"href":"register-kinds.html#contract-entry-register-kind-control","id":"register-kind:control","kind":"register-kind","summary":"Keyboard/UI control surface for presenters that support typed input bindings.","tags":["contracts","register-kind","control"]}
{"field":":before-tool","href":"register-kinds.html#contract-field-register-kind-hook-before-tool","id":"register-kind:hook.before-tool","kind":"contract-field","parent":"register-kind:hook","signature":":before-tool (tool-name args ctx) -> any","summary":"Return {:block true :reason string} to veto.","tags":["contracts","register-kind","field","hook","before-tool","tool-name","args","ctx","-","any"]}
{"fields":["before-tool"],"href":"register-kinds.html#contract-entry-register-kind-hook","id":"register-kind:hook","kind":"register-kind","summary":"Lifecycle hook (currently `before-tool`). Inspects a tool call before it executes.","tags":["contracts","register-kind","hook"]}
{"field":":description","href":"register-kinds.html#contract-field-register-kind-introspect-description","id":"register-kind:introspect.description","kind":"contract-field","parent":"register-kind:introspect","signature":":description string","summary":"Human-readable description shown by diagnostics and docs.","tags":["contracts","register-kind","field","introspect","description","string"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-introspect-name","id":"register-kind:introspect.name","kind":"contract-field","parent":"register-kind:introspect","signature":":name keyword|string","summary":"Owner-scoped snapshot name. Multiple extensions may reuse the same name.","tags":["contracts","register-kind","field","introspect","name","keyword","string"]}
{"field":":snapshot","href":"register-kinds.html#contract-field-register-kind-introspect-snapshot","id":"register-kind:introspect.snapshot","kind":"contract-field","parent":"register-kind:introspect","signature":":snapshot (ctx) -> table","summary":"Cheap, side-effect-free thunk returning JSON-friendly data. It is pcall-isolated and should not expose secrets.","tags":["contracts","register-kind","field","introspect","snapshot","ctx","-","table"]}
{"fields":["description","name","snapshot"],"href":"register-kinds.html#contract-entry-register-kind-introspect","id":"register-kind:introspect","kind":"register-kind","summary":"Read-only extension state snapshot provider. Collected on demand for agent_state, /extensions, and runtime diagnostics.","tags":["contracts","register-kind","introspect"]}
{"field":":enabled?","href":"register-kinds.html#contract-field-register-kind-panel-enabled","id":"register-kind:panel.enabled?","kind":"contract-field","parent":"register-kind:panel","signature":":enabled? (ctx) -> boolean","summary":"Optional predicate that hides the panel without unregistering it.","tags":["contracts","register-kind","field","panel","enabled","ctx","-","boolean"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-panel-name","id":"register-kind:panel.name","kind":"contract-field","parent":"register-kind:panel","signature":":name keyword|string","summary":"Stable panel name used for toggles, docs, and diagnostics.","tags":["contracts","register-kind","field","panel","name","keyword","string"]}
{"field":":render","href":"register-kinds.html#contract-field-register-kind-panel-render","id":"register-kind:panel.render","kind":"contract-field","parent":"register-kind:panel","signature":":render (ctx) -> any","summary":"Callback returning rows or presenter-specific content for the panel body.","tags":["contracts","register-kind","field","panel","render","ctx","-","any"]}
{"field":":title","href":"register-kinds.html#contract-field-register-kind-panel-title","id":"register-kind:panel.title","kind":"contract-field","parent":"register-kind:panel","signature":":title string","summary":"Optional display title when the presenter renders panel chrome.","tags":["contracts","register-kind","field","panel","title","string"]}
{"fields":["enabled?","name","render","title"],"href":"register-kinds.html#contract-entry-register-kind-panel","id":"register-kind:panel","kind":"register-kind","summary":"Non-modal side panel contribution rendered by presenters that support panels.","tags":["contracts","register-kind","panel"]}
{"field":":init","href":"register-kinds.html#contract-field-register-kind-presenter-init","id":"register-kind:presenter.init","kind":"contract-field","parent":"register-kind:presenter","signature":":init (ctx) -> nil","summary":"Optional lifecycle callback run before the presenter loop starts.","tags":["contracts","register-kind","field","presenter","init","ctx","-","nil"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-presenter-name","id":"register-kind:presenter.name","kind":"contract-field","parent":"register-kind:presenter","signature":":name keyword|string","summary":"Presenter name selected by CLI flags or extension activation rules.","tags":["contracts","register-kind","field","presenter","name","keyword","string"]}
{"field":":run","href":"register-kinds.html#contract-field-register-kind-presenter-run","id":"register-kind:presenter.run","kind":"contract-field","parent":"register-kind:presenter","signature":":run (ctx) -> nil","summary":"Main input/output loop for the selected presenter.","tags":["contracts","register-kind","field","presenter","run","ctx","-","nil"]}
{"field":":shutdown","href":"register-kinds.html#contract-field-register-kind-presenter-shutdown","id":"register-kind:presenter.shutdown","kind":"contract-field","parent":"register-kind:presenter","signature":":shutdown (ctx) -> nil","summary":"Optional lifecycle callback used to release terminal, socket, or other UI resources.","tags":["contracts","register-kind","field","presenter","shutdown","ctx","-","nil"]}
{"fields":["init","name","run","shutdown"],"href":"register-kinds.html#contract-entry-register-kind-presenter","id":"register-kind:presenter","kind":"register-kind","summary":"UI driver. Owns the input/output loop. Exactly one is active per run; the loader picks based on flags and manifest hints.","tags":["contracts","register-kind","presenter"]}
{"field":":api","href":"register-kinds.html#contract-field-register-kind-provider-api","id":"register-kind:provider.api","kind":"contract-field","parent":"register-kind:provider","signature":":api keyword","summary":"Protocol family (:openai-completions, :anthropic-messages, ...). Many providers may share an :api.","tags":["contracts","register-kind","field","provider","api","keyword"]}
{"field":":build-body","href":"register-kinds.html#contract-field-register-kind-provider-build-body","id":"register-kind:provider.build-body","kind":"contract-field","parent":"register-kind:provider","signature":":build-body (model ctx options) -> table","summary":"Build the provider request body from a model id, AgentContext, and call options.","tags":["contracts","register-kind","field","provider","build-body","model","ctx","options","-","table"]}
{"field":":complete","href":"register-kinds.html#contract-field-register-kind-provider-complete","id":"register-kind:provider.complete","kind":"contract-field","parent":"register-kind:provider","signature":":complete (model ctx options ?on-event ?yield-fn) -> AssistantMessage","summary":"High-level provider entry point that runs one model turn and returns a canonical assistant message.","tags":["contracts","register-kind","field","provider","complete","model","ctx","options","on-event","yield-fn","-","assistantmessage"]}
{"field":":convert-messages","href":"register-kinds.html#contract-field-register-kind-provider-convert-messages","id":"register-kind:provider.convert-messages","kind":"contract-field","parent":"register-kind:provider","signature":":convert-messages ([Message]) -> [WireMessage]","summary":"Translate canonical conversation messages into this provider's wire message format.","tags":["contracts","register-kind","field","provider","convert-messages","message","-","wiremessage"]}
{"field":":convert-tools","href":"register-kinds.html#contract-field-register-kind-provider-convert-tools","id":"register-kind:provider.convert-tools","kind":"contract-field","parent":"register-kind:provider","signature":":convert-tools ([Tool]) -> [WireTool]","summary":"Translate canonical tool specs into this provider's wire tool schema.","tags":["contracts","register-kind","field","provider","convert-tools","tool","-","wiretool"]}
{"field":":map-stop-reason","href":"register-kinds.html#contract-field-register-kind-provider-map-stop-reason","id":"register-kind:provider.map-stop-reason","kind":"contract-field","parent":"register-kind:provider","signature":":map-stop-reason (string) -> StopReason","summary":"Normalize provider stop reasons into fen's canonical StopReason enum.","tags":["contracts","register-kind","field","provider","map-stop-reason","string","-","stopreason"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-provider-name","id":"register-kind:provider.name","kind":"contract-field","parent":"register-kind:provider","signature":":name keyword|string","summary":"Provider name selected by settings or CLI options.","tags":["contracts","register-kind","field","provider","name","keyword","string"]}
{"field":":parse-response","href":"register-kinds.html#contract-field-register-kind-provider-parse-response","id":"register-kind:provider.parse-response","kind":"contract-field","parent":"register-kind:provider","signature":":parse-response (WireResponse) -> AssistantMessage","summary":"Convert a non-streaming provider response payload into an AssistantMessage.","tags":["contracts","register-kind","field","provider","parse-response","wireresponse","-","assistantmessage"]}
{"fields":["api","build-body","complete","convert-messages","convert-tools","map-stop-reason","name","parse-response"],"href":"register-kinds.html#contract-entry-register-kind-provider","id":"register-kind:provider","kind":"register-kind","summary":"LLM provider contribution. See the :provider-interface contract for the required record.","tags":["contracts","register-kind","provider"]}
{"field":":append","href":"register-kinds.html#contract-field-register-kind-session-backend-append","id":"register-kind:session-backend.append","kind":"contract-field","parent":"register-kind:session-backend","signature":":append (session message) -> nil","summary":"Persist one canonical Message to the active session.","tags":["contracts","register-kind","field","session-backend","append","session","message","-","nil"]}
{"field":":close","href":"register-kinds.html#contract-field-register-kind-session-backend-close","id":"register-kind:session-backend.close","kind":"contract-field","parent":"register-kind:session-backend","signature":":close (session) -> nil","summary":"Flush and release backend resources for an open session.","tags":["contracts","register-kind","field","session-backend","close","session","-","nil"]}
{"field":":find","href":"register-kinds.html#contract-field-register-kind-session-backend-find","id":"register-kind:session-backend.find","kind":"contract-field","parent":"register-kind:session-backend","signature":":find (opts) -> [SessionInfo]","summary":"Search sessions using backend-specific filters.","tags":["contracts","register-kind","field","session-backend","find","opts","-","sessioninfo"]}
{"field":":latest","href":"register-kinds.html#contract-field-register-kind-session-backend-latest","id":"register-kind:session-backend.latest","kind":"contract-field","parent":"register-kind:session-backend","signature":":latest (opts) -> SessionInfo|nil","summary":"Return the newest matching session, if any.","tags":["contracts","register-kind","field","session-backend","latest","opts","-","sessioninfo","nil"]}
{"field":":list","href":"register-kinds.html#contract-field-register-kind-session-backend-list","id":"register-kind:session-backend.list","kind":"contract-field","parent":"register-kind:session-backend","signature":":list (opts) -> [SessionInfo]","summary":"List sessions visible to this backend in a stable display order.","tags":["contracts","register-kind","field","session-backend","list","opts","-","sessioninfo"]}
{"field":":load","href":"register-kinds.html#contract-field-register-kind-session-backend-load","id":"register-kind:session-backend.load","kind":"contract-field","parent":"register-kind:session-backend","signature":":load (path opts) -> [Message]","summary":"Read canonical messages from a stored session path.","tags":["contracts","register-kind","field","session-backend","load","path","opts","-","message"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-session-backend-name","id":"register-kind:session-backend.name","kind":"contract-field","parent":"register-kind:session-backend","signature":":name keyword|string","summary":"Session backend name selected by CLI flags or extension configuration.","tags":["contracts","register-kind","field","session-backend","name","keyword","string"]}
{"field":":open","href":"register-kinds.html#contract-field-register-kind-session-backend-open","id":"register-kind:session-backend.open","kind":"contract-field","parent":"register-kind:session-backend","signature":":open (opts) -> session","summary":"Create or open the active session for a new run.","tags":["contracts","register-kind","field","session-backend","open","opts","-","session"]}
{"field":":open-existing","href":"register-kinds.html#contract-field-register-kind-session-backend-open-existing","id":"register-kind:session-backend.open-existing","kind":"contract-field","parent":"register-kind:session-backend","signature":":open-existing (path opts) -> session","summary":"Open an existing session file or directory for appending.","tags":["contracts","register-kind","field","session-backend","open-existing","path","opts","-","session"]}
{"fields":["append","close","find","latest","list","load","name","open","open-existing"],"href":"register-kinds.html#contract-entry-register-kind-session-backend","id":"register-kind:session-backend","kind":"register-kind","summary":"Persistence backend for canonical JSONL-style sessions. The `--session` flag selects one and `fen.core.extensions.register.session_backend.set-active!` activates it.","tags":["contracts","register-kind","session-backend"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-status-name","id":"register-kind:status.name","kind":"contract-field","parent":"register-kind:status","signature":":name keyword|string","summary":"Stable status item name used for sorting, diagnostics, and docs.","tags":["contracts","register-kind","field","status","name","keyword","string"]}
{"field":":order","href":"register-kinds.html#contract-field-register-kind-status-order","id":"register-kind:status.order","kind":"contract-field","parent":"register-kind:status","signature":":order number","summary":"Sort hint within the status side; lower values render earlier.","tags":["contracts","register-kind","field","status","order","number"]}
{"field":":render","href":"register-kinds.html#contract-field-register-kind-status-render","id":"register-kind:status.render","kind":"contract-field","parent":"register-kind:status","signature":":render (ctx) -> string|nil","summary":"Callback returning the current status text, or nil/empty text to hide it.","tags":["contracts","register-kind","field","status","render","ctx","-","string","nil"]}
{"fields":["name","order","render"],"href":"register-kinds.html#contract-entry-register-kind-status","id":"register-kind:status","kind":"register-kind","summary":"Status-line contributor — produces a short string for the presenter's status row.","tags":["contracts","register-kind","status"]}
{"field":":description","href":"register-kinds.html#contract-field-register-kind-tool-description","id":"register-kind:tool.description","kind":"contract-field","parent":"register-kind:tool","signature":":description string","summary":"Provider-facing guidance explaining when the model should call this tool.","tags":["contracts","register-kind","field","tool","description","string"]}
{"field":":execute","href":"register-kinds.html#contract-field-register-kind-tool-execute","id":"register-kind:tool.execute","kind":"contract-field","parent":"register-kind:tool","signature":":execute (args ?yield-fn) -> AgentToolResult","summary":"Runtime callback that executes decoded arguments and returns canonical tool content.","tags":["contracts","register-kind","field","tool","execute","args","yield-fn","-","agenttoolresult"]}
{"field":":label","href":"register-kinds.html#contract-field-register-kind-tool-label","id":"register-kind:tool.label","kind":"contract-field","parent":"register-kind:tool","signature":":label string","summary":"Optional short UI label shown by presenters while the tool runs.","tags":["contracts","register-kind","field","tool","label","string"]}
{"field":":name","href":"register-kinds.html#contract-field-register-kind-tool-name","id":"register-kind:tool.name","kind":"contract-field","parent":"register-kind:tool","signature":":name string","summary":"Unique tool name exposed to providers and matched against ToolCall.name.","tags":["contracts","register-kind","field","tool","name","string"]}
{"field":":parameters","href":"register-kinds.html#contract-field-register-kind-tool-parameters","id":"register-kind:tool.parameters","kind":"contract-field","parent":"register-kind:tool","signature":":parameters JSONSchema","summary":"JSON object schema describing the tool arguments providers may emit.","tags":["contracts","register-kind","field","tool","parameters","jsonschema"]}
{"fields":["description","execute","label","name","parameters"],"href":"register-kinds.html#contract-entry-register-kind-tool","id":"register-kind:tool","kind":"register-kind","summary":"Agent tool contribution. Merged into the per-step `AgentContext.tools` and dispatched by name when the assistant emits a ToolCall.","tags":["contracts","register-kind","tool"]}
{"field":":agent","href":"events.html#contract-field-event-agent-shutdown-agent","id":"event:agent-shutdown.agent","kind":"contract-field","parent":"event:agent-shutdown","signature":":agent Agent","summary":"Agent instance associated with the event.","tags":["contracts","event","field","agent-shutdown","agent"]}
{"field":":error","href":"events.html#contract-field-event-agent-shutdown-error","id":"event:agent-shutdown.error","kind":"contract-field","parent":"event:agent-shutdown","signature":":error string","summary":"Crash details when shutdown follows an error path.","tags":["contracts","event","field","agent-shutdown","error","string"]}
{"field":":reason","href":"events.html#contract-field-event-agent-shutdown-reason","id":"event:agent-shutdown.reason","kind":"contract-field","parent":"event:agent-shutdown","signature":":reason keyword","summary":":normal | :crashed","tags":["contracts","event","field","agent-shutdown","reason","keyword"]}
{"field":":type","href":"events.html#contract-field-event-agent-shutdown-type","id":"event:agent-shutdown.type","kind":"contract-field","parent":"event:agent-shutdown","signature":":type :agent-shutdown","summary":"Event discriminator for :agent-shutdown events.","tags":["contracts","event","field","agent-shutdown","type"]}
{"fields":["agent","error","reason","type"],"href":"events.html#contract-entry-event-agent-shutdown","id":"event:agent-shutdown","kind":"event","summary":"Emitted once per run during teardown. `:error` is present for crashed paths.","tags":["contracts","event","agent-shutdown"]}
{"field":":agent","href":"events.html#contract-field-event-agent-started-agent","id":"event:agent-started.agent","kind":"contract-field","parent":"event:agent-started","signature":":agent Agent","summary":"Agent instance associated with the event.","tags":["contracts","event","field","agent-started","agent"]}
{"field":":cwd","href":"events.html#contract-field-event-agent-started-cwd","id":"event:agent-started.cwd","kind":"contract-field","parent":"event:agent-started","signature":":cwd string","summary":"Working directory for the active agent run.","tags":["contracts","event","field","agent-started","cwd","string"]}
{"field":":model","href":"events.html#contract-field-event-agent-started-model","id":"event:agent-started.model","kind":"contract-field","parent":"event:agent-started","signature":":model string","summary":"Model identifier selected for the active run.","tags":["contracts","event","field","agent-started","model","string"]}
{"field":":provider","href":"events.html#contract-field-event-agent-started-provider","id":"event:agent-started.provider","kind":"contract-field","parent":"event:agent-started","signature":":provider keyword|string","summary":"Provider name selected for the active run.","tags":["contracts","event","field","agent-started","provider","keyword","string"]}
{"field":":type","href":"events.html#contract-field-event-agent-started-type","id":"event:agent-started.type","kind":"contract-field","parent":"event:agent-started","signature":":type :agent-started","summary":"Event discriminator for :agent-started events.","tags":["contracts","event","field","agent-started","type"]}
{"fields":["agent","cwd","model","provider","type"],"href":"events.html#contract-entry-event-agent-started","id":"event:agent-started","kind":"event","summary":"Emitted once per run after setup and before the first new step.","tags":["contracts","event","agent-started"]}
{"field":":agent","href":"events.html#contract-field-event-agent-turn-complete-agent","id":"event:agent-turn-complete.agent","kind":"contract-field","parent":"event:agent-turn-complete","signature":":agent Agent","summary":"Agent instance associated with the completed turn.","tags":["contracts","event","field","agent-turn-complete","agent"]}
{"field":":error","href":"events.html#contract-field-event-agent-turn-complete-error","id":"event:agent-turn-complete.error","kind":"contract-field","parent":"event:agent-turn-complete","signature":":error string","summary":"Error summary when the turn ended with :status :error.","tags":["contracts","event","field","agent-turn-complete","error","string"]}
{"field":":message-count","href":"events.html#contract-field-event-agent-turn-complete-message-count","id":"event:agent-turn-complete.message-count","kind":"contract-field","parent":"event:agent-turn-complete","signature":":message-count number","summary":"Conversation message count after the turn finished.","tags":["contracts","event","field","agent-turn-complete","message-count","number"]}
{"field":":result","href":"events.html#contract-field-event-agent-turn-complete-result","id":"event:agent-turn-complete.result","kind":"contract-field","parent":"event:agent-turn-complete","signature":":result string","summary":"Final visible assistant text for successful or cancelled turns, when available.","tags":["contracts","event","field","agent-turn-complete","result","string"]}
{"field":":status","href":"events.html#contract-field-event-agent-turn-complete-status","id":"event:agent-turn-complete.status","kind":"contract-field","parent":"event:agent-turn-complete","signature":":status keyword","summary":":ok | :cancelled | :error","tags":["contracts","event","field","agent-turn-complete","status","keyword"]}
{"field":":type","href":"events.html#contract-field-event-agent-turn-complete-type","id":"event:agent-turn-complete.type","kind":"contract-field","parent":"event:agent-turn-complete","signature":":type :agent-turn-complete","summary":"Event discriminator for :agent-turn-complete events.","tags":["contracts","event","field","agent-turn-complete","type"]}
{"fields":["agent","error","message-count","result","status","type"],"href":"events.html#contract-entry-event-agent-turn-complete","id":"event:agent-turn-complete","kind":"event","summary":"Emitted once per submitted user turn after the agent coroutine finishes and the presenter busy flag has been cleared.","tags":["contracts","event","agent-turn-complete"]}
{"field":":type","href":"events.html#contract-field-event-assistant-stream-end-type","id":"event:assistant-stream-end.type","kind":"contract-field","parent":"event:assistant-stream-end","signature":":type :assistant-stream-end","summary":"Event discriminator for :assistant-stream-end events.","tags":["contracts","event","field","assistant-stream-end","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-assistant-stream-end","id":"event:assistant-stream-end","kind":"event","summary":"Stream finished. Emitted once after all per-block end events for a single AssistantMessage.","tags":["contracts","event","assistant-stream-end"]}
{"field":":final?","href":"events.html#contract-field-event-assistant-text-final","id":"event:assistant-text.final?","kind":"contract-field","parent":"event:assistant-text","signature":":final? boolean","summary":"True when this is the final aggregate payload for the current block.","tags":["contracts","event","field","assistant-text","final","boolean"]}
{"field":":text","href":"events.html#contract-field-event-assistant-text-text","id":"event:assistant-text.text","kind":"contract-field","parent":"event:assistant-text","signature":":text string","summary":"Complete assistant text payload for this event.","tags":["contracts","event","field","assistant-text","text","string"]}
{"field":":type","href":"events.html#contract-field-event-assistant-text-type","id":"event:assistant-text.type","kind":"contract-field","parent":"event:assistant-text","signature":":type :assistant-text","summary":"Event discriminator for :assistant-text events.","tags":["contracts","event","field","assistant-text","type"]}
{"fields":["final?","text","type"],"href":"events.html#contract-entry-event-assistant-text","id":"event:assistant-text","kind":"event","summary":"Final visible text emitted by the assistant. One per AssistantMessage with text blocks.","tags":["contracts","event","assistant-text"]}
{"field":":delta","href":"events.html#contract-field-event-assistant-text-delta-delta","id":"event:assistant-text-delta.delta","kind":"contract-field","parent":"event:assistant-text-delta","signature":":delta string","summary":"Incremental streamed text fragment for the open content block.","tags":["contracts","event","field","assistant-text-delta","delta","string"]}
{"field":":type","href":"events.html#contract-field-event-assistant-text-delta-type","id":"event:assistant-text-delta.type","kind":"contract-field","parent":"event:assistant-text-delta","signature":":type :assistant-text-delta","summary":"Event discriminator for :assistant-text-delta events.","tags":["contracts","event","field","assistant-text-delta","type"]}
{"fields":["delta","type"],"href":"events.html#contract-entry-event-assistant-text-delta","id":"event:assistant-text-delta","kind":"event","summary":"Streaming text token. Aggregated by presenters during a stream.","tags":["contracts","event","assistant-text-delta"]}
{"field":":final?","href":"events.html#contract-field-event-assistant-thinking-final","id":"event:assistant-thinking.final?","kind":"contract-field","parent":"event:assistant-thinking","signature":":final? boolean","summary":"True when this is the final aggregate payload for the current block.","tags":["contracts","event","field","assistant-thinking","final","boolean"]}
{"field":":text","href":"events.html#contract-field-event-assistant-thinking-text","id":"event:assistant-thinking.text","kind":"contract-field","parent":"event:assistant-thinking","signature":":text string","summary":"Complete assistant text payload for this event.","tags":["contracts","event","field","assistant-thinking","text","string"]}
{"field":":type","href":"events.html#contract-field-event-assistant-thinking-type","id":"event:assistant-thinking.type","kind":"contract-field","parent":"event:assistant-thinking","signature":":type :assistant-thinking","summary":"Event discriminator for :assistant-thinking events.","tags":["contracts","event","field","assistant-thinking","type"]}
{"fields":["final?","text","type"],"href":"events.html#contract-entry-event-assistant-thinking","id":"event:assistant-thinking","kind":"event","summary":"Final reasoning text from the assistant (for providers that surface reasoning content).","tags":["contracts","event","assistant-thinking"]}
{"field":":delta","href":"events.html#contract-field-event-assistant-thinking-delta-delta","id":"event:assistant-thinking-delta.delta","kind":"contract-field","parent":"event:assistant-thinking-delta","signature":":delta string","summary":"Incremental streamed text fragment for the open content block.","tags":["contracts","event","field","assistant-thinking-delta","delta","string"]}
{"field":":type","href":"events.html#contract-field-event-assistant-thinking-delta-type","id":"event:assistant-thinking-delta.type","kind":"contract-field","parent":"event:assistant-thinking-delta","signature":":type :assistant-thinking-delta","summary":"Event discriminator for :assistant-thinking-delta events.","tags":["contracts","event","field","assistant-thinking-delta","type"]}
{"fields":["delta","type"],"href":"events.html#contract-entry-event-assistant-thinking-delta","id":"event:assistant-thinking-delta","kind":"event","summary":"Streaming reasoning token.","tags":["contracts","event","assistant-thinking-delta"]}
{"field":":type","href":"events.html#contract-field-event-cancelled-type","id":"event:cancelled.type","kind":"contract-field","parent":"event:cancelled","signature":":type :cancelled","summary":"Event discriminator for :cancelled events.","tags":["contracts","event","field","cancelled","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-cancelled","id":"event:cancelled","kind":"event","summary":"Cooperative cancel observed; the current step appended an aborted assistant message.","tags":["contracts","event","cancelled"]}
{"field":":guidance","href":"events.html#contract-field-event-compaction-summary-guidance","id":"event:compaction-summary.guidance","kind":"contract-field","parent":"event:compaction-summary","signature":":guidance string","summary":"Optional user guidance supplied to /compact.","tags":["contracts","event","field","compaction-summary","guidance","string"]}
{"field":":messages-kept","href":"events.html#contract-field-event-compaction-summary-messages-kept","id":"event:compaction-summary.messages-kept","kind":"contract-field","parent":"event:compaction-summary","signature":":messages-kept number","summary":"Number of recent messages kept verbatim.","tags":["contracts","event","field","compaction-summary","messages-kept","number"]}
{"field":":messages-summarized","href":"events.html#contract-field-event-compaction-summary-messages-summarized","id":"event:compaction-summary.messages-summarized","kind":"contract-field","parent":"event:compaction-summary","signature":":messages-summarized number","summary":"Number of older messages summarized.","tags":["contracts","event","field","compaction-summary","messages-summarized","number"]}
{"field":":summary","href":"events.html#contract-field-event-compaction-summary-summary","id":"event:compaction-summary.summary","kind":"contract-field","parent":"event:compaction-summary","signature":":summary string","summary":"Summary text installed into the compacted model context.","tags":["contracts","event","field","compaction-summary","summary","string"]}
{"field":":tokens-after","href":"events.html#contract-field-event-compaction-summary-tokens-after","id":"event:compaction-summary.tokens-after","kind":"contract-field","parent":"event:compaction-summary","signature":":tokens-after number","summary":"Approximate context tokens after compaction.","tags":["contracts","event","field","compaction-summary","tokens-after","number"]}
{"field":":tokens-before","href":"events.html#contract-field-event-compaction-summary-tokens-before","id":"event:compaction-summary.tokens-before","kind":"contract-field","parent":"event:compaction-summary","signature":":tokens-before number","summary":"Approximate context tokens before compaction.","tags":["contracts","event","field","compaction-summary","tokens-before","number"]}
{"field":":trigger","href":"events.html#contract-field-event-compaction-summary-trigger","id":"event:compaction-summary.trigger","kind":"contract-field","parent":"event:compaction-summary","signature":":trigger keyword","summary":"Why compaction ran, such as :manual.","tags":["contracts","event","field","compaction-summary","trigger","keyword"]}
{"field":":type","href":"events.html#contract-field-event-compaction-summary-type","id":"event:compaction-summary.type","kind":"contract-field","parent":"event:compaction-summary","signature":":type :compaction-summary","summary":"Event discriminator for :compaction-summary events.","tags":["contracts","event","field","compaction-summary","type"]}
{"fields":["guidance","messages-kept","messages-summarized","summary","tokens-after","tokens-before","trigger","type"],"href":"events.html#contract-entry-event-compaction-summary","id":"event:compaction-summary","kind":"event","summary":"Context compaction completed and produced a summary for older messages.","tags":["contracts","event","compaction-summary"]}
{"field":":type","href":"events.html#contract-field-event-dismiss-type","id":"event:dismiss.type","kind":"contract-field","parent":"event:dismiss","signature":":type :dismiss","summary":"Event discriminator for :dismiss events.","tags":["contracts","event","field","dismiss","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-dismiss","id":"event:dismiss","kind":"event","summary":"Presenter signal that an open overlay/picker should close.","tags":["contracts","event","dismiss"]}
{"field":":message","href":"events.html#contract-field-event-done-message","id":"event:done.message","kind":"contract-field","parent":"event:done","signature":":message AssistantMessage","summary":"Canonical assistant message produced by the provider stream.","tags":["contracts","event","field","done","message","assistantmessage"]}
{"field":":type","href":"events.html#contract-field-event-done-type","id":"event:done.type","kind":"contract-field","parent":"event:done","signature":":type :done","summary":"Event discriminator for :done events.","tags":["contracts","event","field","done","type"]}
{"fields":["message","type"],"href":"events.html#contract-entry-event-done","id":"event:done","kind":"event","summary":"Provider stream: terminal event for a successful AssistantMessage.","tags":["contracts","event","done"]}
{"field":":error","href":"events.html#contract-field-event-error-error","id":"event:error.error","kind":"contract-field","parent":"event:error","signature":":error string","summary":"Human-readable error message for presenters and logs.","tags":["contracts","event","field","error","string"]}
{"field":":type","href":"events.html#contract-field-event-error-type","id":"event:error.type","kind":"contract-field","parent":"event:error","signature":":type :error","summary":"Event discriminator for :error events.","tags":["contracts","event","field","error","type"]}
{"fields":["error","type"],"href":"events.html#contract-entry-event-error","id":"event:error","kind":"event","summary":"Generic surface error — typically command-dispatch or user-input failures.","tags":["contracts","event","error"]}
{"field":":error","href":"events.html#contract-field-event-extension-error-error","id":"event:extension-error.error","kind":"contract-field","parent":"event:extension-error","signature":":error string","summary":"Human-readable error message for presenters and logs.","tags":["contracts","event","field","extension-error","error","string"]}
{"field":":event","href":"events.html#contract-field-event-extension-error-event","id":"event:extension-error.event","kind":"contract-field","parent":"event:extension-error","signature":":event keyword|string","summary":"Original event being handled when the extension error occurred.","tags":["contracts","event","field","extension-error","keyword","string"]}
{"field":":owner","href":"events.html#contract-field-event-extension-error-owner","id":"event:extension-error.owner","kind":"contract-field","parent":"event:extension-error","signature":":owner keyword|string","summary":"Extension owner whose handler raised, when known.","tags":["contracts","event","field","extension-error","owner","keyword","string"]}
{"field":":type","href":"events.html#contract-field-event-extension-error-type","id":"event:extension-error.type","kind":"contract-field","parent":"event:extension-error","signature":":type :extension-error","summary":"Event discriminator for :extension-error events.","tags":["contracts","event","field","extension-error","type"]}
{"fields":["error","event","owner","type"],"href":"events.html#contract-entry-event-extension-error","id":"event:extension-error","kind":"event","summary":"Emitted when an extension event handler raises. Suppressed for recursive extension-error events to prevent loops.","tags":["contracts","event","extension-error"]}
{"field":":first-party?","href":"events.html#contract-field-event-extension-loaded-first-party","id":"event:extension-loaded.first-party?","kind":"contract-field","parent":"event:extension-loaded","signature":":first-party? boolean","summary":"True when the loaded extension came from fen's bundled extension set.","tags":["contracts","event","field","extension-loaded","first-party","boolean"]}
{"field":":name","href":"events.html#contract-field-event-extension-loaded-name","id":"event:extension-loaded.name","kind":"contract-field","parent":"event:extension-loaded","signature":":name string","summary":"Extension manifest name that was loaded.","tags":["contracts","event","field","extension-loaded","name","string"]}
{"field":":type","href":"events.html#contract-field-event-extension-loaded-type","id":"event:extension-loaded.type","kind":"contract-field","parent":"event:extension-loaded","signature":":type :extension-loaded","summary":"Event discriminator for :extension-loaded events.","tags":["contracts","event","field","extension-loaded","type"]}
{"fields":["first-party?","name","type"],"href":"events.html#contract-entry-event-extension-loaded","id":"event:extension-loaded","kind":"event","summary":"Emitted by the loader for each successfully loaded extension manifest.","tags":["contracts","event","extension-loaded"]}
{"field":":info","href":"events.html#contract-field-event-info-info","id":"event:info.info","kind":"contract-field","parent":"event:info","signature":":info string","summary":"Human-readable informational message payload.","tags":["contracts","event","field","info","string"]}
{"field":":text","href":"events.html#contract-field-event-info-text","id":"event:info.text","kind":"contract-field","parent":"event:info","signature":":text string","summary":"Alternative human-readable informational text.","tags":["contracts","event","field","info","text","string"]}
{"field":":type","href":"events.html#contract-field-event-info-type","id":"event:info.type","kind":"contract-field","parent":"event:info","signature":":type :info","summary":"Event discriminator for :info events.","tags":["contracts","event","field","info","type"]}
{"fields":["info","text","type"],"href":"events.html#contract-entry-event-info","id":"event:info","kind":"event","summary":"Transient informational message intended for the presenter status row or panel.","tags":["contracts","event","info"]}
{"field":":message","href":"events.html#contract-field-event-llm-end-message","id":"event:llm-end.message","kind":"contract-field","parent":"event:llm-end","signature":":message AssistantMessage","summary":"Canonical assistant message produced by the provider stream.","tags":["contracts","event","field","llm-end","message","assistantmessage"]}
{"field":":type","href":"events.html#contract-field-event-llm-end-type","id":"event:llm-end.type","kind":"contract-field","parent":"event:llm-end","signature":":type :llm-end","summary":"Event discriminator for :llm-end events.","tags":["contracts","event","field","llm-end","type"]}
{"fields":["message","type"],"href":"events.html#contract-entry-event-llm-end","id":"event:llm-end","kind":"event","summary":"Provider call completed (success or error). The :message field carries the canonical AssistantMessage.","tags":["contracts","event","llm-end"]}
{"field":":model","href":"events.html#contract-field-event-llm-start-model","id":"event:llm-start.model","kind":"contract-field","parent":"event:llm-start","signature":":model string","summary":"Model identifier used for the provider request, when known.","tags":["contracts","event","field","llm-start","model","string"]}
{"field":":provider","href":"events.html#contract-field-event-llm-start-provider","id":"event:llm-start.provider","kind":"contract-field","parent":"event:llm-start","signature":":provider keyword","summary":"Provider name for the outbound LLM call, when known.","tags":["contracts","event","field","llm-start","provider","keyword"]}
{"field":":type","href":"events.html#contract-field-event-llm-start-type","id":"event:llm-start.type","kind":"contract-field","parent":"event:llm-start","signature":":type :llm-start","summary":"Event discriminator for :llm-start events.","tags":["contracts","event","field","llm-start","type"]}
{"fields":["model","provider","type"],"href":"events.html#contract-entry-event-llm-start","id":"event:llm-start","kind":"event","summary":"Provider call beginning.","tags":["contracts","event","llm-start"]}
{"field":":agent","href":"events.html#contract-field-event-message-appended-agent","id":"event:message-appended.agent","kind":"contract-field","parent":"event:message-appended","signature":":agent Agent","summary":"Agent instance associated with the event.","tags":["contracts","event","field","message-appended","agent"]}
{"field":":index","href":"events.html#contract-field-event-message-appended-index","id":"event:message-appended.index","kind":"contract-field","parent":"event:message-appended","signature":":index number","summary":"1-based index of the appended message.","tags":["contracts","event","field","message-appended","index","number"]}
{"field":":message","href":"events.html#contract-field-event-message-appended-message","id":"event:message-appended.message","kind":"contract-field","parent":"event:message-appended","signature":":message Message","summary":"Canonical message that was appended to the conversation.","tags":["contracts","event","field","message-appended","message"]}
{"field":":type","href":"events.html#contract-field-event-message-appended-type","id":"event:message-appended.type","kind":"contract-field","parent":"event:message-appended","signature":":type :message-appended","summary":"Event discriminator for :message-appended events.","tags":["contracts","event","field","message-appended","type"]}
{"fields":["agent","index","message","type"],"href":"events.html#contract-entry-event-message-appended","id":"event:message-appended","kind":"event","summary":"Emitted by `fen.core.agent` immediately after `agent.messages` grows.","tags":["contracts","event","message-appended"]}
{"field":":line","href":"events.html#contract-field-event-queued-line","id":"event:queued.line","kind":"contract-field","parent":"event:queued","signature":":line string","summary":"Raw user input line associated with the event.","tags":["contracts","event","field","queued","line","string"]}
{"field":":type","href":"events.html#contract-field-event-queued-type","id":"event:queued.type","kind":"contract-field","parent":"event:queued","signature":":type :queued","summary":"Event discriminator for :queued events.","tags":["contracts","event","field","queued","type"]}
{"fields":["line","type"],"href":"events.html#contract-entry-event-queued","id":"event:queued","kind":"event","summary":"User-line queued while the agent is busy. Consumed by the agent on natural-stop.","tags":["contracts","event","queued"]}
{"field":":type","href":"events.html#contract-field-event-redraw-type","id":"event:redraw.type","kind":"contract-field","parent":"event:redraw","signature":":type :redraw","summary":"Event discriminator for :redraw events.","tags":["contracts","event","field","redraw","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-redraw","id":"event:redraw","kind":"event","summary":"Presenter hint that a registered panel needs to be repainted.","tags":["contracts","event","redraw"]}
{"field":":type","href":"events.html#contract-field-event-reinit-presenter-type","id":"event:reinit-presenter.type","kind":"contract-field","parent":"event:reinit-presenter","signature":":type :reinit-presenter","summary":"Event discriminator for :reinit-presenter events.","tags":["contracts","event","field","reinit-presenter","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-reinit-presenter","id":"event:reinit-presenter","kind":"event","summary":"Presenter signal that the UI should be torn down and re-initialized (used by /reload).","tags":["contracts","event","reinit-presenter"]}
{"field":":type","href":"events.html#contract-field-event-reset-conversation-type","id":"event:reset-conversation.type","kind":"contract-field","parent":"event:reset-conversation","signature":":type :reset-conversation","summary":"Event discriminator for :reset-conversation events.","tags":["contracts","event","field","reset-conversation","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-reset-conversation","id":"event:reset-conversation","kind":"event","summary":"Presenter signal that the active conversation should be cleared (used by /new).","tags":["contracts","event","reset-conversation"]}
{"field":":info","href":"events.html#contract-field-event-set-status-info-info","id":"event:set-status-info.info","kind":"contract-field","parent":"event:set-status-info","signature":":info string|nil","summary":"Transient status text to show, or nil to clear it.","tags":["contracts","event","field","set-status-info","info","string","nil"]}
{"field":":type","href":"events.html#contract-field-event-set-status-info-type","id":"event:set-status-info.type","kind":"contract-field","parent":"event:set-status-info","signature":":type :set-status-info","summary":"Event discriminator for :set-status-info events.","tags":["contracts","event","field","set-status-info","type"]}
{"fields":["info","type"],"href":"events.html#contract-entry-event-set-status-info","id":"event:set-status-info","kind":"event","summary":"Presenter-level status hint. Owners post a transient status line; nil clears.","tags":["contracts","event","set-status-info"]}
{"field":":type","href":"events.html#contract-field-event-start-type","id":"event:start.type","kind":"contract-field","parent":"event:start","signature":":type :start","summary":"Event discriminator for :start events.","tags":["contracts","event","field","start","type"]}
{"fields":["type"],"href":"events.html#contract-entry-event-start","id":"event:start","kind":"event","summary":"Provider stream opened. Marker event emitted before any block events.","tags":["contracts","event","start"]}
{"field":":content-index","href":"events.html#contract-field-event-text-delta-content-index","id":"event:text-delta.content-index","kind":"contract-field","parent":"event:text-delta","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","text-delta","content-index","number"]}
{"field":":delta","href":"events.html#contract-field-event-text-delta-delta","id":"event:text-delta.delta","kind":"contract-field","parent":"event:text-delta","signature":":delta string","summary":"Incremental streamed text fragment for the open content block.","tags":["contracts","event","field","text-delta","delta","string"]}
{"field":":type","href":"events.html#contract-field-event-text-delta-type","id":"event:text-delta.type","kind":"contract-field","parent":"event:text-delta","signature":":type :text-delta","summary":"Event discriminator for :text-delta events.","tags":["contracts","event","field","text-delta","type"]}
{"fields":["content-index","delta","type"],"href":"events.html#contract-entry-event-text-delta","id":"event:text-delta","kind":"event","summary":"Provider stream: incremental text token within the open block.","tags":["contracts","event","text-delta"]}
{"field":":content","href":"events.html#contract-field-event-text-end-content","id":"event:text-end.content","kind":"contract-field","parent":"event:text-end","signature":":content string","summary":"Complete text or thinking content for the closed stream block.","tags":["contracts","event","field","text-end","content","string"]}
{"field":":content-index","href":"events.html#contract-field-event-text-end-content-index","id":"event:text-end.content-index","kind":"contract-field","parent":"event:text-end","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","text-end","content-index","number"]}
{"field":":type","href":"events.html#contract-field-event-text-end-type","id":"event:text-end.type","kind":"contract-field","parent":"event:text-end","signature":":type :text-end","summary":"Event discriminator for :text-end events.","tags":["contracts","event","field","text-end","type"]}
{"fields":["content","content-index","type"],"href":"events.html#contract-entry-event-text-end","id":"event:text-end","kind":"event","summary":"Provider stream: TextContent block closed; full text supplied.","tags":["contracts","event","text-end"]}
{"field":":content-index","href":"events.html#contract-field-event-text-start-content-index","id":"event:text-start.content-index","kind":"contract-field","parent":"event:text-start","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","text-start","content-index","number"]}
{"field":":type","href":"events.html#contract-field-event-text-start-type","id":"event:text-start.type","kind":"contract-field","parent":"event:text-start","signature":":type :text-start","summary":"Event discriminator for :text-start events.","tags":["contracts","event","field","text-start","type"]}
{"fields":["content-index","type"],"href":"events.html#contract-entry-event-text-start","id":"event:text-start","kind":"event","summary":"Provider stream: a TextContent block is starting.","tags":["contracts","event","text-start"]}
{"field":":content-index","href":"events.html#contract-field-event-thinking-delta-content-index","id":"event:thinking-delta.content-index","kind":"contract-field","parent":"event:thinking-delta","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","thinking-delta","content-index","number"]}
{"field":":delta","href":"events.html#contract-field-event-thinking-delta-delta","id":"event:thinking-delta.delta","kind":"contract-field","parent":"event:thinking-delta","signature":":delta string","summary":"Incremental streamed text fragment for the open content block.","tags":["contracts","event","field","thinking-delta","delta","string"]}
{"field":":type","href":"events.html#contract-field-event-thinking-delta-type","id":"event:thinking-delta.type","kind":"contract-field","parent":"event:thinking-delta","signature":":type :thinking-delta","summary":"Event discriminator for :thinking-delta events.","tags":["contracts","event","field","thinking-delta","type"]}
{"fields":["content-index","delta","type"],"href":"events.html#contract-entry-event-thinking-delta","id":"event:thinking-delta","kind":"event","summary":"Provider stream: incremental reasoning token within the open block.","tags":["contracts","event","thinking-delta"]}
{"field":":content","href":"events.html#contract-field-event-thinking-end-content","id":"event:thinking-end.content","kind":"contract-field","parent":"event:thinking-end","signature":":content string","summary":"Complete text or thinking content for the closed stream block.","tags":["contracts","event","field","thinking-end","content","string"]}
{"field":":content-index","href":"events.html#contract-field-event-thinking-end-content-index","id":"event:thinking-end.content-index","kind":"contract-field","parent":"event:thinking-end","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","thinking-end","content-index","number"]}
{"field":":type","href":"events.html#contract-field-event-thinking-end-type","id":"event:thinking-end.type","kind":"contract-field","parent":"event:thinking-end","signature":":type :thinking-end","summary":"Event discriminator for :thinking-end events.","tags":["contracts","event","field","thinking-end","type"]}
{"fields":["content","content-index","type"],"href":"events.html#contract-entry-event-thinking-end","id":"event:thinking-end","kind":"event","summary":"Provider stream: ThinkingContent block closed; full text supplied.","tags":["contracts","event","thinking-end"]}
{"field":":content-index","href":"events.html#contract-field-event-thinking-start-content-index","id":"event:thinking-start.content-index","kind":"contract-field","parent":"event:thinking-start","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","thinking-start","content-index","number"]}
{"field":":type","href":"events.html#contract-field-event-thinking-start-type","id":"event:thinking-start.type","kind":"contract-field","parent":"event:thinking-start","signature":":type :thinking-start","summary":"Event discriminator for :thinking-start events.","tags":["contracts","event","field","thinking-start","type"]}
{"fields":["content-index","type"],"href":"events.html#contract-entry-event-thinking-start","id":"event:thinking-start","kind":"event","summary":"Provider stream: a ThinkingContent block is starting.","tags":["contracts","event","thinking-start"]}
{"field":":tool-call","href":"events.html#contract-field-event-tool-call-tool-call","id":"event:tool-call.tool-call","kind":"contract-field","parent":"event:tool-call","signature":":tool-call ToolCall","summary":"Canonical tool-call block associated with this event.","tags":["contracts","event","field","tool-call","toolcall"]}
{"field":":type","href":"events.html#contract-field-event-tool-call-type","id":"event:tool-call.type","kind":"contract-field","parent":"event:tool-call","signature":":type :tool-call","summary":"Event discriminator for :tool-call events.","tags":["contracts","event","field","tool-call","type"]}
{"fields":["tool-call","type"],"href":"events.html#contract-entry-event-tool-call","id":"event:tool-call","kind":"event","summary":"Tool call about to execute. Carries the canonical ToolCall block.","tags":["contracts","event","tool-call"]}
{"field":":content-index","href":"events.html#contract-field-event-tool-call-delta-content-index","id":"event:tool-call-delta.content-index","kind":"contract-field","parent":"event:tool-call-delta","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","tool-call-delta","content-index","number"]}
{"field":":delta","href":"events.html#contract-field-event-tool-call-delta-delta","id":"event:tool-call-delta.delta","kind":"contract-field","parent":"event:tool-call-delta","signature":":delta string","summary":"Incremental streamed text fragment for the open content block.","tags":["contracts","event","field","tool-call-delta","delta","string"]}
{"field":":type","href":"events.html#contract-field-event-tool-call-delta-type","id":"event:tool-call-delta.type","kind":"contract-field","parent":"event:tool-call-delta","signature":":type :tool-call-delta","summary":"Event discriminator for :tool-call-delta events.","tags":["contracts","event","field","tool-call-delta","type"]}
{"fields":["content-index","delta","type"],"href":"events.html#contract-entry-event-tool-call-delta","id":"event:tool-call-delta","kind":"event","summary":"Provider stream: incremental JSON-text fragment for the open ToolCall arguments. Some providers stream arguments token-by-token; consumers may concatenate.","tags":["contracts","event","tool-call-delta"]}
{"field":":content-index","href":"events.html#contract-field-event-tool-call-end-content-index","id":"event:tool-call-end.content-index","kind":"contract-field","parent":"event:tool-call-end","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","tool-call-end","content-index","number"]}
{"field":":tool-call","href":"events.html#contract-field-event-tool-call-end-tool-call","id":"event:tool-call-end.tool-call","kind":"contract-field","parent":"event:tool-call-end","signature":":tool-call ToolCall","summary":"Canonical tool-call block associated with this event.","tags":["contracts","event","field","tool-call-end","tool-call","toolcall"]}
{"field":":type","href":"events.html#contract-field-event-tool-call-end-type","id":"event:tool-call-end.type","kind":"contract-field","parent":"event:tool-call-end","signature":":type :tool-call-end","summary":"Event discriminator for :tool-call-end events.","tags":["contracts","event","field","tool-call-end","type"]}
{"fields":["content-index","tool-call","type"],"href":"events.html#contract-entry-event-tool-call-end","id":"event:tool-call-end","kind":"event","summary":"Provider stream: ToolCall block closed; complete canonical ToolCall block supplied.","tags":["contracts","event","tool-call-end"]}
{"field":":content-index","href":"events.html#contract-field-event-tool-call-start-content-index","id":"event:tool-call-start.content-index","kind":"contract-field","parent":"event:tool-call-start","signature":":content-index number","summary":"Position within the assistant's content array.","tags":["contracts","event","field","tool-call-start","content-index","number"]}
{"field":":type","href":"events.html#contract-field-event-tool-call-start-type","id":"event:tool-call-start.type","kind":"contract-field","parent":"event:tool-call-start","signature":":type :tool-call-start","summary":"Event discriminator for :tool-call-start events.","tags":["contracts","event","field","tool-call-start","type"]}
{"fields":["content-index","type"],"href":"events.html#contract-entry-event-tool-call-start","id":"event:tool-call-start","kind":"event","summary":"Provider stream: a ToolCall block is starting; arguments not yet known.","tags":["contracts","event","tool-call-start"]}
{"field":":result","href":"events.html#contract-field-event-tool-result-result","id":"event:tool-result.result","kind":"contract-field","parent":"event:tool-result","signature":":result ToolResultMessage","summary":"Canonical tool-result message produced by the tool executor.","tags":["contracts","event","field","tool-result","result","toolresultmessage"]}
{"field":":type","href":"events.html#contract-field-event-tool-result-type","id":"event:tool-result.type","kind":"contract-field","parent":"event:tool-result","signature":":type :tool-result","summary":"Event discriminator for :tool-result events.","tags":["contracts","event","field","tool-result","type"]}
{"fields":["result","type"],"href":"events.html#contract-entry-event-tool-result","id":"event:tool-result","kind":"event","summary":"Tool execution finished. Carries the canonical ToolResultMessage.","tags":["contracts","event","tool-result"]}
{"field":":line","href":"events.html#contract-field-event-user-line","id":"event:user.line","kind":"contract-field","parent":"event:user","signature":":line string","summary":"Raw user input line associated with the event.","tags":["contracts","event","field","user","line","string"]}
{"field":":type","href":"events.html#contract-field-event-user-type","id":"event:user.type","kind":"contract-field","parent":"event:user","signature":":type :user","summary":"Event discriminator for :user events.","tags":["contracts","event","field","user","type"]}
{"fields":["line","type"],"href":"events.html#contract-entry-event-user","id":"event:user","kind":"event","summary":"User-submitted line accepted by the presenter input layer. Distinct from :queued (which fires when the line is *queued* during a busy turn).","tags":["contracts","event","user"]}
{"field":":max-tokens","href":"types.html#contract-field-type-agentcontext-max-tokens","id":"type:AgentContext.max-tokens","kind":"contract-field","parent":"type:AgentContext","signature":":max-tokens number","summary":"Maximum output token budget requested for the provider call.","tags":["contracts","type","field","agentcontext","max-tokens","number"]}
{"field":":messages","href":"types.html#contract-field-type-agentcontext-messages","id":"type:AgentContext.messages","kind":"contract-field","parent":"type:AgentContext","signature":":messages [Message]","summary":"Canonical conversation history to convert into provider wire format.","tags":["contracts","type","field","agentcontext","messages","message"]}
{"field":":system-prompt","href":"types.html#contract-field-type-agentcontext-system-prompt","id":"type:AgentContext.system-prompt","kind":"contract-field","parent":"type:AgentContext","signature":":system-prompt string|nil","summary":"Fully rendered system prompt for the current step, or nil when omitted.","tags":["contracts","type","field","agentcontext","system-prompt","string","nil"]}
{"field":":tools","href":"types.html#contract-field-type-agentcontext-tools","id":"type:AgentContext.tools","kind":"contract-field","parent":"type:AgentContext","signature":":tools [Tool]","summary":"Provider-visible tool specs available for this step.","tags":["contracts","type","field","agentcontext","tools","tool"]}
{"fields":["max-tokens","messages","system-prompt","tools"],"href":"types.html#contract-entry-type-agentcontext","id":"type:AgentContext","kind":"type","summary":"Per-call payload handed to a provider's `:complete`.","tags":["contracts","type","agentcontext"]}
{"field":":description","href":"types.html#contract-field-type-agenttool-description","id":"type:AgentTool.description","kind":"contract-field","parent":"type:AgentTool","signature":":description string","summary":"Provider-facing description included in the tool schema.","tags":["contracts","type","field","agenttool","description","string"]}
{"field":":execute","href":"types.html#contract-field-type-agenttool-execute","id":"type:AgentTool.execute","kind":"contract-field","parent":"type:AgentTool","signature":":execute (args ?yield-fn) -> AgentToolResult","summary":"Runtime callback that executes the tool with decoded arguments.","tags":["contracts","type","field","agenttool","execute","args","yield-fn","-","agenttoolresult"]}
{"field":":label","href":"types.html#contract-field-type-agenttool-label","id":"type:AgentTool.label","kind":"contract-field","parent":"type:AgentTool","signature":":label string","summary":"UI label.","tags":["contracts","type","field","agenttool","label","string"]}
{"field":":name","href":"types.html#contract-field-type-agenttool-name","id":"type:AgentTool.name","kind":"contract-field","parent":"type:AgentTool","signature":":name string","summary":"Registry name used to merge and dispatch the tool.","tags":["contracts","type","field","agenttool","name","string"]}
{"field":":parameters","href":"types.html#contract-field-type-agenttool-parameters","id":"type:AgentTool.parameters","kind":"contract-field","parent":"type:AgentTool","signature":":parameters JSONSchema","summary":"Provider-facing argument schema used for validation and prompting.","tags":["contracts","type","field","agenttool","parameters","jsonschema"]}
{"fields":["description","execute","label","name","parameters"],"href":"types.html#contract-entry-type-agenttool","id":"type:AgentTool","kind":"type","summary":"Tool extended with execution metadata for the agent loop. Registered through `(api.register :tool ...)`.","tags":["contracts","type","agenttool"]}
{"field":":content","href":"types.html#contract-field-type-agenttoolresult-content","id":"type:AgentToolResult.content","kind":"contract-field","parent":"type:AgentToolResult","signature":":content [TextContent]","summary":"Text content returned to the provider as the tool observation.","tags":["contracts","type","field","agenttoolresult","content","textcontent"]}
{"field":":details","href":"types.html#contract-field-type-agenttoolresult-details","id":"type:AgentToolResult.details","kind":"contract-field","parent":"type:AgentToolResult","signature":":details any","summary":"Opaque presenter payload (UI-only).","tags":["contracts","type","field","agenttoolresult","details","any"]}
{"field":":is-error?","href":"types.html#contract-field-type-agenttoolresult-is-error","id":"type:AgentToolResult.is-error?","kind":"contract-field","parent":"type:AgentToolResult","signature":":is-error? boolean","summary":"True when the tool observation represents a failed call.","tags":["contracts","type","field","agenttoolresult","is-error","boolean"]}
{"fields":["content","details","is-error?"],"href":"types.html#contract-entry-type-agenttoolresult","id":"type:AgentToolResult","kind":"type","summary":"Outcome of a tool execution.","tags":["contracts","type","agenttoolresult"]}
{"field":":api","href":"types.html#contract-field-type-assistantmessage-api","id":"type:AssistantMessage.api","kind":"contract-field","parent":"type:AssistantMessage","signature":":api keyword","summary":":openai-completions | :openai-responses | :anthropic-messages | :openai-codex","tags":["contracts","type","field","assistantmessage","api","keyword"]}
{"field":":content","href":"types.html#contract-field-type-assistantmessage-content","id":"type:AssistantMessage.content","kind":"contract-field","parent":"type:AssistantMessage","signature":":content [TextContent|ThinkingContent|ToolCall]","summary":"Ordered assistant output blocks, including visible text, reasoning, and tool calls.","tags":["contracts","type","field","assistantmessage","content","textcontent","thinkingcontent","toolcall"]}
{"field":":error-message","href":"types.html#contract-field-type-assistantmessage-error-message","id":"type:AssistantMessage.error-message","kind":"contract-field","parent":"type:AssistantMessage","signature":":error-message string","summary":"Present only when stop-reason = :error.","tags":["contracts","type","field","assistantmessage","error-message","string"]}
{"field":":model","href":"types.html#contract-field-type-assistantmessage-model","id":"type:AssistantMessage.model","kind":"contract-field","parent":"type:AssistantMessage","signature":":model string","summary":"Provider model identifier that produced this response.","tags":["contracts","type","field","assistantmessage","model","string"]}
{"field":":provider","href":"types.html#contract-field-type-assistantmessage-provider","id":"type:AssistantMessage.provider","kind":"contract-field","parent":"type:AssistantMessage","signature":":provider keyword","summary":"Registered provider :name (e.g. :openai, :anthropic).","tags":["contracts","type","field","assistantmessage","provider","keyword"]}
{"field":":role","href":"types.html#contract-field-type-assistantmessage-role","id":"type:AssistantMessage.role","kind":"contract-field","parent":"type:AssistantMessage","signature":":role :assistant","summary":"Message role discriminator for model-authored turns.","tags":["contracts","type","field","assistantmessage","role","assistant"]}
{"field":":stop-reason","href":"types.html#contract-field-type-assistantmessage-stop-reason","id":"type:AssistantMessage.stop-reason","kind":"contract-field","parent":"type:AssistantMessage","signature":":stop-reason StopReason","summary":"Normalized reason the provider stopped generation.","tags":["contracts","type","field","assistantmessage","stop-reason","stopreason"]}
{"field":":timestamp","href":"types.html#contract-field-type-assistantmessage-timestamp","id":"type:AssistantMessage.timestamp","kind":"contract-field","parent":"type:AssistantMessage","signature":":timestamp number","summary":"Milliseconds since epoch when the assistant message was recorded.","tags":["contracts","type","field","assistantmessage","timestamp","number"]}
{"field":":usage","href":"types.html#contract-field-type-assistantmessage-usage","id":"type:AssistantMessage.usage","kind":"contract-field","parent":"type:AssistantMessage","signature":":usage Usage","summary":"Optional token accounting returned by the provider for this response.","tags":["contracts","type","field","assistantmessage","usage"]}
{"fields":["api","content","error-message","model","provider","role","stop-reason","timestamp","usage"],"href":"types.html#contract-entry-type-assistantmessage","id":"type:AssistantMessage","kind":"type","summary":"Single model response. Content is always an array, even when empty.","tags":["contracts","type","assistantmessage"]}
{"category":"variant","href":"types.html#contract-member-type-message-variant-usermessage","id":"type:Message:variant:UserMessage","kind":"contract-member","member":"UserMessage","name":"UserMessage","parent":"type:Message","signature":"UserMessage","summary":"UserMessage is a Message union variant.","tags":["contracts","type","member","variant","message","usermessage"]}
{"category":"variant","href":"types.html#contract-member-type-message-variant-assistantmessage","id":"type:Message:variant:AssistantMessage","kind":"contract-member","member":"AssistantMessage","name":"AssistantMessage","parent":"type:Message","signature":"AssistantMessage","summary":"AssistantMessage is a Message union variant.","tags":["contracts","type","member","variant","message","assistantmessage"]}
{"category":"variant","href":"types.html#contract-member-type-message-variant-toolresultmessage","id":"type:Message:variant:ToolResultMessage","kind":"contract-member","member":"ToolResultMessage","name":"ToolResultMessage","parent":"type:Message","signature":"ToolResultMessage","summary":"ToolResultMessage is a Message union variant.","tags":["contracts","type","member","variant","message","toolresultmessage"]}
{"href":"types.html#contract-entry-type-message","id":"type:Message","kind":"type","summary":"Union of UserMessage, AssistantMessage, ToolResultMessage. Stored on `agent.messages` and passed to providers in `AgentContext.messages`.","tags":["contracts","type","message"],"variants":["UserMessage","AssistantMessage","ToolResultMessage"]}
{"category":"enum","href":"types.html#contract-member-type-stopreason-enum-stop","id":"type:StopReason:enum:stop","kind":"contract-member","member":":stop","name":":stop","parent":"type:StopReason","signature":":stop","summary":":stop is a StopReason enum value.","tags":["contracts","type","member","enum","stopreason","stop"]}
{"category":"enum","href":"types.html#contract-member-type-stopreason-enum-length","id":"type:StopReason:enum:length","kind":"contract-member","member":":length","name":":length","parent":"type:StopReason","signature":":length","summary":":length is a StopReason enum value.","tags":["contracts","type","member","enum","stopreason","length"]}
{"category":"enum","href":"types.html#contract-member-type-stopreason-enum-tool-use","id":"type:StopReason:enum:tool-use","kind":"contract-member","member":":tool-use","name":":tool-use","parent":"type:StopReason","signature":":tool-use","summary":":tool-use is a StopReason enum value.","tags":["contracts","type","member","enum","stopreason","tool-use"]}
{"category":"enum","href":"types.html#contract-member-type-stopreason-enum-error","id":"type:StopReason:enum:error","kind":"contract-member","member":":error","name":":error","parent":"type:StopReason","signature":":error","summary":":error is a StopReason enum value.","tags":["contracts","type","member","enum","stopreason","error"]}
{"category":"enum","href":"types.html#contract-member-type-stopreason-enum-aborted","id":"type:StopReason:enum:aborted","kind":"contract-member","member":":aborted","name":":aborted","parent":"type:StopReason","signature":":aborted","summary":":aborted is a StopReason enum value.","tags":["contracts","type","member","enum","stopreason","aborted"]}
{"enum":["stop","length","tool-use","error","aborted"],"href":"types.html#contract-entry-type-stopreason","id":"type:StopReason","kind":"type","summary":"Why the assistant stopped producing output.","tags":["contracts","type","stopreason"]}
{"field":":text","href":"types.html#contract-field-type-textcontent-text","id":"type:TextContent.text","kind":"contract-field","parent":"type:TextContent","signature":":text string","summary":"Visible UTF-8 text payload.","tags":["contracts","type","field","textcontent","text","string"]}
{"field":":type","href":"types.html#contract-field-type-textcontent-type","id":"type:TextContent.type","kind":"contract-field","parent":"type:TextContent","signature":":type :text","summary":"Content-block discriminator for visible text.","tags":["contracts","type","field","textcontent","text"]}
{"fields":["text","type"],"href":"types.html#contract-entry-type-textcontent","id":"type:TextContent","kind":"type","summary":"Plain visible text block.","tags":["contracts","type","textcontent"]}
{"field":":redacted?","href":"types.html#contract-field-type-thinkingcontent-redacted","id":"type:ThinkingContent.redacted?","kind":"contract-field","parent":"type:ThinkingContent","signature":":redacted? boolean","summary":"True when the provider redacted visible text.","tags":["contracts","type","field","thinkingcontent","redacted","boolean"]}
{"field":":thinking","href":"types.html#contract-field-type-thinkingcontent-thinking","id":"type:ThinkingContent.thinking","kind":"contract-field","parent":"type:ThinkingContent","signature":":thinking string","summary":"Reasoning or extended-thinking text emitted by the provider.","tags":["contracts","type","field","thinkingcontent","thinking","string"]}
{"field":":thinking-signature","href":"types.html#contract-field-type-thinkingcontent-thinking-signature","id":"type:ThinkingContent.thinking-signature","kind":"contract-field","parent":"type:ThinkingContent","signature":":thinking-signature string","summary":"Opaque echo signature; required for multi-turn extended thinking.","tags":["contracts","type","field","thinkingcontent","thinking-signature","string"]}
{"field":":type","href":"types.html#contract-field-type-thinkingcontent-type","id":"type:ThinkingContent.type","kind":"contract-field","parent":"type:ThinkingContent","signature":":type :thinking","summary":"Content-block discriminator for provider reasoning text.","tags":["contracts","type","field","thinkingcontent","thinking"]}
{"fields":["redacted?","thinking","thinking-signature","type"],"href":"types.html#contract-entry-type-thinkingcontent","id":"type:ThinkingContent","kind":"type","summary":"Reasoning/extended-thinking block. Surfaces both Anthropic extended thinking and OpenAI reasoning items.","tags":["contracts","type","thinkingcontent"]}
{"field":":description","href":"types.html#contract-field-type-tool-description","id":"type:Tool.description","kind":"contract-field","parent":"type:Tool","signature":":description string","summary":"Provider-visible explanation of when and how to call the tool.","tags":["contracts","type","field","tool","description","string"]}
{"field":":name","href":"types.html#contract-field-type-tool-name","id":"type:Tool.name","kind":"contract-field","parent":"type:Tool","signature":":name string","summary":"Provider-visible tool name used in tool-call blocks.","tags":["contracts","type","field","tool","name","string"]}
{"field":":parameters","href":"types.html#contract-field-type-tool-parameters","id":"type:Tool.parameters","kind":"contract-field","parent":"type:Tool","signature":":parameters JSONSchema","summary":"{:type :object :properties {...} :required [...]}","tags":["contracts","type","field","tool","parameters","jsonschema"]}
{"fields":["description","name","parameters"],"href":"types.html#contract-entry-type-tool","id":"type:Tool","kind":"type","summary":"Provider-agnostic tool spec — what providers see in `AgentContext.tools`.","tags":["contracts","type","tool"]}
{"field":":arguments","href":"types.html#contract-field-type-toolcall-arguments","id":"type:ToolCall.arguments","kind":"contract-field","parent":"type:ToolCall","signature":":arguments table","summary":"Decoded argument table validated by the target tool implementation.","tags":["contracts","type","field","toolcall","arguments","table"]}
{"field":":id","href":"types.html#contract-field-type-toolcall-id","id":"type:ToolCall.id","kind":"contract-field","parent":"type:ToolCall","signature":":id string","summary":"Provider- or agent-generated id used to match the eventual tool result.","tags":["contracts","type","field","toolcall","id","string"]}
{"field":":name","href":"types.html#contract-field-type-toolcall-name","id":"type:ToolCall.name","kind":"contract-field","parent":"type:ToolCall","signature":":name string","summary":"Registered tool name to execute.","tags":["contracts","type","field","toolcall","name","string"]}
{"field":":type","href":"types.html#contract-field-type-toolcall-type","id":"type:ToolCall.type","kind":"contract-field","parent":"type:ToolCall","signature":":type :tool-call","summary":"Content-block discriminator for tool invocation requests.","tags":["contracts","type","field","toolcall","tool-call"]}
{"fields":["arguments","id","name","type"],"href":"types.html#contract-entry-type-toolcall","id":"type:ToolCall","kind":"type","summary":"Assistant request to invoke a tool. Arguments are a parsed Lua table — providers JSON-decode wire arguments before constructing this block.","tags":["contracts","type","toolcall"]}
{"field":":content","href":"types.html#contract-field-type-toolresultmessage-content","id":"type:ToolResultMessage.content","kind":"contract-field","parent":"type:ToolResultMessage","signature":":content [TextContent]","summary":"Tool output blocks returned to the provider on the next turn.","tags":["contracts","type","field","toolresultmessage","content","textcontent"]}
{"field":":details","href":"types.html#contract-field-type-toolresultmessage-details","id":"type:ToolResultMessage.details","kind":"contract-field","parent":"type:ToolResultMessage","signature":":details any","summary":"Opaque presenter payload (UI-only).","tags":["contracts","type","field","toolresultmessage","details","any"]}
{"field":":is-error?","href":"types.html#contract-field-type-toolresultmessage-is-error","id":"type:ToolResultMessage.is-error?","kind":"contract-field","parent":"type:ToolResultMessage","signature":":is-error? boolean","summary":"True when the tool result should be treated as an error observation.","tags":["contracts","type","field","toolresultmessage","is-error","boolean"]}
{"field":":role","href":"types.html#contract-field-type-toolresultmessage-role","id":"type:ToolResultMessage.role","kind":"contract-field","parent":"type:ToolResultMessage","signature":":role :tool-result","summary":"Message role discriminator for tool execution results.","tags":["contracts","type","field","toolresultmessage","role","tool-result"]}
{"field":":timestamp","href":"types.html#contract-field-type-toolresultmessage-timestamp","id":"type:ToolResultMessage.timestamp","kind":"contract-field","parent":"type:ToolResultMessage","signature":":timestamp number","summary":"Milliseconds since epoch when the tool result was recorded.","tags":["contracts","type","field","toolresultmessage","timestamp","number"]}
{"field":":tool-call-id","href":"types.html#contract-field-type-toolresultmessage-tool-call-id","id":"type:ToolResultMessage.tool-call-id","kind":"contract-field","parent":"type:ToolResultMessage","signature":":tool-call-id string","summary":"Matches the originating ToolCall.id.","tags":["contracts","type","field","toolresultmessage","tool-call-id","string"]}
{"field":":tool-name","href":"types.html#contract-field-type-toolresultmessage-tool-name","id":"type:ToolResultMessage.tool-name","kind":"contract-field","parent":"type:ToolResultMessage","signature":":tool-name string","summary":"Tool name that produced the result, copied from the originating call.","tags":["contracts","type","field","toolresultmessage","tool-name","string"]}
{"fields":["content","details","is-error?","role","timestamp","tool-call-id","tool-name"],"href":"types.html#contract-entry-type-toolresultmessage","id":"type:ToolResultMessage","kind":"type","summary":"Result of a single tool call, carried back to the provider on the next turn.","tags":["contracts","type","toolresultmessage"]}
{"field":":cache-read","href":"types.html#contract-field-type-usage-cache-read","id":"type:Usage.cache-read","kind":"contract-field","parent":"type:Usage","signature":":cache-read number","summary":"Provider cache-read tokens credited for the response.","tags":["contracts","type","field","usage","cache-read","number"]}
{"field":":cache-write","href":"types.html#contract-field-type-usage-cache-write","id":"type:Usage.cache-write","kind":"contract-field","parent":"type:Usage","signature":":cache-write number","summary":"Provider cache-write tokens billed or recorded for the response.","tags":["contracts","type","field","usage","cache-write","number"]}
{"field":":input","href":"types.html#contract-field-type-usage-input","id":"type:Usage.input","kind":"contract-field","parent":"type:Usage","signature":":input number","summary":"Input or prompt tokens counted for the response.","tags":["contracts","type","field","usage","input","number"]}
{"field":":output","href":"types.html#contract-field-type-usage-output","id":"type:Usage.output","kind":"contract-field","parent":"type:Usage","signature":":output number","summary":"Generated output tokens counted for the response.","tags":["contracts","type","field","usage","output","number"]}
{"field":":total-tokens","href":"types.html#contract-field-type-usage-total-tokens","id":"type:Usage.total-tokens","kind":"contract-field","parent":"type:Usage","signature":":total-tokens number","summary":"Provider-reported total tokens, or the best available aggregate.","tags":["contracts","type","field","usage","total-tokens","number"]}
{"fields":["cache-read","cache-write","input","output","total-tokens"],"href":"types.html#contract-entry-type-usage","id":"type:Usage","kind":"type","summary":"Token usage counters returned by the provider (best-effort — providers fill what they can).","tags":["contracts","type","usage"]}
{"field":":content","href":"types.html#contract-field-type-usermessage-content","id":"type:UserMessage.content","kind":"contract-field","parent":"type:UserMessage","signature":":content string|[TextContent]","summary":"Visible user input as plain text or canonical text content blocks.","tags":["contracts","type","field","usermessage","content","string","textcontent"]}
{"field":":role","href":"types.html#contract-field-type-usermessage-role","id":"type:UserMessage.role","kind":"contract-field","parent":"type:UserMessage","signature":":role :user","summary":"Message role discriminator for user-authored turns.","tags":["contracts","type","field","usermessage","role","user"]}
{"field":":timestamp","href":"types.html#contract-field-type-usermessage-timestamp","id":"type:UserMessage.timestamp","kind":"contract-field","parent":"type:UserMessage","signature":":timestamp number","summary":"Milliseconds since epoch.","tags":["contracts","type","field","usermessage","timestamp","number"]}
{"fields":["content","role","timestamp"],"href":"types.html#contract-entry-type-usermessage","id":"type:UserMessage","kind":"type","summary":"Single user turn. Content is either a plain string or an array of TextContent blocks.","tags":["contracts","type","usermessage"]}
{"category":"method","href":"interfaces.html#contract-member-interface-auth-backend-method-api-key","id":"interface:auth-backend:method:api-key","kind":"contract-member","member":":api-key","name":":api-key","parent":"interface:auth-backend","signature":":api-key","summary":":api-key is a required auth-backend interface method.","tags":["contracts","interface","member","method","auth-backend","api-key"]}
{"category":"optional-method","href":"interfaces.html#contract-member-interface-auth-backend-optional-method-login","id":"interface:auth-backend:optional-method:login!","kind":"contract-member","member":":login!","name":":login!","parent":"interface:auth-backend","signature":":login!","summary":":login! is an optional auth-backend interface method.","tags":["contracts","interface","member","optional-method","auth-backend","login"]}
{"category":"optional-method","href":"interfaces.html#contract-member-interface-auth-backend-optional-method-logout","id":"interface:auth-backend:optional-method:logout!","kind":"contract-member","member":":logout!","name":":logout!","parent":"interface:auth-backend","signature":":logout!","summary":":logout! is an optional auth-backend interface method.","tags":["contracts","interface","member","optional-method","auth-backend","logout"]}
{"href":"interfaces.html#contract-entry-interface-auth-backend","id":"interface:auth-backend","kind":"interface","methods":["api-key"],"optional-methods":["login!","logout!"],"summary":"Required record shape for `(api.register :auth-backend ...)`.","tags":["contracts","interface","auth-backend"]}
{"category":"method","href":"interfaces.html#contract-member-interface-provider-method-complete","id":"interface:provider:method:complete","kind":"contract-member","member":":complete","name":":complete","parent":"interface:provider","signature":":complete","summary":":complete is a required provider interface method.","tags":["contracts","interface","member","method","provider","complete"]}
{"category":"method","href":"interfaces.html#contract-member-interface-provider-method-convert-messages","id":"interface:provider:method:convert-messages","kind":"contract-member","member":":convert-messages","name":":convert-messages","parent":"interface:provider","signature":":convert-messages","summary":":convert-messages is a required provider interface method.","tags":["contracts","interface","member","method","provider","convert-messages"]}
{"category":"method","href":"interfaces.html#contract-member-interface-provider-method-convert-tools","id":"interface:provider:method:convert-tools","kind":"contract-member","member":":convert-tools","name":":convert-tools","parent":"interface:provider","signature":":convert-tools","summary":":convert-tools is a required provider interface method.","tags":["contracts","interface","member","method","provider","convert-tools"]}
{"category":"method","href":"interfaces.html#contract-member-interface-provider-method-map-stop-reason","id":"interface:provider:method:map-stop-reason","kind":"contract-member","member":":map-stop-reason","name":":map-stop-reason","parent":"interface:provider","signature":":map-stop-reason","summary":":map-stop-reason is a required provider interface method.","tags":["contracts","interface","member","method","provider","map-stop-reason"]}
{"category":"method","href":"interfaces.html#contract-member-interface-provider-method-parse-response","id":"interface:provider:method:parse-response","kind":"contract-member","member":":parse-response","name":":parse-response","parent":"interface:provider","signature":":parse-response","summary":":parse-response is a required provider interface method.","tags":["contracts","interface","member","method","provider","parse-response"]}
{"category":"method","href":"interfaces.html#contract-member-interface-provider-method-build-body","id":"interface:provider:method:build-body","kind":"contract-member","member":":build-body","name":":build-body","parent":"interface:provider","signature":":build-body","summary":":build-body is a required provider interface method.","tags":["contracts","interface","member","method","provider","build-body"]}
{"href":"interfaces.html#contract-entry-interface-provider","id":"interface:provider","kind":"interface","methods":["complete","convert-messages","convert-tools","map-stop-reason","parse-response","build-body"],"summary":"Required record shape for `(api.register :provider ...)`. See the :provider register-kind for field details.","tags":["contracts","interface","provider"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-open","id":"interface:session-backend:method:open","kind":"contract-member","member":":open","name":":open","parent":"interface:session-backend","signature":":open","summary":":open is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","open"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-open-existing","id":"interface:session-backend:method:open-existing","kind":"contract-member","member":":open-existing","name":":open-existing","parent":"interface:session-backend","signature":":open-existing","summary":":open-existing is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","open-existing"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-append","id":"interface:session-backend:method:append","kind":"contract-member","member":":append","name":":append","parent":"interface:session-backend","signature":":append","summary":":append is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","append"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-close","id":"interface:session-backend:method:close","kind":"contract-member","member":":close","name":":close","parent":"interface:session-backend","signature":":close","summary":":close is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","close"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-load","id":"interface:session-backend:method:load","kind":"contract-member","member":":load","name":":load","parent":"interface:session-backend","signature":":load","summary":":load is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","load"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-find","id":"interface:session-backend:method:find","kind":"contract-member","member":":find","name":":find","parent":"interface:session-backend","signature":":find","summary":":find is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","find"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-list","id":"interface:session-backend:method:list","kind":"contract-member","member":":list","name":":list","parent":"interface:session-backend","signature":":list","summary":":list is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","list"]}
{"category":"method","href":"interfaces.html#contract-member-interface-session-backend-method-latest","id":"interface:session-backend:method:latest","kind":"contract-member","member":":latest","name":":latest","parent":"interface:session-backend","signature":":latest","summary":":latest is a required session-backend interface method.","tags":["contracts","interface","member","method","session-backend","latest"]}
{"href":"interfaces.html#contract-entry-interface-session-backend","id":"interface:session-backend","kind":"interface","methods":["open","open-existing","append","close","load","find","list","latest"],"summary":"Required record shape for `(api.register :session-backend ...)`.","tags":["contracts","interface","session-backend"]}
{"description":"Registered print presenter contribution.","href":"presenters.html#register-site-presenter-print-extensions-adapters-presenters-print-init-fnl-34","id":"register-site:presenter:print:extensions-adapters-presenters-print-init-fnl-34","kind":"register-site:presenter","line":34,"name":"print","path":"extensions/adapters/presenters/print/init.fnl","summary":"Registered print presenter contribution.","tags":["extensions","register-site","presenter","print"]}
{"description":"Registered stdio presenter contribution.","href":"presenters.html#register-site-presenter-stdio-extensions-adapters-presenters-stdio-init-fnl-281","id":"register-site:presenter:stdio:extensions-adapters-presenters-stdio-init-fnl-281","kind":"register-site:presenter","line":281,"name":"stdio","path":"extensions/adapters/presenters/stdio/init.fnl","summary":"Registered stdio presenter contribution.","tags":["extensions","register-site","presenter","stdio"]}
{"description":"Registered model status-line item contribution.","href":"status.html#register-site-status-model-extensions-adapters-presenters-tui-init-fnl-506","id":"register-site:status:model:extensions-adapters-presenters-tui-init-fnl-506","kind":"register-site:status","line":506,"name":"model","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered model status-line item contribution.","tags":["extensions","register-site","status","model"]}
{"description":"Registered thinking status-line item contribution.","href":"status.html#register-site-status-thinking-extensions-adapters-presenters-tui-init-fnl-515","id":"register-site:status:thinking:extensions-adapters-presenters-tui-init-fnl-515","kind":"register-site:status","line":515,"name":"thinking","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered thinking status-line item contribution.","tags":["extensions","register-site","status","thinking"]}
{"description":"Registered context status-line item contribution.","href":"status.html#register-site-status-context-extensions-adapters-presenters-tui-init-fnl-524","id":"register-site:status:context:extensions-adapters-presenters-tui-init-fnl-524","kind":"register-site:status","line":524,"name":"context","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered context status-line item contribution.","tags":["extensions","register-site","status","context"]}
{"description":"Registered steering-queue status-line item contribution.","href":"status.html#register-site-status-steering-queue-extensions-adapters-presenters-tui-init-fnl-533","id":"register-site:status:steering-queue:extensions-adapters-presenters-tui-init-fnl-533","kind":"register-site:status","line":533,"name":"steering-queue","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered steering-queue status-line item contribution.","tags":["extensions","register-site","status","steering-queue"]}
{"description":"Registered follow-up-queue status-line item contribution.","href":"status.html#register-site-status-follow-up-queue-extensions-adapters-presenters-tui-init-fnl-543","id":"register-site:status:follow-up-queue:extensions-adapters-presenters-tui-init-fnl-543","kind":"register-site:status","line":543,"name":"follow-up-queue","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered follow-up-queue status-line item contribution.","tags":["extensions","register-site","status","follow-up-queue"]}
{"description":"Registered attention status-line item contribution.","href":"status.html#register-site-status-attention-extensions-adapters-presenters-tui-init-fnl-553","id":"register-site:status:attention:extensions-adapters-presenters-tui-init-fnl-553","kind":"register-site:status","line":553,"name":"attention","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered attention status-line item contribution.","tags":["extensions","register-site","status","attention"]}
{"description":"Registered scroll status-line item contribution.","href":"status.html#register-site-status-scroll-extensions-adapters-presenters-tui-init-fnl-564","id":"register-site:status:scroll:extensions-adapters-presenters-tui-init-fnl-564","kind":"register-site:status","line":564,"name":"scroll","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered scroll status-line item contribution.","tags":["extensions","register-site","status","scroll"]}
{"description":"Registered version status-line item contribution.","href":"status.html#register-site-status-version-extensions-adapters-presenters-tui-init-fnl-574","id":"register-site:status:version:extensions-adapters-presenters-tui-init-fnl-574","kind":"register-site:status","line":574,"name":"version","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered version status-line item contribution.","tags":["extensions","register-site","status","version"]}
{"description":"TUI error introspection panel showing recent error summaries and traceback details.","href":"panels.html#register-site-panel-errors-extensions-adapters-presenters-tui-init-fnl-589","id":"register-site:panel:errors:extensions-adapters-presenters-tui-init-fnl-589","kind":"register-site:panel","line":589,"name":"errors","path":"extensions/adapters/presenters/tui/init.fnl","summary":"TUI error introspection panel showing recent error summaries and traceback details.","tags":["extensions","register-site","panel","errors"]}
{"description":"TUI busy-state panel showing spinner, retry information, and current turn elapsed time.","href":"panels.html#register-site-panel-busy-extensions-adapters-presenters-tui-init-fnl-593","id":"register-site:panel:busy:extensions-adapters-presenters-tui-init-fnl-593","kind":"register-site:panel","line":593,"name":"busy","path":"extensions/adapters/presenters/tui/init.fnl","summary":"TUI busy-state panel showing spinner, retry information, and current turn elapsed time.","tags":["extensions","register-site","panel","busy"]}
{"description":"Registered tui presenter contribution.","href":"presenters.html#register-site-presenter-tui-extensions-adapters-presenters-tui-init-fnl-601","id":"register-site:presenter:tui:extensions-adapters-presenters-tui-init-fnl-601","kind":"register-site:presenter","line":601,"name":"tui","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Registered tui presenter contribution.","tags":["extensions","register-site","presenter","tui"]}
{"description":"Jump to the latest user message; repeat for previous messages","href":"controls.html#register-site-control-jump-to-user-message-extensions-adapters-presenters-tui-init-fnl-623","id":"register-site:control:jump-to-user-message:extensions-adapters-presenters-tui-init-fnl-623","kind":"register-site:control","line":623,"name":"jump-to-user-message","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Jump to the latest user message; repeat for previous messages","tags":["extensions","register-site","control","jump-to-user-message"]}
{"description":"Jump to the live bottom and resume following transcript output","href":"controls.html#register-site-control-jump-to-live-bottom-extensions-adapters-presenters-tui-init-fnl-629","id":"register-site:control:jump-to-live-bottom:extensions-adapters-presenters-tui-init-fnl-629","kind":"register-site:control","line":629,"name":"jump-to-live-bottom","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Jump to the live bottom and resume following transcript output","tags":["extensions","register-site","control","jump-to-live-bottom"]}
{"description":"Toggle tool-result bodies","href":"controls.html#register-site-control-toggle-tool-results-extensions-adapters-presenters-tui-init-fnl-635","id":"register-site:control:toggle-tool-results:extensions-adapters-presenters-tui-init-fnl-635","kind":"register-site:control","line":635,"name":"toggle-tool-results","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Toggle tool-result bodies","tags":["extensions","register-site","control","toggle-tool-results"]}
{"description":"Toggle thinking blocks","href":"controls.html#register-site-control-toggle-thinking-blocks-extensions-adapters-presenters-tui-init-fnl-641","id":"register-site:control:toggle-thinking-blocks:extensions-adapters-presenters-tui-init-fnl-641","kind":"register-site:control","line":641,"name":"toggle-thinking-blocks","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Toggle thinking blocks","tags":["extensions","register-site","control","toggle-thinking-blocks"]}
{"description":"Quit; ctrl-c also clears input or cancels a busy turn","href":"controls.html#register-site-control-quit-extensions-adapters-presenters-tui-init-fnl-647","id":"register-site:control:quit:extensions-adapters-presenters-tui-init-fnl-647","kind":"register-site:control","line":647,"name":"quit","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Quit; ctrl-c also clears input or cancels a busy turn","tags":["extensions","register-site","control","quit"]}
{"description":"Redraw the screen / recover from terminal corruption","href":"controls.html#register-site-control-hard-refresh-extensions-adapters-presenters-tui-init-fnl-653","id":"register-site:control:hard-refresh:extensions-adapters-presenters-tui-init-fnl-653","kind":"register-site:control","line":653,"name":"hard-refresh","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Redraw the screen / recover from terminal corruption","tags":["extensions","register-site","control","hard-refresh"]}
{"description":"Suspend to the shell (resume with fg)","href":"controls.html#register-site-control-suspend-extensions-adapters-presenters-tui-init-fnl-659","id":"register-site:control:suspend:extensions-adapters-presenters-tui-init-fnl-659","kind":"register-site:control","line":659,"name":"suspend","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Suspend to the shell (resume with fg)","tags":["extensions","register-site","control","suspend"]}
{"description":"Toggle full vs collapsed tool-result bodies","href":"commands.html#register-site-command-expand-extensions-adapters-presenters-tui-init-fnl-665","id":"register-site:command:expand:extensions-adapters-presenters-tui-init-fnl-665","kind":"register-site:command","line":665,"name":"expand","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Toggle full vs collapsed tool-result bodies","tags":["extensions","register-site","command","expand"]}
{"description":"Toggle Markdown rendering of assistant text","href":"commands.html#register-site-command-markdown-extensions-adapters-presenters-tui-init-fnl-681","id":"register-site:command:markdown:extensions-adapters-presenters-tui-init-fnl-681","kind":"register-site:command","line":681,"name":"markdown","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Toggle Markdown rendering of assistant text","tags":["extensions","register-site","command","markdown"]}
{"description":"Toggle TUI busy animations","href":"commands.html#register-site-command-animations-extensions-adapters-presenters-tui-init-fnl-697","id":"register-site:command:animations:extensions-adapters-presenters-tui-init-fnl-697","kind":"register-site:command","line":697,"name":"animations","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Toggle TUI busy animations","tags":["extensions","register-site","command","animations"]}
{"description":"Show or hide assistant thinking blocks","href":"commands.html#register-site-command-thinking-blocks-extensions-adapters-presenters-tui-init-fnl-714","id":"register-site:command:thinking-blocks:extensions-adapters-presenters-tui-init-fnl-714","kind":"register-site:command","line":714,"name":"thinking-blocks","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Show or hide assistant thinking blocks","tags":["extensions","register-site","command","thinking-blocks"]}
{"description":"Toggle recent error details / tracebacks","href":"commands.html#register-site-command-errors-extensions-adapters-presenters-tui-init-fnl-733","id":"register-site:command:errors:extensions-adapters-presenters-tui-init-fnl-733","kind":"register-site:command","line":733,"name":"errors","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Toggle recent error details / tracebacks","tags":["extensions","register-site","command","errors"]}
{"description":"Force a full terminal repaint to recover from corruption","href":"commands.html#register-site-command-redraw-extensions-adapters-presenters-tui-init-fnl-753","id":"register-site:command:redraw:extensions-adapters-presenters-tui-init-fnl-753","kind":"register-site:command","line":753,"name":"redraw","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Force a full terminal repaint to recover from corruption","tags":["extensions","register-site","command","redraw"]}
{"description":"Current TUI presenter state summary without transcript or input contents","href":"introspect.html#register-site-introspect-runtime-extensions-adapters-presenters-tui-init-fnl-760","id":"register-site:introspect:runtime:extensions-adapters-presenters-tui-init-fnl-760","kind":"register-site:introspect","line":760,"name":"runtime","path":"extensions/adapters/presenters/tui/init.fnl","summary":"Current TUI presenter state summary without transcript or input contents","tags":["extensions","register-site","introspect","runtime"]}
{"description":"Registered model status-line item contribution.","href":"status.html#register-site-status-model-extensions-adapters-presenters-web-init-fnl-115","id":"register-site:status:model:extensions-adapters-presenters-web-init-fnl-115","kind":"register-site:status","line":115,"name":"model","path":"extensions/adapters/presenters/web/init.fnl","summary":"Registered model status-line item contribution.","tags":["extensions","register-site","status","model"]}
{"description":"Registered context status-line item contribution.","href":"status.html#register-site-status-context-extensions-adapters-presenters-web-init-fnl-124","id":"register-site:status:context:extensions-adapters-presenters-web-init-fnl-124","kind":"register-site:status","line":124,"name":"context","path":"extensions/adapters/presenters/web/init.fnl","summary":"Registered context status-line item contribution.","tags":["extensions","register-site","status","context"]}
{"description":"Registered steering-queue status-line item contribution.","href":"status.html#register-site-status-steering-queue-extensions-adapters-presenters-web-init-fnl-133","id":"register-site:status:steering-queue:extensions-adapters-presenters-web-init-fnl-133","kind":"register-site:status","line":133,"name":"steering-queue","path":"extensions/adapters/presenters/web/init.fnl","summary":"Registered steering-queue status-line item contribution.","tags":["extensions","register-site","status","steering-queue"]}
{"description":"Registered follow-up-queue status-line item contribution.","href":"status.html#register-site-status-follow-up-queue-extensions-adapters-presenters-web-init-fnl-143","id":"register-site:status:follow-up-queue:extensions-adapters-presenters-web-init-fnl-143","kind":"register-site:status","line":143,"name":"follow-up-queue","path":"extensions/adapters/presenters/web/init.fnl","summary":"Registered follow-up-queue status-line item contribution.","tags":["extensions","register-site","status","follow-up-queue"]}
{"description":"Registered attention status-line item contribution.","href":"status.html#register-site-status-attention-extensions-adapters-presenters-web-init-fnl-153","id":"register-site:status:attention:extensions-adapters-presenters-web-init-fnl-153","kind":"register-site:status","line":153,"name":"attention","path":"extensions/adapters/presenters/web/init.fnl","summary":"Registered attention status-line item contribution.","tags":["extensions","register-site","status","attention"]}
{"description":"Web presenter spinner row shown while the agent is busy.","href":"panels.html#register-site-panel-busy-extensions-adapters-presenters-web-init-fnl-162","id":"register-site:panel:busy:extensions-adapters-presenters-web-init-fnl-162","kind":"register-site:panel","line":162,"name":"busy","path":"extensions/adapters/presenters/web/init.fnl","summary":"Web presenter spinner row shown while the agent is busy.","tags":["extensions","register-site","panel","busy"]}
{"description":"Registered web presenter contribution.","href":"presenters.html#register-site-presenter-web-extensions-adapters-presenters-web-init-fnl-170","id":"register-site:presenter:web:extensions-adapters-presenters-web-init-fnl-170","kind":"register-site:presenter","line":170,"name":"web","path":"extensions/adapters/presenters/web/init.fnl","summary":"Registered web presenter contribution.","tags":["extensions","register-site","presenter","web"]}
{"description":"Current web presenter server/client state summary","href":"introspect.html#register-site-introspect-runtime-extensions-adapters-presenters-web-init-fnl-181","id":"register-site:introspect:runtime:extensions-adapters-presenters-web-init-fnl-181","kind":"register-site:introspect","line":181,"name":"runtime","path":"extensions/adapters/presenters/web/init.fnl","summary":"Current web presenter server/client state summary","tags":["extensions","register-site","introspect","runtime"]}
{"description":"Anthropic Messages provider using ANTHROPIC_API_KEY and the default claude-haiku-4-5 model.","href":"providers.html#register-site-provider-anthropic-extensions-adapters-providers-anthropic-init-fnl-20","id":"register-site:provider:anthropic:extensions-adapters-providers-anthropic-init-fnl-20","kind":"register-site:provider","line":20,"name":"anthropic","path":"extensions/adapters/providers/anthropic/init.fnl","summary":"Anthropic Messages provider using ANTHROPIC_API_KEY and the default claude-haiku-4-5 model.","tags":["extensions","register-site","provider","anthropic"]}
{"description":"OpenAI Chat Completions provider using OPENAI_API_KEY and the default gpt-5.4-nano model.","href":"providers.html#register-site-provider-openai-extensions-adapters-providers-openai-init-fnl-44","id":"register-site:provider:openai:extensions-adapters-providers-openai-init-fnl-44","kind":"register-site:provider","line":44,"name":"openai","path":"extensions/adapters/providers/openai/init.fnl","summary":"OpenAI Chat Completions provider using OPENAI_API_KEY and the default gpt-5.4-nano model.","tags":["extensions","register-site","provider","openai"]}
{"description":"OpenAI Responses API provider using OPENAI_API_KEY and the default gpt-5.4-nano model.","href":"providers.html#register-site-provider-openai-responses-extensions-adapters-providers-openai-init-fnl-50","id":"register-site:provider:openai-responses:extensions-adapters-providers-openai-init-fnl-50","kind":"register-site:provider","line":50,"name":"openai-responses","path":"extensions/adapters/providers/openai/init.fnl","summary":"OpenAI Responses API provider using OPENAI_API_KEY and the default gpt-5.4-nano model.","tags":["extensions","register-site","provider","openai-responses"]}
{"description":"ChatGPT subscription PKCE OAuth credentials stored in fen's auth.json.","href":"auth-backends.html#register-site-auth-backend-openai-codex-extensions-adapters-providers-openai-init-fnl-54","id":"register-site:auth-backend:openai-codex:extensions-adapters-providers-openai-init-fnl-54","kind":"register-site:auth-backend","line":54,"name":"openai-codex","path":"extensions/adapters/providers/openai/init.fnl","summary":"ChatGPT subscription PKCE OAuth credentials stored in fen's auth.json.","tags":["extensions","register-site","auth-backend","openai-codex"]}
{"description":"ChatGPT subscription/Codex Responses provider using the openai-codex OAuth auth backend and default gpt-5.5 model.","href":"providers.html#register-site-provider-openai-codex-extensions-adapters-providers-openai-init-fnl-66","id":"register-site:provider:openai-codex:extensions-adapters-providers-openai-init-fnl-66","kind":"register-site:provider","line":66,"name":"openai-codex","path":"extensions/adapters/providers/openai/init.fnl","summary":"ChatGPT subscription/Codex Responses provider using the openai-codex OAuth auth backend and default gpt-5.5 model.","tags":["extensions","register-site","provider","openai-codex"]}
{"description":"Append-only JSONL session backend under XDG state. Records canonical messages, replayable via --continue / /resume.","href":"session-backends.html#register-site-session-backend-jsonl-extensions-adapters-session-backends-jsonl-init-fnl-9","id":"register-site:session-backend:jsonl:extensions-adapters-session-backends-jsonl-init-fnl-9","kind":"register-site:session-backend","line":9,"name":"jsonl","path":"extensions/adapters/session-backends/jsonl/init.fnl","summary":"Append-only JSONL session backend under XDG state. Records canonical messages, replayable via --continue / /resume.","tags":["extensions","register-site","session-backend","jsonl"]}
{"description":"Reset the current conversation and start a fresh session","href":"commands.html#register-site-command-new-extensions-behaviors-actions-sessions-commands-session-fnl-159","id":"register-site:command:new:extensions-behaviors-actions-sessions-commands-session-fnl-159","kind":"register-site:command","line":159,"name":"new","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Reset the current conversation and start a fresh session","tags":["extensions","register-site","command","new"]}
{"description":"Hot-reload core modules and source overlays","href":"commands.html#register-site-command-reload-extensions-behaviors-actions-sessions-commands-session-fnl-265","id":"register-site:command:reload:extensions-behaviors-actions-sessions-commands-session-fnl-265","kind":"register-site:command","line":265,"name":"reload","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Hot-reload core modules and source overlays","tags":["extensions","register-site","command","reload"]}
{"description":"Alias for /new","href":"commands.html#register-site-command-n-extensions-behaviors-actions-sessions-commands-session-fnl-319","id":"register-site:command:n:extensions-behaviors-actions-sessions-commands-session-fnl-319","kind":"register-site:command","line":319,"name":"n","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Alias for /new","tags":["extensions","register-site","command","n"]}
{"description":"Pick a recent session to resume (overlay)","href":"commands.html#register-site-command-sessions-extensions-behaviors-actions-sessions-commands-session-fnl-326","id":"register-site:command:sessions:extensions-behaviors-actions-sessions-commands-session-fnl-326","kind":"register-site:command","line":326,"name":"sessions","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Pick a recent session to resume (overlay)","tags":["extensions","register-site","command","sessions"]}
{"description":"Resume a session (overlay if no arg; id/prefix/path/index if given)","href":"commands.html#register-site-command-resume-extensions-behaviors-actions-sessions-commands-session-fnl-332","id":"register-site:command:resume:extensions-behaviors-actions-sessions-commands-session-fnl-332","kind":"register-site:command","line":332,"name":"resume","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Resume a session (overlay if no arg; id/prefix/path/index if given)","tags":["extensions","register-site","command","resume"]}
{"description":"Alias for /reload","href":"commands.html#register-site-command-r-extensions-behaviors-actions-sessions-commands-session-fnl-343","id":"register-site:command:r:extensions-behaviors-actions-sessions-commands-session-fnl-343","kind":"register-site:command","line":343,"name":"r","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Alias for /reload","tags":["extensions","register-site","command","r"]}
{"description":"Current session selection and persistence backend summary","href":"introspect.html#register-site-introspect-active-session-extensions-behaviors-actions-sessions-commands-session-fnl-351","id":"register-site:introspect:active-session:extensions-behaviors-actions-sessions-commands-session-fnl-351","kind":"register-site:introspect","line":351,"name":"active-session","path":"extensions/behaviors/actions/sessions/commands/session.fnl","summary":"Current session selection and persistence backend summary","tags":["extensions","register-site","introspect","active-session"]}
{"description":"Read structured state of the running agent. Read-only; does not evaluate code. Query is a tiny Fennel-shaped data language. Examples: (:get :model), (:get :thinking), (:count (:get :messages)), (:get :messages -1), (:pluck (:get :tools) :name), (:get :extensions :panels), (:where (:get :messages) :role :assistant), (:last (:where (:get :messages) :role :assistant)), (:slice (:get :messages) -5 5), (:keys (:get)). Prefer narrow queries over dumping large roots. Output defaults to JSON; use format=fennel for Fennel rendering when available.","href":"tools.html#register-site-tool-agent-state-extensions-behaviors-companions-agent-state-init-fnl-13","id":"register-site:tool:agent_state:extensions-behaviors-companions-agent-state-init-fnl-13","kind":"register-site:tool","line":13,"name":"agent_state","path":"extensions/behaviors/companions/agent-state/init.fnl","summary":"Read structured state of the running agent. Read-only; does not evaluate code. Query is a tiny Fennel-shaped data language. Examples: (:get :model), (:get :thinking), (:count (:get :messages)), (:get :messages -1), (:pluck (:get :tools) :name), (:get :extensions :panels), (:where (:get :messages) :role :assistant), (:last (:where (:get :messages) :role :assistant)), (:slice (:get :messages) -5 5), (:keys (:get)). Prefer narrow queries over dumping large roots. Output defaults to JSON; use format=fennel for Fennel rendering when available.","tags":["extensions","register-site","tool","agent-state"]}
{"description":"agent_state query language capabilities","href":"introspect.html#register-site-introspect-tool-extensions-behaviors-companions-agent-state-init-fnl-29","id":"register-site:introspect:tool:extensions-behaviors-companions-agent-state-init-fnl-29","kind":"register-site:introspect","line":29,"name":"tool","path":"extensions/behaviors/companions/agent-state/init.fnl","summary":"agent_state query language capabilities","tags":["extensions","register-site","introspect","tool"]}
{"description":"Summarize older context and keep recent messages in this session","href":"commands.html#register-site-command-compact-extensions-behaviors-companions-compact-init-fnl-233","id":"register-site:command:compact:extensions-behaviors-companions-compact-init-fnl-233","kind":"register-site:command","line":233,"name":"compact","path":"extensions/behaviors/companions/compact/init.fnl","summary":"Summarize older context and keep recent messages in this session","tags":["extensions","register-site","command","compact"]}
{"description":"Summarize this session, seed a fresh session with the summary","href":"commands.html#register-site-command-handoff-extensions-behaviors-companions-handoff-init-fnl-141","id":"register-site:command:handoff:extensions-behaviors-companions-handoff-init-fnl-141","kind":"register-site:command","line":141,"name":"handoff","path":"extensions/behaviors/companions/handoff/init.fnl","summary":"Summarize this session, seed a fresh session with the summary","tags":["extensions","register-site","command","handoff"]}
{"description":"Toggle the memory diagnostics panel; /mem gc forces a GC pass","href":"commands.html#register-site-command-mem-extensions-behaviors-companions-mem-init-fnl-246","id":"register-site:command:mem:extensions-behaviors-companions-mem-init-fnl-246","kind":"register-site:command","line":246,"name":"mem","path":"extensions/behaviors/companions/mem/init.fnl","summary":"Toggle the memory diagnostics panel; /mem gc forces a GC pass","tags":["extensions","register-site","command","mem"]}
{"description":"Memory diagnostics panel backing the /mem command and heap history display.","href":"panels.html#register-site-panel-mem-extensions-behaviors-companions-mem-init-fnl-260","id":"register-site:panel:mem:extensions-behaviors-companions-mem-init-fnl-260","kind":"register-site:panel","line":260,"name":"mem","path":"extensions/behaviors/companions/mem/init.fnl","summary":"Memory diagnostics panel backing the /mem command and heap history display.","tags":["extensions","register-site","panel","mem"]}
{"description":"Current memory diagnostics panel, heap, and sample history summary","href":"introspect.html#register-site-introspect-diagnostics-extensions-behaviors-companions-mem-init-fnl-262","id":"register-site:introspect:diagnostics:extensions-behaviors-companions-mem-init-fnl-262","kind":"register-site:introspect","line":262,"name":"diagnostics","path":"extensions/behaviors/companions/mem/init.fnl","summary":"Current memory diagnostics panel, heap, and sample history summary","tags":["extensions","register-site","introspect","diagnostics"]}
{"description":"Pick a skill, show details, or list discovered Agent Skills","href":"commands.html#register-site-command-skills-extensions-behaviors-companions-skills-init-fnl-711","id":"register-site:command:skills:extensions-behaviors-companions-skills-init-fnl-711","kind":"register-site:command","line":711,"name":"skills","path":"extensions/behaviors/companions/skills/init.fnl","summary":"Pick a skill, show details, or list discovered Agent Skills","tags":["extensions","register-site","command","skills"]}
{"description":"Skill picker/detail panel backing the /skills command.","href":"panels.html#register-site-panel-skills-extensions-behaviors-companions-skills-init-fnl-733","id":"register-site:panel:skills:extensions-behaviors-companions-skills-init-fnl-733","kind":"register-site:panel","line":733,"name":"skills","path":"extensions/behaviors/companions/skills/init.fnl","summary":"Skill picker/detail panel backing the /skills command.","tags":["extensions","register-site","panel","skills"]}
{"description":"Discovered Agent Skills, source scopes, paths, and model visibility","href":"introspect.html#register-site-introspect-discovered-skills-extensions-behaviors-companions-skills-init-fnl-734","id":"register-site:introspect:discovered-skills:extensions-behaviors-companions-skills-init-fnl-734","kind":"register-site:introspect","line":734,"name":"discovered-skills","path":"extensions/behaviors/companions/skills/init.fnl","summary":"Discovered Agent Skills, source scopes, paths, and model visibility","tags":["extensions","register-site","introspect","discovered-skills"]}
{"description":"Create or update the structured todo list for this session. Use for non-trivial multi-step work. This tool overwrites the full current list; provide every item that should remain. Status must be pending, in_progress, or completed, with at most one in_progress item. Use an empty items array to clear the list.","href":"tools.html#register-site-tool-todo-write-extensions-behaviors-companions-todo-init-fnl-289","id":"register-site:tool:todo_write:extensions-behaviors-companions-todo-init-fnl-289","kind":"register-site:tool","line":289,"name":"todo_write","path":"extensions/behaviors/companions/todo/init.fnl","summary":"Create or update the structured todo list for this session. Use for non-trivial multi-step work. This tool overwrites the full current list; provide every item that should remain. Status must be pending, in_progress, or completed, with at most one in_progress item. Use an empty items array to clear the list.","tags":["extensions","register-site","tool","todo-write"]}
{"description":"Toggle the todo panel; /todos show prints the current list","href":"commands.html#register-site-command-todos-extensions-behaviors-companions-todo-init-fnl-305","id":"register-site:command:todos:extensions-behaviors-companions-todo-init-fnl-305","kind":"register-site:command","line":305,"name":"todos","path":"extensions/behaviors/companions/todo/init.fnl","summary":"Toggle the todo panel; /todos show prints the current list","tags":["extensions","register-site","command","todos"]}
{"description":"Registered (dynamic) panel contribution.","href":"panels.html#register-site-panel-dynamic-extensions-behaviors-companions-todo-init-fnl-311","id":"register-site:panel:(dynamic):extensions-behaviors-companions-todo-init-fnl-311","kind":"register-site:panel","line":311,"name":"(dynamic)","path":"extensions/behaviors/companions/todo/init.fnl","summary":"Registered (dynamic) panel contribution.","tags":["extensions","register-site","panel","dynamic"]}
{"description":"Registered todo status-line item contribution.","href":"status.html#register-site-status-todo-extensions-behaviors-companions-todo-init-fnl-312","id":"register-site:status:todo:extensions-behaviors-companions-todo-init-fnl-312","kind":"register-site:status","line":312,"name":"todo","path":"extensions/behaviors/companions/todo/init.fnl","summary":"Registered todo status-line item contribution.","tags":["extensions","register-site","status","todo"]}
{"description":"Current todo list counts and panel state","href":"introspect.html#register-site-introspect-state-extensions-behaviors-companions-todo-init-fnl-317","id":"register-site:introspect:state:extensions-behaviors-companions-todo-init-fnl-317","kind":"register-site:introspect","line":317,"name":"state","path":"extensions/behaviors/companions/todo/init.fnl","summary":"Current todo list counts and panel state","tags":["extensions","register-site","introspect","state"]}
{"description":"Reload one external extension by name","href":"commands.html#register-site-command-reload-extension-extensions-behaviors-inspectors-extensions-commands-extension-fnl-464","id":"register-site:command:reload-extension:extensions-behaviors-inspectors-extensions-commands-extension-fnl-464","kind":"register-site:command","line":464,"name":"reload-extension","path":"extensions/behaviors/inspectors/extensions/commands/extension.fnl","summary":"Reload one external extension by name","tags":["extensions","register-site","command","reload-extension"]}
{"description":"Pick an extension, show details, or inspect live registry","href":"commands.html#register-site-command-extensions-extensions-behaviors-inspectors-extensions-commands-extension-fnl-494","id":"register-site:command:extensions:extensions-behaviors-inspectors-extensions-commands-extension-fnl-494","kind":"register-site:command","line":494,"name":"extensions","path":"extensions/behaviors/inspectors/extensions/commands/extension.fnl","summary":"Pick an extension, show details, or inspect live registry","tags":["extensions","register-site","command"]}
{"description":"Extension detail and picker panel backing the /extensions command.","href":"panels.html#register-site-panel-extensions-extensions-behaviors-inspectors-extensions-commands-extension-fnl-510","id":"register-site:panel:extensions:extensions-behaviors-inspectors-extensions-commands-extension-fnl-510","kind":"register-site:panel","line":510,"name":"extensions","path":"extensions/behaviors/inspectors/extensions/commands/extension.fnl","summary":"Extension detail and picker panel backing the /extensions command.","tags":["extensions","register-site","panel"]}
{"description":"Current /extensions panel state and cache metadata","href":"introspect.html#register-site-introspect-panel-extensions-behaviors-inspectors-extensions-commands-extension-fnl-512","id":"register-site:introspect:panel:extensions-behaviors-inspectors-extensions-commands-extension-fnl-512","kind":"register-site:introspect","line":512,"name":"panel","path":"extensions/behaviors/inspectors/extensions/commands/extension.fnl","summary":"Current /extensions panel state and cache metadata","tags":["extensions","register-site","introspect","panel"]}
{"description":"Toggle the prompt-fragments panel; /prompt rendered emits the rendered prompt","href":"commands.html#register-site-command-prompt-extensions-behaviors-inspectors-prompt-commands-prompt-fnl-105","id":"register-site:command:prompt:extensions-behaviors-inspectors-prompt-commands-prompt-fnl-105","kind":"register-site:command","line":105,"name":"prompt","path":"extensions/behaviors/inspectors/prompt/commands/prompt.fnl","summary":"Toggle the prompt-fragments panel; /prompt rendered emits the rendered prompt","tags":["extensions","register-site","command","prompt"]}
{"description":"Prompt-fragment inspection panel backing the /prompt command.","href":"panels.html#register-site-panel-prompt-extensions-behaviors-inspectors-prompt-commands-prompt-fnl-118","id":"register-site:panel:prompt:extensions-behaviors-inspectors-prompt-commands-prompt-fnl-118","kind":"register-site:panel","line":118,"name":"prompt","path":"extensions/behaviors/inspectors/prompt/commands/prompt.fnl","summary":"Prompt-fragment inspection panel backing the /prompt command.","tags":["extensions","register-site","panel","prompt"]}
{"description":"Current prompt-fragment panel state and fragment counts","href":"introspect.html#register-site-introspect-panel-extensions-behaviors-inspectors-prompt-commands-prompt-fnl-120","id":"register-site:introspect:panel:extensions-behaviors-inspectors-prompt-commands-prompt-fnl-120","kind":"register-site:introspect","line":120,"name":"panel","path":"extensions/behaviors/inspectors/prompt/commands/prompt.fnl","summary":"Current prompt-fragment panel state and fragment counts","tags":["extensions","register-site","introspect","panel"]}
{"description":"Toggle the queue panel; /queue clear|mode preserve their actions","href":"commands.html#register-site-command-queue-extensions-behaviors-inspectors-queue-commands-queue-fnl-148","id":"register-site:command:queue:extensions-behaviors-inspectors-queue-commands-queue-fnl-148","kind":"register-site:command","line":148,"name":"queue","path":"extensions/behaviors/inspectors/queue/commands/queue.fnl","summary":"Toggle the queue panel; /queue clear|mode preserve their actions","tags":["extensions","register-site","command","queue"]}
{"description":"Cancel current turn and clear queues","href":"commands.html#register-site-command-cancel-all-extensions-behaviors-inspectors-queue-commands-queue-fnl-163","id":"register-site:command:cancel-all:extensions-behaviors-inspectors-queue-commands-queue-fnl-163","kind":"register-site:command","line":163,"name":"cancel-all","path":"extensions/behaviors/inspectors/queue/commands/queue.fnl","summary":"Cancel current turn and clear queues","tags":["extensions","register-site","command","cancel-all"]}
{"description":"Queued follow-up/cancel-all panel backing queue-management commands.","href":"panels.html#register-site-panel-queue-extensions-behaviors-inspectors-queue-commands-queue-fnl-180","id":"register-site:panel:queue:extensions-behaviors-inspectors-queue-commands-queue-fnl-180","kind":"register-site:panel","line":180,"name":"queue","path":"extensions/behaviors/inspectors/queue/commands/queue.fnl","summary":"Queued follow-up/cancel-all panel backing queue-management commands.","tags":["extensions","register-site","panel","queue"]}
{"description":"Current queue panel and pending steering/follow-up counts","href":"introspect.html#register-site-introspect-panel-extensions-behaviors-inspectors-queue-commands-queue-fnl-182","id":"register-site:introspect:panel:extensions-behaviors-inspectors-queue-commands-queue-fnl-182","kind":"register-site:introspect","line":182,"name":"panel","path":"extensions/behaviors/inspectors/queue/commands/queue.fnl","summary":"Current queue panel and pending steering/follow-up counts","tags":["extensions","register-site","introspect","panel"]}
{"description":"Toggle the status panel (model, provider, tokens, session)","href":"commands.html#register-site-command-status-extensions-behaviors-inspectors-status-commands-status-fnl-157","id":"register-site:command:status:extensions-behaviors-inspectors-status-commands-status-fnl-157","kind":"register-site:command","line":157,"name":"status","path":"extensions/behaviors/inspectors/status/commands/status.fnl","summary":"Toggle the status panel (model, provider, tokens, session)","tags":["extensions","register-site","command","status"]}
{"description":"Runtime status details panel backing the /status command.","href":"panels.html#register-site-panel-status-extensions-behaviors-inspectors-status-commands-status-fnl-167","id":"register-site:panel:status:extensions-behaviors-inspectors-status-commands-status-fnl-167","kind":"register-site:panel","line":167,"name":"status","path":"extensions/behaviors/inspectors/status/commands/status.fnl","summary":"Runtime status details panel backing the /status command.","tags":["extensions","register-site","panel","status"]}
{"description":"Current status panel cache and last captured run-state summary","href":"introspect.html#register-site-introspect-panel-extensions-behaviors-inspectors-status-commands-status-fnl-169","id":"register-site:introspect:panel:extensions-behaviors-inspectors-status-commands-status-fnl-169","kind":"register-site:introspect","line":169,"name":"panel","path":"extensions/behaviors/inspectors/status/commands/status.fnl","summary":"Current status panel cache and last captured run-state summary","tags":["extensions","register-site","introspect","panel"]}
{"description":"Dynamic loop registering every built-in tool spec from the builtin tools registry.","href":"tools.html#register-site-tool-builtin-tool-registry-extensions-behaviors-kernel-builtin-tools-init-fnl-17","id":"register-site:tool:builtin-tool-registry:extensions-behaviors-kernel-builtin-tools-init-fnl-17","kind":"register-site:tool","line":17,"name":"builtin-tool-registry","path":"extensions/behaviors/kernel/builtin-tools/init.fnl","summary":"Dynamic loop registering every built-in tool spec from the builtin tools registry.","tags":["extensions","register-site","tool","builtin-tool-registry"]}
{"description":"Browse runtime docs: /docs [topic] [name]","href":"commands.html#register-site-command-docs-extensions-behaviors-kernel-docs-init-fnl-484","id":"register-site:command:docs:extensions-behaviors-kernel-docs-init-fnl-484","kind":"register-site:command","line":484,"name":"docs","path":"extensions/behaviors/kernel/docs/init.fnl","summary":"Browse runtime docs: /docs [topic] [name]","tags":["extensions","register-site","command","docs"]}
{"description":"Read or search fen runtime docs and extension contracts. Useful for implementing extensions: inspect register kinds, canonical types, event shapes, and live commands/tools/providers. Topics: topics, commands, tools, providers, auth-backends, session-backends, presenters, controls, status, panels, prompt-fragments, introspectors, events, types, register-kinds, interfaces, extensions. Use name for a specific entry, e.g. {topic:'register-kinds', name:'tool'} or {topic:'types', name:'ToolResultMessage'}. Use query to search docs, optionally scoped by topic.","href":"tools.html#register-site-tool-fen-docs-extensions-behaviors-kernel-docs-init-fnl-506","id":"register-site:tool:fen_docs:extensions-behaviors-kernel-docs-init-fnl-506","kind":"register-site:tool","line":506,"name":"fen_docs","path":"extensions/behaviors/kernel/docs/init.fnl","summary":"Read or search fen runtime docs and extension contracts. Useful for implementing extensions: inspect register kinds, canonical types, event shapes, and live commands/tools/providers. Topics: topics, commands, tools, providers, auth-backends, session-backends, presenters, controls, status, panels, prompt-fragments, introspectors, events, types, register-kinds, interfaces, extensions. Use name for a specific entry, e.g. {topic:'register-kinds', name:'tool'} or {topic:'types', name:'ToolResultMessage'}. Use query to search docs, optionally scoped by topic.","tags":["extensions","register-site","tool","fen-docs"]}
{"description":"Runtime documentation browser panel backing the /docs command and fen_docs tool.","href":"panels.html#register-site-panel-docs-extensions-behaviors-kernel-docs-init-fnl-526","id":"register-site:panel:docs:extensions-behaviors-kernel-docs-init-fnl-526","kind":"register-site:panel","line":526,"name":"docs","path":"extensions/behaviors/kernel/docs/init.fnl","summary":"Runtime documentation browser panel backing the /docs command and fen_docs tool.","tags":["extensions","register-site","panel","docs"]}
{"description":"Current docs browser panel state and topic counts","href":"introspect.html#register-site-introspect-panel-extensions-behaviors-kernel-docs-init-fnl-528","id":"register-site:introspect:panel:extensions-behaviors-kernel-docs-init-fnl-528","kind":"register-site:introspect","line":528,"name":"panel","path":"extensions/behaviors/kernel/docs/init.fnl","summary":"Current docs browser panel state and topic counts","tags":["extensions","register-site","introspect","panel"]}
{"description":"Show available commands and controls","href":"commands.html#register-site-command-help-extensions-behaviors-kernel-essentials-commands-help-fnl-94","id":"register-site:command:help:extensions-behaviors-kernel-essentials-commands-help-fnl-94","kind":"register-site:command","line":94,"name":"help","path":"extensions/behaviors/kernel/essentials/commands/help.fnl","summary":"Show available commands and controls","tags":["extensions","register-site","command","help"]}
{"description":"Switch model (overlay if no arg; index/name/substring if given)","href":"commands.html#register-site-command-model-extensions-behaviors-kernel-essentials-commands-model-fnl-121","id":"register-site:command:model:extensions-behaviors-kernel-essentials-commands-model-fnl-121","kind":"register-site:command","line":121,"name":"model","path":"extensions/behaviors/kernel/essentials/commands/model.fnl","summary":"Switch model (overlay if no arg; index/name/substring if given)","tags":["extensions","register-site","command","model"]}
{"description":"Show/set thinking effort; /thinking blocks on|off toggles display","href":"commands.html#register-site-command-thinking-extensions-behaviors-kernel-essentials-commands-thinking-fnl-115","id":"register-site:command:thinking:extensions-behaviors-kernel-essentials-commands-thinking-fnl-115","kind":"register-site:command","line":115,"name":"thinking","path":"extensions/behaviors/kernel/essentials/commands/thinking.fnl","summary":"Show/set thinking effort; /thinking blocks on|off toggles display","tags":["extensions","register-site","command","thinking"]}
{"description":"One-shot stdout presenter for --print","href":"extensions.html#register-site-extension-print-extensions-adapters-presenters-print-manifest-fnl-1","id":"extension:print","kind":"extension","line":1,"name":"print","path":"extensions/adapters/presenters/print/manifest.fnl","summary":"One-shot stdout presenter for --print","tags":["extensions","extension","print"]}
{"description":"Line-mode stdin/stdout presenter","href":"extensions.html#register-site-extension-stdio-extensions-adapters-presenters-stdio-manifest-fnl-1","id":"extension:stdio","kind":"extension","line":1,"name":"stdio","path":"extensions/adapters/presenters/stdio/manifest.fnl","summary":"Line-mode stdin/stdout presenter","tags":["extensions","extension","stdio"]}
{"description":"First-party termbox2 presenter","href":"extensions.html#register-site-extension-tui-extensions-adapters-presenters-tui-manifest-fnl-1","id":"extension:tui","kind":"extension","line":1,"name":"tui","path":"extensions/adapters/presenters/tui/manifest.fnl","summary":"First-party termbox2 presenter","tags":["extensions","extension","tui"]}
{"description":"First-party LuaSocket/SSE browser presenter","href":"extensions.html#register-site-extension-web-extensions-adapters-presenters-web-manifest-fnl-1","id":"extension:web","kind":"extension","line":1,"name":"web","path":"extensions/adapters/presenters/web/manifest.fnl","summary":"First-party LuaSocket/SSE browser presenter","tags":["extensions","extension","web"]}
{"description":"First-party Anthropic Messages provider.","href":"extensions.html#register-site-extension-provider-anthropic-extensions-adapters-providers-anthropic-manifest-fnl-1","id":"extension:provider_anthropic","kind":"extension","line":1,"name":"provider_anthropic","path":"extensions/adapters/providers/anthropic/manifest.fnl","summary":"First-party Anthropic Messages provider.","tags":["extensions","extension","provider-anthropic"]}
{"description":"First-party OpenAI provider family (Chat Completions, Responses, Codex subscription, and Codex OAuth auth).","href":"extensions.html#register-site-extension-provider-openai-extensions-adapters-providers-openai-manifest-fnl-1","id":"extension:provider_openai","kind":"extension","line":1,"name":"provider_openai","path":"extensions/adapters/providers/openai/manifest.fnl","summary":"First-party OpenAI provider family (Chat Completions, Responses, Codex subscription, and Codex OAuth auth).","tags":["extensions","extension","provider-openai"]}
{"description":"JSONL session backend","href":"extensions.html#register-site-extension-session-jsonl-extensions-adapters-session-backends-jsonl-manifest-fnl-1","id":"extension:session_jsonl","kind":"extension","line":1,"name":"session_jsonl","path":"extensions/adapters/session-backends/jsonl/manifest.fnl","summary":"JSONL session backend","tags":["extensions","extension","session-jsonl"]}
{"description":"Conversation and session lifecycle commands: new, reload, sessions, resume, and aliases.","href":"extensions.html#register-site-extension-sessions-extensions-behaviors-actions-sessions-manifest-fnl-1","id":"extension:sessions","kind":"extension","line":1,"name":"sessions","path":"extensions/behaviors/actions/sessions/manifest.fnl","summary":"Conversation and session lifecycle commands: new, reload, sessions, resume, and aliases.","tags":["extensions","extension","sessions"]}
{"description":"Read-only introspection tool for the running agent","href":"extensions.html#register-site-extension-agent-state-extensions-behaviors-companions-agent-state-manifest-fnl-1","id":"extension:agent_state","kind":"extension","line":1,"name":"agent_state","path":"extensions/behaviors/companions/agent-state/manifest.fnl","summary":"Read-only introspection tool for the running agent","tags":["extensions","extension","agent-state"]}
{"description":"Context compaction command: summarize older messages and keep recent context.","href":"extensions.html#register-site-extension-compact-extensions-behaviors-companions-compact-manifest-fnl-1","id":"extension:compact","kind":"extension","line":1,"name":"compact","path":"extensions/behaviors/companions/compact/manifest.fnl","summary":"Context compaction command: summarize older messages and keep recent context.","tags":["extensions","extension","compact"]}
{"description":"Session handoff command: summarize current context and seed a fresh session.","href":"extensions.html#register-site-extension-handoff-extensions-behaviors-companions-handoff-manifest-fnl-1","id":"extension:handoff","kind":"extension","line":1,"name":"handoff","path":"extensions/behaviors/companions/handoff/manifest.fnl","summary":"Session handoff command: summarize current context and seed a fresh session.","tags":["extensions","extension","handoff"]}
{"description":"Runtime memory diagnostics command","href":"extensions.html#register-site-extension-mem-extensions-behaviors-companions-mem-manifest-fnl-1","id":"extension:mem","kind":"extension","line":1,"name":"mem","path":"extensions/behaviors/companions/mem/manifest.fnl","summary":"Runtime memory diagnostics command","tags":["extensions","extension","mem"]}
{"description":"Agent Skills discovery and prompt fragment","href":"extensions.html#register-site-extension-skills-extensions-behaviors-companions-skills-manifest-fnl-1","id":"extension:skills","kind":"extension","line":1,"name":"skills","path":"extensions/behaviors/companions/skills/manifest.fnl","summary":"Agent Skills discovery and prompt fragment","tags":["extensions","extension","skills"]}
{"description":"Structured todo list companion tool, panel, and status item","href":"extensions.html#register-site-extension-todo-extensions-behaviors-companions-todo-manifest-fnl-1","id":"extension:todo","kind":"extension","line":1,"name":"todo","path":"extensions/behaviors/companions/todo/manifest.fnl","summary":"Structured todo list companion tool, panel, and status item","tags":["extensions","extension","todo"]}
{"description":"Extension inspector: /extensions, /reload-extension, and extension detail panel.","href":"extensions.html#register-site-extension-extensions-inspector-extensions-behaviors-inspectors-extensions-manifest-fnl-1","id":"extension:extensions_inspector","kind":"extension","line":1,"name":"extensions_inspector","path":"extensions/behaviors/inspectors/extensions/manifest.fnl","summary":"Extension inspector: /extensions, /reload-extension, and extension detail panel.","tags":["extensions","extension","extensions-inspector"]}
{"description":"Prompt inspector: /prompt command and prompt-fragment panel.","href":"extensions.html#register-site-extension-prompt-extensions-behaviors-inspectors-prompt-manifest-fnl-1","id":"extension:prompt","kind":"extension","line":1,"name":"prompt","path":"extensions/behaviors/inspectors/prompt/manifest.fnl","summary":"Prompt inspector: /prompt command and prompt-fragment panel.","tags":["extensions","extension","prompt"]}
{"description":"Queue inspector: /queue, /cancel-all, and queue panel.","href":"extensions.html#register-site-extension-queue-extensions-behaviors-inspectors-queue-manifest-fnl-1","id":"extension:queue","kind":"extension","line":1,"name":"queue","path":"extensions/behaviors/inspectors/queue/manifest.fnl","summary":"Queue inspector: /queue, /cancel-all, and queue panel.","tags":["extensions","extension","queue"]}
{"description":"Runtime status inspector: /status command and status panel.","href":"extensions.html#register-site-extension-status-extensions-behaviors-inspectors-status-manifest-fnl-1","id":"extension:status","kind":"extension","line":1,"name":"status","path":"extensions/behaviors/inspectors/status/manifest.fnl","summary":"Runtime status inspector: /status command and status panel.","tags":["extensions","extension","status"]}
{"description":"Built-in fen tools: bash, read, write, ls, edit, grep, find.","href":"extensions.html#register-site-extension-builtin-tools-extensions-behaviors-kernel-builtin-tools-manifest-fnl-1","id":"extension:builtin_tools","kind":"extension","line":1,"name":"builtin_tools","path":"extensions/behaviors/kernel/builtin-tools/manifest.fnl","summary":"Built-in fen tools: bash, read, write, ls, edit, grep, find.","tags":["extensions","extension","builtin-tools"]}
{"description":"First-party default system prompt policy","href":"extensions.html#register-site-extension-default-prompt-extensions-behaviors-kernel-default-prompt-manifest-fnl-1","id":"extension:default_prompt","kind":"extension","line":1,"name":"default_prompt","path":"extensions/behaviors/kernel/default-prompt/manifest.fnl","summary":"First-party default system prompt policy","tags":["extensions","extension","default-prompt"]}
{"description":"In-agent runtime documentation browser","href":"extensions.html#register-site-extension-docs-extensions-behaviors-kernel-docs-manifest-fnl-1","id":"extension:docs","kind":"extension","line":1,"name":"docs","path":"extensions/behaviors/kernel/docs/manifest.fnl","summary":"In-agent runtime documentation browser","tags":["extensions","extension","docs"]}
{"description":"Essential fen slash commands: help and model selection.","href":"extensions.html#register-site-extension-essentials-extensions-behaviors-kernel-essentials-manifest-fnl-1","id":"extension:essentials","kind":"extension","line":1,"name":"essentials","path":"extensions/behaviors/kernel/essentials/manifest.fnl","summary":"Essential fen slash commands: help and model selection.","tags":["extensions","extension","essentials"]}
{"href":"api.html","id":"generated:core","kind":"generated-page","line":1,"name":"Source API","path":"docs/generated/core.md","summary":"Generated reference for exported Fennel modules, functions, and documented data values, grouped by namespace.","tags":["generated","core","api"]}
{"href":"contracts.html","id":"generated:contracts","kind":"generated-page","line":1,"name":"Contracts","path":"docs/generated/contracts.md","summary":"Generated reference for register kinds, events, canonical types, interfaces, fields, and members.","tags":["generated","contracts","api"]}
{"href":"contributions.html","id":"generated:extensions","kind":"generated-page","line":1,"name":"Extension contributions","path":"docs/generated/extensions.md","summary":"Generated reference for first-party extension manifests and registered commands, tools, providers, panels, status items, and presenters.","tags":["generated","extensions","contributions"]}
{"href":"doc-readme.html","id":"doc:README","kind":"doc-page","line":1,"name":"README","path":"docs/README.md","summary":"`fen` is a small Fennel→Lua coding-agent CLI. It is built as a reloadable microkernel: a tiny core (agent loop, canonical types, provider dispatch, extension registry) with providers, the UI, session storage, and even the built-in tools all shipped as first-party extensions. It mirrors pi-mono's interface shapes in simplified form and targets Lua 5.4 on ARMv7/Raspberry-Pi-class hardware.","tags":["docs","readme"]}
{"href":"doc-architecture.html","id":"doc:architecture","kind":"doc-page","line":1,"name":"architecture","path":"docs/architecture.md","summary":"The stable contracts, module layout, and design principles behind fen's core. For the day-to-day workflow and the full hot-reload model see [`development.md`](development.md); the auto-generated API and contract reference is indexed by the [generated sitemap](sitemap.html).","tags":["docs","architecture"]}
{"href":"doc-development.html","id":"doc:development","kind":"doc-page","line":1,"name":"development","path":"docs/development.md","summary":"This page is the maintainer reference for day-to-day fen development, hot reload, local checks, and disposable build artifacts.","tags":["docs","development"]}
{"href":"doc-distribution.html","id":"doc:distribution","kind":"doc-page","line":1,"name":"distribution","path":"docs/distribution.md","summary":"Nix is the canonical, reproducible build and the source of every release artifact. The public runtime artifact is the production single-file binary from `nix build .#fen`; source-checkout development uses that same binary through `scripts/dev/fen-dev` overlays (see [`development.md`](development.md)).","tags":["docs","distribution"]}
{"href":"doc-extensions.html","id":"doc:extensions","kind":"doc-page","line":1,"name":"extensions","path":"docs/extensions.md","summary":"fen has a small Lua/Fennel extension system for adding behavior around the core agent loop without patching `packages/core/` directly. Extensions can add slash commands, tools, hooks, system-prompt fragments, event subscribers, and presenters.","tags":["docs","extensions"]}
{"href":"doc-providers.html","id":"doc:providers","kind":"doc-page","line":1,"name":"providers","path":"docs/providers.md","summary":"Provider-facing contracts, wire-shape differences, and custom model configuration.","tags":["docs","providers"]}
{"href":"doc-scripts.html","id":"doc:scripts","kind":"doc-page","line":1,"name":"scripts","path":"docs/scripts.md","summary":"`fen run` runs Lua and Fennel scripts with fen's embedded Lua 5.4 runtime. `fen eval` evaluates inline Lua or Fennel code with the same runtime. They are meant for small portable scripts on systems where `lua`, `fennel`, or system LuaRocks are not installed. They are separate from the coding-agent flow and do not initialize providers, sessions, or the TUI.","tags":["docs","scripts"]}
{"href":"doc-sessions.html","id":"doc:sessions","kind":"doc-page","line":1,"name":"sessions","path":"docs/sessions.md","summary":"Session persistence format and CLI behavior.","tags":["docs","sessions"]}
{"href":"doc-skills.html","id":"doc:skills","kind":"doc-page","line":1,"name":"skills","path":"docs/skills.md","summary":"Agent Skills discovery and prompt behavior.","tags":["docs","skills"]}
{"href":"doc-tools.html","id":"doc:tools","kind":"doc-page","line":1,"name":"tools","path":"docs/tools.md","summary":"Contracts and implementation notes for the first-party tool surface.","tags":["docs","tools"]}
{"href":"doc-readme.html#doc-heading-fen-documentation","id":"doc:README#doc-heading-fen-documentation","kind":"doc-heading","line":1,"name":"fen documentation","path":"docs/README.md","summary":"README / fen documentation — `fen` is a small Fennel→Lua coding-agent CLI. It is built as a reloadable microkernel: a tiny core (agent loop, canonical types, provider dispatch, extension registry) with providers, the UI, session storage, and even the built-in tools all shipped as first-party extensions. It mirrors pi-mono's interface shapes in simplified form and targets Lua 5.4 on ARMv7/Raspberry-Pi-class hardware.","tags":["docs","readme","fen","documentation"]}
{"href":"doc-readme.html#doc-heading-guides","id":"doc:README#doc-heading-guides","kind":"doc-heading","line":15,"name":"Guides","path":"docs/README.md","summary":"README / Guides — [Development workflow](development.md) — dev workflow, hot reload, checks, Nix result symlinks.","tags":["docs","readme","guides"]}
{"href":"doc-readme.html#doc-heading-generated-reference","id":"doc:README#doc-heading-generated-reference","kind":"doc-heading","line":27,"name":"Generated reference","path":"docs/README.md","summary":"README / Generated reference — The generated site includes [contracts](contracts.html), [API](api.html), [registries](registries.html), and [graphs](graphs.html) pages scanned directly from source. Use the [sitemap](sitemap.html) for a dense index of every page and the machine-readable artifacts. It is part of the published documentation site rather than the repository.","tags":["docs","readme","generated","reference"]}
{"href":"doc-architecture.html#doc-heading-architecture-notes","id":"doc:architecture#doc-heading-architecture-notes","kind":"doc-heading","line":1,"name":"Architecture notes","path":"docs/architecture.md","summary":"architecture / Architecture notes — The stable contracts, module layout, and design principles behind fen's core. For the day-to-day workflow and the full hot-reload model see [`development.md`](development.md); the auto-generated API and contract reference is indexed by the [generated sitemap](sitemap.html).","tags":["docs","architecture","notes"]}
{"href":"doc-architecture.html#doc-heading-module-map","id":"doc:architecture#doc-heading-module-map","kind":"doc-heading","line":8,"name":"Module map","path":"docs/architecture.md","summary":"architecture / Module map","tags":["docs","architecture","module","map"]}
{"href":"doc-architecture.html#doc-heading-reloadable-microkernel","id":"doc:architecture#doc-heading-reloadable-microkernel","kind":"doc-heading","line":37,"name":"Reloadable microkernel","path":"docs/architecture.md","summary":"architecture / Reloadable microkernel — fen is a tiny core (agent loop, canonical types, provider dispatch, extension registry) with providers, the TUI, session storage, and the built-in tools all shipped as first-party extensions. `/reload` re-runs module bodies in place, so most code lives in reloadable modules.","tags":["docs","architecture","reloadable","microkernel"]}
{"href":"doc-architecture.html#doc-heading-canonical-types-and-pi-mono-divergence","id":"doc:architecture#doc-heading-canonical-types-and-pi-mono-divergence","kind":"doc-heading","line":52,"name":"Canonical types and pi-mono divergence","path":"docs/architecture.md","summary":"architecture / Canonical types and pi-mono divergence — All agent-side code operates on canonical message/tool shapes defined in `packages/core/src/fen/core/types.fnl`; the field-level reference is generated from source rather than restated here. Providers convert to and from wire shape at the boundary, so the agent loop never sees provider-specific JSON — the wire-shape differences are documented in [`providers.md`](providers.md).","tags":["docs","architecture","canonical","types","and","pi-mono","divergence"]}
{"href":"doc-architecture.html#doc-heading-design-principles","id":"doc:architecture#doc-heading-design-principles","kind":"doc-heading","line":70,"name":"Design principles","path":"docs/architecture.md","summary":"architecture / Design principles — These shape the core API and what the generated docs cover. They are values, not signatures, so they don't drift with the code the way restated facts do.","tags":["docs","architecture","design","principles"]}
{"href":"doc-development.html#doc-heading-development-workflow","id":"doc:development#doc-heading-development-workflow","kind":"doc-heading","line":1,"name":"Development workflow","path":"docs/development.md","summary":"development / Development workflow — This page is the maintainer reference for day-to-day fen development, hot reload, local checks, and disposable build artifacts.","tags":["docs","development","workflow"]}
{"href":"doc-development.html#doc-heading-workflow","id":"doc:development#doc-heading-workflow","kind":"doc-heading","line":5,"name":"Workflow","path":"docs/development.md","summary":"development / Workflow — Normal development uses one single-file `fen` binary plus source overlays. No generated Lua tree is needed for `.fnl` edits:","tags":["docs","development","workflow"]}
{"href":"doc-development.html#doc-heading-reproducing-tui-stalls","id":"doc:development#doc-heading-reproducing-tui-stalls","kind":"doc-heading","line":38,"name":"Reproducing TUI stalls","path":"docs/development.md","summary":"development / Reproducing TUI stalls — `make stall-check` (wrapper: `scripts/dev/stall-check.sh`) is an opt-in harness for cooperative-yield stalls — the multi-hundred-ms gaps between coroutine yields that freeze the TUI on slow hardware. It drives the real streaming transport (`fen_http.so` cooperative mode), the real SSE parser, and a per-event JSON decode against a localhost SSE stream, timing the wall gap between yields (the same metric `warn-if-stalled!` reports). `FEN_DEBUG_CHUNK_DELAY_MS` (read once by `fen_http.c`) sleeps that many ms per drained chunk slice, so a desktop reproduces the BB10/ARM per-chunk cost; the harness prints a min/max/avg/median gap histogram and fails if any single resume exceeds `FEN_STALL_BUDGET_MS` (default 250). Knobs: `FEN_DEBUG_CHUNK_DELAY_MS` (default 15), `FEN_STALL_BUDGET_MS`, `FEN_STALL_BODY_KB`, and `FEN_STALL_NICE=1` to also wrap the run in `nice`/`taskset`. `FEN_DEBUG_CHUNK_DELAY_MS` works against the live binary too: set it before launching `fen` and lower `FEN_TUI_STALL_WARN_MS` to make on-device stalls reproducible and loud in `fen.log`.","tags":["docs","development","reproducing","tui","stalls"]}
{"href":"doc-development.html#doc-heading-nix-result-symlinks","id":"doc:development#doc-heading-nix-result-symlinks","kind":"doc-heading","line":70,"name":"Nix result symlinks","path":"docs/development.md","summary":"development / Nix result symlinks — `nix build` creates `result` symlinks in the current directory that point into `/nix/store`. `nix flake check` or multi-output builds may leave numbered links such as `result-1`, `result-2`, etc.; cross-builds may use explicit names like `result-armv7` when passed with `-o`. These are local build artifacts, not source files. It is safe to remove the symlinks from the repo root:","tags":["docs","development","nix","result","symlinks"]}
{"href":"doc-development.html#doc-heading-hot-reload-is-the-development-loop","id":"doc:development#doc-heading-hot-reload-is-the-development-loop","kind":"doc-heading","line":103,"name":"Hot reload is the development loop","path":"docs/development.md","summary":"development / Hot reload is the development loop — `/reload` is *the* way to iterate on this codebase. Under the canonical `.#fen` + `scripts/dev/fen-dev` workflow, edit a `.fnl`, type `/reload` from the running TUI, and keep working on the same session — the embedded Fennel compiler loads the changed source directly through `FEN_DEV_PATH` / `FEN_EXTENSION_ROOT` (as set by `scripts/dev/fen-dev`; equivalent `--dev-path` / `--extension-root` launcher flags remain available for ad hoc runs). Agents do **not** need to rebuild before telling the user a source change is ready to hot reload when the user is on `scripts/dev/fen-dev`.","tags":["docs","development","hot","reload","is","the","loop"]}
{"href":"doc-development.html#doc-heading-how-it-works","id":"doc:development#doc-heading-how-it-works","kind":"doc-heading","line":119,"name":"How it works","path":"docs/development.md","summary":"development / How it works — `packages/fen/src/fen/main.fnl` keeps a `RELOADABLE` list of module names. `/reload` calls `manual-reload!` for each: clear `package.loaded[modname]`, re-`require` (re-runs the module body), then **copy the new exports onto the original module table in place**. A `(local foo (require :fen.core.foo))` capture keeps the same table reference; the next `foo.bar` call resolves through the mutated table and lands on the new function. Module-table lookup is the contract that makes reload work.","tags":["docs","development","how","it","works"]}
{"href":"doc-development.html#doc-heading-what-reloads-what-doesn-t","id":"doc:development#doc-heading-what-reloads-what-doesn-t","kind":"doc-heading","line":129,"name":"What reloads, what doesn't","path":"docs/development.md","summary":"development / What reloads, what doesn't — Reloadable: every `fen.core.*` behavior module in the list (including the loader-owned extension API factory and the registry/event leaf modules), provider implementation modules under `fen.extensions.provider_*`, and `fen.util.*` helpers. First-party extension modules are reloaded by the extension loader from their manifests. Bodies re-run, exports get re-pointed.","tags":["docs","development","what","reloads","doesn","t"]}
{"href":"doc-development.html#doc-heading-rules-for-new-code","id":"doc:development#doc-heading-rules-for-new-code","kind":"doc-heading","line":151,"name":"Rules for new code","path":"docs/development.md","summary":"development / Rules for new code — **Keep long-running work cooperative.** Anything that may touch the network,   drain a subprocess, walk many files/modules, build docs, reload extensions, or   otherwise take more than a quick frame should accept and call a `yield!` /   `?yield-fn` callback between chunks. The TUI drives work from coroutines;   yielding is what lets it repaint, process cancel/quit keys, and show progress   instead of appearing frozen.","tags":["docs","development","rules","for","new","code"]}
{"href":"doc-development.html#doc-heading-why-this-shapes-the-api","id":"doc:development#doc-heading-why-this-shapes-the-api","kind":"doc-heading","line":176,"name":"Why this shapes the api","path":"docs/development.md","summary":"development / Why this shapes the api — Anything exported from a non-reloadable module (`fen.extensions.tui.state`, `fen.core.extensions.state`) is shape-stable — its layout is a contract that callers depend on across reload. Keep those surfaces small; iteration- prone logic does not belong there. Behavior that *consumes* that state (`fen.core.extensions.*`, TUI behavior modules) goes in sibling modules that reload against it, so the state is what's stable, the code is what's editable.","tags":["docs","development","why","this","shapes","the","api"]}
{"href":"doc-distribution.html#doc-heading-distribution","id":"doc:distribution#doc-heading-distribution","kind":"doc-heading","line":1,"name":"Distribution","path":"docs/distribution.md","summary":"distribution / Distribution — Nix is the canonical, reproducible build and the source of every release artifact. The public runtime artifact is the production single-file binary from `nix build .#fen`; source-checkout development uses that same binary through `scripts/dev/fen-dev` overlays (see [`development.md`](development.md)).","tags":["docs","distribution"]}
{"href":"doc-distribution.html#doc-heading-nix-artifacts","id":"doc:distribution#doc-heading-nix-artifacts","kind":"doc-heading","line":14,"name":"Nix artifacts","path":"docs/distribution.md","summary":"distribution / Nix artifacts — Reference table covering Nix attribute, Target, Linking, Release asset (fen-<tag>-…), Checks.","tags":["docs","distribution","nix","artifacts"]}
{"href":"doc-distribution.html#doc-heading-docker-scratch-image","id":"doc:distribution#doc-heading-docker-scratch-image","kind":"doc-heading","line":45,"name":"Docker scratch image","path":"docs/distribution.md","summary":"distribution / Docker scratch image — The flake exposes a tiny scratch image containing the static `fen` binary, BusyBox, CA certificates, and a writable `/tmp`. It is useful for smoke tests or trying Fen on a host with Docker without installing the binary.","tags":["docs","distribution","docker","scratch","image"]}
{"href":"doc-distribution.html#doc-heading-single-file-binary-format","id":"doc:distribution#doc-heading-single-file-binary-format","kind":"doc-heading","line":69,"name":"Single-file binary format","path":"docs/distribution.md","summary":"distribution / Single-file binary format — The binary is a native launcher that statically registers the Fen-owned native modules (cjson, LuaSocket core, `fen_http`, `fen_process`, `fen_random`, termbox2, lfs), then appends a deterministic ZIP of the packaged `share/lua/5.4` module tree to the launcher ELF. At startup it installs `package.searchers` entries that load Lua and Fennel modules from that embedded archive, so the archive carries only Lua/Fennel source. `fen --help` is intentionally lazy-loaded so it does not require JSON, HTTP, TUI, or provider modules before printing usage.","tags":["docs","distribution","single-file","binary","format"]}
{"href":"doc-distribution.html#doc-heading-searcher-precedence","id":"doc:distribution#doc-heading-searcher-precedence","kind":"doc-heading","line":87,"name":"Searcher precedence","path":"docs/distribution.md","summary":"distribution / Searcher precedence — `package.searchers` is set up by the launcher before `(require :fen.main)` runs, in this order (lower index wins):","tags":["docs","distribution","searcher","precedence"]}
{"href":"doc-distribution.html#doc-heading-dev-overlays","id":"doc:distribution#doc-heading-dev-overlays","kind":"doc-heading","line":111,"name":"Dev overlays","path":"docs/distribution.md","summary":"distribution / Dev overlays — Two repeatable flags redirect module resolution to a source checkout, each with an equivalent env var:","tags":["docs","distribution","dev","overlays"]}
{"href":"doc-distribution.html#doc-heading-building-without-nix","id":"doc:distribution#doc-heading-building-without-nix","kind":"doc-heading","line":147,"name":"Building without Nix","path":"docs/distribution.md","summary":"distribution / Building without Nix — For people who do not have Nix, `make fen` produces the same single-file binary by linking against the host's Lua and libcurl instead. There is no separate `./configure` step: the Makefile probes the toolchain and fetches third-party sources itself, only when a portable goal is the make goal (so `make test` and friends never shell out to pkg-config or the network). This path is a convenience, not a release path: its binaries are not the published artifacts and carry a `make` source stamp rather than `nix`.","tags":["docs","distribution","building","without","nix"]}
{"href":"doc-distribution.html#doc-heading-install-script","id":"doc:distribution#doc-heading-install-script","kind":"doc-heading","line":199,"name":"Install script","path":"docs/distribution.md","summary":"distribution / Install script — `scripts/install.sh` is a POSIX `sh` one-liner installer for the prebuilt release binaries, served from the docs site (the `docs-publish` target copies it to `dist/docs/install.sh`):","tags":["docs","distribution","install","script"]}
{"href":"doc-distribution.html#doc-heading-self-update-fen-update","id":"doc:distribution#doc-heading-self-update-fen-update","kind":"doc-heading","line":245,"name":"Self-update (`fen update`)","path":"docs/distribution.md","summary":"distribution / Self-update (`fen update`) — `fen update` replaces the running single-file binary with the latest GitHub release. Because the binary is a C launcher with an appended zip, an update is a whole-file swap, not a partial patch. The flow lives in `fen.update` (`packages/fen/src/fen/update.fnl`) and reuses in-tree primitives only — no system `curl`/`sha256sum` dependency:","tags":["docs","distribution","self-update","fen","update"]}
{"href":"doc-distribution.html#doc-heading-releases","id":"doc:distribution#doc-heading-releases","kind":"doc-heading","line":272,"name":"Releases","path":"docs/distribution.md","summary":"distribution / Releases — Pushing a version tag matching `v*` runs `.github/workflows/release.yml`. The workflow first runs release-targeted native checks (`fennelCheck` and `tests`), then builds the supported Linux executables in parallel matrix jobs. The x86_64 job smoke-runs the default static artifact with `--help` / `--version` and runs the no-store-reference and no-dynamic-dependency checks; cross jobs run the matching QEMU smoke, no-store-reference, and no-dynamic-dependency checks. A final publish job downloads all binaries, creates `SHA256SUMS`, and uploads the assets (named `fen-<tag>-<asset>` per the matrix above, plus `SHA256SUMS`) to the GitHub Release for that tag.","tags":["docs","distribution","releases"]}
{"href":"doc-distribution.html#doc-heading-docker-smoke","id":"doc:distribution#doc-heading-docker-smoke","kind":"doc-heading","line":310,"name":"Docker smoke","path":"docs/distribution.md","summary":"distribution / Docker smoke — `nix run .#dockerSmoke` builds/loads a scratch-based Docker image and runs   `fen --help`.","tags":["docs","distribution","docker","smoke"]}
{"href":"doc-extensions.html#doc-heading-extensions","id":"doc:extensions#doc-heading-extensions","kind":"doc-heading","line":1,"name":"Extensions","path":"docs/extensions.md","summary":"extensions / Extensions — fen has a small Lua/Fennel extension system for adding behavior around the core agent loop without patching `packages/core/` directly. Extensions can add slash commands, tools, hooks, system-prompt fragments, event subscribers, and presenters.","tags":["docs","extensions"]}
{"href":"doc-extensions.html#doc-heading-mental-model","id":"doc:extensions#doc-heading-mental-model","kind":"doc-heading","line":12,"name":"Mental model","path":"docs/extensions.md","summary":"extensions / Mental model — There are three pieces:","tags":["docs","extensions","mental","model"]}
{"href":"doc-extensions.html#doc-heading-discovery","id":"doc:extensions#doc-heading-discovery","kind":"doc-heading","line":57,"name":"Discovery","path":"docs/extensions.md","summary":"extensions / Discovery — Extensions are discovered by walking known roots for extension directories and single-file entries. Internal first-party extensions are loaded from the embedded manifest registry. First-party overlay roots are walked recursively so the in-repo adapter/behavior taxonomy can be used during source-checkout development. Project and user drop-in roots remain shallow and flat.","tags":["docs","extensions","discovery"]}
{"href":"doc-extensions.html#doc-heading-manifest","id":"doc:extensions#doc-heading-manifest","kind":"doc-heading","line":116,"name":"Manifest","path":"docs/extensions.md","summary":"extensions / Manifest — Directory extensions may declare a `manifest.fnl` (or `manifest.lua`) at their root. A Fennel manifest is just a table:","tags":["docs","extensions","manifest"]}
{"href":"doc-extensions.html#doc-heading-entrypoint-shape","id":"doc:extensions#doc-heading-entrypoint-shape","kind":"doc-heading","line":159,"name":"Entrypoint shape","path":"docs/extensions.md","summary":"extensions / Entrypoint shape — One entrypoint shape is preferred: the loaded entry returns a register function that receives `api`. A manifest can point at either a file (`:entry`) or a module (`:entry-module`); without a manifest, the `init.{fnl,lua}` file fallback is used. The loader creates the API, removes prior owner-tagged contributions, and invokes the register function, so normal extensions do not need to call `unregister-by-owner` themselves:","tags":["docs","extensions","entrypoint","shape"]}
{"href":"doc-extensions.html#doc-heading-api-surface","id":"doc:extensions#doc-heading-api-surface","kind":"doc-heading","line":212,"name":"API surface","path":"docs/extensions.md","summary":"extensions / API surface — The API table passed to an extension contains:","tags":["docs","extensions","api","surface"]}
{"href":"doc-extensions.html#doc-heading-registering-commands","id":"doc:extensions#doc-heading-registering-commands","kind":"doc-heading","line":242,"name":"Registering commands","path":"docs/extensions.md","summary":"extensions / Registering commands","tags":["docs","extensions","registering","commands"]}
{"href":"doc-extensions.html#doc-heading-registering-tools","id":"doc:extensions#doc-heading-registering-tools","kind":"doc-heading","line":259,"name":"Registering tools","path":"docs/extensions.md","summary":"extensions / Registering tools — Tool specs match the built-in `AgentTool` shape handled by `packages/core/src/fen/core/tools.fnl`:","tags":["docs","extensions","registering","tools"]}
{"href":"doc-extensions.html#doc-heading-hooks","id":"doc:extensions#doc-heading-hooks","kind":"doc-heading","line":277,"name":"Hooks","path":"docs/extensions.md","summary":"extensions / Hooks — v1 exposes a before-tool hook:","tags":["docs","extensions","hooks"]}
{"href":"doc-extensions.html#doc-heading-system-prompt-fragments","id":"doc:extensions#doc-heading-system-prompt-fragments","kind":"doc-heading","line":292,"name":"System prompt fragments","path":"docs/extensions.md","summary":"extensions / System prompt fragments — Prefer the ergonomic `api.prompt` helper:","tags":["docs","extensions","system","prompt","fragments"]}
{"href":"doc-extensions.html#doc-heading-event-bus","id":"doc:extensions#doc-heading-event-bus","kind":"doc-heading","line":310,"name":"Event bus","path":"docs/extensions.md","summary":"extensions / Event bus — Subscribe to one event:","tags":["docs","extensions","event","bus"]}
{"href":"doc-extensions.html#doc-heading-registering-introspection-snapshots","id":"doc:extensions#doc-heading-registering-introspection-snapshots","kind":"doc-heading","line":351,"name":"Registering introspection snapshots","path":"docs/extensions.md","summary":"extensions / Registering introspection snapshots — An `:introspect` contribution exposes a sanitized, read-only snapshot of extension-owned state. Snapshots are collected on demand by `agent_state`, `/extensions <name>`, and future runtime diagnostics.","tags":["docs","extensions","registering","introspection","snapshots"]}
{"href":"doc-extensions.html#doc-heading-presenters","id":"doc:extensions#doc-heading-presenters","kind":"doc-heading","line":380,"name":"Presenters","path":"docs/extensions.md","summary":"extensions / Presenters — A presenter is an interactive host such as the built-in TUI, a future REPL, or an RPC server. Only one active presenter owns the UI slot.","tags":["docs","extensions","presenters"]}
{"href":"doc-extensions.html#doc-heading-registering-status-items","id":"doc:extensions#doc-heading-registering-status-items","kind":"doc-heading","line":405,"name":"Registering status items","path":"docs/extensions.md","summary":"extensions / Registering status items — A `:status` is one block in the presenter's status bar, in the Waybar/Polybar style: each item renders independently and the presenter composes them. First-party status items in the TUI surface the model name, context tokens, queue counts, and scroll offset.","tags":["docs","extensions","registering","status","items"]}
{"href":"doc-extensions.html#doc-heading-registering-panels","id":"doc:extensions#doc-heading-registering-panels","kind":"doc-heading","line":432,"name":"Registering panels","path":"docs/extensions.md","summary":"extensions / Registering panels — A `:panel` is a bounded vertical region above the input or below the status bar. It owns a row count per frame and a list of rows to paint; the presenter handles geometry, clipping, and clamping to available space. The TUI's busy spinner is the smallest first-party example (`extensions/adapters/presenters/tui/panels/busy.fnl`).","tags":["docs","extensions","registering","panels"]}
{"href":"doc-extensions.html#doc-heading-semantic-styles","id":"doc:extensions#doc-heading-semantic-styles","kind":"doc-heading","line":471,"name":"Semantic styles","path":"docs/extensions.md","summary":"extensions / Semantic styles — `:status` items and `:panel` rows declare colors with semantic keywords; presenters own the actual color tables.","tags":["docs","extensions","semantic","styles"]}
{"href":"doc-extensions.html#doc-heading-reload-behavior","id":"doc:extensions#doc-heading-reload-behavior","kind":"doc-heading","line":489,"name":"Reload behavior","path":"docs/extensions.md","summary":"extensions / Reload behavior — `/reload` does two things:","tags":["docs","extensions","reload","behavior"]}
{"href":"doc-extensions.html#doc-heading-introspection","id":"doc:extensions#doc-heading-introspection","kind":"doc-heading","line":536,"name":"Introspection","path":"docs/extensions.md","summary":"extensions / Introspection — Interactive commands:","tags":["docs","extensions","introspection"]}
{"href":"doc-extensions.html#doc-heading-packaging-and-dependencies","id":"doc:extensions#doc-heading-packaging-and-dependencies","kind":"doc-heading","line":573,"name":"Packaging and dependencies","path":"docs/extensions.md","summary":"extensions / Packaging and dependencies — Flat manifest directories are the authoring shape for first-party and project-local extensions. Rockspecs remain useful for publishing and declaring extension dependencies, but users should build local extension dependencies via fen rather than invoking LuaRocks directly:","tags":["docs","extensions","packaging","and","dependencies"]}
{"href":"doc-extensions.html#doc-heading-minimal-extension-example","id":"doc:extensions#doc-heading-minimal-extension-example","kind":"doc-heading","line":604,"name":"Minimal extension example","path":"docs/extensions.md","summary":"extensions / Minimal extension example — A path-shaped extension under your user config extension dir. No `:entry-module`, no rock — just a directory with an `init.fnl` and, for global discovery, a manifest that enables it.","tags":["docs","extensions","minimal","extension","example"]}
{"href":"doc-providers.html#doc-heading-providers-and-models","id":"doc:providers#doc-heading-providers-and-models","kind":"doc-heading","line":1,"name":"Providers and models","path":"docs/providers.md","summary":"providers / Providers and models — Provider-facing contracts, wire-shape differences, and custom model configuration.","tags":["docs","providers","and","models"]}
{"href":"doc-providers.html#doc-heading-first-run-setup-help","id":"doc:providers#doc-heading-first-run-setup-help","kind":"doc-heading","line":5,"name":"First-run setup help","path":"docs/providers.md","summary":"providers / First-run setup help — Fen starts with the saved provider from `~/.config/fen/settings.json`, or `openai` when no setting exists. If that provider is missing credentials, startup prints provider onboarding guidance instead of only naming the missing variable. Use the provider setup pages for manpage-style help without starting the TUI:","tags":["docs","providers","first-run","setup","help"]}
{"href":"doc-providers.html#doc-heading-provider-interface","id":"doc:providers#doc-heading-provider-interface","kind":"doc-heading","line":30,"name":"Provider interface","path":"docs/providers.md","summary":"providers / Provider interface — Each provider module exports a record with at minimum: `{:api :provider :complete :convert-messages :convert-tools :map-stop-reason   :parse-response :build-body}`.","tags":["docs","providers","provider","interface"]}
{"href":"doc-providers.html#doc-heading-wire-shape-differences","id":"doc:providers#doc-heading-wire-shape-differences","kind":"doc-heading","line":52,"name":"Wire-shape differences","path":"docs/providers.md","summary":"providers / Wire-shape differences — The agent loop only ever sees canonical messages; each provider converts to and from wire shape at the boundary and absorbs these differences:","tags":["docs","providers","wire-shape","differences"]}
{"href":"doc-providers.html#doc-heading-http-transport-and-tls-trust","id":"doc:providers#doc-heading-http-transport-and-tls-trust","kind":"doc-heading","line":72,"name":"HTTP transport and TLS trust","path":"docs/providers.md","summary":"providers / HTTP transport and TLS trust — All provider HTTP, including Codex OAuth login and refresh, goes through `fen.util.http`. The default backend is fen's project-owned `fen_http` C module (built from `packages/util/vendor/fen_http.c`), which wraps libcurl; fen does not shell out to `curl(1)` or use the old `lua-curl` rock. JSON uses `lua-cjson`, loaded as `cjson`.","tags":["docs","providers","http","transport","and","tls","trust"]}
{"href":"doc-providers.html#doc-heading-thinking-controls","id":"doc:providers#doc-heading-thinking-controls","kind":"doc-heading","line":89,"name":"Thinking controls","path":"docs/providers.md","summary":"providers / Thinking controls — Use `--thinking LEVEL` for provider-neutral thinking control. Accepted levels are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`. Anthropic maps levels to coarse `thinking-budget` token buckets; OpenAI Responses, Codex Responses, and Chat Completions map levels to `reasoning-effort` / `reasoning_effort`.","tags":["docs","providers","thinking","controls"]}
{"href":"doc-providers.html#doc-heading-custom-providers-models-json","id":"doc:providers#doc-heading-custom-providers-models-json","kind":"doc-heading","line":103,"name":"Custom providers (models.json)","path":"docs/providers.md","summary":"providers / Custom providers (models.json) — OpenAI-compat HTTP endpoints (Ollama local, Ollama Cloud, vLLM, LM Studio, proxies) are configured via `~/.config/fen/models.json` — read by `packages/core/src/fen/core/llm/models.fnl` at first call and cached until `/reload` re-requires the module. Mirrors the floor of pi-mono's `models.json` schema (see `pi-mono/packages/coding-agent/docs/models.md`).","tags":["docs","providers","custom","models","json"]}
{"href":"doc-scripts.html#doc-heading-scripts","id":"doc:scripts#doc-heading-scripts","kind":"doc-heading","line":1,"name":"Scripts","path":"docs/scripts.md","summary":"scripts / Scripts — `fen run` runs Lua and Fennel scripts with fen's embedded Lua 5.4 runtime. `fen eval` evaluates inline Lua or Fennel code with the same runtime. They are meant for small portable scripts on systems where `lua`, `fennel`, or system LuaRocks are not installed. They are separate from the coding-agent flow and do not initialize providers, sessions, or the TUI.","tags":["docs","scripts"]}
{"href":"doc-scripts.html#doc-heading-usage","id":"doc:scripts#doc-heading-usage","kind":"doc-heading","line":8,"name":"Usage","path":"docs/scripts.md","summary":"scripts / Usage","tags":["docs","scripts","usage"]}
{"href":"doc-scripts.html#doc-heading-script-and-eval-arguments","id":"doc:scripts#doc-heading-script-and-eval-arguments","kind":"doc-heading","line":42,"name":"Script and eval arguments","path":"docs/scripts.md","summary":"scripts / Script and eval arguments — `fen run` follows Lua's script argument convention. Inside a script, `arg[0]` is the script path. `arg[1]` through `arg[n]` are the arguments after the script path. The same script arguments are also passed as varargs, so a script can read them through `...`. Arguments before the script path, such as `fen`, `run`, and language flags, are available at negative `arg` indexes for compatibility.","tags":["docs","scripts","script","and","eval","arguments"]}
{"href":"doc-scripts.html#doc-heading-fennel-modules","id":"doc:scripts#doc-heading-fennel-modules","kind":"doc-heading","line":62,"name":"Fennel modules","path":"docs/scripts.md","summary":"scripts / Fennel modules — When running a `.fnl` script, using `fen run --fennel`, or using `fen eval --fennel`, fen installs Fennel's module searcher for the process. This lets Fennel scripts and eval snippets require sibling modules from the current working directory, such as `require \"helper\"` loading `helper.fnl`. The runner exits after the script or eval completes, so this searcher mutation does not leak into agent mode.","tags":["docs","scripts","fennel","modules"]}
{"href":"doc-scripts.html#doc-heading-dependencies-and-fen-ext-build","id":"doc:scripts#doc-heading-dependencies-and-fen-ext-build","kind":"doc-heading","line":68,"name":"Dependencies and `fen ext build`","path":"docs/scripts.md","summary":"scripts / Dependencies and `fen ext build` — On startup, fen prepends the fen-managed rocks tree to `package.path` and `package.cpath` when the tree exists. The default tree is:","tags":["docs","scripts","dependencies","and","fen","ext","build"]}
{"href":"doc-scripts.html#doc-heading-safety","id":"doc:scripts#doc-heading-safety","kind":"doc-heading","line":94,"name":"Safety","path":"docs/scripts.md","summary":"scripts / Safety — `fen run` and `fen eval` are not sandboxes. They execute arbitrary local code with the same permissions as the `fen` process. Use them only with code you trust.","tags":["docs","scripts","safety"]}
{"href":"doc-scripts.html#doc-heading-supported-module-surface","id":"doc:scripts#doc-heading-supported-module-surface","kind":"doc-heading","line":100,"name":"Supported module surface","path":"docs/scripts.md","summary":"scripts / Supported module surface — The supported script/eval surface is intentionally small:","tags":["docs","scripts","supported","module","surface"]}
{"href":"doc-scripts.html#doc-heading-exit-codes","id":"doc:scripts#doc-heading-exit-codes","kind":"doc-heading","line":113,"name":"Exit codes","path":"docs/scripts.md","summary":"scripts / Exit codes — Reference table covering exit code, meaning.","tags":["docs","scripts","exit","codes"]}
{"href":"doc-sessions.html#doc-heading-sessions","id":"doc:sessions#doc-heading-sessions","kind":"doc-heading","line":1,"name":"Sessions","path":"docs/sessions.md","summary":"sessions / Sessions — Session persistence format and CLI behavior.","tags":["docs","sessions"]}
{"href":"doc-sessions.html#doc-heading-sessions-2","id":"doc:sessions#doc-heading-sessions-2","kind":"doc-heading","line":5,"name":"Sessions","path":"docs/sessions.md","summary":"sessions / Sessions — Conversations persist as append-only JSONL under `${XDG_STATE_HOME:-~/.local/state}/fen/sessions/<cwd-slug>/<ISO>_<id>.jsonl`. Line 1 is a `{:type :session :version 2 :id :timestamp :cwd}` header; subsequent lines are session entries. Message entries are `{:type :message :id :parent-id :timestamp :message <canonical-msg>}`. Compaction entries are `{:type :compaction :id :parent-id :timestamp :summary :first-kept-entry-id :tokens-before :tokens-after :guidance :trigger}`. Entry IDs are in-tree UUIDv7-shaped strings generated by `fen.util.id`; `:parent-id` points to the previously appended entry when available. Older version-1 files without entry IDs still load. The `cwd-slug` mirrors pi-mono's `--<encoded-cwd>--` shape (slashes → `-`, sandwiched in `--`).","tags":["docs","sessions"]}
{"href":"doc-sessions.html#doc-heading-compaction","id":"doc:sessions#doc-heading-compaction","kind":"doc-heading","line":33,"name":"Compaction","path":"docs/sessions.md","summary":"sessions / Compaction — `/compact [guidance]` summarizes older messages in the current session and keeps recent messages verbatim. It appends a `:compaction` entry rather than rewriting prior message entries. On `--continue`, the JSONL backend finds the latest valid compaction entry and reconstructs context as a synthetic summary user message followed by messages from `:first-kept-entry-id` onward. If the compaction entry is malformed or points at a missing message entry, it is ignored and the full message history is replayed.","tags":["docs","sessions","compaction"]}
{"href":"doc-skills.html#doc-heading-skills","id":"doc:skills#doc-heading-skills","kind":"doc-heading","line":1,"name":"Skills","path":"docs/skills.md","summary":"skills / Skills — Agent Skills discovery and prompt behavior.","tags":["docs","skills"]}
{"href":"doc-skills.html#doc-heading-skills-2","id":"doc:skills#doc-heading-skills-2","kind":"doc-heading","line":5,"name":"Skills","path":"docs/skills.md","summary":"skills / Skills — `SKILL.md` files are discovered recursively from the original fen roots plus pi/Agent Skills-compatible locations: `${XDG_CONFIG_HOME:-~/.config}/fen/skills`, `.fen/skills`, bundled fen skills materialized under `${XDG_DATA_HOME:-~/.local/share}/fen/skills/bundled`, `~/.pi/agent/skills`, `~/.agents/skills`, project `.pi/skills`, ancestor `.agents/skills`, and common Claude/Codex skill roots. User and project skills are discovered before bundled skills, so a skill with the same `name` shadows the bundled copy. Set `FEN_DISABLE_BUNDLED_SKILLS=1` to skip bundled-skill materialization and discovery. Discovery skips dotdirs, `node_modules`, and paths matched by `.gitignore`, `.ignore`, or `.fdignore`. Explicit paths can be passed via `--skill <path>`; `--skills <dir>` remains a compatibility alias.","tags":["docs","skills"]}
{"href":"doc-tools.html#doc-heading-built-in-tools","id":"doc:tools#doc-heading-built-in-tools","kind":"doc-heading","line":1,"name":"Built-in tools","path":"docs/tools.md","summary":"tools / Built-in tools — Contracts and implementation notes for the first-party tool surface.","tags":["docs","tools","built-in"]}
{"href":"doc-tools.html#doc-heading-tui-rendering","id":"doc:tools#doc-heading-tui-rendering","kind":"doc-heading","line":5,"name":"TUI rendering","path":"docs/tools.md","summary":"tools / TUI rendering — The TUI keeps tool-heavy transcripts compact by rendering built-in tool calls as short status rows, for example `tool> run read README.md:1-20` or `tool> run $ make test`. When the result arrives, the call/result pair folds into a single console-friendly row such as `tool> ok  read README.md (42 lines, 3.1KB)` or `tool> err read missing.txt (1 line, 24B)`. Use `/expand` or `ctrl-o` in the TUI to toggle expanded tool-result body previews under the paired summary row. Expanded previews are capped by the presenter preview limit so very large outputs do not flood the transcript.","tags":["docs","tools","tui","rendering"]}
{"href":"doc-tools.html#doc-heading-tool-result-sanitation","id":"doc:tools#doc-heading-tool-result-sanitation","kind":"doc-heading","line":12,"name":"Tool-result sanitation","path":"docs/tools.md","summary":"tools / Tool-result sanitation — Fen sanitizes provider-visible tool-result text before new results are emitted and stored in the JSONL transcript; those sanitized stored results are then safe to replay to later provider calls. Raw NUL bytes, invalid UTF-8 bytes, and control bytes other than tab/newline/carriage-return are escaped as visible ASCII such as `\\\\x00`. Each text block in a tool result is also capped by bytes (`FEN_TOOL_RESULT_MAX_BYTES`, default 65536), and Fen appends an explicit marker when output was sanitized or truncated. This is a final safety net against provider 400s and wedged sessions; tools should still summarize or truncate domain-specific output themselves when possible. The sanitizer preserves the required one-result-per-tool-call pairing rather than dropping unsafe results. Structured `details` payloads are preserved for presenters/replay and are not sent to providers. Already-written legacy sessions are repaired separately at provider replay/session-doctor boundaries.","tags":["docs","tools","tool-result","sanitation"]}
{"href":"doc-tools.html#doc-heading-tools","id":"doc:tools#doc-heading-tools","kind":"doc-heading","line":22,"name":"Tools","path":"docs/tools.md","summary":"tools / Tools — Built-ins are registered by the first-party `builtin_tools` extension and their implementations live under `extensions/behaviors/kernel/builtin-tools/`. They mirror pi-mono's `bash`, `read`, `write`, `ls`, `edit`, `grep`, `find`. POSIX-only stance:","tags":["docs","tools"]}
{"href":"doc-tools.html#doc-heading-cooperative-execution","id":"doc:tools#doc-heading-cooperative-execution","kind":"doc-heading","line":74,"name":"Cooperative execution","path":"docs/tools.md","summary":"tools / Cooperative execution — Tool executors may receive an optional cooperative yield callback from the agent loop. Long local work should call it between chunks, scans, pipe reads, and writes so the TUI can repaint and observe cancellation. The callback may raise to cancel the operation. Tools that open files, pipes, subprocesses, or spill outputs must close those resources before rethrowing cancellation or other errors. This callback is an implementation detail of the runtime and is backward-compatible with tools that ignore the extra argument.","tags":["docs","tools","cooperative","execution"]}
