backseat-driver-internals

star 56

Backseat Driver extension internals — Ex framework contracts, app-db state architecture, MCP socket server lifecycle, enrichment system, Datascript output log, activation sequences, and namespace reference. Use when: modifying core extension code, debugging state issues, working with app-db or Ex framework, understanding activation or MCP server flow, investigating enrichment or Datascript connections, or working with tool registration.

BetterThanTomorrow By BetterThanTomorrow schedule Updated 4/30/2026

name: backseat-driver-internals description: 'Backseat Driver extension internals — Ex framework contracts, app-db state architecture, MCP socket server lifecycle, enrichment system, Datascript output log, activation sequences, and namespace reference. Use when: modifying core extension code, debugging state issues, working with app-db or Ex framework, understanding activation or MCP server flow, investigating enrichment or Datascript connections, or working with tool registration.'

Backseat Driver Extension Internals

Subsystem contracts, state architecture, and temporal sequences for the Backseat Driver extension.

Key Namespaces

Namespace Purpose
ex.ex Dispatcher — the only entry point for state changes
ex.ax Action routing, enrichment, accumulation
ex.fx Effect routing (context-enriched before domain dispatch)
app.db !app-db atom, !output-conn & !history-conn Datascript, serialization
app.axs App lifecycle actions (activate, init, commands, cleanup)
app.fxs App effects (logging, command registration, Language Model tools)
db.axs Generic state mutation actions (assoc-in, update-in)
mcp.axs MCP server lifecycle actions (start/stop/error/handle-request)
mcp.fxs MCP effects (start/stop server, notifications, request handling, wrapper copy)
mcp.server TCP socket server implementation (low-level net, port file, buffering)
mcp.requests MCP protocol handler — tool listings, initialize, tools/call dispatch
mcp.skills Skill frontmatter parsing, filtering, instruction composition
mcp.logging MCP server log output
extension VS Code activate/deactivate entry points
integrations.calva.api Calva API access (REPL eval, ranges, editor, document, info)
integrations.calva.editor Structural editing implementation
integrations.calva.editor-util File context formatting (line-numbered windows)
integrations.vscode.tools VS Code Language Model tool registration
integrations.parinfer Bracket balancing via Parinfer
stdio.wrapper MCP stdio-to-socket relay (dist/calva-mcp-server.js)

Subsystem Contracts

λ app_db_contract.
  db/!app-db ≡ atom {
    :vscode/extension-context    ExtensionContext     ;; set before dispatch, circular refs
    :app/getConfiguration        fn                   ;; VS Code config reader

    ;; From init-db
    :extension/disposables       [Disposable]         ;; VS Code subscriptions
    :extension/when-contexts     {:calva-mcp-extension/activated? bool
                                  :calva-backseat-driver/started? bool
                                  :calva-backseat-driver/starting? bool
                                  :calva-backseat-driver/stopping? bool}
    :calva/output-line-counter   int                  ;; monotonic for output entities

    ;; From initial-state (extension.cljs)
    :app/log-file-uri            Uri                  ;; log location
    :app/min-log-level           keyword              ;; :debug/:info/:warn/:error
    :mcp/wrapper-config-path     string               ;; ~/.config/calva/backseat-driver
    :calva/history-storage-uri   Uri|nil              ;; eval-history.transit.json

    ;; Runtime
    :app/log-dir-initialized+    promise              ;; resolved when log dir exists
    :app/server-info             {:server/instance Server
                                  :server/port int
                                  :server/port-file-uri Uri
                                  :server/port-note string?}
  }
  | inspection: always(dissoc :vscode/extension-context) | circular_ref_guard
  | mutation: only_through_dispatch! | ¬direct_swap!

λ ex_dispatcher_contract.
  dispatch!(context, actions) ≡ the_only_state_entry_point
  | ~16 lines of code | the entire framework
  |
  | flow:
  |   ax/handle-actions(@!app-db, context, actions)
  |     reduce_over_actions:
  |       1. enrich-from-context(action, context)    → :context/x.y → js-get-in
  |       2. enrich-from-state(action, state)        → [:db/get k], :vscode/config.x
  |       3. route_by(namespace action-kw) → domain_handler
  |       4. handler_returns {:ex/db, :ex/fxs, :ex/dxs}
  |     accumulate: merge_db, into_fxs(enriched_from_state), into_dxs
  |   when db → reset!(!app-db)
  |   when dxs → recursive dispatch!(context, dxs)
  |   when fxs → for_each: enrich_from_context → route → execute

λ enrichment_contract.
  context_enrichment:
    :context/x.y.z → js-get-in(context, ["x" "y" "z"])
    | applied_to: actions ∧ effects
  state_enrichment:
    [:db/get key] → (get state key)
    :vscode/config.settingName → VS Code configuration API
    | applied_to: actions_only (effects get context enrichment only)
  args_enrichment:
    :ex/action-args → entire_result_from_effect
    :ex/action-args%N → (nth result (dec N))
    | applied_to: continuation_actions_via :ex/then

λ action_routing.
  (namespace action-kw) → handler_namespace:
    "app"      → app.axs
    "mcp"      → mcp.axs
    "db"       → db.axs
    "vscode"   → integrations.vscode (via axs)
    "node"     → integrations.node (via axs)
    "calva"    → integrations.calva (via axs)
  | new_domain → add_case_in ex/ax.cljs handle-action

λ effect_routing.
  (namespace fx-kw) → handler_namespace:
    "app"      → app.fxs
    "mcp"      → mcp.fxs
    "vscode"   → integrations.vscode (via fxs)
    "node"     → integrations.node (via fxs)
    "calva"    → integrations.calva (via fxs)
  | effects_receive(dispatch!, context, enriched-fx)
  | new_domain → add_case_in ex/fx.cljs perform-effect!

λ datascript_contract.
  !output-conn ≡ session_scoped | schemaless | cap: 1000 entities
    | all_output_categories: evaluationResults, evaluatedCode, evaluationOutput,
    |   evaluationErrorOutput, otherOutput, otherErrorOutput
  !history-conn ≡ persistent | schema: {:output/line {:db/unique :db.unique/identity}}
    | cap: 10000 | evaluatedCode_only
    | serialized_to: eval-history.transit.json | cognitect.transit JSON
    | format: {:format-version 1 :entities [...]}
  entity_attributes:
    :output/line        int (monotonic, from :calva/output-line-counter)
    :output/category    string
    :output/text        string
    :output/who         string?
    :output/timestamp   inst
    :output/ns          string?
    :output/repl-session-key string?

λ mcp_server_contract.
  socket_server: TCP | net.createServer | localhost_only
  | port: configured(default 1664) | 0 ≡ random | EADDRINUSE → fallback_to_0
  | port_file: ${workspaceFolder}/.calva/mcp-server/port
  | protocol: newline_delimited_JSON | buffered_partial_reads
  | active_sockets: atom | tracks_connected_clients
  | notifications: broadcast_to_all_active_sockets

  stdio_wrapper: dist/calva-mcp-server.js
  | reads_port_from_port_file → TCP_connect → relay(stdio ↔ socket)
  | one_server_per_workspace_folder

λ calva_api_contract.
  calva-api ≡ {
    :repl     {:evaluateCode, :currentSessionKey, :onOutputLogged}
    :ranges   {:currentTopLevelForm, :currentEnclosingForm, ...}
    :editor   {:replace}
    :document {:getNamespace, :getNamespaceAndNsForm}
    :info     {:getSymbolInfo, :getClojureDocsDotOrg}
  }
  | accessed_at: integrations.calva.api/calva-api
  | capability_gated: tools_appear_disappear_based_on_calva_support

λ structural_editing_contract.
  editing_unit ≡ top_level_form | ¬lines_of_text
  | parinfer: bracket_balancing | integrations/parinfer.cljs
  | targeting: targetLineText + line ±2 scan_window
  | rich_comments: forms_inside(comment ...) ≡ top_level
  | diagnostic_context: 21_line_window | line_numbers | → arrow_marker
  | bottom_to_top: multiple_edits_highest_line_first

Temporal Sequences

λ activation_sequence.
  1_vscode_calls: extension.activate(context) | entry_point
  2_store_context: assoc(:vscode/extension-context) into !app-db | before_dispatch
  3_store_config_reader: assoc(:app/getConfiguration) | vscode/workspace.getConfiguration
  4_dispatch_activate: [:app/ax.activate (initial-state context)]
  5_ax.activate: merge(init-db, initial-state) | set when-contexts | dispatch ax.init
  6_ax.init: register_commands ∧ language_model_tools | init_output_listener
  7_fx.init-logging: ensure_log_directory | resolve(:app/log-dir-initialized+)
  8_fx.copy-wrapper-script: copy(calva-mcp-server.js) to(~/.config/calva/backseat-driver/)
  9_auto_start_check: if(:vscode/config.autoStartMCPServer) → dispatch(ax.start-server)
  | skip(2) → enrichment_fails | context_not_available
  | skip(8) → stdio_wrapper_missing | MCP_clients_cant_connect

λ mcp_server_lifecycle.
  start:
    1_dispatch: [:mcp/ax.start-server]
    2_set_starting: when-context(starting? → true, stopping? → false)
    3_fx.start-server → server/start-server!+
      3a_create_server: net.createServer(TCP)
      3b_listen: configured_port | EADDRINUSE → port_0
      3c_write_port_file: .calva/mcp-server/port
    4_ax.server-started: store(:app/server-info) | when-context(started? → true, starting? → false)
    5_fx.show-server-started-message: info_notification_with_port

  client_connection:
    1_socket_connects: stdio_wrapper → TCP_connect(port)
    2_data_handler: UTF-8 | buffer → split(\n) → parse_JSON
    3_dispatch: [:mcp/ax.handle-request parsed-message]
    4_fx.handle-request → requests/handle-request-fn
    5_response: write_JSON\n_to_socket

  stop:
    1_dispatch: [:mcp/ax.stop-server]
    2_set_stopping: when-context(stopping? → true)
    3_fx.stop-server → server/stop-server!+
      3a_end_sockets: end+destroy_all_active_sockets
      3b_close_server: server.close()
      3c_delete_port_file: vscode_workspace.fs | node_fs_fallback
    4_ax.server-stopped: clear(:app/server-info) | when-context(started? → false, stopping? → false)

λ mcp_request_flow.
  initialize → {:protocolVersion "2024-11-05", :capabilities, :instructions (compose-instructions)}
  tools/list → read(package.json languageModelTools) → transform_to_mcp_format | capability_filtered
  tools/call → multimethod(handle-tool-call) by(:name) → {:content [{:type :text :text result}]}
  resources/list → skill_manifests | filtered_by_settings
  resources/read → read(assets/skills/{name}/SKILL.md) | full_content

λ tool_registration_sequence.
  1_package_json: languageModelTools manifest (name, description, inputSchema, when-clause)
  2_activation: ax.register-language-model-tools → fx.register-language-model-tools
  3_vscode_api: tools.cljs registers with Language Model API
  4_mcp_server: requests.cljs reads same manifests at runtime
  5_capability_gating: tools conditionally available based on Calva version + settings
  | single_source_of_truth: package.json | change_once → applied_everywhere

λ hot_reload_sequence.
  1_edit_source: modify .cljs file | save
  2_shadow_detects: file_watcher → incremental_compile
  3_compile: cljs → js | check_for_warnings
  4_extension_host: picks_up_changes | ¬restart_needed
  5_verify: re_evaluate_in_repl | require_with_reload
  | zero_warnings_policy: new_warnings_stand_out_only_when_baseline_clean
  | package_json_changes → extension_host_restart_required

Interactive Development Patterns

;; Explore runtime state
(in-ns 'calva-backseat-driver.app.db)
(dissoc @!app-db :vscode/extension-context)

;; Test Calva API
(in-ns 'calva-backseat-driver.integrations.calva.api)
(keys (:repl calva-api))

;; Inspect MCP server state
(in-ns 'calva-backseat-driver.mcp.server)
@active-sockets

;; Query output log
(in-ns 'calva-backseat-driver.app.db)
(d/q '[:find ?text :where [?e :output/category "evaluatedCode"] [?e :output/text ?text]] @!output-conn)

;; Test enrichment
(in-ns 'calva-backseat-driver.ex.ax)
(enrich-from-context [:some/ax.test :context/subscriptions] context)

Configuration Settings

Setting Type Default Purpose
enableMcpReplEvaluation boolean true Expose REPL eval via MCP (set false to disable)
mcpSocketServerPort number 1664 Socket server port (0 = random)
autoStartMCPServer boolean false Start MCP server on activation
provideBdSkill boolean true Provide Backseat Driver skill via MCP
provideEditSkill boolean true Provide structural editing skill via MCP

Settings accessed via enrichment: :vscode/config.settingName in action handlers.

Install via CLI
npx skills add https://github.com/BetterThanTomorrow/calva-backseat-driver --skill backseat-driver-internals
Repository Details
star Stars 56
call_split Forks 5
navigation Branch main
article Path SKILL.md
More from Creator
BetterThanTomorrow
BetterThanTomorrow Explore all skills →