



  

<!DOCTYPE html>
<html
  lang="en"
  
  data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
  data-a11y-animated-images="system" data-a11y-link-underlines="true"
  
  >




  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
  <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
  <link rel="preconnect" href="https://avatars.githubusercontent.com">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-0f910d8806d5761b.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-a7abd4d4c49ac593.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-5fc4c4a9cb41e596.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-ed0cee9214dedabd.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-78a2491d538dab5a.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-c26b63d7c532d0a2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-a6f60cea68c08405.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-f66faf28b2ea18b6.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-6701f6218c53cf5b.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-7037fa46ae124d97.css" />

  <style type="text/css">
    :root {
      --tab-size-preference: 4;
    }

    pre, code {
      tab-size: var(--tab-size-preference);
    }
  </style>

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-97df7784617ce1ea.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-9be9fe6313f476af.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-62747e27e61258dc.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-7a418ea859d1654d.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-72bd7d974b5ac1cc.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-4c5c0895f723f870.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_caches_react_shell","actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","actions_runners_react_shell","activity_diff_file_tree","activity_repos_file_tree","activity_repos_overview_header","activity_repos_overview_sidebar","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_automation_repo_mcp_servers","copilot_automations_pagination","copilot_base_model_policy_row","copilot_chat_auto_mode_v2","copilot_chat_clear_model_selection_for_default_change","copilot_chat_early_task_provisioning","copilot_chat_persist_session_drafts","copilot_chat_vision_dotcom_chat_ga_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_hide_hovercard","copilot_immersive_task_hyperlinking","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_awps_batching","copilot_mission_control_early_stop","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_discussion_comment_trigger","copilot_swe_agent_discussion_opened_trigger","copilot_swe_agent_discussion_updated_trigger","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_assigned_trigger","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_issue_labeled_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_assigned_trigger","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_labeled_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_ready_for_review_trigger","copilot_swe_agent_pull_request_review_requested_trigger","copilot_swe_agent_pull_request_review_submitted_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_sub_issue_added_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_workbench_sunset_redirect","dashboard_agents_module_auth_token_check","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","fgpat_permissions_selector_redesign","glc_code_quality_repo_settings_workflow_config","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_ubb_individual_budget_banner","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_team_vs_personal","issue_relative_time_micro","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_index_data_router","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_cookie_consent_banner","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_queue_restricted_pushers_warning","merge_status_header_feedback","milestone_closed_issues_prioritization","milestone_show_data_router","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_copilot_attribution_header","pull_request_overview_merge_control","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_navigation_shortcuts","pull_request_virtualization_image_estimate","pull_request_virtualization_loader_batching","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_logged_out_repository_header","react_query_props_with_key","react_sandbox_future_tanstack","repo_app_turbo","repo_issues_sidebar_layout","repo_pulls_dashboard_declutter","repo_pulls_dashboard_ga","repo_pulls_dashboard_persistence","repo_pulls_dashboard_sidebar_links","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_nav_spark_models_removed","speculation_rules_ui_service","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","update_issue_suggestions","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workstream_plugin_bootstrap"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-b752d992928a526c.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-3d724f91bb12ac15.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-2f08c823163591a8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-633ad94fa06c334b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-0fb4c544a797ec0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-7c872b58ac9f1b39.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tp-7e9817cf5c068979.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-e2c7d9b56ea85c83.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.bef03fb24bb03be8.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-52ed81112a548e10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e8810f64c443fb9b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-0417f617ad744a0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-9da36843ba9d191d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-9a1160b939f2cd52.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3h-55903cf2303047ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hk-f1498fec45311acd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-7aa1ff0a0e750f41.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-1d800d09e9a8720a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-9697c1c8f5cbf523.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-f48dde857ba079b2.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-5ca1990512ce9293.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-5e0b3ae3c4036207.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-524a06aa946df6fc.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-b1ee53c2200b172a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-7bf7b9d689fe3d10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a9-ca3bc10b816bcc1f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-21ec1e439ee2d87c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t-4c39f7195fc42cc8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pb-53cfff089eaac51b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6n-afcf86ccabc4cad2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zj-4d9cf83cf08e1643.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wo-6991af5b3829ffe8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/nfv-a6c14301d3ea6d67.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b5-a2fde30ce0c692b9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sw-9d0489dbf9a9c942.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ttf-7d5abe1b447ced2c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sj-c7a44023ee90d468.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0pd-c46d8dfae89c2b64.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-c2c2df50a7f31171.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.255cab819a92f7e1.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-ed075240458e4b06.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-8503588299651923.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-66e64888bc4615bb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qmp-c7cfba40cf5a93b0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-148a74299e5a01ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-a9404625ec30bbc7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4u-8f9f1d6be01d6a22.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/s0-68d09e5e8a80cb94.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y5-0cb3f75cec297941.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4u-cd9039ad946274ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8s-00bd469c4017a543.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-27679061f16e1495.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/iu-2d03f5e6d4fdd54d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gru-2b0fac8887ff8c57.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a0-234e967e7c6d22ce.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gz3-5bdfbfceac967bb6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/15m-64f3034430471048.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/1e-c15441bdb94d54ae.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gzu-6ad9a0527a5d7afd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bi-3a42b8714e06c4d0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tu1-37e16844272ddefa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b1-ac66ededed061993.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gmn-1e5497c041b66231.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0l5-d1b2a63015b5eb6d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/c2-e85522be441acf73.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/f9-baf0a4193779952e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sp-87dce99c82a27004.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zkm-116b01b8485bbe3f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/og-518d12c9e011601d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b9-947db365ea875cfa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/14-8c7b4ad3c845664c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dsj-2e7d883cb843e9e6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ec-38012819307fd539.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/du-6607da3b8b579202.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/20-f43eb09c2be69457.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ql0-107312645ac2b72d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-fa7cdc0f7656d876.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p0l-fe491d943adf7508.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/v1e-d099d9fd21ad25e5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fn-7b298a45c55fb6fb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7cw-6e493a20eaaa04b5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ok-290e4b9465ba9c5b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6d-ca6d584a0fd6368c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y8-e2f18f5a24733f3b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xc-3fd4a2e7dcbad8e2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vjg-2874f95f389c4d3f.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-7ebc2e6daa7c8336.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/xc.de2b1dde0494f261.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.fe8185756c08c07d.module.css" />


  <title>nullclaw/README.md at main · nullclaw/nullclaw · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:1a7dc794-38b1-eec8-a36f-b0062d703cee">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="D430:3EB60C:440B6D:5450A7:6AC7893B" data-pjax-transient="true"/><meta name="html-safe-nonce" content="c6372fa46bfee70768473bcffdb00f069e7f3987cf606ef53984eceeb4c5bc76" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENDMwOjNFQjYwQzo0NDBCNkQ6NTQ1MEE3OjZBQzc4OTNCIiwidmlzaXRvcl9pZCI6IjMwODkwMzU4NDY1Mjg1MDIwNzUiLCJyZWdpb25fZWRnZSI6ImZyYSIsInJlZ2lvbl9yZW5kZXIiOiJmcmEifQ==" data-pjax-transient="true"/><meta name="visitor-hmac" content="be48d7a6a60489c96a1234d842dcfa0b747559742534f50cc7bdbd8907fdc0df" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:1159542259" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" data-turbo-transient>
  <link rel="assets" href="https://github.githubassets.com/">

    <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">

<meta name="octolytics-url" content="https://collector.github.com/github/collect" />





  <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="Fastest, smallest, and fully autonomous AI assistant infrastructure written in Zig - nullclaw/README.md at main · nullclaw/nullclaw">

      <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">

    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <meta property="fb:app_id" content="1401488693436528">
    <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/nullclaw/nullclaw/blob/main/README.md" />

      <meta name="twitter:image" content="https://opengraph.githubassets.com/825ecff44ab681b9ae11f51319588e3ddbfb705fcbe54c1abca37e242ee4b628/nullclaw/nullclaw" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="nullclaw/README.md at main · nullclaw/nullclaw" /><meta name="twitter:description" content="Fastest, smallest, and fully autonomous AI assistant infrastructure written in Zig - nullclaw/nullclaw" />
  <meta property="og:image" content="https://opengraph.githubassets.com/825ecff44ab681b9ae11f51319588e3ddbfb705fcbe54c1abca37e242ee4b628/nullclaw/nullclaw" /><meta property="og:image:alt" content="Fastest, smallest, and fully autonomous AI assistant infrastructure written in Zig - nullclaw/nullclaw" /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="nullclaw/README.md at main · nullclaw/nullclaw" /><meta property="og:url" content="https://github.com/nullclaw/nullclaw/blob/main/README.md" /><meta property="og:description" content="Fastest, smallest, and fully autonomous AI assistant infrastructure written in Zig - nullclaw/nullclaw" />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="5ae8b4ba8a4be23b638a948af46d4760710b9eeafaeef8ffd3a066a87f439cab" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="c4a65e47b0c850e1157ae8e66298070851d7e3b558038de5a3b4ff7a93e630ed" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="1ff3f1d4e1abd61f6f135b47d3b815e2f7169f8dd418f0118c6b1cf4de6cbc86" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="7c762ef82adaf98b9fbb02482b925ff53c4dd7b1778a6dffac62ffb579b37c39" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/nullclaw/nullclaw git https://github.com/nullclaw/nullclaw.git">

  <meta name="octolytics-dimension-user_id" content="262007611" /><meta name="octolytics-dimension-user_login" content="nullclaw" /><meta name="octolytics-dimension-repository_id" content="1159542259" /><meta name="octolytics-dimension-repository_nwo" content="nullclaw/nullclaw" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="1159542259" /><meta name="octolytics-dimension-repository_network_root_nwo" content="nullclaw/nullclaw" />
  



    

    <meta name="turbo-body-classes" content="logged-out env-production page-responsive">
  <meta name="disable-turbo" content="false">


  <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">


  <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

  <meta name="release" content="acf81f254b225f7dd3493ed02d8bd168abfffbf4" data-turbo-track="reload">
  <meta name="ui-target" content="full">

  <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
  <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
  <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">

<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />


  <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

  </head>

  <body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
    <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
      <div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
      

    <div class="position-relative header-wrapper js-header-wrapper ">
      <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>

      <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
    <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>      
      <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qc-1bbbe8787ea1cd4b.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-79183764d9db225c.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.3158a73a95382d59.module.css" />

<react-partial
  partial-name="keyboard-shortcuts-dialog"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>





      

          <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-install-banner-partial-46deaef4fa9abcf6.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-install-banner-partial.afb275bc17fddee0.module.css" />

<react-partial
  partial-name="app-install-banner-partial"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>


          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2l-e468179ba7123a2e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/rwd-069fc3d9814ff9fe.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz-e662bc3745e171e7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jag-3559ee48016881a2.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3d-7f22b36f29a9dd94.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tua-4998592d21eb16f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/8i-756d611a52e5f265.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-30705a8b2a0dea92.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.05b219cdb8e80c43.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/8i.779dd52a6bc5b0b6.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Fnullclaw%2Fnullclaw%2Fblob%2Fmain%2FREADME.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=nullclaw%2Fnullclaw","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/nullclaw/nullclaw/blob/main/README.md\",\"user_id\":null}}","auth_hydro_click_hmac":"12a3bb0c916e4cb19a6a6359ed84c91e684dcb3658f8e36f038e18a375879c74","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path></svg></a><div class="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fnullclaw%2Fnullclaw%2Fblob%2Fmain%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/nullclaw/nullclaw/blob/main/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="12a3bb0c916e4cb19a6a6359ed84c91e684dcb3658f8e36f038e18a375879c74"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path></svg>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg><span class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fnullclaw%2Fnullclaw%2Fblob%2Fmain%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/nullclaw/nullclaw/blob/main/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="12a3bb0c916e4cb19a6a6359ed84c91e684dcb3658f8e36f038e18a375879c74"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=nullclaw%2Fnullclaw" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/nullclaw/nullclaw/blob/main/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="12a3bb0c916e4cb19a6a6359ed84c91e684dcb3658f8e36f038e18a375879c74"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
  
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>

    <button id="icon-button-688f2322-a815-4441-9cd2-cbf67a5e1ca7" aria-labelledby="tooltip-4440bd02-4150-4a18-abe5-9e296de1d864" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-4440bd02-4150-4a18-abe5-9e296de1d864" for="icon-button-688f2322-a815-4441-9cd2-cbf67a5e1ca7" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>


  
</div>
    </div>

  <div id="start-of-content" class="show-on-focus"></div>








    <div id="js-flash-container" class="flash-container" data-turbo-replace>






  <template class="js-flash-template">
    
<div class="flash flash-full   {{ className }}">
  <div >
    <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    <div aria-atomic="true" role="alert" class="js-flash-alert">
      
      <div>{{ message }}</div>

    </div>
  </div>
</div>
  </template>
</div>


    






  <div
    class="application-main "
    data-commit-hovercards-enabled
    data-discussion-hovercards-enabled
    data-issue-and-pr-hovercards-enabled
    data-project-hovercards-enabled
  >
        <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
    <main id="js-repo-pjax-container" >
      
      
    


    








  

    <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ym-1a7ce813a378e1f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mn-bb458474353a279e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t5-26d19272bbf73ca3.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2d5-9abb2f6ba5c935d0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/24-b11e1c4108322883.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mrn-12afac2ecd2be980.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dgq-bbf7670f9cdba2e0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7w-740b4e942974ccba.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/we-c9f93392098ad6c9.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/775-5adcc74216a7c5ae.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bn-fcef0645a47703fc.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xgw-6c6cb7b2ed77f52e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ge-ca1c0ba8656f9680.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9f-e543bc691db8262e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/global-nav-bar-ac8546fca03a5b74.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-nav-bar.e9a3da281d459eec.module.css" />

<react-partial
  partial-name="global-nav-bar"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"contextRegion":{"crumbs":[{"crumb_type":"organization","label":"nullclaw","is_root":false,"href":"/nullclaw"},{"crumb_type":"repository","label":"nullclaw","is_root":false,"href":"/nullclaw/nullclaw"}],"localNavigation":[{"id":"code","icon":"code","label":"Code","href":"/nullclaw/nullclaw","selectedLinks":["repo_source","repo_downloads","repo_commits","repo_releases","repo_tags","repo_branches","repo_packages","repo_deployments","repo_attestations"],"popoverTarget":false,"commandId":"repositories:go-to-code","reactNav":{"appTarget":"code-view","anchor":"code-view-repo-link"},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"issues","icon":"issue-opened","label":"Issues","href":"/nullclaw/nullclaw/issues","selectedLinks":["repo_issues","repo_labels","repo_milestones"],"count":43,"popoverTarget":false,"commandId":"repositories:go-to-issues","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"pull-requests","icon":"git-pull-request","label":"Pull requests","href":"/nullclaw/nullclaw/pulls","selectedLinks":["repo_pulls","checks"],"count":27,"popoverTarget":false,"commandId":"repositories:go-to-pull-requests","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"discussions","icon":"comment-discussion","label":"Discussions","href":"/nullclaw/nullclaw/discussions","selectedLinks":["repo_discussions"],"popoverTarget":false,"commandId":"repositories:go-to-discussions","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"actions","icon":"play","label":"Actions","href":"/nullclaw/nullclaw/actions","selectedLinks":["repo_actions"],"popoverTarget":false,"commandId":"repositories:go-to-actions","reactNav":{"appTarget":"actions-workflows","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"projects","icon":"table","label":"Projects","href":"/nullclaw/nullclaw/projects","selectedLinks":["repo_projects","new_repo_project","repo_project"],"popoverTarget":false,"commandId":"repositories:go-to-projects","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"security-and-quality","icon":"shield","label":"Security and quality","href":"/nullclaw/nullclaw/security","selectedLinks":["security","overview","alerts","policy","token_scanning","code_scanning"],"count":0,"popoverTarget":false,"commandId":"repositories:go-to-security","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"insights","icon":"graph","label":"Insights","href":"/nullclaw/nullclaw/pulse","selectedLinks":["repo_graphs","repo_contributors","dependency_graph","dependabot_updates","pulse","people","community"],"popoverTarget":false,"commandId":"repositories:go-to-insights","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}}],"localNavigationUpdateChannel":null,"selectedLink":"repo_source"},"owner":null,"headerLogo":{"href":"/","aria-label":"Homepage "},"notifications":{"indicatorMode":"disabled","websocketChannel":null,"fetchIndicatorSrc":"/notifications/indicator","fetchIndicatorEnabled":false},"issues":{"href":"/issues"},"pulls":{"href":"/pulls"},"contributedRepos":{"href":"/repos"},"copilot":{"show":false,"showAgentsButton":false,"showRelaunchAnnouncement":false,"copilotChatUrl":null,"copilotApiUrl":"https://api.githubcopilot.com"},"search":{"show":true,"showCommandPalette":false,"isSearchPage":false,"isJumpToSearch":false,"searchContext":{"scope":"repo:nullclaw/nullclaw","current_repo_name":"nullclaw","current_repo_nwo":"nullclaw/nullclaw","current_repo_org":"nullclaw","user_id":"nullclaw"}},"commandPalette":null,"enterpriseBar":{"show":false},"globalTransactionalMessage":[],"payloadsUrl":"/_global-navigation/payloads.json?can_toggle_site_admin_and_employee_status=0\u0026is_admin_mode_on=0\u0026is_ui_opted_out=0\u0026show_ui_opt_out=0\u0026v=6","contextRegionUrl":"/_global-navigation/context-region.json"}}</script>
  <div data-target="react-partial.reactRoot"><header aria-label="Global navigation menu" data-component="Stack" class="GlobalNav styles-module__appHeader__YzYWk prc-Stack-Stack-UQ9k6" data-gap="none" data-direction="vertical" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="none"><div data-component="Stack" class="prc-Stack-Stack-UQ9k6" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="center" data-padding="none"><div data-testid="top-nav-center" data-component="Stack" class="styles-module__center__R3QRv styles-module__withLocalNavigation__rjTJ_ GlobalNavBar-module__loggedOut__Jv1rk prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="normal"><nav class="styles-module__contextRegion__VbSp2 prc-Breadcrumbs-BreadcrumbsBase-3Gb-B" aria-label="Breadcrumbs" data-overflow="menu" data-variant="normal" data-component="Breadcrumbs"><ol class="prc-Breadcrumbs-BreadcrumbsList-BKjpe"><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/nullclaw" data-discover="true"><span class="">nullclaw</span></a></li><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/nullclaw/nullclaw" data-discover="true"><span class="styles-module__contextCrumbLast__tI2e3">nullclaw</span></a></li></ol></nav></div><div data-testid="top-nav-right" data-component="Stack" class="styles-module__right__mlBQg styles-module__withLocalNavigation__rjTJ_ styles-module__rightWithResponsiveCreateButton__SKn2W prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="start" data-padding="normal"></div></div><h2 class="prc-src-InternalVisuallyHidden-2YaI6">Repository navigation</h2><nav class="prc-components-UnderlineWrapper-eT-Yj prc-UnderlineNav-UnderlineWrapper-GWONT LocalNavigation-module__LocalNavigation__b0Xc0" aria-label="Repository" data-variant="inset" data-overflow-mode="wrap" data-hide-icons-breakpoint="medium"><ul class="prc-UnderlineNav-ItemsList-oj8gN prc-components-UnderlineItemList-xKlKC" role="list"><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a aria-current="page" data-tab-item="code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg></span><span data-component="text" data-content="Code">Code</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="issues" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/issues" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg></span><span data-component="text" data-content="Issues">Issues</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">43</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->43<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="pull-requests" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/pulls" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-pull-request" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path></svg></span><span data-component="text" data-content="Pull requests">Pull requests</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">27</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->27<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="discussions" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/discussions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg></span><span data-component="text" data-content="Discussions">Discussions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="actions" data-react-nav="actions-workflows" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/actions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-play" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path></svg></span><span data-component="text" data-content="Actions">Actions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="projects" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/projects" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-table" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path></svg></span><span data-component="text" data-content="Projects">Projects</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="security-and-quality" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/security" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg></span><span data-component="text" data-content="Security and quality">Security and quality</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="insights" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/nullclaw/nullclaw/pulse" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-graph" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg></span><span data-component="text" data-content="Insights">Insights</span></a></li></ul><div class="prc-UnderlineNav-MoreButtonContainer-Dnrq6"><div class="prc-UnderlineNav-MoreButtonDivider-dN0a-"></div><button data-component="overflow-menu-button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk prc-UnderlineNav-MoreButton-Y8soj" data-loading="false" data-size="medium" data-variant="invisible" id="_R_2ktl_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3"><span>More<span class="prc-src-InternalVisuallyHidden-2YaI6"> items</span></span></span></span><span data-component="trailingAction" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></button></div></nav><div class="d-none"></div></header></div>
</react-partial>


  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/nullclaw/nullclaw/blob/main/README.md"
  style="display: block; min-height: calc(100vh - 64px);"
  data-attempted-ssr="true"
  data-ssr="true"
  data-lazy="false"
  data-alternate="false"
  data-data-router-enabled="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":"NullClaw","anchor":"nullclaw","htmlText":"NullClaw"},{"level":3,"text":"Features","anchor":"features","htmlText":"Features"},{"level":3,"text":"Why nullclaw","anchor":"why-nullclaw","htmlText":"Why nullclaw"},{"level":2,"text":"Benchmark Snapshot","anchor":"benchmark-snapshot","htmlText":"Benchmark Snapshot"},{"level":2,"text":"Documentation","anchor":"documentation","htmlText":"Documentation"},{"level":2,"text":"Choose Your Path","anchor":"choose-your-path","htmlText":"Choose Your Path"},{"level":2,"text":"After This README","anchor":"after-this-readme","htmlText":"After This README"},{"level":2,"text":"Quick Start","anchor":"quick-start","htmlText":"Quick Start"},{"level":3,"text":"1) Recommended install (Homebrew)","anchor":"1-recommended-install-homebrew","htmlText":"1) Recommended install (Homebrew)"},{"level":3,"text":"2) Build from source","anchor":"2-build-from-source","htmlText":"2) Build from source"},{"level":3,"text":"3) Run with Docker Compose","anchor":"3-run-with-docker-compose","htmlText":"3) Run with Docker Compose"},{"level":3,"text":"4) Common commands","anchor":"4-common-commands","htmlText":"4) Common commands"},{"level":2,"text":"Edge MVP (Hybrid Host + WASM Logic)","anchor":"edge-mvp-hybrid-host--wasm-logic","htmlText":"Edge MVP (Hybrid Host + WASM Logic)"},{"level":2,"text":"Architecture","anchor":"architecture","htmlText":"Architecture"},{"level":3,"text":"Memory System","anchor":"memory-system","htmlText":"Memory System"},{"level":2,"text":"Security","anchor":"security","htmlText":"Security"},{"level":3,"text":"Channel Allowlists","anchor":"channel-allowlists","htmlText":"Channel Allowlists"},{"level":3,"text":"Nostr Channel Setup","anchor":"nostr-channel-setup","htmlText":"Nostr Channel Setup"},{"level":2,"text":"Configuration","anchor":"configuration","htmlText":"Configuration"},{"level":3,"text":"Full Web Search + Shell Access","anchor":"full-web-search--shell-access","htmlText":"Full Web Search + Shell Access"},{"level":3,"text":"Web UI / Browser Relay","anchor":"web-ui--browser-relay","htmlText":"Web UI / Browser Relay"},{"level":2,"text":"Gateway API","anchor":"gateway-api","htmlText":"Gateway API"},{"level":3,"text":"A2A (Agent-to-Agent Protocol v0.3.0)","anchor":"a2a-agent-to-agent-protocol-v030","htmlText":"A2A (Agent-to-Agent Protocol v0.3.0)"},{"level":3,"text":"Media transcription","anchor":"media-transcription","htmlText":"Media transcription"},{"level":2,"text":"Commands","anchor":"commands","htmlText":"Commands"},{"level":2,"text":"Development","anchor":"development","htmlText":"Development"},{"level":3,"text":"Channel Flow Coverage","anchor":"channel-flow-coverage","htmlText":"Channel Flow Coverage"},{"level":3,"text":"Project Stats","anchor":"project-stats","htmlText":"Project Stats"},{"level":3,"text":"Source Layout","anchor":"source-layout","htmlText":"Source Layout"},{"level":2,"text":"Versioning","anchor":"versioning","htmlText":"Versioning"},{"level":2,"text":"Contributing","anchor":"contributing","htmlText":"Contributing"},{"level":2,"text":"Chinese Docs (中文文档)","anchor":"chinese-docs-中文文档","htmlText":"Chinese Docs (中文文档)"},{"level":2,"text":"English Docs","anchor":"english-docs","htmlText":"English Docs"},{"level":2,"text":"Disclaimer","anchor":"disclaimer","htmlText":"Disclaimer"},{"level":2,"text":"License","anchor":"license","htmlText":"License"},{"level":2,"text":"Star History","anchor":"star-history","htmlText":"Star History"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cp dir=\"auto\"\u003eWant a simpler way to install and configure nullclaw with a UI? Try \u003ca href=\"https://github.com/nullclaw/nullhub\"\u003enullhub\u003c/a\u003e! (currently in beta)\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://github.com/nullclaw/nullhub\"\u003enullhub\u003c/a\u003e provides a UI layer for the Null ecosystem: simpler nullclaw setup and configuration, orchestration from \u003ca href=\"https://github.com/nullclaw/nullboiler\"\u003enullboiler\u003c/a\u003e, observability from \u003ca href=\"https://github.com/nullclaw/nullwatch\"\u003enullwatch\u003c/a\u003e, and task tracking from \u003ca href=\"https://github.com/nullclaw/nulltickets\"\u003enulltickets\u003c/a\u003e.\u003c/p\u003e\n\u003cp align=\"center\" dir=\"auto\"\u003e\n  \u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"/nullclaw/nullclaw/blob/main/nullclaw.png\"\u003e\u003cimg src=\"/nullclaw/nullclaw/raw/main/nullclaw.png\" alt=\"nullclaw\" width=\"200\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 align=\"center\" tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eNullClaw\u003c/h1\u003e\u003ca id=\"user-content-nullclaw\" class=\"anchor\" aria-label=\"Permalink: NullClaw\" href=\"#nullclaw\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp align=\"center\" dir=\"auto\"\u003e\n  \u003cstrong\u003eNull overhead. Null compromise. 100% Zig. 100% Agnostic.\u003c/strong\u003e\u003cbr\u003e\n  \u003cstrong\u003e678 KB binary. ~1 MB RAM. Boots in \u0026lt;2 ms. Runs on anything with a CPU.\u003c/strong\u003e\n\u003c/p\u003e\n\u003cp align=\"center\" dir=\"auto\"\u003e\n  \u003ca href=\"https://github.com/nullclaw/nullclaw/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/nullclaw/nullclaw/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/nullclaw/nullclaw/actions/workflows/nightly.yml\"\u003e\u003cimg src=\"https://github.com/nullclaw/nullclaw/actions/workflows/nightly.yml/badge.svg\" alt=\"Nightly\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://nullclaw.github.io\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/f6832e8695458d93bbf0f66febf111280effe2360a444fdc3427d187fb02432b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d6e756c6c636c61772e6769746875622e696f2d696e666f726d6174696f6e616c\" alt=\"Documentation\" data-canonical-src=\"https://img.shields.io/badge/docs-nullclaw.github.io-informational\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://discord.gg/Bfmdua22Ud\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/4514aff09ec21d0816fed58175d5505c84ee249249a3b5c669a42fa5ed43654d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646973636f72642d6a6f696e253230636f6d6d756e6974792d3538363546323f6c6f676f3d646973636f7264266c6f676f436f6c6f723d7768697465\" alt=\"Discord\" data-canonical-src=\"https://img.shields.io/badge/discord-join%20community-5865F2?logo=discord\u0026amp;logoColor=white\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"/nullclaw/nullclaw/blob/main/LICENSE\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667\" alt=\"License: MIT\" data-canonical-src=\"https://img.shields.io/badge/license-MIT-blue.svg\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe smallest fully autonomous AI assistant infrastructure — a static Zig binary that fits on any $5 board, boots in milliseconds, and requires nothing but libc.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDocs: \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/README.md\"\u003eEnglish\u003c/a\u003e · \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/README.md\"\u003e中文\u003c/a\u003e · \u003ca href=\"/nullclaw/nullclaw/blob/main/CONTRIBUTING.md\"\u003eContributing\u003c/a\u003e · \u003ca href=\"https://discord.gg/Bfmdua22Ud\" rel=\"nofollow\"\u003eDiscord\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"678 KB binary · \u0026lt;2 ms startup · 5,300+ tests · 50+ providers · 19 channels · Pluggable everything\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e678 KB binary · \u0026lt;2 ms startup · 5,300+ tests · 50+ providers · 19 channels · Pluggable everything\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFeatures\u003c/h3\u003e\u003ca id=\"user-content-features\" class=\"anchor\" aria-label=\"Permalink: Features\" href=\"#features\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eImpossibly Small:\u003c/strong\u003e 678 KB static binary — no runtime, no VM, no framework overhead.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNear-Zero Memory:\u003c/strong\u003e ~1 MB peak RSS. Runs comfortably on the cheapest ARM SBCs and microcontrollers.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eInstant Startup:\u003c/strong\u003e \u0026lt;2 ms on Apple Silicon, \u0026lt;8 ms on a 0.8 GHz edge core.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eTrue Portability:\u003c/strong\u003e Single self-contained binary across ARM, x86, and RISC-V. Drop it anywhere, it just runs.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFeature-Complete:\u003c/strong\u003e 50+ providers, 19 channels, 35+ tools, 10 memory engines, multi-layer sandbox, tunnels, hardware peripherals, MCP, subagents, streaming, voice — the full stack.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhy nullclaw\u003c/h3\u003e\u003ca id=\"user-content-why-nullclaw\" class=\"anchor\" aria-label=\"Permalink: Why nullclaw\" href=\"#why-nullclaw\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eLean by default:\u003c/strong\u003e Zig compiles to a tiny static binary. No allocator overhead, no garbage collector, no runtime.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSecure by design:\u003c/strong\u003e pairing, strict sandboxing (landlock, firejail, bubblewrap, docker), explicit allowlists, workspace scoping, encrypted secrets.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFully swappable:\u003c/strong\u003e core systems are vtable interfaces (providers, channels, tools, memory, tunnels, peripherals, observers, runtimes).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNo lock-in:\u003c/strong\u003e OpenAI-compatible provider support + pluggable custom endpoints.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBenchmark Snapshot\u003c/h2\u003e\u003ca id=\"user-content-benchmark-snapshot\" class=\"anchor\" aria-label=\"Permalink: Benchmark Snapshot\" href=\"#benchmark-snapshot\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eLocal machine benchmark (macOS arm64, Feb 2026), normalized for 0.8 GHz edge hardware.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e\u003c/th\u003e\n\u003cth\u003e\u003ca href=\"https://github.com/openclaw/openclaw\"\u003eOpenClaw\u003c/a\u003e\u003c/th\u003e\n\u003cth\u003e\u003ca href=\"https://github.com/HKUDS/nanobot\"\u003eNanoBot\u003c/a\u003e\u003c/th\u003e\n\u003cth\u003e\u003ca href=\"https://github.com/sipeed/picoclaw\"\u003ePicoClaw\u003c/a\u003e\u003c/th\u003e\n\u003cth\u003e\u003ca href=\"https://github.com/zeroclaw-labs/zeroclaw\"\u003eZeroClaw\u003c/a\u003e\u003c/th\u003e\n\u003cth\u003e\u003cstrong\u003e\u003ca href=\"https://github.com/nullclaw/nullclaw\"\u003e🦞 NullClaw\u003c/a\u003e\u003c/strong\u003e\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eLanguage\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eTypeScript\u003c/td\u003e\n\u003ctd\u003ePython\u003c/td\u003e\n\u003ctd\u003eGo\u003c/td\u003e\n\u003ctd\u003eRust\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eZig\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eRAM\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u0026gt; 1 GB\u003c/td\u003e\n\u003ctd\u003e\u0026gt; 100 MB\u003c/td\u003e\n\u003ctd\u003e\u0026lt; 10 MB\u003c/td\u003e\n\u003ctd\u003e\u0026lt; 5 MB\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003e~1 MB\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eStartup (0.8 GHz)\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u0026gt; 500 s\u003c/td\u003e\n\u003ctd\u003e\u0026gt; 30 s\u003c/td\u003e\n\u003ctd\u003e\u0026lt; 1 s\u003c/td\u003e\n\u003ctd\u003e\u0026lt; 10 ms\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003e\u0026lt; 8 ms\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eBinary Size\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e~28 MB (dist)\u003c/td\u003e\n\u003ctd\u003eN/A (Scripts)\u003c/td\u003e\n\u003ctd\u003e~8 MB\u003c/td\u003e\n\u003ctd\u003e~8.8 MB\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003e678 KB\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTests\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003ctd\u003e1,017\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003e5,300+\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSource Files\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e~400+\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003ctd\u003e~120\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003e~230\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eCost\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eMac Mini $599\u003c/td\u003e\n\u003ctd\u003eLinux SBC ~$50\u003c/td\u003e\n\u003ctd\u003eLinux Board $10\u003c/td\u003e\n\u003ctd\u003eAny $10 hardware\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eAny $5 hardware\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eMeasured with \u003ccode\u003e/usr/bin/time -l\u003c/code\u003e on ReleaseSmall builds. nullclaw is a static binary with zero runtime dependencies.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eReproduce locally:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"zig build -Doptimize=ReleaseSmall\nls -lh zig-out/bin/nullclaw\n\n/usr/bin/time -l zig-out/bin/nullclaw --help\n/usr/bin/time -l zig-out/bin/nullclaw status\"\u003e\u003cpre\u003ezig build -Doptimize=ReleaseSmall\nls -lh zig-out/bin/nullclaw\n\n/usr/bin/time -l zig-out/bin/nullclaw --help\n/usr/bin/time -l zig-out/bin/nullclaw status\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDocumentation\u003c/h2\u003e\u003ca id=\"user-content-documentation\" class=\"anchor\" aria-label=\"Permalink: Documentation\" href=\"#documentation\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eStart here if you want the shortest path to install, configure, operate, or extend nullclaw.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLocalized documentation lives under \u003ccode\u003edocs/en/\u003c/code\u003e and \u003ccode\u003edocs/zh/\u003c/code\u003e. Use the links below to jump straight to the page you need.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eNeed\u003c/th\u003e\n\u003cth\u003eEnglish\u003c/th\u003e\n\u003cth\u003e中文\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eStart here\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/README.md\"\u003e\u003ccode\u003edocs/en/README.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/README.md\"\u003e\u003ccode\u003edocs/zh/README.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eInstall\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/installation.md\"\u003e\u003ccode\u003edocs/en/installation.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/installation.md\"\u003e\u003ccode\u003edocs/zh/installation.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eInstall Zig\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/zig-installation.md\"\u003e\u003ccode\u003edocs/en/zig-installation.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/zig-installation.md\"\u003e\u003ccode\u003edocs/zh/zig-installation.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eConfigure\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/configuration.md\"\u003e\u003ccode\u003edocs/en/configuration.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/configuration.md\"\u003e\u003ccode\u003edocs/zh/configuration.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eCommands\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/commands.md\"\u003e\u003ccode\u003edocs/en/commands.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/commands.md\"\u003e\u003ccode\u003edocs/zh/commands.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDevelopment\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/development.md\"\u003e\u003ccode\u003edocs/en/development.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/development.md\"\u003e\u003ccode\u003edocs/zh/development.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eOperations\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/usage.md\"\u003e\u003ccode\u003edocs/en/usage.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/usage.md\"\u003e\u003ccode\u003edocs/zh/usage.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eArchitecture\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/architecture.md\"\u003e\u003ccode\u003edocs/en/architecture.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/architecture.md\"\u003e\u003ccode\u003edocs/zh/architecture.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSecurity\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/security.md\"\u003e\u003ccode\u003edocs/en/security.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/security.md\"\u003e\u003ccode\u003edocs/zh/security.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eGateway API\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/gateway-api.md\"\u003e\u003ccode\u003edocs/en/gateway-api.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/gateway-api.md\"\u003e\u003ccode\u003edocs/zh/gateway-api.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eSpecialized guides: \u003ca href=\"/nullclaw/nullclaw/blob/main/CONTRIBUTING.md\"\u003e\u003ccode\u003eCONTRIBUTING.md\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"/nullclaw/nullclaw/blob/main/SECURITY.md\"\u003e\u003ccode\u003eSECURITY.md\u003c/code\u003e\u003c/a\u003e, \u003ca href=\"/nullclaw/nullclaw/blob/main/SIGNAL.md\"\u003e\u003ccode\u003eSIGNAL.md\u003c/code\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChoose Your Path\u003c/h2\u003e\u003ca id=\"user-content-choose-your-path\" class=\"anchor\" aria-label=\"Permalink: Choose Your Path\" href=\"#choose-your-path\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eGoal\u003c/th\u003e\n\u003cth\u003eOpen this first\u003c/th\u003e\n\u003cth\u003eThen go to\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eFirst run in English\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/README.md\"\u003e\u003ccode\u003edocs/en/README.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/installation.md\"\u003e\u003ccode\u003edocs/en/installation.md\u003c/code\u003e\u003c/a\u003e → \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/configuration.md\"\u003e\u003ccode\u003edocs/en/configuration.md\u003c/code\u003e\u003c/a\u003e → \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/usage.md\"\u003e\u003ccode\u003edocs/en/usage.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eChinese Quick Start (中文快速上手)\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/README.md\"\u003e\u003ccode\u003edocs/zh/README.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/installation.md\"\u003e\u003ccode\u003edocs/zh/installation.md\u003c/code\u003e\u003c/a\u003e → \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/configuration.md\"\u003e\u003ccode\u003edocs/zh/configuration.md\u003c/code\u003e\u003c/a\u003e → \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/usage.md\"\u003e\u003ccode\u003edocs/zh/usage.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eFind the right CLI command\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/commands.md\"\u003e\u003ccode\u003edocs/en/commands.md\u003c/code\u003e\u003c/a\u003e / \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/commands.md\"\u003e\u003ccode\u003edocs/zh/commands.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003enullclaw help\u003c/code\u003e → task-specific subcommand page\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eContribute code or docs\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/CONTRIBUTING.md\"\u003e\u003ccode\u003eCONTRIBUTING.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/development.md\"\u003e\u003ccode\u003edocs/en/development.md\u003c/code\u003e\u003c/a\u003e / \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/development.md\"\u003e\u003ccode\u003edocs/zh/development.md\u003c/code\u003e\u003c/a\u003e → relevant architecture page\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eOperate or secure a deployment\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/usage.md\"\u003e\u003ccode\u003edocs/en/usage.md\u003c/code\u003e\u003c/a\u003e / \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/usage.md\"\u003e\u003ccode\u003edocs/zh/usage.md\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/security.md\"\u003e\u003ccode\u003edocs/en/security.md\u003c/code\u003e\u003c/a\u003e / \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/security.md\"\u003e\u003ccode\u003edocs/zh/security.md\u003c/code\u003e\u003c/a\u003e → Gateway API\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAfter This README\u003c/h2\u003e\u003ca id=\"user-content-after-this-readme\" class=\"anchor\" aria-label=\"Permalink: After This README\" href=\"#after-this-readme\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNew here: jump to \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/README.md\"\u003e\u003ccode\u003edocs/en/README.md\u003c/code\u003e\u003c/a\u003e or \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/README.md\"\u003e\u003ccode\u003edocs/zh/README.md\u003c/code\u003e\u003c/a\u003e and follow the guided reading order.\u003c/li\u003e\n\u003cli\u003eWant commands fast: open \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/commands.md\"\u003e\u003ccode\u003edocs/en/commands.md\u003c/code\u003e\u003c/a\u003e or \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/commands.md\"\u003e\u003ccode\u003edocs/zh/commands.md\u003c/code\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eWant to submit a PR: start with \u003ca href=\"/nullclaw/nullclaw/blob/main/CONTRIBUTING.md\"\u003e\u003ccode\u003eCONTRIBUTING.md\u003c/code\u003e\u003c/a\u003e, then read \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/development.md\"\u003e\u003ccode\u003edocs/en/development.md\u003c/code\u003e\u003c/a\u003e or \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/development.md\"\u003e\u003ccode\u003edocs/zh/development.md\u003c/code\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eQuick Start\u003c/h2\u003e\u003ca id=\"user-content-quick-start\" class=\"anchor\" aria-label=\"Permalink: Quick Start\" href=\"#quick-start\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e1) Recommended install (Homebrew)\u003c/h3\u003e\u003ca id=\"user-content-1-recommended-install-homebrew\" class=\"anchor\" aria-label=\"Permalink: 1) Recommended install (Homebrew)\" href=\"#1-recommended-install-homebrew\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe simplest path: install a ready-to-run binary with no extra runtime dependencies.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"brew install nullclaw\nnullclaw --help\"\u003e\u003cpre\u003ebrew install nullclaw\nnullclaw --help\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e2) Build from source\u003c/h3\u003e\u003ca id=\"user-content-2-build-from-source\" class=\"anchor\" aria-label=\"Permalink: 2) Build from source\" href=\"#2-build-from-source\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePrerequisite:\u003c/strong\u003e use \u003cstrong\u003eZig 0.16.0\u003c/strong\u003e (exact version).\nOther Zig versions are currently unsupported and may fail to build.\nVerify before building: \u003ccode\u003ezig version\u003c/code\u003e should print \u003ccode\u003e0.16.0\u003c/code\u003e.\nDebian users who need Zig first can follow \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/zig-installation.md\"\u003e\u003ccode\u003edocs/en/zig-installation.md\u003c/code\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"git clone https://github.com/nullclaw/nullclaw.git\ncd nullclaw\nzig build -Doptimize=ReleaseSmall\nzig build test --summary all\"\u003e\u003cpre\u003egit clone https://github.com/nullclaw/nullclaw.git\n\u003cspan class=\"pl-c1\"\u003ecd\u003c/span\u003e nullclaw\nzig build -Doptimize=ReleaseSmall\nzig build \u003cspan class=\"pl-c1\"\u003etest\u003c/span\u003e --summary all\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMake \u003ccode\u003enullclaw\u003c/code\u003e available on \u003ccode\u003ePATH\u003c/code\u003e:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003emacOS/Linux (zsh/bash):\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"zig build -Doptimize=ReleaseSmall -p \u0026quot;$HOME/.local\u0026quot;\necho 'export PATH=\u0026quot;$HOME/.local/bin:$PATH\u0026quot;' \u0026gt;\u0026gt; ~/.zshrc\n# or ~/.bashrc\"\u003e\u003cpre\u003ezig build -Doptimize=ReleaseSmall -p \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$HOME\u003c/span\u003e/.local\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c1\"\u003eecho\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003eexport PATH=\"$HOME/.local/bin:$PATH\"\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e~\u003c/span\u003e/.zshrc\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e or ~/.bashrc\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWindows (PowerShell):\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-powershell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"zig build -Doptimize=ReleaseSmall -p \u0026quot;$HOME\\.local\u0026quot;\n\n$bin = \u0026quot;$HOME\\.local\\bin\u0026quot;\n$user_path = [Environment]::GetEnvironmentVariable(\u0026quot;Path\u0026quot;, \u0026quot;User\u0026quot;)\nif (-not ($user_path -split \u0026quot;;\u0026quot; | Where-Object { $_ -eq $bin })) {\n  [Environment]::SetEnvironmentVariable(\u0026quot;Path\u0026quot;, \u0026quot;$user_path;$bin\u0026quot;, \u0026quot;User\u0026quot;)\n}\n$env:Path = \u0026quot;$env:Path;$bin\u0026quot;\"\u003e\u003cpre\u003ezig build \u003cspan class=\"pl-k\"\u003e-\u003c/span\u003eDoptimize\u003cspan class=\"pl-k\"\u003e=\u003c/span\u003eReleaseSmall \u003cspan class=\"pl-k\"\u003e-\u003c/span\u003ep \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e$HOME\u003c/span\u003e\\.local\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003e$bin\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e$HOME\u003c/span\u003e\\.local\\bin\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003e$user_path\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e [\u003cspan class=\"pl-k\"\u003eEnvironment\u003c/span\u003e]::GetEnvironmentVariable(\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ePath\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"pl-k\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eUser\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e)\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-k\"\u003e-not\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003e$user_path\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-split\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e;\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eWhere-Object\u003c/span\u003e { \u003cspan class=\"pl-c1\"\u003e$_\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-eq\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003e$bin\u003c/span\u003e })) {\n  [\u003cspan class=\"pl-k\"\u003eEnvironment\u003c/span\u003e]::SetEnvironmentVariable(\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ePath\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"pl-k\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$user_path\u003c/span\u003e;\u003cspan class=\"pl-smi\"\u003e$bin\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"pl-k\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eUser\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e)\n}\n\u003cspan class=\"pl-smi\"\u003e$\u003cspan class=\"pl-c1\"\u003eenv:\u003c/span\u003ePath\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003e$\u003cspan class=\"pl-c1\"\u003eenv:\u003c/span\u003ePath\u003c/span\u003e;\u003cspan class=\"pl-smi\"\u003e$bin\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThen:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"nullclaw --help\"\u003e\u003cpre\u003enullclaw --help\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e3) Run with Docker Compose\u003c/h3\u003e\u003ca id=\"user-content-3-run-with-docker-compose\" class=\"anchor\" aria-label=\"Permalink: 3) Run with Docker Compose\" href=\"#3-run-with-docker-compose\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe repository includes a Makefile wrapper around Docker Compose for local\ncontainerized runs.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"make build\nmake config\nmake up\"\u003e\u003cpre\u003emake build\nmake config\nmake up\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003emake config\u003c/code\u003e runs \u003ccode\u003enullclaw onboard --interactive\u003c/code\u003e inside the agent container.\nPass only non-secret flags through \u003ccode\u003eCONFIG_ARGS\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"make config CONFIG_ARGS=\u0026quot;--provider openrouter\u0026quot;\"\u003e\u003cpre\u003emake config CONFIG_ARGS=\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e--provider openrouter\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAvoid putting API keys or bot tokens in \u003ccode\u003eCONFIG_ARGS\u003c/code\u003e; command-line arguments\ncan be exposed through shell history and process listings.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe compose gateway defaults to \u003ccode\u003eNULLCLAW_PORT=3210\u003c/code\u003e, binds inside the\ncontainer on \u003ccode\u003e0.0.0.0\u003c/code\u003e, and publishes to localhost on the host:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"curl http://127.0.0.1:3210/health\"\u003e\u003cpre\u003ecurl http://127.0.0.1:3210/health\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOverride the port or host bind address when needed:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"make up NULLCLAW_PORT=8080\nmake up NULLCLAW_BIND=0.0.0.0\"\u003e\u003cpre\u003emake up NULLCLAW_PORT=8080\nmake up NULLCLAW_BIND=0.0.0.0\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOperational shortcuts:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"make logs\nmake down\nmake shell\"\u003e\u003cpre\u003emake logs\nmake down\nmake shell\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOnly set \u003ccode\u003eNULLCLAW_BIND=0.0.0.0\u003c/code\u003e on trusted networks with pairing, webhook\nsecrets, allowlists, and host firewall rules configured.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e4) Common commands\u003c/h3\u003e\u003ca id=\"user-content-4-common-commands\" class=\"anchor\" aria-label=\"Permalink: 4) Common commands\" href=\"#4-common-commands\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\n# Quick setup\nnullclaw onboard --api-key sk-... --provider openrouter\n\n# Or interactive wizard\nnullclaw onboard --interactive\n\n# Chat\nnullclaw agent -m \u0026quot;Hello, nullclaw!\u0026quot;\n\n# Interactive mode\nnullclaw agent\n\n# Start gateway runtime (gateway + all configured channels/accounts + heartbeat + scheduler)\nnullclaw gateway                # default: 127.0.0.1:3000\nnullclaw gateway --port 8080    # custom port\n\n# Check status\nnullclaw status\n\n# Run system diagnostics\nnullclaw doctor\n\n# Check channel health\nnullclaw channel status\n\n# Start specific channels\nnullclaw channel start telegram\nnullclaw channel start discord\nnullclaw channel start signal\n\n# Manage background service\n# Linux supports systemd user services and OpenRC\nnullclaw service install\nnullclaw service status\n\n# Optional secret injection hook for service mode:\n# if ~/.nullclaw/service-env is executable, the installed service launcher runs it\n# before starting `nullclaw gateway` (for example via dotenvx or sops)\n\n# Migrate memory from OpenClaw\nnullclaw migrate openclaw --dry-run\nnullclaw migrate openclaw\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Quick setup\u003c/span\u003e\nnullclaw onboard --api-key sk-... --provider openrouter\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Or interactive wizard\u003c/span\u003e\nnullclaw onboard --interactive\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Chat\u003c/span\u003e\nnullclaw agent -m \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eHello, nullclaw!\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Interactive mode\u003c/span\u003e\nnullclaw agent\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Start gateway runtime (gateway + all configured channels/accounts + heartbeat + scheduler)\u003c/span\u003e\nnullclaw gateway                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e default: 127.0.0.1:3000\u003c/span\u003e\nnullclaw gateway --port 8080    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e custom port\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Check status\u003c/span\u003e\nnullclaw status\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Run system diagnostics\u003c/span\u003e\nnullclaw doctor\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Check channel health\u003c/span\u003e\nnullclaw channel status\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Start specific channels\u003c/span\u003e\nnullclaw channel start telegram\nnullclaw channel start discord\nnullclaw channel start signal\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Manage background service\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Linux supports systemd user services and OpenRC\u003c/span\u003e\nnullclaw service install\nnullclaw service status\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Optional secret injection hook for service mode:\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e if ~/.nullclaw/service-env is executable, the installed service launcher runs it\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e before starting `nullclaw gateway` (for example via dotenvx or sops)\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Migrate memory from OpenClaw\u003c/span\u003e\nnullclaw migrate openclaw --dry-run\nnullclaw migrate openclaw\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eEdge MVP (Hybrid Host + WASM Logic)\u003c/h2\u003e\u003ca id=\"user-content-edge-mvp-hybrid-host--wasm-logic\" class=\"anchor\" aria-label=\"Permalink: Edge MVP (Hybrid Host + WASM Logic)\" href=\"#edge-mvp-hybrid-host--wasm-logic\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you want edge deployment (Cloudflare Worker) with Telegram + OpenAI while keeping agent policy in WASM, see:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003eexamples/edge/cloudflare-worker/\u003c/code\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis pattern keeps networking/secrets in the edge host and lets you swap/update logic by replacing a tiny Zig WASM module.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eArchitecture\u003c/h2\u003e\u003ca id=\"user-content-architecture\" class=\"anchor\" aria-label=\"Permalink: Architecture\" href=\"#architecture\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eEvery subsystem is a \u003cstrong\u003evtable interface\u003c/strong\u003e — swap implementations with a config change, zero code changes.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSubsystem\u003c/th\u003e\n\u003cth\u003eInterface\u003c/th\u003e\n\u003cth\u003eShips with\u003c/th\u003e\n\u003cth\u003eExtend\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eAI Models\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eProvider\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e50+ providers (OpenRouter, Anthropic, OpenAI, Azure OpenAI, Gemini, Vertex AI, Ollama, Venice, NEAR AI Cloud, Atlas Cloud, Evolink, Eden AI, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, and many OpenAI-compatible endpoints)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ecustom:https://your-api.com\u003c/code\u003e — any OpenAI-compatible API\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eChannels\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eChannel\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCLI, Telegram, Signal, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook, IRC, Lark/Feishu, OneBot, Line, DingTalk, Email, Nostr, QQ, MaixCam, Mattermost\u003c/td\u003e\n\u003ctd\u003eAny messaging API\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eMemory\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eMemory\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSQLite with hybrid search (FTS5 + vector cosine similarity), Markdown, ClickHouse, PostgreSQL, Redis, LanceDB, Lucid, LRU, API\u003c/td\u003e\n\u003ctd\u003eAny persistence backend\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTools\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTool\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eshell, file_read, file_write, file_edit, file_edit_hashed, file_read_hashed, file_append, memory_store, memory_recall, memory_forget, memory_list, browser_open, screenshot, composio, http_request, web_fetch, web_search, delegate, schedule, hardware_info, hardware_memory, pushover, message, spawn, git, image, i2c, spi, and more\u003c/td\u003e\n\u003ctd\u003eAny capability\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eObservability\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eObserver\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNoop, Log, File, Multi\u003c/td\u003e\n\u003ctd\u003ePrometheus, OTel\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eRuntime\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eRuntimeAdapter\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNative, Docker (sandboxed), WASM (wasmtime)\u003c/td\u003e\n\u003ctd\u003eAny runtime\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSecurity\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eSandbox\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eLandlock, Firejail, Bubblewrap, Docker, auto-detect\u003c/td\u003e\n\u003ctd\u003eAny sandbox backend\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eIdentity\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eIdentityConfig\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOpenClaw (markdown), AIEOS v1.1 (JSON)\u003c/td\u003e\n\u003ctd\u003eAny identity format\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eTunnel\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTunnel\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNone, Cloudflare, Tailscale, ngrok, Custom\u003c/td\u003e\n\u003ctd\u003eAny tunnel binary\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eHeartbeat\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eEngine\u003c/td\u003e\n\u003ctd\u003eHEARTBEAT.md periodic tasks\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSkills\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eLoader\u003c/td\u003e\n\u003ctd\u003eTOML/JSON manifests or YAML frontmatter in \u003ccode\u003eSKILL.md\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCommunity skill packs\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003ePeripherals\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ePeripheral\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSerial, Arduino, Raspberry Pi GPIO, STM32/Nucleo\u003c/td\u003e\n\u003ctd\u003eAny hardware interface\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eCron\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eScheduler\u003c/td\u003e\n\u003ctd\u003eCron expressions + one-shot timers with JSON persistence\u003c/td\u003e\n\u003ctd\u003e—\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMemory System\u003c/h3\u003e\u003ca id=\"user-content-memory-system\" class=\"anchor\" aria-label=\"Permalink: Memory System\" href=\"#memory-system\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll custom, zero external dependencies for the core path:\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eLayer\u003c/th\u003e\n\u003cth\u003eImplementation\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eVector DB\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eEmbeddings stored as BLOB in SQLite, cosine similarity search\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eKeyword Search\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eFTS5 virtual tables with BM25 scoring\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eHybrid Merge\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eWeighted merge (configurable vector/keyword weights)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eEmbeddings\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eEmbeddingProvider\u003c/code\u003e vtable — OpenAI, custom URL, or noop\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eHygiene\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eAutomatic archival + purge of stale memories\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSnapshots\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eExport/import full memory state for migration\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eEngines\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eSQLite (default), Markdown, ClickHouse, PostgreSQL, Redis, LanceDB, Lucid, LRU, API, None\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;memory\u0026quot;: {\n    \u0026quot;backend\u0026quot;: \u0026quot;sqlite\u0026quot;,\n    \u0026quot;auto_save\u0026quot;: true,\n    \u0026quot;embedding_provider\u0026quot;: \u0026quot;openai\u0026quot;,\n    \u0026quot;vector_weight\u0026quot;: 0.7,\n    \u0026quot;keyword_weight\u0026quot;: 0.3,\n    \u0026quot;hygiene_enabled\u0026quot;: true,\n    \u0026quot;snapshot_enabled\u0026quot;: false\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"memory\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"backend\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esqlite\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"auto_save\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"embedding_provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eopenai\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"vector_weight\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e0.7\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"keyword_weight\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e0.3\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"hygiene_enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"snapshot_enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSecurity\u003c/h2\u003e\u003ca id=\"user-content-security\" class=\"anchor\" aria-label=\"Permalink: Security\" href=\"#security\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003enullclaw enforces security at \u003cstrong\u003eevery layer\u003c/strong\u003e.\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e#\u003c/th\u003e\n\u003cth\u003eItem\u003c/th\u003e\n\u003cth\u003eStatus\u003c/th\u003e\n\u003cth\u003eHow\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e1\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eGateway not publicly exposed\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003eBinds \u003ccode\u003e127.0.0.1\u003c/code\u003e by default. Refuses \u003ccode\u003e0.0.0.0\u003c/code\u003e without tunnel or explicit \u003ccode\u003eallow_public_bind\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e2\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003ePairing required\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003e6-digit one-time code on startup. Exchange via \u003ccode\u003ePOST /pair\u003c/code\u003e for bearer token.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e3\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eFilesystem scoped\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eworkspace_only = true\u003c/code\u003e by default. Null byte injection blocked. Symlink escape detection.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e4\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eAccess via tunnel only\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003eGateway refuses public bind without active tunnel. Supports Tailscale, Cloudflare, ngrok, or custom.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e5\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eSandbox isolation\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003eAuto-detects best backend: Landlock, Firejail, Bubblewrap, or Docker.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e6\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eEncrypted secrets\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003eAPI keys encrypted with ChaCha20-Poly1305 using local key file.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e7\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eResource limits\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003eConfigurable memory, CPU, disk, and subprocess limits.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e8\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eAudit logging\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003eDone\u003c/td\u003e\n\u003ctd\u003eSigned event trail with configurable retention.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChannel Allowlists\u003c/h3\u003e\u003ca id=\"user-content-channel-allowlists\" class=\"anchor\" aria-label=\"Permalink: Channel Allowlists\" href=\"#channel-allowlists\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eEmpty allowlist = \u003cstrong\u003edeny all inbound messages\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\"*\"\u003c/code\u003e = \u003cstrong\u003eallow all\u003c/strong\u003e (explicit opt-in)\u003c/li\u003e\n\u003cli\u003eOtherwise = exact-match allowlist\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eNostr additionally: the \u003ccode\u003eowner_pubkey\u003c/code\u003e is \u003cstrong\u003ealways\u003c/strong\u003e allowed regardless of \u003ccode\u003edm_allowed_pubkeys\u003c/code\u003e. Private keys are encrypted at rest via SecretStore (\u003ccode\u003eenc2:\u003c/code\u003e prefix) and only decrypted into memory while the channel is running; zeroed on channel stop.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eNostr Channel Setup\u003c/h3\u003e\u003ca id=\"user-content-nostr-channel-setup\" class=\"anchor\" aria-label=\"Permalink: Nostr Channel Setup\" href=\"#nostr-channel-setup\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003enullclaw\u003c/code\u003e speaks Nostr natively via NIP-17 (gift-wrapped private DMs) and NIP-04 (legacy DMs), using \u003ca href=\"https://github.com/fiatjaf/nak\"\u003e\u003ccode\u003enak\u003c/code\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003ePrerequisites:\u003c/strong\u003e Install \u003ccode\u003enak\u003c/code\u003e and ensure it's in your \u003ccode\u003e$PATH\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eSetup via onboarding wizard:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"nullclaw onboard --interactive   # Step 7 configures Nostr\"\u003e\u003cpre\u003enullclaw onboard --interactive   \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Step 7 configures Nostr\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe wizard will:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eGenerate a new keypair for your bot or import a key \u0026amp; encrypt it with ChaCha20-Poly1305\u003c/li\u003e\n\u003cli\u003eAsk for your (owner) pubkey (npub or hex) — always allowed through DM policy\u003c/li\u003e\n\u003cli\u003eConfigure relays and DM relays (kind:10050 inbox)\u003c/li\u003e\n\u003cli\u003eDisplay the bot's pubkey\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eOr configure manually in the \u003ca href=\"#configuration\"\u003econfig\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eHow it works:\u003c/strong\u003e On startup, nullclaw announces its DM inbox relays (kind:10050), then listens for incoming NIP-17 gift wraps and NIP-04 encrypted DMs. Outbound messages mirror the sender's protocol. Multi-relay rumor deduplication prevents duplicate responses when the same message is delivered via multiple relays.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConfiguration\u003c/h2\u003e\u003ca id=\"user-content-configuration\" class=\"anchor\" aria-label=\"Permalink: Configuration\" href=\"#configuration\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eConfig: \u003ccode\u003e~/.nullclaw/config.json\u003c/code\u003e (created by \u003ccode\u003eonboard\u003c/code\u003e)\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eOpenClaw compatible:\u003c/strong\u003e nullclaw uses the same config structure as \u003ca href=\"https://github.com/openclaw/openclaw\"\u003eOpenClaw\u003c/a\u003e (snake_case). Providers live under \u003ccode\u003emodels.providers\u003c/code\u003e, the default model under \u003ccode\u003eagents.defaults.model.primary\u003c/code\u003e, and channels use \u003ccode\u003eaccounts\u003c/code\u003e wrappers.\nTop-level \u003ccode\u003edefault_provider\u003c/code\u003e / \u003ccode\u003edefault_model\u003c/code\u003e keys are not supported.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eVertex AI note:\u003c/strong\u003e \u003ccode\u003emodels.providers.vertex.api_key\u003c/code\u003e supports either:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003ea bearer token (\u003ccode\u003eya29...\u003c/code\u003e), or\u003c/li\u003e\n\u003cli\u003ea full Google service-account JSON object (same shape as Apps Script \u003ccode\u003eGEMINI_KEY\u003c/code\u003e with \u003ccode\u003eproject_id\u003c/code\u003e, \u003ccode\u003eclient_email\u003c/code\u003e, \u003ccode\u003eprivate_key\u003c/code\u003e).\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003emodels.providers.vertex.base_url\u003c/code\u003e can be set explicitly (\u003ccode\u003e.../projects/\u0026lt;id\u0026gt;/locations/\u0026lt;loc\u0026gt;/publishers/google/models\u003c/code\u003e), or omitted when service-account JSON is used (nullclaw will derive it from \u003ccode\u003eproject_id\u003c/code\u003e, with \u003ccode\u003eVERTEX_LOCATION\u003c/code\u003e defaulting to \u003ccode\u003eglobal\u003c/code\u003e).\nService-account mode requires \u003ccode\u003eopenssl\u003c/code\u003e available in \u003ccode\u003e$PATH\u003c/code\u003e for RS256 JWT signing.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;default_temperature\u0026quot;: 0.7,\n\n  \u0026quot;models\u0026quot;: {\n    \u0026quot;providers\u0026quot;: {\n      \u0026quot;openrouter\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;sk-or-...\u0026quot; },\n      \u0026quot;nearai\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;YOUR_NEARAI_API_KEY\u0026quot; },\n      \u0026quot;atlas-cloud\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;YOUR_ATLASCLOUD_API_KEY\u0026quot; },\n      \u0026quot;evolink\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;YOUR_EVOLINK_API_KEY\u0026quot; },\n      \u0026quot;edenai\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;YOUR_EDENAI_API_KEY\u0026quot; },\n      \u0026quot;groq\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;gsk_...\u0026quot; },\n      \u0026quot;azure\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;YOUR_AZURE_OPENAI_API_KEY\u0026quot;, \u0026quot;base_url\u0026quot;: \u0026quot;https://your-resource.openai.azure.com\u0026quot; },\n      \u0026quot;vertex\u0026quot;: {\n        \u0026quot;api_key\u0026quot;: {\n          \u0026quot;type\u0026quot;: \u0026quot;service_account\u0026quot;,\n          \u0026quot;project_id\u0026quot;: \u0026quot;your-project\u0026quot;,\n          \u0026quot;client_email\u0026quot;: \u0026quot;svc@your-project.iam.gserviceaccount.com\u0026quot;,\n          \u0026quot;private_key\u0026quot;: \u0026quot;-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n\u0026quot;\n        },\n        \u0026quot;base_url\u0026quot;: \u0026quot;https://aiplatform.googleapis.com/v1/projects/your-project/locations/global/publishers/google/models\u0026quot;\n      },\n      \u0026quot;anthropic\u0026quot;: { \u0026quot;api_key\u0026quot;: \u0026quot;sk-ant-...\u0026quot; }\n    }\n  },\n\n  \u0026quot;agents\u0026quot;: {\n    \u0026quot;defaults\u0026quot;: {\n      \u0026quot;model\u0026quot;: { \u0026quot;primary\u0026quot;: \u0026quot;openrouter/anthropic/claude-sonnet-4\u0026quot; },\n      \u0026quot;heartbeat\u0026quot;: { \u0026quot;every\u0026quot;: \u0026quot;30m\u0026quot; }\n    },\n    \u0026quot;list\u0026quot;: [\n      { \u0026quot;id\u0026quot;: \u0026quot;researcher\u0026quot;, \u0026quot;model\u0026quot;: { \u0026quot;primary\u0026quot;: \u0026quot;openrouter/anthropic/claude-opus-4\u0026quot; }, \u0026quot;system_prompt\u0026quot;: \u0026quot;...\u0026quot; }\n    ]\n  },\n\n  \u0026quot;channels\u0026quot;: {\n    \u0026quot;telegram\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;main\u0026quot;: {\n          \u0026quot;bot_token\u0026quot;: \u0026quot;123:ABC\u0026quot;,\n          \u0026quot;allow_from\u0026quot;: [\u0026quot;user1\u0026quot;],\n          \u0026quot;reply_in_private\u0026quot;: true,\n          \u0026quot;proxy\u0026quot;: \u0026quot;socks5://...\u0026quot;\n        }\n      }\n    },\n    \u0026quot;discord\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;main\u0026quot;: {\n          \u0026quot;token\u0026quot;: \u0026quot;disc-token\u0026quot;,\n          \u0026quot;guild_id\u0026quot;: \u0026quot;12345\u0026quot;,\n          \u0026quot;allow_from\u0026quot;: [\u0026quot;user1\u0026quot;],\n          \u0026quot;allow_bots\u0026quot;: false\n        }\n      }\n    },\n    \u0026quot;irc\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;main\u0026quot;: {\n          \u0026quot;host\u0026quot;: \u0026quot;irc.libera.chat\u0026quot;,\n          \u0026quot;port\u0026quot;: 6697,\n          \u0026quot;nick\u0026quot;: \u0026quot;nullclaw\u0026quot;,\n          \u0026quot;channels\u0026quot;: [\u0026quot;#nullclaw\u0026quot;],\n          \u0026quot;tls\u0026quot;: true,\n          \u0026quot;allow_from\u0026quot;: [\u0026quot;user1\u0026quot;]\n        },\n        \u0026quot;meshrelay\u0026quot;: {\n          \u0026quot;host\u0026quot;: \u0026quot;irc.meshrelay.xyz\u0026quot;,\n          \u0026quot;port\u0026quot;: 6697,\n          \u0026quot;nick\u0026quot;: \u0026quot;nullclaw\u0026quot;,\n          \u0026quot;channels\u0026quot;: [\u0026quot;#agents\u0026quot;],\n          \u0026quot;tls\u0026quot;: true,\n          \u0026quot;nickserv_password\u0026quot;: \u0026quot;YOUR_NICKSERV_PASSWORD\u0026quot;,\n          \u0026quot;allow_from\u0026quot;: [\u0026quot;*\u0026quot;]\n        }\n      }\n    },\n    \u0026quot;slack\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;main\u0026quot;: {\n          \u0026quot;bot_token\u0026quot;: \u0026quot;xoxb-...\u0026quot;,\n          \u0026quot;app_token\u0026quot;: \u0026quot;xapp-...\u0026quot;,\n          \u0026quot;allow_from\u0026quot;: [\u0026quot;user1\u0026quot;]\n        }\n      }\n    },\n    \u0026quot;nostr\u0026quot;: {\n      \u0026quot;private_key\u0026quot;: \u0026quot;enc2:...\u0026quot;,\n      \u0026quot;owner_pubkey\u0026quot;: \u0026quot;hex-pubkey-of-owner\u0026quot;,\n      \u0026quot;relays\u0026quot;: [\u0026quot;wss://relay.damus.io\u0026quot;, \u0026quot;wss://nos.lol\u0026quot;, \u0026quot;wss://relay.nostr.band\u0026quot;],\n      \u0026quot;dm_allowed_pubkeys\u0026quot;: [\u0026quot;*\u0026quot;],\n      \u0026quot;display_name\u0026quot;: \u0026quot;NullClaw\u0026quot;,\n      \u0026quot;about\u0026quot;: \u0026quot;AI assistant on Nostr\u0026quot;,\n      \u0026quot;nip05\u0026quot;: \u0026quot;nullclaw@yourdomain.com\u0026quot;,\n      \u0026quot;lnurl\u0026quot;: \u0026quot;lnurl1...\u0026quot;\n    }\n  },\n\n  \u0026quot;tools\u0026quot;: {\n    \u0026quot;media\u0026quot;: {\n      \u0026quot;audio\u0026quot;: {\n        \u0026quot;enabled\u0026quot;: true,\n        \u0026quot;language\u0026quot;: \u0026quot;ru\u0026quot;,\n        \u0026quot;models\u0026quot;: [{ \u0026quot;provider\u0026quot;: \u0026quot;groq\u0026quot;, \u0026quot;model\u0026quot;: \u0026quot;whisper-large-v3\u0026quot; }]\n      }\n    }\n  },\n\n  \u0026quot;mcp_servers\u0026quot;: {\n    \u0026quot;filesystem\u0026quot;: {\n      \u0026quot;transport\u0026quot;: \u0026quot;stdio\u0026quot;,\n      \u0026quot;command\u0026quot;: \u0026quot;npx\u0026quot;,\n      \u0026quot;args\u0026quot;: [\u0026quot;-y\u0026quot;, \u0026quot;@modelcontextprotocol/server-filesystem\u0026quot;],\n      \u0026quot;timeout_ms\u0026quot;: 10000\n    },\n    \u0026quot;remote\u0026quot;: {\n      \u0026quot;transport\u0026quot;: \u0026quot;http\u0026quot;,\n      \u0026quot;url\u0026quot;: \u0026quot;https://mcp.example.com/rpc\u0026quot;,\n      \u0026quot;timeout_ms\u0026quot;: 10000,\n      \u0026quot;headers\u0026quot;: {\n        \u0026quot;Authorization\u0026quot;: \u0026quot;Bearer example-token\u0026quot;\n      }\n    }\n  },\n\n  \u0026quot;memory\u0026quot;: {\n    \u0026quot;backend\u0026quot;: \u0026quot;sqlite\u0026quot;,\n    \u0026quot;auto_save\u0026quot;: true,\n    \u0026quot;embedding_provider\u0026quot;: \u0026quot;openai\u0026quot;,\n    \u0026quot;vector_weight\u0026quot;: 0.7,\n    \u0026quot;keyword_weight\u0026quot;: 0.3\n  },\n\n  \u0026quot;gateway\u0026quot;: {\n    \u0026quot;port\u0026quot;: 3000,\n    \u0026quot;require_pairing\u0026quot;: true,\n    \u0026quot;allow_public_bind\u0026quot;: false\n  },\n\n  \u0026quot;autonomy\u0026quot;: {\n    \u0026quot;level\u0026quot;: \u0026quot;supervised\u0026quot;,\n    \u0026quot;workspace_only\u0026quot;: true,\n    \u0026quot;max_actions_per_hour\u0026quot;: 20\n  },\n\n  \u0026quot;runtime\u0026quot;: {\n    \u0026quot;kind\u0026quot;: \u0026quot;native\u0026quot;,\n    \u0026quot;docker\u0026quot;: {\n      \u0026quot;image\u0026quot;: \u0026quot;alpine:3.24\u0026quot;,\n      \u0026quot;network\u0026quot;: \u0026quot;none\u0026quot;,\n      \u0026quot;memory_limit_mb\u0026quot;: 512,\n      \u0026quot;read_only_rootfs\u0026quot;: true\n    }\n  },\n\n\n  \u0026quot;tunnel\u0026quot;: { \u0026quot;provider\u0026quot;: \u0026quot;none\u0026quot; },\n  \u0026quot;secrets\u0026quot;: { \u0026quot;encrypt\u0026quot;: true },\n  \u0026quot;identity\u0026quot;: { \u0026quot;format\u0026quot;: \u0026quot;openclaw\u0026quot; },\n\n  \u0026quot;security\u0026quot;: {\n    \u0026quot;sandbox\u0026quot;: { \u0026quot;backend\u0026quot;: \u0026quot;auto\u0026quot; },\n    \u0026quot;resources\u0026quot;: { \u0026quot;max_memory_mb\u0026quot;: 512, \u0026quot;max_cpu_percent\u0026quot;: 80 },\n    \u0026quot;audit\u0026quot;: { \u0026quot;enabled\u0026quot;: true, \u0026quot;retention_days\u0026quot;: 90 }\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"default_temperature\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e0.7\u003c/span\u003e,\n\n  \u003cspan class=\"pl-ent\"\u003e\"models\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"providers\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"openrouter\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esk-or-...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"nearai\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_NEARAI_API_KEY\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"atlas-cloud\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_ATLASCLOUD_API_KEY\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"evolink\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_EVOLINK_API_KEY\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"edenai\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_EDENAI_API_KEY\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"groq\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003egsk_...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"azure\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_AZURE_OPENAI_API_KEY\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"base_url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://your-resource.openai.azure.com\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"vertex\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"type\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eservice_account\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"project_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eyour-project\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"client_email\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esvc@your-project.iam.gserviceaccount.com\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"private_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e-----BEGIN PRIVATE KEY-----\u003cspan class=\"pl-cce\"\u003e\\n\u003c/span\u003e...\u003cspan class=\"pl-cce\"\u003e\\n\u003c/span\u003e-----END PRIVATE KEY-----\u003cspan class=\"pl-cce\"\u003e\\n\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n        },\n        \u003cspan class=\"pl-ent\"\u003e\"base_url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://aiplatform.googleapis.com/v1/projects/your-project/locations/global/publishers/google/models\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n      },\n      \u003cspan class=\"pl-ent\"\u003e\"anthropic\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"api_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esk-ant-...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }\n    }\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"agents\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"defaults\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"model\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"primary\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eopenrouter/anthropic/claude-sonnet-4\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n      \u003cspan class=\"pl-ent\"\u003e\"heartbeat\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"every\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e30m\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }\n    },\n    \u003cspan class=\"pl-ent\"\u003e\"list\"\u003c/span\u003e: [\n      { \u003cspan class=\"pl-ent\"\u003e\"id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eresearcher\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"model\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"primary\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eopenrouter/anthropic/claude-opus-4\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }, \u003cspan class=\"pl-ent\"\u003e\"system_prompt\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }\n    ]\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"channels\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"telegram\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"main\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"bot_token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e123:ABC\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allow_from\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003euser1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n          \u003cspan class=\"pl-ent\"\u003e\"reply_in_private\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"proxy\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esocks5://...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n        }\n      }\n    },\n    \u003cspan class=\"pl-ent\"\u003e\"discord\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"main\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003edisc-token\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"guild_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e12345\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allow_from\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003euser1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n          \u003cspan class=\"pl-ent\"\u003e\"allow_bots\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n        }\n      }\n    },\n    \u003cspan class=\"pl-ent\"\u003e\"irc\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"main\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"host\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eirc.libera.chat\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"port\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e6697\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"nick\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enullclaw\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"channels\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e#nullclaw\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n          \u003cspan class=\"pl-ent\"\u003e\"tls\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allow_from\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003euser1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e]\n        },\n        \u003cspan class=\"pl-ent\"\u003e\"meshrelay\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"host\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eirc.meshrelay.xyz\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"port\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e6697\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"nick\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enullclaw\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"channels\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e#agents\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n          \u003cspan class=\"pl-ent\"\u003e\"tls\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"nickserv_password\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_NICKSERV_PASSWORD\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allow_from\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e*\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e]\n        }\n      }\n    },\n    \u003cspan class=\"pl-ent\"\u003e\"slack\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"main\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"bot_token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003exoxb-...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"app_token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003exapp-...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allow_from\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003euser1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e]\n        }\n      }\n    },\n    \u003cspan class=\"pl-ent\"\u003e\"nostr\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"private_key\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eenc2:...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"owner_pubkey\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehex-pubkey-of-owner\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"relays\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ewss://relay.damus.io\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ewss://nos.lol\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ewss://relay.nostr.band\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n      \u003cspan class=\"pl-ent\"\u003e\"dm_allowed_pubkeys\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e*\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n      \u003cspan class=\"pl-ent\"\u003e\"display_name\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eNullClaw\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"about\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eAI assistant on Nostr\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"nip05\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enullclaw@yourdomain.com\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"lnurl\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003elnurl1...\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n    }\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"tools\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"media\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"audio\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"language\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eru\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"models\"\u003c/span\u003e: [{ \u003cspan class=\"pl-ent\"\u003e\"provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003egroq\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"model\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ewhisper-large-v3\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }]\n      }\n    }\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"mcp_servers\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"filesystem\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"transport\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003estdio\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"command\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enpx\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"args\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e-y\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e@modelcontextprotocol/server-filesystem\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n      \u003cspan class=\"pl-ent\"\u003e\"timeout_ms\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e10000\u003c/span\u003e\n    },\n    \u003cspan class=\"pl-ent\"\u003e\"remote\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"transport\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttp\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://mcp.example.com/rpc\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"timeout_ms\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e10000\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"headers\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"Authorization\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eBearer example-token\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n      }\n    }\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"memory\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"backend\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esqlite\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"auto_save\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"embedding_provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eopenai\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"vector_weight\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e0.7\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"keyword_weight\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e0.3\u003c/span\u003e\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"gateway\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"port\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e3000\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"require_pairing\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"allow_public_bind\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"autonomy\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"level\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003esupervised\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"workspace_only\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"max_actions_per_hour\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e20\u003c/span\u003e\n  },\n\n  \u003cspan class=\"pl-ent\"\u003e\"runtime\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"kind\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enative\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"docker\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"image\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ealpine:3.24\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"network\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enone\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"memory_limit_mb\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e512\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"read_only_rootfs\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n    }\n  },\n\n\n  \u003cspan class=\"pl-ent\"\u003e\"tunnel\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enone\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n  \u003cspan class=\"pl-ent\"\u003e\"secrets\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"encrypt\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e },\n  \u003cspan class=\"pl-ent\"\u003e\"identity\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"format\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eopenclaw\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n\n  \u003cspan class=\"pl-ent\"\u003e\"security\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"sandbox\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"backend\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eauto\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e },\n    \u003cspan class=\"pl-ent\"\u003e\"resources\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"max_memory_mb\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e512\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"max_cpu_percent\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e80\u003c/span\u003e },\n    \u003cspan class=\"pl-ent\"\u003e\"audit\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"retention_days\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e90\u003c/span\u003e }\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eConfig values are literal. NullClaw does not expand \u003ccode\u003e${VAR}\u003c/code\u003e inside \u003ccode\u003econfig.json\u003c/code\u003e\nstrings, including custom header values. If you need environment-based secrets,\nrender \u003ccode\u003econfig.json\u003c/code\u003e ahead of time with your own deployment tooling.\nMCP \u003ccode\u003etimeout_ms\u003c/code\u003e bounds each HTTP or stdio request; a timed-out stdio server is\nterminated with its launcher process group so blocked child processes do not remain.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTelegram forum topics:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eTopic session isolation is automatic. You do not add a \u003ccode\u003etopic_id\u003c/code\u003e field under \u003ccode\u003echannels.telegram\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe easiest operator flow is:\n\u003col dir=\"auto\"\u003e\n\u003cli\u003edefine named agent profiles under \u003ccode\u003eagents.list\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eopen the target Telegram chat or forum topic\u003c/li\u003e\n\u003cli\u003erun \u003ccode\u003e/bind \u0026lt;agent\u0026gt;\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003eTo bind a specific Telegram forum topic to a specific agent, use \u003ccode\u003ebindings[].match.peer.id\u003c/code\u003e with the canonical thread form \u003ccode\u003e\"\u0026lt;chat_id\u0026gt;:thread:\u0026lt;topic_id\u0026gt;\"\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eTo bind the whole Telegram group as a fallback for all other topics, keep a normal group binding with \u003ccode\u003e\"\u0026lt;chat_id\u0026gt;\"\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/bind status\u003c/code\u003e shows the current effective route and the available agent ids.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/bind clear\u003c/code\u003e removes only the exact binding for the current account/chat/topic and falls back to the broader route.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/bind\u003c/code\u003e persists an exact \u003ccode\u003ebindings[]\u003c/code\u003e entry for the current Telegram account and peer.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/bind status\u003c/code\u003e distinguishes an exact local override from an inherited broader fallback.\u003c/li\u003e\n\u003cli\u003eTopic-specific bindings win over group fallback by route priority; the order in \u003ccode\u003ebindings[]\u003c/code\u003e does not matter.\u003c/li\u003e\n\u003cli\u003eTelegram menu visibility for \u003ccode\u003e/bind\u003c/code\u003e is controlled by \u003ccode\u003echannels.telegram.accounts.\u0026lt;id\u0026gt;.binding_commands_enabled\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eExample:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;bindings\u0026quot;: [\n    {\n      \u0026quot;agent_id\u0026quot;: \u0026quot;coder\u0026quot;,\n      \u0026quot;match\u0026quot;: {\n        \u0026quot;channel\u0026quot;: \u0026quot;telegram\u0026quot;,\n        \u0026quot;account_id\u0026quot;: \u0026quot;main\u0026quot;,\n        \u0026quot;peer\u0026quot;: { \u0026quot;kind\u0026quot;: \u0026quot;group\u0026quot;, \u0026quot;id\u0026quot;: \u0026quot;-1001234567890:thread:42\u0026quot; }\n      }\n    },\n    {\n      \u0026quot;agent_id\u0026quot;: \u0026quot;orchestrator\u0026quot;,\n      \u0026quot;match\u0026quot;: {\n        \u0026quot;channel\u0026quot;: \u0026quot;telegram\u0026quot;,\n        \u0026quot;account_id\u0026quot;: \u0026quot;main\u0026quot;,\n        \u0026quot;peer\u0026quot;: { \u0026quot;kind\u0026quot;: \u0026quot;group\u0026quot;, \u0026quot;id\u0026quot;: \u0026quot;-1001234567890\u0026quot; }\n      }\n    }\n  ]\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"bindings\"\u003c/span\u003e: [\n    {\n      \u003cspan class=\"pl-ent\"\u003e\"agent_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ecoder\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"match\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"channel\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003etelegram\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"account_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003emain\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"peer\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"kind\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003egroup\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e-1001234567890:thread:42\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }\n      }\n    },\n    {\n      \u003cspan class=\"pl-ent\"\u003e\"agent_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eorchestrator\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"match\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"channel\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003etelegram\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"account_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003emain\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"peer\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"kind\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003egroup\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e-1001234567890\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }\n      }\n    }\n  ]\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn that setup, topic \u003ccode\u003e42\u003c/code\u003e routes to \u003ccode\u003ecoder\u003c/code\u003e, while the rest of the forum falls back to \u003ccode\u003eorchestrator\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNamed agent profiles are configured separately from bindings. Bindings only choose which named agent handles a given chat/topic.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf a named agent should run from its own workspace, set \u003ccode\u003eagents.list[].workspace_path\u003c/code\u003e.\nRelative paths are resolved from the directory that contains \u003ccode\u003econfig.json\u003c/code\u003e, the workspace is scaffolded on first use, and the agent gets a durable memory namespace \u003ccode\u003eagent:\u0026lt;agent-id\u0026gt;\u003c/code\u003e.\nSetting \u003ccode\u003eworkspace_path\u003c/code\u003e does not disable \u003ccode\u003esystem_prompt\u003c/code\u003e: when both are configured, the named profile prompt is still applied and the workspace bootstrap files are loaded from that dedicated workspace.\nThis applies to \u003ccode\u003enullclaw agent --agent \u0026lt;id\u0026gt;\u003c/code\u003e, \u003ccode\u003e/subagents spawn --agent \u0026lt;id\u0026gt;\u003c/code\u003e, and routed sessions resolved through \u003ccode\u003ebindings\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMinimal end-to-end example:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;agents\u0026quot;: {\n    \u0026quot;list\u0026quot;: [\n      {\n        \u0026quot;id\u0026quot;: \u0026quot;orchestrator\u0026quot;,\n        \u0026quot;provider\u0026quot;: \u0026quot;openrouter\u0026quot;,\n        \u0026quot;model\u0026quot;: \u0026quot;anthropic/claude-sonnet-4\u0026quot;\n      },\n      {\n        \u0026quot;id\u0026quot;: \u0026quot;coder\u0026quot;,\n        \u0026quot;provider\u0026quot;: \u0026quot;ollama\u0026quot;,\n        \u0026quot;model\u0026quot;: \u0026quot;qwen2.5-coder:14b\u0026quot;,\n        \u0026quot;system_prompt\u0026quot;: \u0026quot;You are the coding agent for this topic.\u0026quot;\n      }\n    ]\n  },\n  \u0026quot;channels\u0026quot;: {\n    \u0026quot;telegram\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;main\u0026quot;: {\n          \u0026quot;bot_token\u0026quot;: \u0026quot;123456:ABCDEF\u0026quot;,\n          \u0026quot;allow_from\u0026quot;: [\u0026quot;YOUR_TELEGRAM_USER_ID\u0026quot;],\n          \u0026quot;binding_commands_enabled\u0026quot;: true,\n          \u0026quot;topic_commands_enabled\u0026quot;: true,\n          \u0026quot;topic_map_command_enabled\u0026quot;: true,\n          \u0026quot;commands_menu_mode\u0026quot;: \u0026quot;scoped\u0026quot;\n        }\n      }\n    }\n  },\n  \u0026quot;bindings\u0026quot;: [\n    {\n      \u0026quot;agent_id\u0026quot;: \u0026quot;orchestrator\u0026quot;,\n      \u0026quot;match\u0026quot;: {\n        \u0026quot;channel\u0026quot;: \u0026quot;telegram\u0026quot;,\n        \u0026quot;account_id\u0026quot;: \u0026quot;main\u0026quot;,\n        \u0026quot;peer\u0026quot;: { \u0026quot;kind\u0026quot;: \u0026quot;group\u0026quot;, \u0026quot;id\u0026quot;: \u0026quot;-1001234567890\u0026quot; }\n      }\n    }\n  ]\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"agents\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"list\"\u003c/span\u003e: [\n      {\n        \u003cspan class=\"pl-ent\"\u003e\"id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eorchestrator\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eopenrouter\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"model\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eanthropic/claude-sonnet-4\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n      },\n      {\n        \u003cspan class=\"pl-ent\"\u003e\"id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ecoder\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eollama\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"model\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eqwen2.5-coder:14b\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"system_prompt\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYou are the coding agent for this topic.\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n      }\n    ]\n  },\n  \u003cspan class=\"pl-ent\"\u003e\"channels\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"telegram\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"main\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"bot_token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e123456:ABCDEF\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allow_from\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eYOUR_TELEGRAM_USER_ID\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n          \u003cspan class=\"pl-ent\"\u003e\"binding_commands_enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"topic_commands_enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"topic_map_command_enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"commands_menu_mode\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003escoped\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n        }\n      }\n    }\n  },\n  \u003cspan class=\"pl-ent\"\u003e\"bindings\"\u003c/span\u003e: [\n    {\n      \u003cspan class=\"pl-ent\"\u003e\"agent_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eorchestrator\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n      \u003cspan class=\"pl-ent\"\u003e\"match\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"channel\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003etelegram\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"account_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003emain\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n        \u003cspan class=\"pl-ent\"\u003e\"peer\"\u003c/span\u003e: { \u003cspan class=\"pl-ent\"\u003e\"kind\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003egroup\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e-1001234567890\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e }\n      }\n    }\n  ]\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOperator flow:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eSend \u003ccode\u003e/bind coder\u003c/code\u003e inside the target forum topic.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enullclaw\u003c/code\u003e writes a new exact \u003ccode\u003ebindings[]\u003c/code\u003e entry to \u003ccode\u003e~/.nullclaw/config.json\u003c/code\u003e for that topic and Telegram account.\u003c/li\u003e\n\u003cli\u003eThe next message in that topic uses the new routed agent profile.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enullclaw\u003c/code\u003e must have write access to \u003ccode\u003e~/.nullclaw/config.json\u003c/code\u003e for \u003ccode\u003e/bind\u003c/code\u003e to persist changes.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eAbout \u003ccode\u003eaccount_id\u003c/code\u003e:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eaccount_id\u003c/code\u003e identifies the configured Telegram account entry, not a topic and not an agent.\u003c/li\u003e\n\u003cli\u003eIn the usual \u003ccode\u003echannels.telegram.accounts\u003c/code\u003e form, the object key becomes the account id. For example, \u003ccode\u003eaccounts.main\u003c/code\u003e means \u003ccode\u003eaccount_id = \"main\"\u003c/code\u003e, and \u003ccode\u003eaccounts.backup\u003c/code\u003e means \u003ccode\u003eaccount_id = \"backup\"\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eIn \u003ccode\u003ebindings\u003c/code\u003e, \u003ccode\u003ematch.account_id\u003c/code\u003e limits that binding to one specific Telegram account.\u003c/li\u003e\n\u003cli\u003eIf \u003ccode\u003ematch.account_id\u003c/code\u003e is omitted, the binding can match any Telegram account for that channel.\u003c/li\u003e\n\u003cli\u003eUse different account ids only when you run multiple Telegram bot accounts/tokens in the same nullclaw instance.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eEffect on delivery:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIncoming Telegram updates are processed by the account that received them.\u003c/li\u003e\n\u003cli\u003eRouting uses that same \u003ccode\u003eaccount_id\u003c/code\u003e, so \u003ccode\u003ematch.account_id = \"main\"\u003c/code\u003e matches only messages received by \u003ccode\u003echannels.telegram.accounts.main\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eReplies go back out through the same Telegram account/runtime that handled the message.\u003c/li\u003e\n\u003cli\u003eSetting one binding to \u003ccode\u003eaccount_id = \"main\"\u003c/code\u003e and another to \u003ccode\u003eaccount_id = \"sub\"\u003c/code\u003e does not split one chat across two agents automatically; it scopes each binding to a different configured Telegram account.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFull Web Search + Shell Access\u003c/h3\u003e\u003ca id=\"user-content-full-web-search--shell-access\" class=\"anchor\" aria-label=\"Permalink: Full Web Search + Shell Access\" href=\"#full-web-search--shell-access\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse this when you want full web-search provider control plus unrestricted shell command allowlist behavior:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;http_request\u0026quot;: {\n    \u0026quot;enabled\u0026quot;: true,\n    \u0026quot;search_base_url\u0026quot;: \u0026quot;https://searx.example.com\u0026quot;,\n    \u0026quot;search_provider\u0026quot;: \u0026quot;auto\u0026quot;,\n    \u0026quot;search_fallback_providers\u0026quot;: [\u0026quot;jina\u0026quot;, \u0026quot;duckduckgo\u0026quot;]\n  },\n  \u0026quot;autonomy\u0026quot;: {\n    \u0026quot;level\u0026quot;: \u0026quot;full\u0026quot;,\n    \u0026quot;allowed_commands\u0026quot;: [\u0026quot;*\u0026quot;],\n    \u0026quot;allowed_paths\u0026quot;: [\u0026quot;*\u0026quot;],\n    \u0026quot;require_approval_for_medium_risk\u0026quot;: false,\n    \u0026quot;block_medium_risk_commands\u0026quot;: false,\n    \u0026quot;block_high_risk_commands\u0026quot;: false\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"http_request\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"search_base_url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://searx.example.com\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"search_provider\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eauto\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"search_fallback_providers\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ejina\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003educkduckgo\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e]\n  },\n  \u003cspan class=\"pl-ent\"\u003e\"autonomy\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"level\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003efull\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"allowed_commands\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e*\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n    \u003cspan class=\"pl-ent\"\u003e\"allowed_paths\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e*\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n    \u003cspan class=\"pl-ent\"\u003e\"require_approval_for_medium_risk\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"block_medium_risk_commands\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"block_high_risk_commands\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003ehttp_request.search_base_url\u003c/code\u003e accepts either instance root (\u003ccode\u003ehttps://host\u003c/code\u003e) or explicit endpoint (\u003ccode\u003ehttps://host/search\u003c/code\u003e); local/private SearXNG instances may also use plain HTTP such as \u003ccode\u003ehttp://localhost:8888\u003c/code\u003e or \u003ccode\u003ehttp://192.168.1.10:8888/search\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eInvalid \u003ccode\u003ehttp_request.search_base_url\u003c/code\u003e now fails config validation at startup (no automatic fallback for malformed URL).\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehttp_request.search_provider\u003c/code\u003e supports: \u003ccode\u003eauto\u003c/code\u003e, \u003ccode\u003esearxng\u003c/code\u003e, \u003ccode\u003educkduckgo\u003c/code\u003e (\u003ccode\u003eddg\u003c/code\u003e), \u003ccode\u003ebrave\u003c/code\u003e, \u003ccode\u003efirecrawl\u003c/code\u003e, \u003ccode\u003etavily\u003c/code\u003e, \u003ccode\u003eperplexity\u003c/code\u003e, \u003ccode\u003eexa\u003c/code\u003e, \u003ccode\u003ejina\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehttp_request.search_fallback_providers\u003c/code\u003e is optional and is tried in order when the primary provider fails.\u003c/li\u003e\n\u003cli\u003eProvider env vars: \u003ccode\u003eBRAVE_API_KEY\u003c/code\u003e, \u003ccode\u003eFIRECRAWL_API_KEY\u003c/code\u003e, \u003ccode\u003eTAVILY_API_KEY\u003c/code\u003e, \u003ccode\u003ePERPLEXITY_API_KEY\u003c/code\u003e, \u003ccode\u003eEXA_API_KEY\u003c/code\u003e, \u003ccode\u003eJINA_API_KEY\u003c/code\u003e (or shared \u003ccode\u003eWEB_SEARCH_API_KEY\u003c/code\u003e where supported). DuckDuckGo and SearXNG do not require API keys.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eallowed_commands\u003c/code\u003e entries support \u003ccode\u003e\"cmd\"\u003c/code\u003e, \u003ccode\u003e\"cmd *\"\u003c/code\u003e, and \u003ccode\u003e\"*\"\u003c/code\u003e formats.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e\"cmd\"\u003c/code\u003e and \u003ccode\u003e\"cmd *\"\u003c/code\u003e both allow that command family at the allowlist stage.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\"*\"\u003c/code\u003e allows any command at the allowlist stage.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eHigh-risk and medium-risk runtime gates still apply after the allowlist check; set \u003ccode\u003eblock_medium_risk_commands: false\u003c/code\u003e when you intentionally allow network/transfer commands such as \u003ccode\u003ecurl\u003c/code\u003e/\u003ccode\u003ewget\u003c/code\u003e or other medium-risk mutations.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eallowed_paths: [\"*\"]\u003c/code\u003e allows access outside workspace, except system-protected paths.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWeb UI / Browser Relay\u003c/h3\u003e\u003ca id=\"user-content-web-ui--browser-relay\" class=\"anchor\" aria-label=\"Permalink: Web UI / Browser Relay\" href=\"#web-ui--browser-relay\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse \u003ccode\u003echannels.web\u003c/code\u003e for browser UI events (WebChannel v1):\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;channels\u0026quot;: {\n    \u0026quot;web\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;default\u0026quot;: {\n          \u0026quot;transport\u0026quot;: \u0026quot;local\u0026quot;,\n          \u0026quot;listen\u0026quot;: \u0026quot;127.0.0.1\u0026quot;,\n          \u0026quot;port\u0026quot;: 32123,\n          \u0026quot;path\u0026quot;: \u0026quot;/ws\u0026quot;,\n          \u0026quot;auth_token\u0026quot;: \u0026quot;replace-with-long-random-token\u0026quot;,\n          \u0026quot;message_auth_mode\u0026quot;: \u0026quot;pairing\u0026quot;,\n          \u0026quot;allowed_origins\u0026quot;: [\u0026quot;http://localhost:5173\u0026quot;, \u0026quot;chrome-extension://your-extension-id\u0026quot;]\n        }\n      }\n    }\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"channels\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"web\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"default\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"transport\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003elocal\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"listen\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e127.0.0.1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"port\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e32123\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"path\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e/ws\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"auth_token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ereplace-with-long-random-token\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"message_auth_mode\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003epairing\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"allowed_origins\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttp://localhost:5173\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003echrome-extension://your-extension-id\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e]\n        }\n      }\n    }\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eLocal: keep \u003ccode\u003e\"listen\": \"127.0.0.1\"\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emessage_auth_mode\u003c/code\u003e controls inbound \u003ccode\u003euser_message\u003c/code\u003e auth:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e\"pairing\"\u003c/code\u003e (default): send \u003ccode\u003epairing_request\u003c/code\u003e, receive \u003ccode\u003epairing_result\u003c/code\u003e, include UI \u003ccode\u003eaccess_token\u003c/code\u003e in every \u003ccode\u003euser_message\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\"token\"\u003c/code\u003e (local transport only): include \u003ccode\u003eauth_token\u003c/code\u003e in each \u003ccode\u003euser_message\u003c/code\u003e payload (\u003ccode\u003eaccess_token\u003c/code\u003e is also accepted for compatibility).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eauth_token\u003c/code\u003e hardens the WebSocket upgrade and becomes required when binding non-loopback addresses.\u003c/li\u003e\n\u003cli\u003eUnauthenticated WebSocket upgrade is loopback-only. Pairing-first local UX works on \u003ccode\u003e127.0.0.1\u003c/code\u003e, but a public/LAN bind must authenticate the \u003ccode\u003e/ws\u003c/code\u003e upgrade on the first hop with \u003ccode\u003e?token=\u0026lt;auth_token\u0026gt;\u003c/code\u003e or \u003ccode\u003eAuthorization: Bearer \u0026lt;auth_token\u0026gt;\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eLocal loopback pairing no longer depends on a fixed shared code. \u003ccode\u003epairing_request\u003c/code\u003e may omit \u003ccode\u003epayload.pairing_code\u003c/code\u003e, and legacy loopback clients that still send \u003ccode\u003e123456\u003c/code\u003e remain compatible.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e/ws\u003c/code\u003e is the WebSocket endpoint. \u003ccode\u003e/pair\u003c/code\u003e belongs to the HTTP gateway API and is not part of the web channel handshake.\u003c/li\u003e\n\u003cli\u003eRemote/headless host: if you bind \u003ccode\u003e\"listen\": \"0.0.0.0\"\u003c/code\u003e, prefer a stable configured token plus \u003ccode\u003emessage_auth_mode: \"token\"\u003c/code\u003e behind TLS/reverse proxy, or keep loopback bind and expose it through SSH tunnel/proxy.\u003c/li\u003e\n\u003cli\u003eUI/extension should live in a separate repository and connect via this WebSocket endpoint.\u003c/li\u003e\n\u003cli\u003eFor orchestration, use local token mode with a stable token from config or env (\u003ccode\u003eNULLCLAW_WEB_TOKEN\u003c/code\u003e, \u003ccode\u003eNULLCLAW_GATEWAY_TOKEN\u003c/code\u003e, \u003ccode\u003eOPENCLAW_GATEWAY_TOKEN\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eRelay transport (outbound agent socket) is configured via:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;channels\u0026quot;: {\n    \u0026quot;web\u0026quot;: {\n      \u0026quot;accounts\u0026quot;: {\n        \u0026quot;default\u0026quot;: {\n          \u0026quot;transport\u0026quot;: \u0026quot;relay\u0026quot;,\n          \u0026quot;relay_url\u0026quot;: \u0026quot;wss://relay.nullclaw.io/ws/agent\u0026quot;,\n          \u0026quot;relay_agent_id\u0026quot;: \u0026quot;default\u0026quot;,\n          \u0026quot;relay_token\u0026quot;: \u0026quot;replace-with-relay-token\u0026quot;,\n          \u0026quot;relay_token_ttl_secs\u0026quot;: 2592000,\n          \u0026quot;relay_pairing_code_ttl_secs\u0026quot;: 300,\n          \u0026quot;relay_ui_token_ttl_secs\u0026quot;: 86400,\n          \u0026quot;relay_e2e_required\u0026quot;: false\n        }\n      }\n    }\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"channels\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"web\"\u003c/span\u003e: {\n      \u003cspan class=\"pl-ent\"\u003e\"accounts\"\u003c/span\u003e: {\n        \u003cspan class=\"pl-ent\"\u003e\"default\"\u003c/span\u003e: {\n          \u003cspan class=\"pl-ent\"\u003e\"transport\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003erelay\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ewss://relay.nullclaw.io/ws/agent\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_agent_id\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003edefault\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_token\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ereplace-with-relay-token\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_token_ttl_secs\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e2592000\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_pairing_code_ttl_secs\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e300\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_ui_token_ttl_secs\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e86400\u003c/span\u003e,\n          \u003cspan class=\"pl-ent\"\u003e\"relay_e2e_required\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\n        }\n      }\n    }\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRelay token lifecycle (dedicated): \u003ccode\u003erelay_token\u003c/code\u003e (config) -\u0026gt; \u003ccode\u003eNULLCLAW_RELAY_TOKEN\u003c/code\u003e (env) -\u0026gt; persisted \u003ccode\u003eweb-relay-\u0026lt;account_id\u0026gt;\u003c/code\u003e credential -\u0026gt; generated token.\u003c/li\u003e\n\u003cli\u003eRelay UI handshake: send \u003ccode\u003epairing_request\u003c/code\u003e with one-time \u003ccode\u003epairing_code\u003c/code\u003e, receive \u003ccode\u003epairing_result\u003c/code\u003e with UI \u003ccode\u003eaccess_token\u003c/code\u003e JWT (and optional \u003ccode\u003eset_cookie\u003c/code\u003e string for relay HTTP layer).\u003c/li\u003e\n\u003cli\u003eRelay \u003ccode\u003euser_message\u003c/code\u003e must include valid UI JWT in \u003ccode\u003eaccess_token\u003c/code\u003e (top-level or \u003ccode\u003epayload.access_token\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eIf E2E is enabled (\u003ccode\u003erelay_e2e_required=true\u003c/code\u003e), UI and agent exchange X25519 keys during pairing and send encrypted payloads in \u003ccode\u003epayload.e2e\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eWebChannel event envelope is defined in \u003ca href=\"/nullclaw/nullclaw/blob/main/spec/webchannel_v1.json\"\u003e\u003ccode\u003espec/webchannel_v1.json\u003c/code\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eGateway API\u003c/h2\u003e\u003ca id=\"user-content-gateway-api\" class=\"anchor\" aria-label=\"Permalink: Gateway API\" href=\"#gateway-api\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eEndpoint\u003c/th\u003e\n\u003cth\u003eMethod\u003c/th\u003e\n\u003cth\u003eAuth\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/health\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eGET\u003c/td\u003e\n\u003ctd\u003eNone\u003c/td\u003e\n\u003ctd\u003eHealth check (always public)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/pair\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePOST\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eX-Pairing-Code\u003c/code\u003e header\u003c/td\u003e\n\u003ctd\u003eExchange one-time code for bearer token\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/webhook\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePOST\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eAuthorization: Bearer \u0026lt;token\u0026gt;\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSend message: \u003ccode\u003e{\"message\": \"your prompt\"}\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/media/transcribe\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePOST\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eAuthorization: Bearer \u0026lt;token\u0026gt;\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eTranscribe \u003ccode\u003eaudio_base64\u003c/code\u003e payloads through configured STT\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/.well-known/agent-card.json\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eGET\u003c/td\u003e\n\u003ctd\u003eNone\u003c/td\u003e\n\u003ctd\u003eA2A Agent Card discovery (public)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/a2a\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePOST\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eAuthorization: Bearer \u0026lt;token\u0026gt;\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eA2A JSON-RPC endpoint (canonical methods plus legacy slash aliases)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/whatsapp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eGET\u003c/td\u003e\n\u003ctd\u003eQuery params\u003c/td\u003e\n\u003ctd\u003eMeta webhook verification\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e/whatsapp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePOST\u003c/td\u003e\n\u003ctd\u003eNone (Meta signature)\u003c/td\u003e\n\u003ctd\u003eWhatsApp incoming message webhook\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eA2A (Agent-to-Agent Protocol v0.3.0)\u003c/h3\u003e\u003ca id=\"user-content-a2a-agent-to-agent-protocol-v030\" class=\"anchor\" aria-label=\"Permalink: A2A (Agent-to-Agent Protocol v0.3.0)\" href=\"#a2a-agent-to-agent-protocol-v030\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNullClaw implements Google's \u003ca href=\"https://github.com/google/A2A\"\u003eA2A protocol\u003c/a\u003e v0.3.0, allowing any A2A-compatible agent or client to discover, authenticate, and interact with your instance over JSON-RPC 2.0.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eEnable in \u003ccode\u003e~/.nullclaw/config.json\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;a2a\u0026quot;: {\n    \u0026quot;enabled\u0026quot;: true,\n    \u0026quot;name\u0026quot;: \u0026quot;nullclaw\u0026quot;,\n    \u0026quot;description\u0026quot;: \u0026quot;General-purpose AI assistant\u0026quot;,\n    \u0026quot;url\u0026quot;: \u0026quot;https://example.com\u0026quot;,\n    \u0026quot;version\u0026quot;: \u0026quot;1.0.0\u0026quot;\n  }\n}\"\u003e\u003cpre\u003e{\n  \u003cspan class=\"pl-ent\"\u003e\"a2a\"\u003c/span\u003e: {\n    \u003cspan class=\"pl-ent\"\u003e\"enabled\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"name\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003enullclaw\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"description\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eGeneral-purpose AI assistant\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://example.com\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n    \u003cspan class=\"pl-ent\"\u003e\"version\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e1.0.0\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eEndpoints:\u003c/strong\u003e\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eEndpoint\u003c/th\u003e\n\u003cth\u003eAuth\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eGET /.well-known/agent-card.json\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNone\u003c/td\u003e\n\u003ctd\u003eAgent Card discovery (public)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ePOST /a2a\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eBearer token\u003c/td\u003e\n\u003ctd\u003eJSON-RPC 2.0 dispatch\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eSupported methods:\u003c/strong\u003e \u003ccode\u003emessage/send\u003c/code\u003e, \u003ccode\u003emessage/stream\u003c/code\u003e, \u003ccode\u003etasks/get\u003c/code\u003e, \u003ccode\u003etasks/cancel\u003c/code\u003e, \u003ccode\u003etasks/list\u003c/code\u003e, \u003ccode\u003etasks/resubscribe\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eQuick test:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# 1. Get a bearer token\n# Set PAIRING_CODE to the one-time code for this gateway session.\nTOKEN=$(curl -s -X POST -H \u0026quot;X-Pairing-Code: $PAIRING_CODE\u0026quot; http://localhost:3000/pair | jq -r .token)\n\n# 2. Discover the agent\ncurl http://localhost:3000/.well-known/agent-card.json\n\n# 3. Send a message\ncurl -X POST -H \u0026quot;Authorization: Bearer $TOKEN\u0026quot; \\\n  -H \u0026quot;Content-Type: application/json\u0026quot; \\\n  -d '{\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;,\u0026quot;id\u0026quot;:1,\u0026quot;method\u0026quot;:\u0026quot;message/send\u0026quot;,\u0026quot;params\u0026quot;:{\u0026quot;message\u0026quot;:{\u0026quot;messageId\u0026quot;:\u0026quot;msg-1\u0026quot;,\u0026quot;role\u0026quot;:\u0026quot;user\u0026quot;,\u0026quot;parts\u0026quot;:[{\u0026quot;kind\u0026quot;:\u0026quot;text\u0026quot;,\u0026quot;text\u0026quot;:\u0026quot;Hello\u0026quot;}]}}}' \\\n  http://localhost:3000/a2a\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e 1. Get a bearer token\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Set PAIRING_CODE to the one-time code for this gateway session.\u003c/span\u003e\nTOKEN=\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e$(\u003c/span\u003ecurl -s -X POST -H \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eX-Pairing-Code: \u003cspan class=\"pl-smi\"\u003e$PAIRING_CODE\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e http://localhost:3000/pair \u003cspan class=\"pl-k\"\u003e|\u003c/span\u003e jq -r .token\u003cspan class=\"pl-pds\"\u003e)\u003c/span\u003e\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e 2. Discover the agent\u003c/span\u003e\ncurl http://localhost:3000/.well-known/agent-card.json\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e 3. Send a message\u003c/span\u003e\ncurl -X POST -H \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eAuthorization: Bearer \u003cspan class=\"pl-smi\"\u003e$TOKEN\u003c/span\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \\\n  -H \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eContent-Type: application/json\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e \\\n  -d \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"messageId\":\"msg-1\",\"role\":\"user\",\"parts\":[{\"kind\":\"text\",\"text\":\"Hello\"}]}}}\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e \\\n  http://localhost:3000/a2a\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSee \u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/gateway-api.md\"\u003eGateway API docs\u003c/a\u003e for full A2A reference including streaming, task lifecycle, and configuration details.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMedia transcription\u003c/h3\u003e\u003ca id=\"user-content-media-transcription\" class=\"anchor\" aria-label=\"Permalink: Media transcription\" href=\"#media-transcription\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003ePOST /media/transcribe\u003c/code\u003e accepts JSON with \u003ccode\u003eaudio_base64\u003c/code\u003e, \u003ccode\u003emime_type\u003c/code\u003e, \u003ccode\u003esource\u003c/code\u003e, and optional \u003ccode\u003elanguage\u003c/code\u003e, then returns \u003ccode\u003e{\"text\":\"...\"}\u003c/code\u003e plus metadata. Configure STT under \u003ccode\u003etools.media.audio\u003c/code\u003e; remote custom STT endpoints must use HTTPS. Raise \u003ccode\u003egateway.max_body_size_bytes\u003c/code\u003e, \u003ccode\u003egateway.request_timeout_secs\u003c/code\u003e, and \u003ccode\u003egateway.webhook_rate_limit_per_minute\u003c/code\u003e for live desktop audio chunking.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCommands\u003c/h2\u003e\u003ca id=\"user-content-commands\" class=\"anchor\" aria-label=\"Permalink: Commands\" href=\"#commands\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eCommand\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eonboard --api-key sk-... --provider openrouter\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eQuick setup with API key and provider\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eonboard --interactive\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFull interactive wizard\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eonboard --channels-only\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eReconfigure channels/allowlists only\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eagent -m \"...\"\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSingle message mode\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eacp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStart the Agent Client Protocol stdio adapter for ACP-compatible editors\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eagent\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eInteractive chat mode\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003egateway\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eStart long-running runtime (default: \u003ccode\u003e127.0.0.1:3000\u003c/code\u003e)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eservice install|start|stop|restart|status|uninstall\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eManage background service\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003edoctor\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDiagnose system health\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003estatus [--json]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow full system status or emit the machine-readable runtime snapshot\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003echannel list|info|start|status|add|remove\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eManage channels, including JSON account inventory for automation\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ecron list|status|add|add-agent|once|once-agent|remove|pause|resume|run|update|runs\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eManage scheduled tasks\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eskills list|install|remove|info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eManage skill packs, including \u003ccode\u003einstall --name \u0026lt;query\u0026gt;\u003c/code\u003e registry search\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ehistory list|show\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eView session conversation history\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ememory stats|count|reindex|search|get|list|export-jsonl|hygiene-report|drain-outbox|forget\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eInspect, export, and maintain memory\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ehardware scan|flash|monitor\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eHardware device management\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003econfig show|get\u003c/code\u003e, \u003ccode\u003emodels list|summary|info|benchmark|refresh\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRead config/model admin state and manage the model catalog\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eworkspace edit|reset-md\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eMaintain workspace markdown/bootstrap files\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ecapabilities [--json]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eShow runtime capabilities manifest\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eauth login|status|logout\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eManage OAuth authentication\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003emigrate openclaw [--dry-run] [--source PATH]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eImport memory + migrate config from OpenClaw\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eupdate [--check] [--yes]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCheck for and install updates\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDevelopment\u003c/h2\u003e\u003ca id=\"user-content-development\" class=\"anchor\" aria-label=\"Permalink: Development\" href=\"#development\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBuild and tests are pinned to \u003cstrong\u003eZig 0.16.0\u003c/strong\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"zig build                          # Dev build\nzig build -Doptimize=ReleaseSmall  # Release build (678 KB)\nzig build test --summary all       # 5,300+ tests\"\u003e\u003cpre\u003ezig build                          \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Dev build\u003c/span\u003e\nzig build -Doptimize=ReleaseSmall  \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Release build (678 KB)\u003c/span\u003e\nzig build \u003cspan class=\"pl-c1\"\u003etest\u003c/span\u003e --summary all       \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e 5,300+ tests\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChannel Flow Coverage\u003c/h3\u003e\u003ca id=\"user-content-channel-flow-coverage\" class=\"anchor\" aria-label=\"Permalink: Channel Flow Coverage\" href=\"#channel-flow-coverage\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eChannel CJM coverage (ingress parsing/filtering, session key routing, account propagation, bus handoff) is validated by tests in:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003esrc/channel_manager.zig\u003c/code\u003e (runtime channel registration/start semantics + listener mode wiring)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esrc/config.zig\u003c/code\u003e (OpenClaw-compatible \u003ccode\u003echannels.*.accounts\u003c/code\u003e parsing, multi-account selection/ordering, aliases)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esrc/gateway.zig\u003c/code\u003e (Telegram/WhatsApp/LINE/Lark routed session keys from webhook payloads)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esrc/daemon.zig\u003c/code\u003e (gateway-loop inbound route resolution for Discord/QQ/OneBot/Mattermost/MaixCam)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esrc/channels/discord.zig\u003c/code\u003e, \u003ccode\u003esrc/channels/mattermost.zig\u003c/code\u003e, \u003ccode\u003esrc/channels/qq.zig\u003c/code\u003e, \u003ccode\u003esrc/channels/onebot.zig\u003c/code\u003e, \u003ccode\u003esrc/channels/signal.zig\u003c/code\u003e, \u003ccode\u003esrc/channels/line.zig\u003c/code\u003e, \u003ccode\u003esrc/channels/whatsapp.zig\u003c/code\u003e (per-channel inbound/outbound contracts)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eProject Stats\u003c/h3\u003e\u003ca id=\"user-content-project-stats\" class=\"anchor\" aria-label=\"Permalink: Project Stats\" href=\"#project-stats\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"Language:     Zig 0.16.0\nSource files: ~250\nLines of code: ~249,000\nTests:        5,300+\nBinary:       678 KB (ReleaseSmall)\nPeak RSS:     ~1 MB\nStartup:      \u0026lt;2 ms (Apple Silicon)\nDependencies: 0 (besides libc + optional SQLite)\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003eLanguage:     Zig 0.16.0\nSource files: ~250\nLines of code: ~249,000\nTests:        5,300+\nBinary:       678 KB (ReleaseSmall)\nPeak RSS:     ~1 MB\nStartup:      \u0026lt;2 ms (Apple Silicon)\nDependencies: 0 (besides libc + optional SQLite)\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSource Layout\u003c/h3\u003e\u003ca id=\"user-content-source-layout\" class=\"anchor\" aria-label=\"Permalink: Source Layout\" href=\"#source-layout\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"src/\n  main.zig              CLI entry point + argument parsing\n  root.zig              Module hierarchy (public API)\n  config.zig            JSON config loader + 30 sub-config structs\n  agent.zig             Agent loop, auto-compaction, tool dispatch\n  daemon.zig            Daemon supervisor with exponential backoff\n  gateway.zig           HTTP gateway (rate limiting, idempotency, pairing)\n  channels/             19 channel implementations (telegram, signal, discord, slack, nostr, matrix, whatsapp, line, lark, onebot, mattermost, qq, ...)\n  providers/            50+ AI provider integrations\n  memory/               SQLite backend, embeddings, vector search, hygiene, snapshots\n  tools/                35+ tool implementations\n  security/             Secrets (ChaCha20), sandbox backends (landlock, firejail, ...)\n  cron.zig              Cron scheduler with JSON persistence\n  health.zig            Component health registry\n  tunnel.zig            Tunnel vtable (cloudflare, ngrok, tailscale, custom)\n  peripherals.zig       Hardware peripheral vtable (serial, Arduino, RPi, Nucleo)\n  runtime.zig           Runtime vtable (native, docker, WASM)\n  skillforge.zig        Skill discovery (GitHub), evaluation, integration\n  ...\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003esrc/\n  main.zig              CLI entry point + argument parsing\n  root.zig              Module hierarchy (public API)\n  config.zig            JSON config loader + 30 sub-config structs\n  agent.zig             Agent loop, auto-compaction, tool dispatch\n  daemon.zig            Daemon supervisor with exponential backoff\n  gateway.zig           HTTP gateway (rate limiting, idempotency, pairing)\n  channels/             19 channel implementations (telegram, signal, discord, slack, nostr, matrix, whatsapp, line, lark, onebot, mattermost, qq, ...)\n  providers/            50+ AI provider integrations\n  memory/               SQLite backend, embeddings, vector search, hygiene, snapshots\n  tools/                35+ tool implementations\n  security/             Secrets (ChaCha20), sandbox backends (landlock, firejail, ...)\n  cron.zig              Cron scheduler with JSON persistence\n  health.zig            Component health registry\n  tunnel.zig            Tunnel vtable (cloudflare, ngrok, tailscale, custom)\n  peripherals.zig       Hardware peripheral vtable (serial, Arduino, RPi, Nucleo)\n  runtime.zig           Runtime vtable (native, docker, WASM)\n  skillforge.zig        Skill discovery (GitHub), evaluation, integration\n  ...\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVersioning\u003c/h2\u003e\u003ca id=\"user-content-versioning\" class=\"anchor\" aria-label=\"Permalink: Versioning\" href=\"#versioning\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003enullclaw uses \u003cstrong\u003eCalVer\u003c/strong\u003e (\u003ccode\u003eYYYY.M.D\u003c/code\u003e) for releases — e.g. \u003ccode\u003ev2026.2.20\u003c/code\u003e.\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eTag format:\u003c/strong\u003e \u003ccode\u003evYYYY.M.D\u003c/code\u003e (one release per day max; patch suffix \u003ccode\u003evYYYY.M.D.N\u003c/code\u003e if needed)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRelease binaries derive their embedded version from the git tag\u003c/strong\u003e (\u003ccode\u003ev...\u003c/code\u003e -\u0026gt; \u003ccode\u003enullclaw --version\u003c/code\u003e)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNon-release builds default to \u003ccode\u003edev\u003c/code\u003e\u003c/strong\u003e unless you override with \u003ccode\u003ezig build -Dversion=...\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNo stability guarantees yet\u003c/strong\u003e — the project is pre-1.0, config and CLI may change between releases\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003enullclaw --version\u003c/code\u003e\u003c/strong\u003e prints the current version\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eContributing\u003c/h2\u003e\u003ca id=\"user-content-contributing\" class=\"anchor\" aria-label=\"Permalink: Contributing\" href=\"#contributing\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSee \u003ca href=\"/nullclaw/nullclaw/blob/main/CONTRIBUTING.md\"\u003e\u003ccode\u003eCONTRIBUTING.md\u003c/code\u003e\u003c/a\u003e for development environment setup, workflow, validation commands, and the PR checklist.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eImplement a vtable interface, submit a PR:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNew \u003ccode\u003eProvider\u003c/code\u003e -\u0026gt; \u003ccode\u003esrc/providers/\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003eChannel\u003c/code\u003e -\u0026gt; \u003ccode\u003esrc/channels/\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003eTool\u003c/code\u003e -\u0026gt; \u003ccode\u003esrc/tools/\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003eMemory\u003c/code\u003e backend -\u0026gt; \u003ccode\u003esrc/memory/\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003eTunnel\u003c/code\u003e -\u0026gt; \u003ccode\u003esrc/tunnel.zig\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003eSandbox\u003c/code\u003e backend -\u0026gt; \u003ccode\u003esrc/security/\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003ePeripheral\u003c/code\u003e -\u0026gt; \u003ccode\u003esrc/peripherals.zig\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003eSkill\u003c/code\u003e -\u0026gt; \u003ccode\u003e~/.nullclaw/workspace/skills/\u0026lt;name\u0026gt;/\u003c/code\u003e or \u003ccode\u003e~/.nullclaw/workspace/skills/\u0026lt;category\u0026gt;/\u0026lt;name\u0026gt;/\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChinese Docs (中文文档)\u003c/h2\u003e\u003ca id=\"user-content-chinese-docs-中文文档\" class=\"anchor\" aria-label=\"Permalink: Chinese Docs (中文文档)\" href=\"#chinese-docs-中文文档\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/README.md\"\u003eChinese docs overview (中文文档总览)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/installation.md\"\u003eInstallation guide (安装指南)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/zig-installation.md\"\u003eZig installation (Zig 安装指南)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/configuration.md\"\u003eConfiguration guide (配置指南)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/usage.md\"\u003eUsage and operations (使用与运维)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/architecture.md\"\u003eArchitecture overview (架构总览)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/security.md\"\u003eSecurity model (安全机制)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/gateway-api.md\"\u003eGateway API (中文)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/commands.md\"\u003eCommands reference (命令参考)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/zh/development.md\"\u003eDevelopment guide (开发指南)\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eEnglish Docs\u003c/h2\u003e\u003ca id=\"user-content-english-docs\" class=\"anchor\" aria-label=\"Permalink: English Docs\" href=\"#english-docs\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/README.md\"\u003eEnglish docs overview\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/installation.md\"\u003eInstallation\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/zig-installation.md\"\u003eZig Installation\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/configuration.md\"\u003eConfiguration\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/usage.md\"\u003eUsage and operations\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/architecture.md\"\u003eArchitecture\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/security.md\"\u003eSecurity\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/gateway-api.md\"\u003eGateway API\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/commands.md\"\u003eCommands\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/nullclaw/nullclaw/blob/main/docs/en/development.md\"\u003eDevelopment\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDisclaimer\u003c/h2\u003e\u003ca id=\"user-content-disclaimer\" class=\"anchor\" aria-label=\"Permalink: Disclaimer\" href=\"#disclaimer\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003enullclaw is a pure open-source software project. It has \u003cstrong\u003eno token, no cryptocurrency, no blockchain component, and no financial instrument\u003c/strong\u003e of any kind. This project is not affiliated with any token or financial product.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLicense\u003c/h2\u003e\u003ca id=\"user-content-license\" class=\"anchor\" aria-label=\"Permalink: License\" href=\"#license\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eMIT — see \u003ca href=\"/nullclaw/nullclaw/blob/main/LICENSE\"\u003eLICENSE\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003enullclaw\u003c/strong\u003e — Null overhead. Null compromise. Deploy anywhere. Swap anything.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStar History\u003c/h2\u003e\u003ca id=\"user-content-star-history\" class=\"anchor\" aria-label=\"Permalink: Star History\" href=\"#star-history\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://www.star-history.com/#nullclaw/nullclaw\u0026amp;type=date\u0026amp;legend=top-left\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/6f6c8ccd4df24bf8571b31aad846a45109644fcf2459fa2af11765aaf1674723/68747470733a2f2f6170692e737461722d686973746f72792e636f6d2f7376673f7265706f733d6e756c6c636c61772f6e756c6c636c617726747970653d64617465266c6567656e643d746f702d6c656674\" alt=\"Star History Chart\" data-canonical-src=\"https://api.star-history.com/svg?repos=nullclaw/nullclaw\u0026amp;type=date\u0026amp;legend=top-left\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"Features","fully_qualified_name":"Features","kind":"section_3","ident_start":2031,"ident_end":2039,"extent_start":2027,"extent_end":2615,"ident_utf16":{"start":{"line_number":31,"utf16_col":4},"end":{"line_number":31,"utf16_col":12}},"extent_utf16":{"start":{"line_number":31,"utf16_col":0},"end":{"line_number":39,"utf16_col":0}}},{"name":"Why nullclaw","fully_qualified_name":"Why nullclaw","kind":"section_3","ident_start":2619,"ident_end":2631,"extent_start":2615,"extent_end":3126,"ident_utf16":{"start":{"line_number":39,"utf16_col":4},"end":{"line_number":39,"utf16_col":16}},"extent_utf16":{"start":{"line_number":39,"utf16_col":0},"end":{"line_number":46,"utf16_col":0}}},{"name":"Benchmark Snapshot","fully_qualified_name":"Benchmark Snapshot","kind":"section_2","ident_start":3129,"ident_end":3147,"extent_start":3126,"extent_end":4336,"ident_utf16":{"start":{"line_number":46,"utf16_col":3},"end":{"line_number":46,"utf16_col":21}},"extent_utf16":{"start":{"line_number":46,"utf16_col":0},"end":{"line_number":72,"utf16_col":0}}},{"name":"Documentation","fully_qualified_name":"Documentation","kind":"section_2","ident_start":4339,"ident_end":4352,"extent_start":4336,"extent_end":5905,"ident_utf16":{"start":{"line_number":72,"utf16_col":3},"end":{"line_number":72,"utf16_col":16}},"extent_utf16":{"start":{"line_number":72,"utf16_col":0},"end":{"line_number":93,"utf16_col":0}}},{"name":"Choose Your Path","fully_qualified_name":"Choose Your Path","kind":"section_2","ident_start":5908,"ident_end":5924,"extent_start":5905,"extent_end":7059,"ident_utf16":{"start":{"line_number":93,"utf16_col":3},"end":{"line_number":93,"utf16_col":19}},"extent_utf16":{"start":{"line_number":93,"utf16_col":0},"end":{"line_number":103,"utf16_col":0}}},{"name":"After This README","fully_qualified_name":"After This README","kind":"section_2","ident_start":7062,"ident_end":7079,"extent_start":7059,"extent_end":7533,"ident_utf16":{"start":{"line_number":103,"utf16_col":3},"end":{"line_number":103,"utf16_col":20}},"extent_utf16":{"start":{"line_number":103,"utf16_col":0},"end":{"line_number":109,"utf16_col":0}}},{"name":"Quick Start","fully_qualified_name":"Quick Start","kind":"section_2","ident_start":7536,"ident_end":7547,"extent_start":7533,"extent_end":10904,"ident_utf16":{"start":{"line_number":109,"utf16_col":3},"end":{"line_number":109,"utf16_col":14}},"extent_utf16":{"start":{"line_number":109,"utf16_col":0},"end":{"line_number":257,"utf16_col":0}}},{"name":"1) Recommended install (Homebrew)","fully_qualified_name":"1) Recommended install (Homebrew)","kind":"section_3","ident_start":7553,"ident_end":7586,"extent_start":7549,"extent_end":7725,"ident_utf16":{"start":{"line_number":111,"utf16_col":4},"end":{"line_number":111,"utf16_col":37}},"extent_utf16":{"start":{"line_number":111,"utf16_col":0},"end":{"line_number":120,"utf16_col":0}}},{"name":"2) Build from source","fully_qualified_name":"2) Build from source","kind":"section_3","ident_start":7729,"ident_end":7749,"extent_start":7725,"extent_end":8783,"ident_utf16":{"start":{"line_number":120,"utf16_col":4},"end":{"line_number":120,"utf16_col":24}},"extent_utf16":{"start":{"line_number":120,"utf16_col":0},"end":{"line_number":163,"utf16_col":0}}},{"name":"3) Run with Docker Compose","fully_qualified_name":"3) Run with Docker Compose","kind":"section_3","ident_start":8787,"ident_end":8813,"extent_start":8783,"extent_end":9792,"ident_utf16":{"start":{"line_number":163,"utf16_col":4},"end":{"line_number":163,"utf16_col":30}},"extent_utf16":{"start":{"line_number":163,"utf16_col":0},"end":{"line_number":209,"utf16_col":0}}},{"name":"4) Common commands","fully_qualified_name":"4) Common commands","kind":"section_3","ident_start":9796,"ident_end":9814,"extent_start":9792,"extent_end":10904,"ident_utf16":{"start":{"line_number":209,"utf16_col":4},"end":{"line_number":209,"utf16_col":22}},"extent_utf16":{"start":{"line_number":209,"utf16_col":0},"end":{"line_number":257,"utf16_col":0}}},{"name":"Edge MVP (Hybrid Host + WASM Logic)","fully_qualified_name":"Edge MVP (Hybrid Host + WASM Logic)","kind":"section_2","ident_start":10907,"ident_end":10942,"extent_start":10904,"extent_end":11217,"ident_utf16":{"start":{"line_number":257,"utf16_col":3},"end":{"line_number":257,"utf16_col":38}},"extent_utf16":{"start":{"line_number":257,"utf16_col":0},"end":{"line_number":265,"utf16_col":0}}},{"name":"Architecture","fully_qualified_name":"Architecture","kind":"section_2","ident_start":11220,"ident_end":11232,"extent_start":11217,"extent_end":14291,"ident_utf16":{"start":{"line_number":265,"utf16_col":3},"end":{"line_number":265,"utf16_col":15}},"extent_utf16":{"start":{"line_number":265,"utf16_col":0},"end":{"line_number":313,"utf16_col":0}}},{"name":"Memory System","fully_qualified_name":"Memory System","kind":"section_3","ident_start":13394,"ident_end":13407,"extent_start":13390,"extent_end":14291,"ident_utf16":{"start":{"line_number":285,"utf16_col":4},"end":{"line_number":285,"utf16_col":17}},"extent_utf16":{"start":{"line_number":285,"utf16_col":0},"end":{"line_number":313,"utf16_col":0}}},{"name":"Security","fully_qualified_name":"Security","kind":"section_2","ident_start":14294,"ident_end":14302,"extent_start":14291,"extent_end":16726,"ident_utf16":{"start":{"line_number":313,"utf16_col":3},"end":{"line_number":313,"utf16_col":11}},"extent_utf16":{"start":{"line_number":313,"utf16_col":0},"end":{"line_number":358,"utf16_col":0}}},{"name":"Channel Allowlists","fully_qualified_name":"Channel Allowlists","kind":"section_3","ident_start":15337,"ident_end":15355,"extent_start":15333,"extent_end":15737,"ident_utf16":{"start":{"line_number":328,"utf16_col":4},"end":{"line_number":328,"utf16_col":22}},"extent_utf16":{"start":{"line_number":328,"utf16_col":0},"end":{"line_number":336,"utf16_col":0}}},{"name":"Nostr Channel Setup","fully_qualified_name":"Nostr Channel Setup","kind":"section_3","ident_start":15741,"ident_end":15760,"extent_start":15737,"extent_end":16726,"ident_utf16":{"start":{"line_number":336,"utf16_col":4},"end":{"line_number":336,"utf16_col":23}},"extent_utf16":{"start":{"line_number":336,"utf16_col":0},"end":{"line_number":358,"utf16_col":0}}},{"name":"Configuration","fully_qualified_name":"Configuration","kind":"section_2","ident_start":16729,"ident_end":16742,"extent_start":16726,"extent_end":32450,"ident_utf16":{"start":{"line_number":358,"utf16_col":3},"end":{"line_number":358,"utf16_col":16}},"extent_utf16":{"start":{"line_number":358,"utf16_col":0},"end":{"line_number":763,"utf16_col":0}}},{"name":"Full Web Search + Shell Access","fully_qualified_name":"Full Web Search + Shell Access","kind":"section_3","ident_start":27270,"ident_end":27300,"extent_start":27266,"extent_end":29225,"ident_utf16":{"start":{"line_number":665,"utf16_col":4},"end":{"line_number":665,"utf16_col":34}},"extent_utf16":{"start":{"line_number":665,"utf16_col":0},"end":{"line_number":699,"utf16_col":0}}},{"name":"Web UI / Browser Relay","fully_qualified_name":"Web UI / Browser Relay","kind":"section_3","ident_start":29229,"ident_end":29251,"extent_start":29225,"extent_end":32450,"ident_utf16":{"start":{"line_number":699,"utf16_col":4},"end":{"line_number":699,"utf16_col":26}},"extent_utf16":{"start":{"line_number":699,"utf16_col":0},"end":{"line_number":763,"utf16_col":0}}},{"name":"Gateway API","fully_qualified_name":"Gateway API","kind":"section_2","ident_start":32453,"ident_end":32464,"extent_start":32450,"extent_end":35229,"ident_utf16":{"start":{"line_number":763,"utf16_col":3},"end":{"line_number":763,"utf16_col":14}},"extent_utf16":{"start":{"line_number":763,"utf16_col":0},"end":{"line_number":826,"utf16_col":0}}},{"name":"A2A (Agent-to-Agent Protocol v0.3.0)","fully_qualified_name":"A2A (Agent-to-Agent Protocol v0.3.0)","kind":"section_3","ident_start":33282,"ident_end":33318,"extent_start":33278,"extent_end":34820,"ident_utf16":{"start":{"line_number":776,"utf16_col":4},"end":{"line_number":776,"utf16_col":40}},"extent_utf16":{"start":{"line_number":776,"utf16_col":0},"end":{"line_number":822,"utf16_col":0}}},{"name":"Media transcription","fully_qualified_name":"Media transcription","kind":"section_3","ident_start":34824,"ident_end":34843,"extent_start":34820,"extent_end":35229,"ident_utf16":{"start":{"line_number":822,"utf16_col":4},"end":{"line_number":822,"utf16_col":23}},"extent_utf16":{"start":{"line_number":822,"utf16_col":0},"end":{"line_number":826,"utf16_col":0}}},{"name":"Commands","fully_qualified_name":"Commands","kind":"section_2","ident_start":35232,"ident_end":35240,"extent_start":35229,"extent_end":37099,"ident_utf16":{"start":{"line_number":826,"utf16_col":3},"end":{"line_number":826,"utf16_col":11}},"extent_utf16":{"start":{"line_number":826,"utf16_col":0},"end":{"line_number":853,"utf16_col":0}}},{"name":"Development","fully_qualified_name":"Development","kind":"section_2","ident_start":37102,"ident_end":37113,"extent_start":37099,"extent_end":39646,"ident_utf16":{"start":{"line_number":853,"utf16_col":3},"end":{"line_number":853,"utf16_col":14}},"extent_utf16":{"start":{"line_number":853,"utf16_col":0},"end":{"line_number":910,"utf16_col":0}}},{"name":"Channel Flow Coverage","fully_qualified_name":"Channel Flow Coverage","kind":"section_3","ident_start":37336,"ident_end":37357,"extent_start":37332,"extent_end":38127,"ident_utf16":{"start":{"line_number":863,"utf16_col":4},"end":{"line_number":863,"utf16_col":25}},"extent_utf16":{"start":{"line_number":863,"utf16_col":0},"end":{"line_number":873,"utf16_col":0}}},{"name":"Project Stats","fully_qualified_name":"Project Stats","kind":"section_3","ident_start":38131,"ident_end":38144,"extent_start":38127,"extent_end":38385,"ident_utf16":{"start":{"line_number":873,"utf16_col":4},"end":{"line_number":873,"utf16_col":17}},"extent_utf16":{"start":{"line_number":873,"utf16_col":0},"end":{"line_number":886,"utf16_col":0}}},{"name":"Source Layout","fully_qualified_name":"Source Layout","kind":"section_3","ident_start":38389,"ident_end":38402,"extent_start":38385,"extent_end":39646,"ident_utf16":{"start":{"line_number":886,"utf16_col":4},"end":{"line_number":886,"utf16_col":17}},"extent_utf16":{"start":{"line_number":886,"utf16_col":0},"end":{"line_number":910,"utf16_col":0}}},{"name":"Versioning","fully_qualified_name":"Versioning","kind":"section_2","ident_start":39649,"ident_end":39659,"extent_start":39646,"extent_end":40186,"ident_utf16":{"start":{"line_number":910,"utf16_col":3},"end":{"line_number":910,"utf16_col":13}},"extent_utf16":{"start":{"line_number":910,"utf16_col":0},"end":{"line_number":920,"utf16_col":0}}},{"name":"Contributing","fully_qualified_name":"Contributing","kind":"section_2","ident_start":40189,"ident_end":40201,"extent_start":40186,"extent_end":40750,"ident_utf16":{"start":{"line_number":920,"utf16_col":3},"end":{"line_number":920,"utf16_col":15}},"extent_utf16":{"start":{"line_number":920,"utf16_col":0},"end":{"line_number":935,"utf16_col":0}}},{"name":"Chinese Docs (中文文档)","fully_qualified_name":"Chinese Docs (中文文档)","kind":"section_2","ident_start":40753,"ident_end":40780,"extent_start":40750,"extent_end":41397,"ident_utf16":{"start":{"line_number":935,"utf16_col":3},"end":{"line_number":935,"utf16_col":22}},"extent_utf16":{"start":{"line_number":935,"utf16_col":0},"end":{"line_number":948,"utf16_col":0}}},{"name":"English Docs","fully_qualified_name":"English Docs","kind":"section_2","ident_start":41400,"ident_end":41412,"extent_start":41397,"extent_end":41829,"ident_utf16":{"start":{"line_number":948,"utf16_col":3},"end":{"line_number":948,"utf16_col":15}},"extent_utf16":{"start":{"line_number":948,"utf16_col":0},"end":{"line_number":961,"utf16_col":0}}},{"name":"Disclaimer","fully_qualified_name":"Disclaimer","kind":"section_2","ident_start":41832,"ident_end":41842,"extent_start":41829,"extent_end":42068,"ident_utf16":{"start":{"line_number":961,"utf16_col":3},"end":{"line_number":961,"utf16_col":13}},"extent_utf16":{"start":{"line_number":961,"utf16_col":0},"end":{"line_number":965,"utf16_col":0}}},{"name":"License","fully_qualified_name":"License","kind":"section_2","ident_start":42071,"ident_end":42078,"extent_start":42068,"extent_end":42199,"ident_utf16":{"start":{"line_number":965,"utf16_col":3},"end":{"line_number":965,"utf16_col":10}},"extent_utf16":{"start":{"line_number":965,"utf16_col":0},"end":{"line_number":973,"utf16_col":0}}},{"name":"Star History","fully_qualified_name":"Star History","kind":"section_2","ident_start":42202,"ident_end":42214,"extent_start":42199,"extent_end":42399,"ident_utf16":{"start":{"line_number":973,"utf16_col":3},"end":{"line_number":973,"utf16_col":15}},"extent_utf16":{"start":{"line_number":973,"utf16_col":0},"end":{"line_number":976,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":1159542259,"defaultBranch":"main","name":"nullclaw","ownerLogin":"nullclaw","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2026-02-16T21:17:27.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/262007611?v=4","public":true,"private":false,"isOrgOwned":true,"isArchived":false},"currentUser":null,"uploadToken":"gapwwfTbtpCp9dsKi-Y7V1f3UsT_gMAG8OikHapCMz0EC3dUJCjzb_X4sFVexOBY8GahsHX58gFFb2aEYu1iYw","allShortcutsEnabled":false,"treeExpanded":true,"path":"README.md","symbolsExpanded":false,"refInfo":{"name":"main","listCacheKey":"v0:1791453467.0","canEdit":false,"currentOid":"5f1cade05c19b6ecdfb9565ae3305e892e484da9"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"":{"items":[{"name":".githooks","path":".githooks","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"examples","path":"examples","contentType":"directory"},{"name":"spec","path":"spec","contentType":"directory"},{"name":"src","path":"src","contentType":"directory"},{"name":"vendor","path":"vendor","contentType":"directory"},{"name":".dockerignore","path":".dockerignore","contentType":"file"},{"name":".env.example","path":".env.example","contentType":"file"},{"name":".envrc","path":".envrc","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"AGENTS.md","path":"AGENTS.md","contentType":"file"},{"name":"CLAUDE.md","path":"CLAUDE.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"Dockerfile","path":"Dockerfile","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"Makefile","path":"Makefile","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"RELEASING.md","path":"RELEASING.md","contentType":"file"},{"name":"SECURITY-PATCH-PLAN-2026-05-10.md","path":"SECURITY-PATCH-PLAN-2026-05-10.md","contentType":"file"},{"name":"SECURITY.md","path":"SECURITY.md","contentType":"file"},{"name":"SIGNAL.md","path":"SIGNAL.md","contentType":"file"},{"name":"build.zig","path":"build.zig","contentType":"file"},{"name":"build.zig.zon","path":"build.zig.zon","contentType":"file"},{"name":"build.zig.zon2json-lock","path":"build.zig.zon2json-lock","contentType":"file"},{"name":"config.example.json","path":"config.example.json","contentType":"file"},{"name":"docker-compose.signal.yml","path":"docker-compose.signal.yml","contentType":"file"},{"name":"docker-compose.yml","path":"docker-compose.yml","contentType":"file"},{"name":"flake.lock","path":"flake.lock","contentType":"file"},{"name":"flake.nix","path":"flake.nix","contentType":"file"},{"name":"nullclaw.png","path":"nullclaw.png","contentType":"file"},{"name":"run","path":"run","contentType":"file"}],"totalCount":32}},"fileTreeProcessingTime":24.61864,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"main","listCacheKey":"v0:1791453467.0","canEdit":false,"refType":"branch","currentOid":"5f1cade05c19b6ecdfb9565ae3305e892e484da9","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"README.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/nullclaw/nullclaw/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"README.md","displayUrl":"https://github.com/nullclaw/nullclaw/blob/main/README.md?raw=true","headerInfo":{"blobSize":"41.4 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"e23c4ec","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fnullclaw%2Fnullclaw%2Fblob%2Fmain%2FREADME.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"976","truncatedSloc":"792"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/nullclaw/nullclaw/blob/main/README.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/nullclaw/nullclaw/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/nullclaw/nullclaw/raw/refs/heads/main/README.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["Want a simpler way to install and configure nullclaw with a UI? Try [nullhub](https://github.com/nullclaw/nullhub)! (currently in beta)","","[nullhub](https://github.com/nullclaw/nullhub) provides a UI layer for the Null ecosystem: simpler nullclaw setup and configuration, orchestration from [nullboiler](https://github.com/nullclaw/nullboiler), observability from [nullwatch](https://github.com/nullclaw/nullwatch), and task tracking from [nulltickets](https://github.com/nullclaw/nulltickets).","","\u003cp align=\"center\"\u003e","  \u003cimg src=\"nullclaw.png\" alt=\"nullclaw\" width=\"200\" /\u003e","\u003c/p\u003e","","\u003ch1 align=\"center\"\u003eNullClaw\u003c/h1\u003e","","\u003cp align=\"center\"\u003e","  \u003cstrong\u003eNull overhead. Null compromise. 100% Zig. 100% Agnostic.\u003c/strong\u003e\u003cbr\u003e","  \u003cstrong\u003e678 KB binary. ~1 MB RAM. Boots in \u003c2 ms. Runs on anything with a CPU.\u003c/strong\u003e","\u003c/p\u003e","","\u003cp align=\"center\"\u003e","  \u003ca href=\"https://github.com/nullclaw/nullclaw/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/nullclaw/nullclaw/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" /\u003e\u003c/a\u003e","  \u003ca href=\"https://github.com/nullclaw/nullclaw/actions/workflows/nightly.yml\"\u003e\u003cimg src=\"https://github.com/nullclaw/nullclaw/actions/workflows/nightly.yml/badge.svg\" alt=\"Nightly\" /\u003e\u003c/a\u003e","  \u003ca href=\"https://nullclaw.github.io\"\u003e\u003cimg src=\"https://img.shields.io/badge/docs-nullclaw.github.io-informational\" alt=\"Documentation\" /\u003e\u003c/a\u003e","  \u003ca href=\"https://discord.gg/Bfmdua22Ud\"\u003e\u003cimg src=\"https://img.shields.io/badge/discord-join%20community-5865F2?logo=discord\u0026logoColor=white\" alt=\"Discord\" /\u003e\u003c/a\u003e","  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License: MIT\" /\u003e\u003c/a\u003e","\u003c/p\u003e","","The smallest fully autonomous AI assistant infrastructure — a static Zig binary that fits on any $5 board, boots in milliseconds, and requires nothing but libc.","","Docs: [English](docs/en/README.md) · [中文](docs/zh/README.md) · [Contributing](CONTRIBUTING.md) · [Discord](https://discord.gg/Bfmdua22Ud)","","```","678 KB binary · \u003c2 ms startup · 5,300+ tests · 50+ providers · 19 channels · Pluggable everything","```","","### Features","","- **Impossibly Small:** 678 KB static binary — no runtime, no VM, no framework overhead.","- **Near-Zero Memory:** ~1 MB peak RSS. Runs comfortably on the cheapest ARM SBCs and microcontrollers.","- **Instant Startup:** \u003c2 ms on Apple Silicon, \u003c8 ms on a 0.8 GHz edge core.","- **True Portability:** Single self-contained binary across ARM, x86, and RISC-V. Drop it anywhere, it just runs.","- **Feature-Complete:** 50+ providers, 19 channels, 35+ tools, 10 memory engines, multi-layer sandbox, tunnels, hardware peripherals, MCP, subagents, streaming, voice — the full stack.","","### Why nullclaw","","- **Lean by default:** Zig compiles to a tiny static binary. No allocator overhead, no garbage collector, no runtime.","- **Secure by design:** pairing, strict sandboxing (landlock, firejail, bubblewrap, docker), explicit allowlists, workspace scoping, encrypted secrets.","- **Fully swappable:** core systems are vtable interfaces (providers, channels, tools, memory, tunnels, peripherals, observers, runtimes).","- **No lock-in:** OpenAI-compatible provider support + pluggable custom endpoints.","","## Benchmark Snapshot","","Local machine benchmark (macOS arm64, Feb 2026), normalized for 0.8 GHz edge hardware.","","| | [OpenClaw](https://github.com/openclaw/openclaw) | [NanoBot](https://github.com/HKUDS/nanobot) | [PicoClaw](https://github.com/sipeed/picoclaw) | [ZeroClaw](https://github.com/zeroclaw-labs/zeroclaw) | **[🦞 NullClaw](https://github.com/nullclaw/nullclaw)** |","|---|---|---|---|---|---|","| **Language** | TypeScript | Python | Go | Rust | **Zig** |","| **RAM** | \u003e 1 GB | \u003e 100 MB | \u003c 10 MB | \u003c 5 MB | **~1 MB** |","| **Startup (0.8 GHz)** | \u003e 500 s | \u003e 30 s | \u003c 1 s | \u003c 10 ms | **\u003c 8 ms** |","| **Binary Size** | ~28 MB (dist) | N/A (Scripts) | ~8 MB | ~8.8 MB | **678 KB** |","| **Tests** | — | — | — | 1,017 | **5,300+** |","| **Source Files** | ~400+ | — | — | ~120 | **~230** |","| **Cost** | Mac Mini $599 | Linux SBC ~$50 | Linux Board $10 | Any $10 hardware | **Any $5 hardware** |","","\u003e Measured with `/usr/bin/time -l` on ReleaseSmall builds. nullclaw is a static binary with zero runtime dependencies.","","Reproduce locally:","","```bash","zig build -Doptimize=ReleaseSmall","ls -lh zig-out/bin/nullclaw","","/usr/bin/time -l zig-out/bin/nullclaw --help","/usr/bin/time -l zig-out/bin/nullclaw status","```","","## Documentation","","Start here if you want the shortest path to install, configure, operate, or extend nullclaw.","","Localized documentation lives under `docs/en/` and `docs/zh/`. Use the links below to jump straight to the page you need.","","| Need | English | 中文 |","|---|---|---|","| Start here | [`docs/en/README.md`](docs/en/README.md) | [`docs/zh/README.md`](docs/zh/README.md) |","| Install | [`docs/en/installation.md`](docs/en/installation.md) | [`docs/zh/installation.md`](docs/zh/installation.md) |","| Install Zig | [`docs/en/zig-installation.md`](docs/en/zig-installation.md) | [`docs/zh/zig-installation.md`](docs/zh/zig-installation.md) |","| Configure | [`docs/en/configuration.md`](docs/en/configuration.md) | [`docs/zh/configuration.md`](docs/zh/configuration.md) |","| Commands | [`docs/en/commands.md`](docs/en/commands.md) | [`docs/zh/commands.md`](docs/zh/commands.md) |","| Development | [`docs/en/development.md`](docs/en/development.md) | [`docs/zh/development.md`](docs/zh/development.md) |","| Operations | [`docs/en/usage.md`](docs/en/usage.md) | [`docs/zh/usage.md`](docs/zh/usage.md) |","| Architecture | [`docs/en/architecture.md`](docs/en/architecture.md) | [`docs/zh/architecture.md`](docs/zh/architecture.md) |","| Security | [`docs/en/security.md`](docs/en/security.md) | [`docs/zh/security.md`](docs/zh/security.md) |","| Gateway API | [`docs/en/gateway-api.md`](docs/en/gateway-api.md) | [`docs/zh/gateway-api.md`](docs/zh/gateway-api.md) |","","- Specialized guides: [`CONTRIBUTING.md`](CONTRIBUTING.md), [`SECURITY.md`](SECURITY.md), [`SIGNAL.md`](SIGNAL.md)","","## Choose Your Path","","| Goal | Open this first | Then go to |","|---|---|---|","| First run in English | [`docs/en/README.md`](docs/en/README.md) | [`docs/en/installation.md`](docs/en/installation.md) → [`docs/en/configuration.md`](docs/en/configuration.md) → [`docs/en/usage.md`](docs/en/usage.md) |","| Chinese Quick Start (中文快速上手) | [`docs/zh/README.md`](docs/zh/README.md) | [`docs/zh/installation.md`](docs/zh/installation.md) → [`docs/zh/configuration.md`](docs/zh/configuration.md) → [`docs/zh/usage.md`](docs/zh/usage.md) |","| Find the right CLI command | [`docs/en/commands.md`](docs/en/commands.md) / [`docs/zh/commands.md`](docs/zh/commands.md) | `nullclaw help` → task-specific subcommand page |","| Contribute code or docs | [`CONTRIBUTING.md`](CONTRIBUTING.md) | [`docs/en/development.md`](docs/en/development.md) / [`docs/zh/development.md`](docs/zh/development.md) → relevant architecture page |","| Operate or secure a deployment | [`docs/en/usage.md`](docs/en/usage.md) / [`docs/zh/usage.md`](docs/zh/usage.md) | [`docs/en/security.md`](docs/en/security.md) / [`docs/zh/security.md`](docs/zh/security.md) → Gateway API |","","## After This README","","- New here: jump to [`docs/en/README.md`](docs/en/README.md) or [`docs/zh/README.md`](docs/zh/README.md) and follow the guided reading order.","- Want commands fast: open [`docs/en/commands.md`](docs/en/commands.md) or [`docs/zh/commands.md`](docs/zh/commands.md).","- Want to submit a PR: start with [`CONTRIBUTING.md`](CONTRIBUTING.md), then read [`docs/en/development.md`](docs/en/development.md) or [`docs/zh/development.md`](docs/zh/development.md).","","## Quick Start","","### 1) Recommended install (Homebrew)","","The simplest path: install a ready-to-run binary with no extra runtime dependencies.","","```bash","brew install nullclaw","nullclaw --help","```","","### 2) Build from source","","\u003e **Prerequisite:** use **Zig 0.16.0** (exact version).","\u003e Other Zig versions are currently unsupported and may fail to build.","\u003e Verify before building: `zig version` should print `0.16.0`.","\u003e Debian users who need Zig first can follow [`docs/en/zig-installation.md`](docs/en/zig-installation.md).","","```bash","git clone https://github.com/nullclaw/nullclaw.git","cd nullclaw","zig build -Doptimize=ReleaseSmall","zig build test --summary all","```","","Make `nullclaw` available on `PATH`:","","macOS/Linux (zsh/bash):","","```bash","zig build -Doptimize=ReleaseSmall -p \"$HOME/.local\"","echo 'export PATH=\"$HOME/.local/bin:$PATH\"' \u003e\u003e ~/.zshrc","# or ~/.bashrc","```","","Windows (PowerShell):","","```powershell","zig build -Doptimize=ReleaseSmall -p \"$HOME\\.local\"","","$bin = \"$HOME\\.local\\bin\"","$user_path = [Environment]::GetEnvironmentVariable(\"Path\", \"User\")","if (-not ($user_path -split \";\" | Where-Object { $_ -eq $bin })) {","  [Environment]::SetEnvironmentVariable(\"Path\", \"$user_path;$bin\", \"User\")","}","$env:Path = \"$env:Path;$bin\"","```","","Then:","","```bash","nullclaw --help","```","","### 3) Run with Docker Compose","","The repository includes a Makefile wrapper around Docker Compose for local","containerized runs.","","```bash","make build","make config","make up","```","","`make config` runs `nullclaw onboard --interactive` inside the agent container.","Pass only non-secret flags through `CONFIG_ARGS`:","","```bash","make config CONFIG_ARGS=\"--provider openrouter\"","```","","Avoid putting API keys or bot tokens in `CONFIG_ARGS`; command-line arguments","can be exposed through shell history and process listings.","","The compose gateway defaults to `NULLCLAW_PORT=3210`, binds inside the","container on `0.0.0.0`, and publishes to localhost on the host:","","```bash","curl http://127.0.0.1:3210/health","```","","Override the port or host bind address when needed:","","```bash","make up NULLCLAW_PORT=8080","make up NULLCLAW_BIND=0.0.0.0","```","","Operational shortcuts:","","```bash","make logs","make down","make shell","```","","Only set `NULLCLAW_BIND=0.0.0.0` on trusted networks with pairing, webhook","secrets, allowlists, and host firewall rules configured.","","### 4) Common commands","","```bash","","# Quick setup","nullclaw onboard --api-key sk-... --provider openrouter","","# Or interactive wizard","nullclaw onboard --interactive","","# Chat","nullclaw agent -m \"Hello, nullclaw!\"","","# Interactive mode","nullclaw agent","","# Start gateway runtime (gateway + all configured channels/accounts + heartbeat + scheduler)","nullclaw gateway                # default: 127.0.0.1:3000","nullclaw gateway --port 8080    # custom port","","# Check status","nullclaw status","","# Run system diagnostics","nullclaw doctor","","# Check channel health","nullclaw channel status","","# Start specific channels","nullclaw channel start telegram","nullclaw channel start discord","nullclaw channel start signal","","# Manage background service","# Linux supports systemd user services and OpenRC","nullclaw service install","nullclaw service status","","# Optional secret injection hook for service mode:","# if ~/.nullclaw/service-env is executable, the installed service launcher runs it","# before starting `nullclaw gateway` (for example via dotenvx or sops)","","# Migrate memory from OpenClaw","nullclaw migrate openclaw --dry-run","nullclaw migrate openclaw","```","","## Edge MVP (Hybrid Host + WASM Logic)","","If you want edge deployment (Cloudflare Worker) with Telegram + OpenAI while keeping agent policy in WASM, see:","","`examples/edge/cloudflare-worker/`","","This pattern keeps networking/secrets in the edge host and lets you swap/update logic by replacing a tiny Zig WASM module.","","## Architecture","","Every subsystem is a **vtable interface** — swap implementations with a config change, zero code changes.","","| Subsystem | Interface | Ships with | Extend |","|-----------|-----------|------------|--------|","| **AI Models** | `Provider` | 50+ providers (OpenRouter, Anthropic, OpenAI, Azure OpenAI, Gemini, Vertex AI, Ollama, Venice, NEAR AI Cloud, Atlas Cloud, Evolink, Eden AI, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, and many OpenAI-compatible endpoints) | `custom:https://your-api.com` — any OpenAI-compatible API |","| **Channels** | `Channel` | CLI, Telegram, Signal, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook, IRC, Lark/Feishu, OneBot, Line, DingTalk, Email, Nostr, QQ, MaixCam, Mattermost | Any messaging API |","| **Memory** | `Memory` | SQLite with hybrid search (FTS5 + vector cosine similarity), Markdown, ClickHouse, PostgreSQL, Redis, LanceDB, Lucid, LRU, API | Any persistence backend |","| **Tools** | `Tool` | shell, file_read, file_write, file_edit, file_edit_hashed, file_read_hashed, file_append, memory_store, memory_recall, memory_forget, memory_list, browser_open, screenshot, composio, http_request, web_fetch, web_search, delegate, schedule, hardware_info, hardware_memory, pushover, message, spawn, git, image, i2c, spi, and more | Any capability |","| **Observability** | `Observer` | Noop, Log, File, Multi | Prometheus, OTel |","| **Runtime** | `RuntimeAdapter` | Native, Docker (sandboxed), WASM (wasmtime) | Any runtime |","| **Security** | `Sandbox` | Landlock, Firejail, Bubblewrap, Docker, auto-detect | Any sandbox backend |","| **Identity** | `IdentityConfig` | OpenClaw (markdown), AIEOS v1.1 (JSON) | Any identity format |","| **Tunnel** | `Tunnel` | None, Cloudflare, Tailscale, ngrok, Custom | Any tunnel binary |","| **Heartbeat** | Engine | HEARTBEAT.md periodic tasks | — |","| **Skills** | Loader | TOML/JSON manifests or YAML frontmatter in `SKILL.md` | Community skill packs |","| **Peripherals** | `Peripheral` | Serial, Arduino, Raspberry Pi GPIO, STM32/Nucleo | Any hardware interface |","| **Cron** | Scheduler | Cron expressions + one-shot timers with JSON persistence | — |","","### Memory System","","All custom, zero external dependencies for the core path:","","| Layer | Implementation |","|-------|---------------|","| **Vector DB** | Embeddings stored as BLOB in SQLite, cosine similarity search |","| **Keyword Search** | FTS5 virtual tables with BM25 scoring |","| **Hybrid Merge** | Weighted merge (configurable vector/keyword weights) |","| **Embeddings** | `EmbeddingProvider` vtable — OpenAI, custom URL, or noop |","| **Hygiene** | Automatic archival + purge of stale memories |","| **Snapshots** | Export/import full memory state for migration |","| **Engines** | SQLite (default), Markdown, ClickHouse, PostgreSQL, Redis, LanceDB, Lucid, LRU, API, None |","","```json","{","  \"memory\": {","    \"backend\": \"sqlite\",","    \"auto_save\": true,","    \"embedding_provider\": \"openai\",","    \"vector_weight\": 0.7,","    \"keyword_weight\": 0.3,","    \"hygiene_enabled\": true,","    \"snapshot_enabled\": false","  }","}","```","","## Security","","nullclaw enforces security at **every layer**.","","| # | Item | Status | How |","|---|------|--------|-----|","| 1 | **Gateway not publicly exposed** | Done | Binds `127.0.0.1` by default. Refuses `0.0.0.0` without tunnel or explicit `allow_public_bind`. |","| 2 | **Pairing required** | Done | 6-digit one-time code on startup. Exchange via `POST /pair` for bearer token. |","| 3 | **Filesystem scoped** | Done | `workspace_only = true` by default. Null byte injection blocked. Symlink escape detection. |","| 4 | **Access via tunnel only** | Done | Gateway refuses public bind without active tunnel. Supports Tailscale, Cloudflare, ngrok, or custom. |","| 5 | **Sandbox isolation** | Done | Auto-detects best backend: Landlock, Firejail, Bubblewrap, or Docker. |","| 6 | **Encrypted secrets** | Done | API keys encrypted with ChaCha20-Poly1305 using local key file. |","| 7 | **Resource limits** | Done | Configurable memory, CPU, disk, and subprocess limits. |","| 8 | **Audit logging** | Done | Signed event trail with configurable retention. |","","### Channel Allowlists","","- Empty allowlist = **deny all inbound messages**","- `\"*\"` = **allow all** (explicit opt-in)","- Otherwise = exact-match allowlist","","Nostr additionally: the `owner_pubkey` is **always** allowed regardless of `dm_allowed_pubkeys`. Private keys are encrypted at rest via SecretStore (`enc2:` prefix) and only decrypted into memory while the channel is running; zeroed on channel stop.","","### Nostr Channel Setup","","`nullclaw` speaks Nostr natively via NIP-17 (gift-wrapped private DMs) and NIP-04 (legacy DMs), using [`nak`](https://github.com/fiatjaf/nak).","","**Prerequisites:** Install `nak` and ensure it's in your `$PATH`.","","**Setup via onboarding wizard:**","","```bash","nullclaw onboard --interactive   # Step 7 configures Nostr","```","","The wizard will:","1. Generate a new keypair for your bot or import a key \u0026 encrypt it with ChaCha20-Poly1305","2. Ask for your (owner) pubkey (npub or hex) — always allowed through DM policy","3. Configure relays and DM relays (kind:10050 inbox)","4. Display the bot's pubkey","","Or configure manually in the [config](#configuration).","","**How it works:** On startup, nullclaw announces its DM inbox relays (kind:10050), then listens for incoming NIP-17 gift wraps and NIP-04 encrypted DMs. Outbound messages mirror the sender's protocol. Multi-relay rumor deduplication prevents duplicate responses when the same message is delivered via multiple relays.","","## Configuration","","Config: `~/.nullclaw/config.json` (created by `onboard`)","","\u003e **OpenClaw compatible:** nullclaw uses the same config structure as [OpenClaw](https://github.com/openclaw/openclaw) (snake_case). Providers live under `models.providers`, the default model under `agents.defaults.model.primary`, and channels use `accounts` wrappers.","\u003e Top-level `default_provider` / `default_model` keys are not supported.","\u003e","\u003e **Vertex AI note:** `models.providers.vertex.api_key` supports either:","\u003e 1. a bearer token (`ya29...`), or","\u003e 2. a full Google service-account JSON object (same shape as Apps Script `GEMINI_KEY` with `project_id`, `client_email`, `private_key`).","\u003e","\u003e `models.providers.vertex.base_url` can be set explicitly (`.../projects/\u003cid\u003e/locations/\u003cloc\u003e/publishers/google/models`), or omitted when service-account JSON is used (nullclaw will derive it from `project_id`, with `VERTEX_LOCATION` defaulting to `global`).","\u003e Service-account mode requires `openssl` available in `$PATH` for RS256 JWT signing.","","```json","{","  \"default_temperature\": 0.7,","","  \"models\": {","    \"providers\": {","      \"openrouter\": { \"api_key\": \"sk-or-...\" },","      \"nearai\": { \"api_key\": \"YOUR_NEARAI_API_KEY\" },","      \"atlas-cloud\": { \"api_key\": \"YOUR_ATLASCLOUD_API_KEY\" },","      \"evolink\": { \"api_key\": \"YOUR_EVOLINK_API_KEY\" },","      \"edenai\": { \"api_key\": \"YOUR_EDENAI_API_KEY\" },","      \"groq\": { \"api_key\": \"gsk_...\" },","      \"azure\": { \"api_key\": \"YOUR_AZURE_OPENAI_API_KEY\", \"base_url\": \"https://your-resource.openai.azure.com\" },","      \"vertex\": {","        \"api_key\": {","          \"type\": \"service_account\",","          \"project_id\": \"your-project\",","          \"client_email\": \"svc@your-project.iam.gserviceaccount.com\",","          \"private_key\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n\"","        },","        \"base_url\": \"https://aiplatform.googleapis.com/v1/projects/your-project/locations/global/publishers/google/models\"","      },","      \"anthropic\": { \"api_key\": \"sk-ant-...\" }","    }","  },","","  \"agents\": {","    \"defaults\": {","      \"model\": { \"primary\": \"openrouter/anthropic/claude-sonnet-4\" },","      \"heartbeat\": { \"every\": \"30m\" }","    },","    \"list\": [","      { \"id\": \"researcher\", \"model\": { \"primary\": \"openrouter/anthropic/claude-opus-4\" }, \"system_prompt\": \"...\" }","    ]","  },","","  \"channels\": {","    \"telegram\": {","      \"accounts\": {","        \"main\": {","          \"bot_token\": \"123:ABC\",","          \"allow_from\": [\"user1\"],","          \"reply_in_private\": true,","          \"proxy\": \"socks5://...\"","        }","      }","    },","    \"discord\": {","      \"accounts\": {","        \"main\": {","          \"token\": \"disc-token\",","          \"guild_id\": \"12345\",","          \"allow_from\": [\"user1\"],","          \"allow_bots\": false","        }","      }","    },","    \"irc\": {","      \"accounts\": {","        \"main\": {","          \"host\": \"irc.libera.chat\",","          \"port\": 6697,","          \"nick\": \"nullclaw\",","          \"channels\": [\"#nullclaw\"],","          \"tls\": true,","          \"allow_from\": [\"user1\"]","        },","        \"meshrelay\": {","          \"host\": \"irc.meshrelay.xyz\",","          \"port\": 6697,","          \"nick\": \"nullclaw\",","          \"channels\": [\"#agents\"],","          \"tls\": true,","          \"nickserv_password\": \"YOUR_NICKSERV_PASSWORD\",","          \"allow_from\": [\"*\"]","        }","      }","    },","    \"slack\": {","      \"accounts\": {","        \"main\": {","          \"bot_token\": \"xoxb-...\",","          \"app_token\": \"xapp-...\",","          \"allow_from\": [\"user1\"]","        }","      }","    },","    \"nostr\": {","      \"private_key\": \"enc2:...\",","      \"owner_pubkey\": \"hex-pubkey-of-owner\",","      \"relays\": [\"wss://relay.damus.io\", \"wss://nos.lol\", \"wss://relay.nostr.band\"],","      \"dm_allowed_pubkeys\": [\"*\"],","      \"display_name\": \"NullClaw\",","      \"about\": \"AI assistant on Nostr\",","      \"nip05\": \"nullclaw@yourdomain.com\",","      \"lnurl\": \"lnurl1...\"","    }","  },","","  \"tools\": {","    \"media\": {","      \"audio\": {","        \"enabled\": true,","        \"language\": \"ru\",","        \"models\": [{ \"provider\": \"groq\", \"model\": \"whisper-large-v3\" }]","      }","    }","  },","","  \"mcp_servers\": {","    \"filesystem\": {","      \"transport\": \"stdio\",","      \"command\": \"npx\",","      \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\"],","      \"timeout_ms\": 10000","    },","    \"remote\": {","      \"transport\": \"http\",","      \"url\": \"https://mcp.example.com/rpc\",","      \"timeout_ms\": 10000,","      \"headers\": {","        \"Authorization\": \"Bearer example-token\"","      }","    }","  },","","  \"memory\": {","    \"backend\": \"sqlite\",","    \"auto_save\": true,","    \"embedding_provider\": \"openai\",","    \"vector_weight\": 0.7,","    \"keyword_weight\": 0.3","  },","","  \"gateway\": {","    \"port\": 3000,","    \"require_pairing\": true,","    \"allow_public_bind\": false","  },","","  \"autonomy\": {","    \"level\": \"supervised\",","    \"workspace_only\": true,","    \"max_actions_per_hour\": 20","  },","","  \"runtime\": {","    \"kind\": \"native\",","    \"docker\": {","      \"image\": \"alpine:3.24\",","      \"network\": \"none\",","      \"memory_limit_mb\": 512,","      \"read_only_rootfs\": true","    }","  },","","","  \"tunnel\": { \"provider\": \"none\" },","  \"secrets\": { \"encrypt\": true },","  \"identity\": { \"format\": \"openclaw\" },","","  \"security\": {","    \"sandbox\": { \"backend\": \"auto\" },","    \"resources\": { \"max_memory_mb\": 512, \"max_cpu_percent\": 80 },","    \"audit\": { \"enabled\": true, \"retention_days\": 90 }","  }","}","```","","Config values are literal. NullClaw does not expand `${VAR}` inside `config.json`","strings, including custom header values. If you need environment-based secrets,","render `config.json` ahead of time with your own deployment tooling.","MCP `timeout_ms` bounds each HTTP or stdio request; a timed-out stdio server is","terminated with its launcher process group so blocked child processes do not remain.","","Telegram forum topics:","","- Topic session isolation is automatic. You do not add a `topic_id` field under `channels.telegram`.","- The easiest operator flow is:","  1. define named agent profiles under `agents.list`","  2. open the target Telegram chat or forum topic","  3. run `/bind \u003cagent\u003e`","- To bind a specific Telegram forum topic to a specific agent, use `bindings[].match.peer.id` with the canonical thread form `\"\u003cchat_id\u003e:thread:\u003ctopic_id\u003e\"`.","- To bind the whole Telegram group as a fallback for all other topics, keep a normal group binding with `\"\u003cchat_id\u003e\"`.","- `/bind status` shows the current effective route and the available agent ids.","- `/bind clear` removes only the exact binding for the current account/chat/topic and falls back to the broader route.","- `/bind` persists an exact `bindings[]` entry for the current Telegram account and peer.","- `/bind status` distinguishes an exact local override from an inherited broader fallback.","- Topic-specific bindings win over group fallback by route priority; the order in `bindings[]` does not matter.","- Telegram menu visibility for `/bind` is controlled by `channels.telegram.accounts.\u003cid\u003e.binding_commands_enabled`.","","Example:","","```json","{","  \"bindings\": [","    {","      \"agent_id\": \"coder\",","      \"match\": {","        \"channel\": \"telegram\",","        \"account_id\": \"main\",","        \"peer\": { \"kind\": \"group\", \"id\": \"-1001234567890:thread:42\" }","      }","    },","    {","      \"agent_id\": \"orchestrator\",","      \"match\": {","        \"channel\": \"telegram\",","        \"account_id\": \"main\",","        \"peer\": { \"kind\": \"group\", \"id\": \"-1001234567890\" }","      }","    }","  ]","}","```","","In that setup, topic `42` routes to `coder`, while the rest of the forum falls back to `orchestrator`.","","Named agent profiles are configured separately from bindings. Bindings only choose which named agent handles a given chat/topic.","","If a named agent should run from its own workspace, set `agents.list[].workspace_path`.","Relative paths are resolved from the directory that contains `config.json`, the workspace is scaffolded on first use, and the agent gets a durable memory namespace `agent:\u003cagent-id\u003e`.","Setting `workspace_path` does not disable `system_prompt`: when both are configured, the named profile prompt is still applied and the workspace bootstrap files are loaded from that dedicated workspace.","This applies to `nullclaw agent --agent \u003cid\u003e`, `/subagents spawn --agent \u003cid\u003e`, and routed sessions resolved through `bindings`.","","Minimal end-to-end example:","","```json","{","  \"agents\": {","    \"list\": [","      {","        \"id\": \"orchestrator\",","        \"provider\": \"openrouter\",","        \"model\": \"anthropic/claude-sonnet-4\"","      },","      {","        \"id\": \"coder\",","        \"provider\": \"ollama\",","        \"model\": \"qwen2.5-coder:14b\",","        \"system_prompt\": \"You are the coding agent for this topic.\"","      }","    ]","  },","  \"channels\": {","    \"telegram\": {","      \"accounts\": {","        \"main\": {","          \"bot_token\": \"123456:ABCDEF\",","          \"allow_from\": [\"YOUR_TELEGRAM_USER_ID\"],","          \"binding_commands_enabled\": true,","          \"topic_commands_enabled\": true,","          \"topic_map_command_enabled\": true,","          \"commands_menu_mode\": \"scoped\"","        }","      }","    }","  },","  \"bindings\": [","    {","      \"agent_id\": \"orchestrator\",","      \"match\": {","        \"channel\": \"telegram\",","        \"account_id\": \"main\",","        \"peer\": { \"kind\": \"group\", \"id\": \"-1001234567890\" }","      }","    }","  ]","}","```","","Operator flow:","","- Send `/bind coder` inside the target forum topic.","- `nullclaw` writes a new exact `bindings[]` entry to `~/.nullclaw/config.json` for that topic and Telegram account.","- The next message in that topic uses the new routed agent profile.","- `nullclaw` must have write access to `~/.nullclaw/config.json` for `/bind` to persist changes.","","About `account_id`:","","- `account_id` identifies the configured Telegram account entry, not a topic and not an agent.","- In the usual `channels.telegram.accounts` form, the object key becomes the account id. For example, `accounts.main` means `account_id = \"main\"`, and `accounts.backup` means `account_id = \"backup\"`.","- In `bindings`, `match.account_id` limits that binding to one specific Telegram account.","- If `match.account_id` is omitted, the binding can match any Telegram account for that channel.","- Use different account ids only when you run multiple Telegram bot accounts/tokens in the same nullclaw instance.","","Effect on delivery:","","- Incoming Telegram updates are processed by the account that received them.","- Routing uses that same `account_id`, so `match.account_id = \"main\"` matches only messages received by `channels.telegram.accounts.main`.","- Replies go back out through the same Telegram account/runtime that handled the message.","- Setting one binding to `account_id = \"main\"` and another to `account_id = \"sub\"` does not split one chat across two agents automatically; it scopes each binding to a different configured Telegram account.","","### Full Web Search + Shell Access","","Use this when you want full web-search provider control plus unrestricted shell command allowlist behavior:","","```json","{","  \"http_request\": {","    \"enabled\": true,","    \"search_base_url\": \"https://searx.example.com\",","    \"search_provider\": \"auto\",","    \"search_fallback_providers\": [\"jina\", \"duckduckgo\"]","  },","  \"autonomy\": {","    \"level\": \"full\",","    \"allowed_commands\": [\"*\"],","    \"allowed_paths\": [\"*\"],","    \"require_approval_for_medium_risk\": false,","    \"block_medium_risk_commands\": false,","    \"block_high_risk_commands\": false","  }","}","```","","- `http_request.search_base_url` accepts either instance root (`https://host`) or explicit endpoint (`https://host/search`); local/private SearXNG instances may also use plain HTTP such as `http://localhost:8888` or `http://192.168.1.10:8888/search`.","- Invalid `http_request.search_base_url` now fails config validation at startup (no automatic fallback for malformed URL).","- `http_request.search_provider` supports: `auto`, `searxng`, `duckduckgo` (`ddg`), `brave`, `firecrawl`, `tavily`, `perplexity`, `exa`, `jina`.","- `http_request.search_fallback_providers` is optional and is tried in order when the primary provider fails.","- Provider env vars: `BRAVE_API_KEY`, `FIRECRAWL_API_KEY`, `TAVILY_API_KEY`, `PERPLEXITY_API_KEY`, `EXA_API_KEY`, `JINA_API_KEY` (or shared `WEB_SEARCH_API_KEY` where supported). DuckDuckGo and SearXNG do not require API keys.","- `allowed_commands` entries support `\"cmd\"`, `\"cmd *\"`, and `\"*\"` formats.","  - `\"cmd\"` and `\"cmd *\"` both allow that command family at the allowlist stage.","  - `\"*\"` allows any command at the allowlist stage.","- High-risk and medium-risk runtime gates still apply after the allowlist check; set `block_medium_risk_commands: false` when you intentionally allow network/transfer commands such as `curl`/`wget` or other medium-risk mutations.","- `allowed_paths: [\"*\"]` allows access outside workspace, except system-protected paths.","","### Web UI / Browser Relay","","Use `channels.web` for browser UI events (WebChannel v1):","","```json","{","  \"channels\": {","    \"web\": {","      \"accounts\": {","        \"default\": {","          \"transport\": \"local\",","          \"listen\": \"127.0.0.1\",","          \"port\": 32123,","          \"path\": \"/ws\",","          \"auth_token\": \"replace-with-long-random-token\",","          \"message_auth_mode\": \"pairing\",","          \"allowed_origins\": [\"http://localhost:5173\", \"chrome-extension://your-extension-id\"]","        }","      }","    }","  }","}","```","","- Local: keep `\"listen\": \"127.0.0.1\"`.","- `message_auth_mode` controls inbound `user_message` auth:","  - `\"pairing\"` (default): send `pairing_request`, receive `pairing_result`, include UI `access_token` in every `user_message`.","  - `\"token\"` (local transport only): include `auth_token` in each `user_message` payload (`access_token` is also accepted for compatibility).","- `auth_token` hardens the WebSocket upgrade and becomes required when binding non-loopback addresses.","- Unauthenticated WebSocket upgrade is loopback-only. Pairing-first local UX works on `127.0.0.1`, but a public/LAN bind must authenticate the `/ws` upgrade on the first hop with `?token=\u003cauth_token\u003e` or `Authorization: Bearer \u003cauth_token\u003e`.","- Local loopback pairing no longer depends on a fixed shared code. `pairing_request` may omit `payload.pairing_code`, and legacy loopback clients that still send `123456` remain compatible.","- `/ws` is the WebSocket endpoint. `/pair` belongs to the HTTP gateway API and is not part of the web channel handshake.","- Remote/headless host: if you bind `\"listen\": \"0.0.0.0\"`, prefer a stable configured token plus `message_auth_mode: \"token\"` behind TLS/reverse proxy, or keep loopback bind and expose it through SSH tunnel/proxy.","- UI/extension should live in a separate repository and connect via this WebSocket endpoint.","- For orchestration, use local token mode with a stable token from config or env (`NULLCLAW_WEB_TOKEN`, `NULLCLAW_GATEWAY_TOKEN`, `OPENCLAW_GATEWAY_TOKEN`).","- Relay transport (outbound agent socket) is configured via:","","```json","{","  \"channels\": {","    \"web\": {","      \"accounts\": {","        \"default\": {","          \"transport\": \"relay\",","          \"relay_url\": \"wss://relay.nullclaw.io/ws/agent\",","          \"relay_agent_id\": \"default\",","          \"relay_token\": \"replace-with-relay-token\",","          \"relay_token_ttl_secs\": 2592000,","          \"relay_pairing_code_ttl_secs\": 300,","          \"relay_ui_token_ttl_secs\": 86400,","          \"relay_e2e_required\": false","        }","      }","    }","  }","}","```","","- Relay token lifecycle (dedicated): `relay_token` (config) -\u003e `NULLCLAW_RELAY_TOKEN` (env) -\u003e persisted `web-relay-\u003caccount_id\u003e` credential -\u003e generated token.","- Relay UI handshake: send `pairing_request` with one-time `pairing_code`, receive `pairing_result` with UI `access_token` JWT (and optional `set_cookie` string for relay HTTP layer).","- Relay `user_message` must include valid UI JWT in `access_token` (top-level or `payload.access_token`).","- If E2E is enabled (`relay_e2e_required=true`), UI and agent exchange X25519 keys during pairing and send encrypted payloads in `payload.e2e`.","- WebChannel event envelope is defined in [`spec/webchannel_v1.json`](spec/webchannel_v1.json).","","## Gateway API","","| Endpoint | Method | Auth | Description |","|----------|--------|------|-------------|","| `/health` | GET | None | Health check (always public) |","| `/pair` | POST | `X-Pairing-Code` header | Exchange one-time code for bearer token |","| `/webhook` | POST | `Authorization: Bearer \u003ctoken\u003e` | Send message: `{\"message\": \"your prompt\"}` |","| `/media/transcribe` | POST | `Authorization: Bearer \u003ctoken\u003e` | Transcribe `audio_base64` payloads through configured STT |","| `/.well-known/agent-card.json` | GET | None | A2A Agent Card discovery (public) |","| `/a2a` | POST | `Authorization: Bearer \u003ctoken\u003e` | A2A JSON-RPC endpoint (canonical methods plus legacy slash aliases) |","| `/whatsapp` | GET | Query params | Meta webhook verification |","| `/whatsapp` | POST | None (Meta signature) | WhatsApp incoming message webhook |","","### A2A (Agent-to-Agent Protocol v0.3.0)","","NullClaw implements Google's [A2A protocol](https://github.com/google/A2A) v0.3.0, allowing any A2A-compatible agent or client to discover, authenticate, and interact with your instance over JSON-RPC 2.0.","","Enable in `~/.nullclaw/config.json`:","","```json","{","  \"a2a\": {","    \"enabled\": true,","    \"name\": \"nullclaw\",","    \"description\": \"General-purpose AI assistant\",","    \"url\": \"https://example.com\",","    \"version\": \"1.0.0\"","  }","}","```","","**Endpoints:**","","| Endpoint | Auth | Description |","|----------|------|-------------|","| `GET /.well-known/agent-card.json` | None | Agent Card discovery (public) |","| `POST /a2a` | Bearer token | JSON-RPC 2.0 dispatch |","","**Supported methods:** `message/send`, `message/stream`, `tasks/get`, `tasks/cancel`, `tasks/list`, `tasks/resubscribe`.","","**Quick test:**","","```bash","# 1. Get a bearer token","# Set PAIRING_CODE to the one-time code for this gateway session.","TOKEN=$(curl -s -X POST -H \"X-Pairing-Code: $PAIRING_CODE\" http://localhost:3000/pair | jq -r .token)","","# 2. Discover the agent","curl http://localhost:3000/.well-known/agent-card.json","","# 3. Send a message","curl -X POST -H \"Authorization: Bearer $TOKEN\" \\","  -H \"Content-Type: application/json\" \\","  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"messageId\":\"msg-1\",\"role\":\"user\",\"parts\":[{\"kind\":\"text\",\"text\":\"Hello\"}]}}}' \\","  http://localhost:3000/a2a","```","","See [Gateway API docs](docs/en/gateway-api.md) for full A2A reference including streaming, task lifecycle, and configuration details.","","### Media transcription","","`POST /media/transcribe` accepts JSON with `audio_base64`, `mime_type`, `source`, and optional `language`, then returns `{\"text\":\"...\"}` plus metadata. Configure STT under `tools.media.audio`; remote custom STT endpoints must use HTTPS. Raise `gateway.max_body_size_bytes`, `gateway.request_timeout_secs`, and `gateway.webhook_rate_limit_per_minute` for live desktop audio chunking.","","## Commands","","| Command | Description |","|---------|-------------|","| `onboard --api-key sk-... --provider openrouter` | Quick setup with API key and provider |","| `onboard --interactive` | Full interactive wizard |","| `onboard --channels-only` | Reconfigure channels/allowlists only |","| `agent -m \"...\"` | Single message mode |","| `acp` | Start the Agent Client Protocol stdio adapter for ACP-compatible editors |","| `agent` | Interactive chat mode |","| `gateway` | Start long-running runtime (default: `127.0.0.1:3000`) |","| `service install\\|start\\|stop\\|restart\\|status\\|uninstall` | Manage background service |","| `doctor` | Diagnose system health |","| `status [--json]` | Show full system status or emit the machine-readable runtime snapshot |","| `channel list\\|info\\|start\\|status\\|add\\|remove` | Manage channels, including JSON account inventory for automation |","| `cron list\\|status\\|add\\|add-agent\\|once\\|once-agent\\|remove\\|pause\\|resume\\|run\\|update\\|runs` | Manage scheduled tasks |","| `skills list\\|install\\|remove\\|info` | Manage skill packs, including `install --name \u003cquery\u003e` registry search |","| `history list\\|show` | View session conversation history |","| `memory stats\\|count\\|reindex\\|search\\|get\\|list\\|export-jsonl\\|hygiene-report\\|drain-outbox\\|forget` | Inspect, export, and maintain memory |","| `hardware scan\\|flash\\|monitor` | Hardware device management |","| `config show\\|get`, `models list\\|summary\\|info\\|benchmark\\|refresh` | Read config/model admin state and manage the model catalog |","| `workspace edit\\|reset-md` | Maintain workspace markdown/bootstrap files |","| `capabilities [--json]` | Show runtime capabilities manifest |","| `auth login\\|status\\|logout` | Manage OAuth authentication |","| `migrate openclaw [--dry-run] [--source PATH]` | Import memory + migrate config from OpenClaw |","| `update [--check] [--yes]` | Check for and install updates |","","## Development","","Build and tests are pinned to **Zig 0.16.0**.","","```bash","zig build                          # Dev build","zig build -Doptimize=ReleaseSmall  # Release build (678 KB)","zig build test --summary all       # 5,300+ tests","```","","### Channel Flow Coverage","","Channel CJM coverage (ingress parsing/filtering, session key routing, account propagation, bus handoff) is validated by tests in:","","- `src/channel_manager.zig` (runtime channel registration/start semantics + listener mode wiring)","- `src/config.zig` (OpenClaw-compatible `channels.*.accounts` parsing, multi-account selection/ordering, aliases)","- `src/gateway.zig` (Telegram/WhatsApp/LINE/Lark routed session keys from webhook payloads)","- `src/daemon.zig` (gateway-loop inbound route resolution for Discord/QQ/OneBot/Mattermost/MaixCam)","- `src/channels/discord.zig`, `src/channels/mattermost.zig`, `src/channels/qq.zig`, `src/channels/onebot.zig`, `src/channels/signal.zig`, `src/channels/line.zig`, `src/channels/whatsapp.zig` (per-channel inbound/outbound contracts)","","### Project Stats","","```","Language:     Zig 0.16.0","Source files: ~250","Lines of code: ~249,000","Tests:        5,300+","Binary:       678 KB (ReleaseSmall)","Peak RSS:     ~1 MB","Startup:      \u003c2 ms (Apple Silicon)","Dependencies: 0 (besides libc + optional SQLite)","```","","### Source Layout","","```","src/","  main.zig              CLI entry point + argument parsing","  root.zig              Module hierarchy (public API)","  config.zig            JSON config loader + 30 sub-config structs","  agent.zig             Agent loop, auto-compaction, tool dispatch","  daemon.zig            Daemon supervisor with exponential backoff","  gateway.zig           HTTP gateway (rate limiting, idempotency, pairing)","  channels/             19 channel implementations (telegram, signal, discord, slack, nostr, matrix, whatsapp, line, lark, onebot, mattermost, qq, ...)","  providers/            50+ AI provider integrations","  memory/               SQLite backend, embeddings, vector search, hygiene, snapshots","  tools/                35+ tool implementations","  security/             Secrets (ChaCha20), sandbox backends (landlock, firejail, ...)","  cron.zig              Cron scheduler with JSON persistence","  health.zig            Component health registry","  tunnel.zig            Tunnel vtable (cloudflare, ngrok, tailscale, custom)","  peripherals.zig       Hardware peripheral vtable (serial, Arduino, RPi, Nucleo)","  runtime.zig           Runtime vtable (native, docker, WASM)","  skillforge.zig        Skill discovery (GitHub), evaluation, integration","  ...","```","","## Versioning","","nullclaw uses **CalVer** (`YYYY.M.D`) for releases — e.g. `v2026.2.20`.","","- **Tag format:** `vYYYY.M.D` (one release per day max; patch suffix `vYYYY.M.D.N` if needed)","- **Release binaries derive their embedded version from the git tag** (`v...` -\u003e `nullclaw --version`)","- **Non-release builds default to `dev`** unless you override with `zig build -Dversion=...`","- **No stability guarantees yet** — the project is pre-1.0, config and CLI may change between releases","- **`nullclaw --version`** prints the current version","","## Contributing","","See [`CONTRIBUTING.md`](CONTRIBUTING.md) for development environment setup, workflow, validation commands, and the PR checklist.","","Implement a vtable interface, submit a PR:","","- New `Provider` -\u003e `src/providers/`","- New `Channel` -\u003e `src/channels/`","- New `Tool` -\u003e `src/tools/`","- New `Memory` backend -\u003e `src/memory/`","- New `Tunnel` -\u003e `src/tunnel.zig`","- New `Sandbox` backend -\u003e `src/security/`","- New `Peripheral` -\u003e `src/peripherals.zig`","- New `Skill` -\u003e `~/.nullclaw/workspace/skills/\u003cname\u003e/` or `~/.nullclaw/workspace/skills/\u003ccategory\u003e/\u003cname\u003e/`","","## Chinese Docs (中文文档)","","- [Chinese docs overview (中文文档总览)](docs/zh/README.md)","- [Installation guide (安装指南)](docs/zh/installation.md)","- [Zig installation (Zig 安装指南)](docs/zh/zig-installation.md)","- [Configuration guide (配置指南)](docs/zh/configuration.md)","- [Usage and operations (使用与运维)](docs/zh/usage.md)","- [Architecture overview (架构总览)](docs/zh/architecture.md)","- [Security model (安全机制)](docs/zh/security.md)","- [Gateway API (中文)](docs/zh/gateway-api.md)","- [Commands reference (命令参考)](docs/zh/commands.md)","- [Development guide (开发指南)](docs/zh/development.md)","","## English Docs","","- [English docs overview](docs/en/README.md)","- [Installation](docs/en/installation.md)","- [Zig Installation](docs/en/zig-installation.md)","- [Configuration](docs/en/configuration.md)","- [Usage and operations](docs/en/usage.md)","- [Architecture](docs/en/architecture.md)","- [Security](docs/en/security.md)","- [Gateway API](docs/en/gateway-api.md)","- [Commands](docs/en/commands.md)","- [Development](docs/en/development.md)","","## Disclaimer","","nullclaw is a pure open-source software project. It has **no token, no cryptocurrency, no blockchain component, and no financial instrument** of any kind. This project is not affiliated with any token or financial product.","","## License","","MIT — see [LICENSE](LICENSE)","","---","","**nullclaw** — Null overhead. Null compromise. Deploy anywhere. Swap anything.","","## Star History","","[![Star History Chart](https://api.star-history.com/svg?repos=nullclaw/nullclaw\u0026type=date\u0026legend=top-left)](https://www.star-history.com/#nullclaw/nullclaw\u0026type=date\u0026legend=top-left)"],"stylingDirectives":[[[68,69,"pl-s"],[76,77,"pl-s"],[77,78,"pl-s"],[78,113,"pl-corl"],[113,114,"pl-s"]],[],[[0,1,"pl-s"],[8,9,"pl-s"],[9,10,"pl-s"],[10,45,"pl-corl"],[45,46,"pl-s"],[152,153,"pl-s"],[163,164,"pl-s"],[164,165,"pl-s"],[165,203,"pl-corl"],[203,204,"pl-s"],[225,226,"pl-s"],[235,236,"pl-s"],[236,237,"pl-s"],[237,274,"pl-corl"],[274,275,"pl-s"],[300,301,"pl-s"],[312,313,"pl-s"],[313,314,"pl-s"],[314,353,"pl-corl"],[353,354,"pl-s"]],[],[[1,2,"pl-ent"],[3,8,"pl-e"],[9,10,"pl-s"],[10,16,"pl-s"],[16,17,"pl-s"]],[[3,6,"pl-ent"],[7,10,"pl-e"],[11,12,"pl-s"],[12,24,"pl-s"],[24,25,"pl-s"],[26,29,"pl-e"],[30,31,"pl-s"],[31,39,"pl-s"],[39,40,"pl-s"],[41,46,"pl-e"],[47,48,"pl-s"],[48,51,"pl-s"],[51,52,"pl-s"]],[[2,3,"pl-ent"]],[],[[1,3,"pl-ent"],[4,9,"pl-e"],[10,11,"pl-s"],[11,17,"pl-s"],[17,18,"pl-s"],[29,31,"pl-ent"]],[],[[1,2,"pl-ent"],[3,8,"pl-e"],[9,10,"pl-s"],[10,16,"pl-s"],[16,17,"pl-s"]],[[3,9,"pl-ent"],[68,74,"pl-ent"],[76,78,"pl-ent"]],[[3,9,"pl-ent"],[25,26,"pl-s"],[82,88,"pl-ent"]],[[2,3,"pl-ent"]],[],[[1,2,"pl-ent"],[3,8,"pl-e"],[9,10,"pl-s"],[10,16,"pl-s"],[16,17,"pl-s"]],[[3,4,"pl-ent"],[5,9,"pl-e"],[10,11,"pl-s"],[11,72,"pl-s"],[72,73,"pl-s"],[75,78,"pl-ent"],[79,82,"pl-e"],[83,84,"pl-s"],[84,155,"pl-s"],[155,156,"pl-s"],[157,160,"pl-e"],[161,162,"pl-s"],[162,164,"pl-s"],[164,165,"pl-s"],[170,171,"pl-ent"]],[[3,4,"pl-ent"],[5,9,"pl-e"],[10,11,"pl-s"],[11,77,"pl-s"],[77,78,"pl-s"],[80,83,"pl-ent"],[84,87,"pl-e"],[88,89,"pl-s"],[89,165,"pl-s"],[165,166,"pl-s"],[167,170,"pl-e"],[171,172,"pl-s"],[172,179,"pl-s"],[179,180,"pl-s"],[185,186,"pl-ent"]],[[3,4,"pl-ent"],[5,9,"pl-e"],[10,11,"pl-s"],[11,37,"pl-s"],[37,38,"pl-s"],[40,43,"pl-ent"],[44,47,"pl-e"],[48,49,"pl-s"],[49,115,"pl-s"],[115,116,"pl-s"],[117,120,"pl-e"],[121,122,"pl-s"],[122,135,"pl-s"],[135,136,"pl-s"],[141,142,"pl-ent"]],[[3,4,"pl-ent"],[5,9,"pl-e"],[10,11,"pl-s"],[11,40,"pl-s"],[40,41,"pl-s"],[43,46,"pl-ent"],[47,50,"pl-e"],[51,52,"pl-s"],[52,141,"pl-s"],[141,142,"pl-s"],[143,146,"pl-e"],[147,148,"pl-s"],[148,155,"pl-s"],[155,156,"pl-s"],[161,162,"pl-ent"]],[[3,4,"pl-ent"],[5,9,"pl-e"],[10,11,"pl-s"],[11,18,"pl-s"],[18,19,"pl-s"],[21,24,"pl-ent"],[25,28,"pl-e"],[29,30,"pl-s"],[30,79,"pl-s"],[79,80,"pl-s"],[81,84,"pl-e"],[85,86,"pl-s"],[86,98,"pl-s"],[98,99,"pl-s"],[104,105,"pl-ent"]],[[2,3,"pl-ent"]],[],[],[],[[6,7,"pl-s"],[14,15,"pl-s"],[15,16,"pl-s"],[16,33,"pl-corl"],[33,34,"pl-s"],[37,38,"pl-s"],[40,41,"pl-s"],[41,42,"pl-s"],[42,59,"pl-corl"],[59,60,"pl-s"],[63,64,"pl-s"],[76,77,"pl-s"],[77,78,"pl-s"],[78,93,"pl-corl"],[93,94,"pl-s"],[97,98,"pl-s"],[105,106,"pl-s"],[106,107,"pl-s"],[107,136,"pl-corl"],[136,137,"pl-s"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,97,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,12,"pl-mh"],[4,12,"pl-en"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[21,23,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[21,23,"pl-s"],[24,25,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[20,22,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[21,23,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[21,23,"pl-s"]],[],[[0,16,"pl-mh"],[4,16,"pl-en"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[20,22,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[21,23,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[20,22,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[15,17,"pl-s"]],[],[[0,21,"pl-mh"],[3,21,"pl-en"]],[],[],[],[[0,1,"pl-ml"],[2,3,"pl-ml"],[4,5,"pl-s"],[13,14,"pl-s"],[14,15,"pl-s"],[15,51,"pl-corl"],[51,52,"pl-s"],[53,54,"pl-ml"],[55,56,"pl-s"],[63,64,"pl-s"],[64,65,"pl-s"],[65,97,"pl-corl"],[97,98,"pl-s"],[99,100,"pl-ml"],[101,102,"pl-s"],[110,111,"pl-s"],[111,112,"pl-s"],[112,146,"pl-corl"],[146,147,"pl-s"],[148,149,"pl-ml"],[150,151,"pl-s"],[159,160,"pl-s"],[160,161,"pl-s"],[161,202,"pl-corl"],[202,203,"pl-s"],[204,205,"pl-ml"],[206,208,"pl-s"],[208,209,"pl-s"],[220,221,"pl-s"],[221,222,"pl-s"],[222,258,"pl-corl"],[258,259,"pl-s"],[259,261,"pl-s"],[262,263,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[8,9,"pl-ml"],[12,13,"pl-ml"],[16,17,"pl-ml"],[20,21,"pl-ml"],[24,25,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[12,14,"pl-s"],[15,16,"pl-ml"],[28,29,"pl-ml"],[37,38,"pl-ml"],[42,43,"pl-ml"],[49,50,"pl-ml"],[51,53,"pl-s"],[56,58,"pl-s"],[59,60,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[7,9,"pl-s"],[10,11,"pl-ml"],[19,20,"pl-ml"],[30,31,"pl-ml"],[40,41,"pl-ml"],[49,50,"pl-ml"],[51,53,"pl-s"],[53,54,"pl-s"],[58,60,"pl-s"],[61,62,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[21,23,"pl-s"],[24,25,"pl-ml"],[34,35,"pl-ml"],[43,44,"pl-ml"],[51,52,"pl-ml"],[61,62,"pl-ml"],[63,65,"pl-s"],[71,73,"pl-s"],[74,75,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[15,17,"pl-s"],[18,19,"pl-ml"],[20,21,"pl-s"],[34,35,"pl-ml"],[50,51,"pl-ml"],[52,53,"pl-s"],[58,59,"pl-ml"],[60,61,"pl-s"],[68,69,"pl-ml"],[70,72,"pl-s"],[78,80,"pl-s"],[81,82,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[9,11,"pl-s"],[12,13,"pl-ml"],[16,17,"pl-ml"],[20,21,"pl-ml"],[24,25,"pl-ml"],[32,33,"pl-ml"],[34,36,"pl-s"],[42,44,"pl-s"],[45,46,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[16,18,"pl-s"],[19,20,"pl-ml"],[21,22,"pl-s"],[27,28,"pl-ml"],[31,32,"pl-ml"],[35,36,"pl-ml"],[37,38,"pl-s"],[42,43,"pl-ml"],[44,46,"pl-s"],[46,47,"pl-s"],[50,52,"pl-s"],[53,54,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[8,10,"pl-s"],[11,12,"pl-ml"],[27,28,"pl-ml"],[39,40,"pl-s"],[44,45,"pl-ml"],[62,63,"pl-ml"],[81,82,"pl-ml"],[83,85,"pl-s"],[100,102,"pl-s"],[103,104,"pl-ml"]],[],[[0,118,"pl-ent"],[0,2,"pl-ent"],[16,17,"pl-s"],[17,33,"pl-c1"],[33,34,"pl-s"]],[[0,0,"pl-ent"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[],[],[],[[0,3,"pl-s"]],[],[[0,16,"pl-mh"],[3,16,"pl-en"]],[],[],[],[[36,37,"pl-s"],[37,45,"pl-c1"],[45,46,"pl-s"],[51,52,"pl-s"],[52,60,"pl-c1"],[60,61,"pl-s"]],[],[[0,1,"pl-ml"],[7,8,"pl-ml"],[17,18,"pl-ml"],[22,23,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[8,9,"pl-ml"],[12,13,"pl-ml"]],[[0,1,"pl-ml"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,17,"pl-s"],[17,34,"pl-c1"],[34,35,"pl-s"],[35,36,"pl-s"],[36,37,"pl-s"],[37,54,"pl-corl"],[54,55,"pl-s"],[56,57,"pl-ml"],[58,59,"pl-s"],[59,60,"pl-s"],[60,77,"pl-c1"],[77,78,"pl-s"],[78,79,"pl-s"],[79,80,"pl-s"],[80,97,"pl-corl"],[97,98,"pl-s"],[99,100,"pl-ml"]],[[0,1,"pl-ml"],[10,11,"pl-ml"],[12,13,"pl-s"],[13,14,"pl-s"],[14,37,"pl-c1"],[37,38,"pl-s"],[38,39,"pl-s"],[39,40,"pl-s"],[40,63,"pl-corl"],[63,64,"pl-s"],[65,66,"pl-ml"],[67,68,"pl-s"],[68,69,"pl-s"],[69,92,"pl-c1"],[92,93,"pl-s"],[93,94,"pl-s"],[94,95,"pl-s"],[95,118,"pl-corl"],[118,119,"pl-s"],[120,121,"pl-ml"]],[[0,1,"pl-ml"],[14,15,"pl-ml"],[16,17,"pl-s"],[17,18,"pl-s"],[18,45,"pl-c1"],[45,46,"pl-s"],[46,47,"pl-s"],[47,48,"pl-s"],[48,75,"pl-corl"],[75,76,"pl-s"],[77,78,"pl-ml"],[79,80,"pl-s"],[80,81,"pl-s"],[81,108,"pl-c1"],[108,109,"pl-s"],[109,110,"pl-s"],[110,111,"pl-s"],[111,138,"pl-corl"],[138,139,"pl-s"],[140,141,"pl-ml"]],[[0,1,"pl-ml"],[12,13,"pl-ml"],[14,15,"pl-s"],[15,16,"pl-s"],[16,40,"pl-c1"],[40,41,"pl-s"],[41,42,"pl-s"],[42,43,"pl-s"],[43,67,"pl-corl"],[67,68,"pl-s"],[69,70,"pl-ml"],[71,72,"pl-s"],[72,73,"pl-s"],[73,97,"pl-c1"],[97,98,"pl-s"],[98,99,"pl-s"],[99,100,"pl-s"],[100,124,"pl-corl"],[124,125,"pl-s"],[126,127,"pl-ml"]],[[0,1,"pl-ml"],[11,12,"pl-ml"],[13,14,"pl-s"],[14,15,"pl-s"],[15,34,"pl-c1"],[34,35,"pl-s"],[35,36,"pl-s"],[36,37,"pl-s"],[37,56,"pl-corl"],[56,57,"pl-s"],[58,59,"pl-ml"],[60,61,"pl-s"],[61,62,"pl-s"],[62,81,"pl-c1"],[81,82,"pl-s"],[82,83,"pl-s"],[83,84,"pl-s"],[84,103,"pl-corl"],[103,104,"pl-s"],[105,106,"pl-ml"]],[[0,1,"pl-ml"],[14,15,"pl-ml"],[16,17,"pl-s"],[17,18,"pl-s"],[18,40,"pl-c1"],[40,41,"pl-s"],[41,42,"pl-s"],[42,43,"pl-s"],[43,65,"pl-corl"],[65,66,"pl-s"],[67,68,"pl-ml"],[69,70,"pl-s"],[70,71,"pl-s"],[71,93,"pl-c1"],[93,94,"pl-s"],[94,95,"pl-s"],[95,96,"pl-s"],[96,118,"pl-corl"],[118,119,"pl-s"],[120,121,"pl-ml"]],[[0,1,"pl-ml"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,17,"pl-s"],[17,33,"pl-c1"],[33,34,"pl-s"],[34,35,"pl-s"],[35,36,"pl-s"],[36,52,"pl-corl"],[52,53,"pl-s"],[54,55,"pl-ml"],[56,57,"pl-s"],[57,58,"pl-s"],[58,74,"pl-c1"],[74,75,"pl-s"],[75,76,"pl-s"],[76,77,"pl-s"],[77,93,"pl-corl"],[93,94,"pl-s"],[95,96,"pl-ml"]],[[0,1,"pl-ml"],[15,16,"pl-ml"],[17,18,"pl-s"],[18,19,"pl-s"],[19,42,"pl-c1"],[42,43,"pl-s"],[43,44,"pl-s"],[44,45,"pl-s"],[45,68,"pl-corl"],[68,69,"pl-s"],[70,71,"pl-ml"],[72,73,"pl-s"],[73,74,"pl-s"],[74,97,"pl-c1"],[97,98,"pl-s"],[98,99,"pl-s"],[99,100,"pl-s"],[100,123,"pl-corl"],[123,124,"pl-s"],[125,126,"pl-ml"]],[[0,1,"pl-ml"],[11,12,"pl-ml"],[13,14,"pl-s"],[14,15,"pl-s"],[15,34,"pl-c1"],[34,35,"pl-s"],[35,36,"pl-s"],[36,37,"pl-s"],[37,56,"pl-corl"],[56,57,"pl-s"],[58,59,"pl-ml"],[60,61,"pl-s"],[61,62,"pl-s"],[62,81,"pl-c1"],[81,82,"pl-s"],[82,83,"pl-s"],[83,84,"pl-s"],[84,103,"pl-corl"],[103,104,"pl-s"],[105,106,"pl-ml"]],[[0,1,"pl-ml"],[14,15,"pl-ml"],[16,17,"pl-s"],[17,18,"pl-s"],[18,40,"pl-c1"],[40,41,"pl-s"],[41,42,"pl-s"],[42,43,"pl-s"],[43,65,"pl-corl"],[65,66,"pl-s"],[67,68,"pl-ml"],[69,70,"pl-s"],[70,71,"pl-s"],[71,93,"pl-c1"],[93,94,"pl-s"],[94,95,"pl-s"],[95,96,"pl-s"],[96,118,"pl-corl"],[118,119,"pl-s"],[120,121,"pl-ml"]],[],[[0,1,"pl-v"],[22,23,"pl-s"],[23,24,"pl-s"],[24,39,"pl-c1"],[39,40,"pl-s"],[40,41,"pl-s"],[41,42,"pl-s"],[42,57,"pl-corl"],[57,58,"pl-s"],[60,61,"pl-s"],[61,62,"pl-s"],[62,73,"pl-c1"],[73,74,"pl-s"],[74,75,"pl-s"],[75,76,"pl-s"],[76,87,"pl-corl"],[87,88,"pl-s"],[90,91,"pl-s"],[91,92,"pl-s"],[92,101,"pl-c1"],[101,102,"pl-s"],[102,103,"pl-s"],[103,104,"pl-s"],[104,113,"pl-corl"],[113,114,"pl-s"]],[],[[0,19,"pl-mh"],[3,19,"pl-en"]],[],[[0,1,"pl-ml"],[7,8,"pl-ml"],[25,26,"pl-ml"],[38,39,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[8,9,"pl-ml"],[12,13,"pl-ml"]],[[0,1,"pl-ml"],[23,24,"pl-ml"],[25,26,"pl-s"],[26,27,"pl-s"],[27,44,"pl-c1"],[44,45,"pl-s"],[45,46,"pl-s"],[46,47,"pl-s"],[47,64,"pl-corl"],[64,65,"pl-s"],[66,67,"pl-ml"],[68,69,"pl-s"],[69,70,"pl-s"],[70,93,"pl-c1"],[93,94,"pl-s"],[94,95,"pl-s"],[95,96,"pl-s"],[96,119,"pl-corl"],[119,120,"pl-s"],[123,124,"pl-s"],[124,125,"pl-s"],[125,149,"pl-c1"],[149,150,"pl-s"],[150,151,"pl-s"],[151,152,"pl-s"],[152,176,"pl-corl"],[176,177,"pl-s"],[180,181,"pl-s"],[181,182,"pl-s"],[182,198,"pl-c1"],[198,199,"pl-s"],[199,200,"pl-s"],[200,201,"pl-s"],[201,217,"pl-corl"],[217,218,"pl-s"],[219,220,"pl-ml"]],[[0,1,"pl-ml"],[31,32,"pl-ml"],[33,34,"pl-s"],[34,35,"pl-s"],[35,52,"pl-c1"],[52,53,"pl-s"],[53,54,"pl-s"],[54,55,"pl-s"],[55,72,"pl-corl"],[72,73,"pl-s"],[74,75,"pl-ml"],[76,77,"pl-s"],[77,78,"pl-s"],[78,101,"pl-c1"],[101,102,"pl-s"],[102,103,"pl-s"],[103,104,"pl-s"],[104,127,"pl-corl"],[127,128,"pl-s"],[131,132,"pl-s"],[132,133,"pl-s"],[133,157,"pl-c1"],[157,158,"pl-s"],[158,159,"pl-s"],[159,160,"pl-s"],[160,184,"pl-corl"],[184,185,"pl-s"],[188,189,"pl-s"],[189,190,"pl-s"],[190,206,"pl-c1"],[206,207,"pl-s"],[207,208,"pl-s"],[208,209,"pl-s"],[209,225,"pl-corl"],[225,226,"pl-s"],[227,228,"pl-ml"]],[[0,1,"pl-ml"],[29,30,"pl-ml"],[31,32,"pl-s"],[32,33,"pl-s"],[33,52,"pl-c1"],[52,53,"pl-s"],[53,54,"pl-s"],[54,55,"pl-s"],[55,74,"pl-corl"],[74,75,"pl-s"],[78,79,"pl-s"],[79,80,"pl-s"],[80,99,"pl-c1"],[99,100,"pl-s"],[100,101,"pl-s"],[101,102,"pl-s"],[102,121,"pl-corl"],[121,122,"pl-s"],[123,124,"pl-ml"],[125,126,"pl-s"],[126,139,"pl-c1"],[139,140,"pl-s"],[173,174,"pl-ml"]],[[0,1,"pl-ml"],[26,27,"pl-ml"],[28,29,"pl-s"],[29,30,"pl-s"],[30,45,"pl-c1"],[45,46,"pl-s"],[46,47,"pl-s"],[47,48,"pl-s"],[48,63,"pl-corl"],[63,64,"pl-s"],[65,66,"pl-ml"],[67,68,"pl-s"],[68,69,"pl-s"],[69,91,"pl-c1"],[91,92,"pl-s"],[92,93,"pl-s"],[93,94,"pl-s"],[94,116,"pl-corl"],[116,117,"pl-s"],[120,121,"pl-s"],[121,122,"pl-s"],[122,144,"pl-c1"],[144,145,"pl-s"],[145,146,"pl-s"],[146,147,"pl-s"],[147,169,"pl-corl"],[169,170,"pl-s"],[200,201,"pl-ml"]],[[0,1,"pl-ml"],[33,34,"pl-ml"],[35,36,"pl-s"],[36,37,"pl-s"],[37,53,"pl-c1"],[53,54,"pl-s"],[54,55,"pl-s"],[55,56,"pl-s"],[56,72,"pl-corl"],[72,73,"pl-s"],[76,77,"pl-s"],[77,78,"pl-s"],[78,94,"pl-c1"],[94,95,"pl-s"],[95,96,"pl-s"],[96,97,"pl-s"],[97,113,"pl-corl"],[113,114,"pl-s"],[115,116,"pl-ml"],[117,118,"pl-s"],[118,119,"pl-s"],[119,138,"pl-c1"],[138,139,"pl-s"],[139,140,"pl-s"],[140,141,"pl-s"],[141,160,"pl-corl"],[160,161,"pl-s"],[164,165,"pl-s"],[165,166,"pl-s"],[166,185,"pl-c1"],[185,186,"pl-s"],[186,187,"pl-s"],[187,188,"pl-s"],[188,207,"pl-corl"],[207,208,"pl-s"],[223,224,"pl-ml"]],[],[[0,20,"pl-mh"],[3,20,"pl-en"]],[],[[0,1,"pl-v"],[20,21,"pl-s"],[21,22,"pl-s"],[22,39,"pl-c1"],[39,40,"pl-s"],[40,41,"pl-s"],[41,42,"pl-s"],[42,59,"pl-corl"],[59,60,"pl-s"],[64,65,"pl-s"],[65,66,"pl-s"],[66,83,"pl-c1"],[83,84,"pl-s"],[84,85,"pl-s"],[85,86,"pl-s"],[86,103,"pl-corl"],[103,104,"pl-s"]],[[0,1,"pl-v"],[27,28,"pl-s"],[28,29,"pl-s"],[29,48,"pl-c1"],[48,49,"pl-s"],[49,50,"pl-s"],[50,51,"pl-s"],[51,70,"pl-corl"],[70,71,"pl-s"],[75,76,"pl-s"],[76,77,"pl-s"],[77,96,"pl-c1"],[96,97,"pl-s"],[97,98,"pl-s"],[98,99,"pl-s"],[99,118,"pl-corl"],[118,119,"pl-s"]],[[0,1,"pl-v"],[34,35,"pl-s"],[35,36,"pl-s"],[36,51,"pl-c1"],[51,52,"pl-s"],[52,53,"pl-s"],[53,54,"pl-s"],[54,69,"pl-corl"],[69,70,"pl-s"],[82,83,"pl-s"],[83,84,"pl-s"],[84,106,"pl-c1"],[106,107,"pl-s"],[107,108,"pl-s"],[108,109,"pl-s"],[109,131,"pl-corl"],[131,132,"pl-s"],[136,137,"pl-s"],[137,138,"pl-s"],[138,160,"pl-c1"],[160,161,"pl-s"],[161,162,"pl-s"],[162,163,"pl-s"],[163,185,"pl-corl"],[185,186,"pl-s"]],[],[[0,14,"pl-mh"],[3,14,"pl-en"]],[],[[0,37,"pl-mh"],[4,37,"pl-en"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[[0,3,"pl-s"]],[],[[0,24,"pl-mh"],[4,24,"pl-en"]],[],[[0,55,"pl-ent"],[0,2,"pl-ent"],[2,4,"pl-s"],[17,19,"pl-s"],[24,26,"pl-s"],[36,38,"pl-s"]],[[0,69,"pl-ent"],[0,2,"pl-ent"]],[[0,62,"pl-ent"],[0,2,"pl-ent"],[26,27,"pl-s"],[27,38,"pl-c1"],[38,39,"pl-s"],[53,54,"pl-s"],[54,60,"pl-c1"],[60,61,"pl-s"]],[[0,106,"pl-ent"],[0,2,"pl-ent"],[45,46,"pl-s"],[46,47,"pl-s"],[47,74,"pl-c1"],[74,75,"pl-s"],[75,76,"pl-s"],[76,77,"pl-s"],[77,104,"pl-corl"],[104,105,"pl-s"]],[[0,0,"pl-ent"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,2,"pl-c1"]],[],[[10,14,"pl-c1"]],[[0,3,"pl-s"]],[],[[5,6,"pl-s"],[6,14,"pl-c1"],[14,15,"pl-s"],[29,30,"pl-s"],[30,34,"pl-c1"],[34,35,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[37,51,"pl-s"],[37,38,"pl-pds"],[38,43,"pl-smi"],[50,51,"pl-pds"]],[[0,4,"pl-c1"],[5,43,"pl-s"],[5,6,"pl-pds"],[42,43,"pl-pds"],[44,46,"pl-k"],[47,48,"pl-k"]],[[0,14,"pl-c"],[0,1,"pl-c"]],[[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,13,"pl-en"],[13,13,"pl-c1"]],[[0,51,"pl-c1"]],[[0,0,"pl-c1"]],[[0,25,"pl-c1"]],[[0,66,"pl-c1"]],[[0,66,"pl-c1"]],[[0,74,"pl-c1"]],[[0,1,"pl-c1"]],[[0,28,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,3,"pl-s"]],[],[[0,30,"pl-mh"],[4,30,"pl-en"]],[],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-s"],[1,12,"pl-c1"],[12,13,"pl-s"],[19,20,"pl-s"],[20,50,"pl-c1"],[50,51,"pl-s"]],[[35,36,"pl-s"],[36,47,"pl-c1"],[47,48,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[24,47,"pl-s"],[24,25,"pl-pds"],[46,47,"pl-pds"]],[[0,3,"pl-s"]],[],[[40,41,"pl-s"],[41,52,"pl-c1"],[52,53,"pl-s"]],[],[],[[32,33,"pl-s"],[33,51,"pl-c1"],[51,52,"pl-s"]],[[13,14,"pl-s"],[14,21,"pl-c1"],[21,22,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[[0,3,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[],[],[[0,3,"pl-s"]],[],[[9,10,"pl-s"],[10,31,"pl-c1"],[31,32,"pl-s"]],[],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[0,13,"pl-c"],[0,1,"pl-c"]],[],[],[[0,23,"pl-c"],[0,1,"pl-c"]],[],[],[[0,6,"pl-c"],[0,1,"pl-c"]],[[18,36,"pl-s"],[18,19,"pl-pds"],[35,36,"pl-pds"]],[],[[0,18,"pl-c"],[0,1,"pl-c"]],[],[],[[0,92,"pl-c"],[0,1,"pl-c"]],[[32,57,"pl-c"],[32,33,"pl-c"]],[[32,45,"pl-c"],[32,33,"pl-c"]],[],[[0,14,"pl-c"],[0,1,"pl-c"]],[],[],[[0,24,"pl-c"],[0,1,"pl-c"]],[],[],[[0,22,"pl-c"],[0,1,"pl-c"]],[],[],[[0,25,"pl-c"],[0,1,"pl-c"]],[],[],[],[],[[0,27,"pl-c"],[0,1,"pl-c"]],[[0,49,"pl-c"],[0,1,"pl-c"]],[],[],[],[[0,50,"pl-c"],[0,1,"pl-c"]],[[0,82,"pl-c"],[0,1,"pl-c"]],[[0,70,"pl-c"],[0,1,"pl-c"]],[],[[0,30,"pl-c"],[0,1,"pl-c"]],[],[],[[0,3,"pl-s"]],[],[[0,38,"pl-mh"],[3,38,"pl-en"]],[],[],[],[[0,1,"pl-s"],[1,33,"pl-c1"],[33,34,"pl-s"]],[],[],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[21,23,"pl-s"],[39,41,"pl-s"]],[],[[0,1,"pl-ml"],[12,13,"pl-ml"],[24,25,"pl-ml"],[37,38,"pl-ml"],[46,47,"pl-ml"]],[[0,1,"pl-ml"],[12,13,"pl-ml"],[24,25,"pl-ml"],[37,38,"pl-ml"],[46,47,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[13,15,"pl-s"],[16,17,"pl-ml"],[18,19,"pl-s"],[19,27,"pl-c1"],[27,28,"pl-s"],[29,30,"pl-ml"],[290,291,"pl-ml"],[292,293,"pl-s"],[293,320,"pl-c1"],[320,321,"pl-s"],[350,351,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[12,14,"pl-s"],[15,16,"pl-ml"],[17,18,"pl-s"],[18,25,"pl-c1"],[25,26,"pl-s"],[27,28,"pl-ml"],[185,186,"pl-ml"],[205,206,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[10,12,"pl-s"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[153,154,"pl-ml"],[179,180,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[9,11,"pl-s"],[12,13,"pl-ml"],[14,15,"pl-s"],[15,19,"pl-c1"],[19,20,"pl-s"],[21,22,"pl-ml"],[352,353,"pl-ml"],[369,370,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[17,19,"pl-s"],[20,21,"pl-ml"],[22,23,"pl-s"],[23,31,"pl-c1"],[31,32,"pl-s"],[33,34,"pl-ml"],[58,59,"pl-ml"],[77,78,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[11,13,"pl-s"],[14,15,"pl-ml"],[16,17,"pl-s"],[17,31,"pl-c1"],[31,32,"pl-s"],[33,34,"pl-ml"],[79,80,"pl-ml"],[93,94,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[12,14,"pl-s"],[15,16,"pl-ml"],[17,18,"pl-s"],[18,25,"pl-c1"],[25,26,"pl-s"],[27,28,"pl-ml"],[81,82,"pl-ml"],[103,104,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[12,14,"pl-s"],[15,16,"pl-ml"],[17,18,"pl-s"],[18,32,"pl-c1"],[32,33,"pl-s"],[34,35,"pl-ml"],[75,76,"pl-ml"],[97,98,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[10,12,"pl-s"],[13,14,"pl-ml"],[15,16,"pl-s"],[16,22,"pl-c1"],[22,23,"pl-s"],[24,25,"pl-ml"],[69,70,"pl-ml"],[89,90,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[13,15,"pl-s"],[16,17,"pl-ml"],[25,26,"pl-ml"],[55,56,"pl-ml"],[59,60,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[10,12,"pl-s"],[13,14,"pl-ml"],[22,23,"pl-ml"],[67,68,"pl-s"],[68,76,"pl-c1"],[76,77,"pl-s"],[78,79,"pl-ml"],[102,103,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[15,17,"pl-s"],[18,19,"pl-ml"],[20,21,"pl-s"],[21,31,"pl-c1"],[31,32,"pl-s"],[33,34,"pl-ml"],[84,85,"pl-ml"],[109,110,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[8,10,"pl-s"],[11,12,"pl-ml"],[23,24,"pl-ml"],[82,83,"pl-ml"],[86,87,"pl-ml"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[],[],[[0,1,"pl-ml"],[8,9,"pl-ml"],[25,26,"pl-ml"]],[[0,1,"pl-ml"],[8,9,"pl-ml"],[24,25,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[13,15,"pl-s"],[16,17,"pl-ml"],[80,81,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[18,20,"pl-s"],[21,22,"pl-ml"],[61,62,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[16,18,"pl-s"],[19,20,"pl-ml"],[74,75,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[14,16,"pl-s"],[17,18,"pl-ml"],[19,20,"pl-s"],[20,37,"pl-c1"],[37,38,"pl-s"],[76,77,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[11,13,"pl-s"],[14,15,"pl-ml"],[61,62,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[13,15,"pl-s"],[16,17,"pl-ml"],[64,65,"pl-ml"]],[[0,1,"pl-ml"],[2,4,"pl-s"],[11,13,"pl-s"],[14,15,"pl-ml"],[106,107,"pl-ml"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,10,"pl-ent"]],[[4,13,"pl-ent"],[15,23,"pl-s"],[15,16,"pl-pds"],[22,23,"pl-pds"]],[[4,15,"pl-ent"],[17,21,"pl-c1"]],[[4,24,"pl-ent"],[26,34,"pl-s"],[26,27,"pl-pds"],[33,34,"pl-pds"]],[[4,19,"pl-ent"],[21,24,"pl-c1"]],[[4,20,"pl-ent"],[22,25,"pl-c1"]],[[4,21,"pl-ent"],[23,27,"pl-c1"]],[[4,22,"pl-ent"],[24,29,"pl-c1"]],[],[],[[0,3,"pl-s"]],[],[[0,11,"pl-mh"],[3,11,"pl-en"]],[],[[30,32,"pl-s"],[43,45,"pl-s"]],[],[[0,1,"pl-ml"],[4,5,"pl-ml"],[11,12,"pl-ml"],[20,21,"pl-ml"],[26,27,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[11,12,"pl-ml"],[20,21,"pl-ml"],[26,27,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[36,38,"pl-s"],[39,40,"pl-ml"],[46,47,"pl-ml"],[54,55,"pl-s"],[55,64,"pl-c1"],[64,65,"pl-s"],[86,87,"pl-s"],[87,94,"pl-c1"],[94,95,"pl-s"],[123,124,"pl-s"],[124,141,"pl-c1"],[141,142,"pl-s"],[144,145,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[24,26,"pl-s"],[27,28,"pl-ml"],[34,35,"pl-ml"],[83,84,"pl-s"],[84,94,"pl-c1"],[94,95,"pl-s"],[114,115,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[25,27,"pl-s"],[28,29,"pl-ml"],[35,36,"pl-ml"],[37,38,"pl-s"],[38,59,"pl-c1"],[59,60,"pl-s"],[128,129,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[30,32,"pl-s"],[33,34,"pl-ml"],[40,41,"pl-ml"],[143,144,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[25,27,"pl-s"],[28,29,"pl-ml"],[35,36,"pl-ml"],[107,108,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[25,27,"pl-s"],[28,29,"pl-ml"],[35,36,"pl-ml"],[101,102,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[23,25,"pl-s"],[26,27,"pl-ml"],[33,34,"pl-ml"],[90,91,"pl-ml"]],[[0,1,"pl-ml"],[4,5,"pl-ml"],[6,8,"pl-s"],[21,23,"pl-s"],[24,25,"pl-ml"],[31,32,"pl-ml"],[81,82,"pl-ml"]],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[0,1,"pl-v"],[20,22,"pl-s"],[47,49,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[10,12,"pl-s"],[21,23,"pl-s"]],[[0,1,"pl-v"]],[],[[24,25,"pl-s"],[25,37,"pl-c1"],[37,38,"pl-s"],[42,44,"pl-s"],[50,52,"pl-s"],[75,76,"pl-s"],[76,94,"pl-c1"],[94,95,"pl-s"],[149,150,"pl-s"],[150,155,"pl-c1"],[155,156,"pl-s"]],[],[[0,23,"pl-mh"],[4,23,"pl-en"]],[],[[0,1,"pl-s"],[1,9,"pl-c1"],[9,10,"pl-s"],[102,103,"pl-s"],[103,104,"pl-s"],[104,107,"pl-c1"],[107,108,"pl-s"],[108,109,"pl-s"],[109,110,"pl-s"],[110,140,"pl-corl"],[140,141,"pl-s"]],[],[[0,2,"pl-s"],[16,18,"pl-s"],[27,28,"pl-s"],[28,31,"pl-c1"],[31,32,"pl-s"],[57,58,"pl-s"],[58,63,"pl-c1"],[63,64,"pl-s"]],[],[[0,2,"pl-s"],[30,32,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[33,58,"pl-c"],[33,34,"pl-c"]],[[0,3,"pl-s"]],[],[],[[0,1,"pl-s"],[1,2,"pl-v"]],[[0,1,"pl-s"],[1,2,"pl-v"]],[[0,1,"pl-s"],[1,2,"pl-v"]],[[0,1,"pl-s"],[1,2,"pl-v"]],[],[[29,30,"pl-s"],[36,37,"pl-s"],[37,38,"pl-s"],[38,52,"pl-corl"],[52,53,"pl-s"]],[],[[0,2,"pl-s"],[15,17,"pl-s"]],[],[[0,16,"pl-mh"],[3,16,"pl-en"]],[],[[8,9,"pl-s"],[9,32,"pl-c1"],[32,33,"pl-s"],[46,47,"pl-s"],[47,54,"pl-c1"],[54,55,"pl-s"]],[],[[0,268,"pl-ent"],[0,2,"pl-ent"],[2,4,"pl-s"],[24,26,"pl-s"],[70,71,"pl-s"],[79,80,"pl-s"],[80,81,"pl-s"],[81,117,"pl-corl"],[117,118,"pl-s"],[154,155,"pl-s"],[155,171,"pl-c1"],[171,172,"pl-s"],[198,199,"pl-s"],[199,228,"pl-c1"],[228,229,"pl-s"],[248,249,"pl-s"],[249,257,"pl-c1"],[257,258,"pl-s"]],[[0,72,"pl-ent"],[0,2,"pl-ent"],[12,13,"pl-s"],[13,29,"pl-c1"],[29,30,"pl-s"],[33,34,"pl-s"],[34,47,"pl-c1"],[47,48,"pl-s"]],[[0,1,"pl-ent"],[0,1,"pl-ent"]],[[0,72,"pl-ent"],[0,2,"pl-ent"],[2,4,"pl-s"],[19,21,"pl-s"],[22,23,"pl-s"],[23,54,"pl-c1"],[54,55,"pl-s"]],[[0,35,"pl-ent"],[0,2,"pl-ent"],[2,3,"pl-s"],[3,4,"pl-v"],[21,22,"pl-s"],[22,29,"pl-c1"],[29,30,"pl-s"]],[[0,137,"pl-ent"],[0,2,"pl-ent"],[2,3,"pl-s"],[3,4,"pl-v"],[74,75,"pl-s"],[75,85,"pl-c1"],[85,86,"pl-s"],[92,93,"pl-s"],[93,103,"pl-c1"],[103,104,"pl-s"],[106,107,"pl-s"],[107,119,"pl-c1"],[119,120,"pl-s"],[122,123,"pl-s"],[123,134,"pl-c1"],[134,135,"pl-s"]],[[0,1,"pl-ent"],[0,1,"pl-ent"]],[[0,259,"pl-ent"],[0,2,"pl-ent"],[2,3,"pl-s"],[3,35,"pl-c1"],[35,36,"pl-s"],[60,61,"pl-s"],[61,119,"pl-c1"],[119,120,"pl-s"],[198,199,"pl-s"],[199,209,"pl-c1"],[209,210,"pl-s"],[217,218,"pl-s"],[218,233,"pl-c1"],[233,234,"pl-s"],[249,250,"pl-s"],[250,256,"pl-c1"],[256,257,"pl-s"]],[[0,85,"pl-ent"],[0,2,"pl-ent"],[32,33,"pl-s"],[33,40,"pl-c1"],[40,41,"pl-s"],[55,56,"pl-s"],[56,61,"pl-c1"],[61,62,"pl-s"]],[[0,0,"pl-ent"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,23,"pl-ent"],[25,28,"pl-c1"]],[],[[2,10,"pl-ent"]],[[4,15,"pl-ent"]],[[6,18,"pl-ent"],[22,31,"pl-ent"],[33,44,"pl-s"],[33,34,"pl-pds"],[43,44,"pl-pds"]],[[6,14,"pl-ent"],[18,27,"pl-ent"],[29,50,"pl-s"],[29,30,"pl-pds"],[49,50,"pl-pds"]],[[6,19,"pl-ent"],[23,32,"pl-ent"],[34,59,"pl-s"],[34,35,"pl-pds"],[58,59,"pl-pds"]],[[6,15,"pl-ent"],[19,28,"pl-ent"],[30,52,"pl-s"],[30,31,"pl-pds"],[51,52,"pl-pds"]],[[6,14,"pl-ent"],[18,27,"pl-ent"],[29,50,"pl-s"],[29,30,"pl-pds"],[49,50,"pl-pds"]],[[6,12,"pl-ent"],[16,25,"pl-ent"],[27,36,"pl-s"],[27,28,"pl-pds"],[35,36,"pl-pds"]],[[6,13,"pl-ent"],[17,26,"pl-ent"],[28,55,"pl-s"],[28,29,"pl-pds"],[54,55,"pl-pds"],[57,67,"pl-ent"],[69,109,"pl-s"],[69,70,"pl-pds"],[108,109,"pl-pds"]],[[6,14,"pl-ent"]],[[8,17,"pl-ent"]],[[10,16,"pl-ent"],[18,35,"pl-s"],[18,19,"pl-pds"],[34,35,"pl-pds"]],[[10,22,"pl-ent"],[24,38,"pl-s"],[24,25,"pl-pds"],[37,38,"pl-pds"]],[[10,24,"pl-ent"],[26,68,"pl-s"],[26,27,"pl-pds"],[67,68,"pl-pds"]],[[10,23,"pl-ent"],[25,88,"pl-s"],[25,26,"pl-pds"],[53,55,"pl-cce"],[58,60,"pl-cce"],[85,87,"pl-cce"],[87,88,"pl-pds"]],[],[[8,18,"pl-ent"],[20,122,"pl-s"],[20,21,"pl-pds"],[121,122,"pl-pds"]],[],[[6,17,"pl-ent"],[21,30,"pl-ent"],[32,44,"pl-s"],[32,33,"pl-pds"],[43,44,"pl-pds"]],[],[],[],[[2,10,"pl-ent"]],[[4,14,"pl-ent"]],[[6,13,"pl-ent"],[17,26,"pl-ent"],[28,66,"pl-s"],[28,29,"pl-pds"],[65,66,"pl-pds"]],[[6,17,"pl-ent"],[21,28,"pl-ent"],[30,35,"pl-s"],[30,31,"pl-pds"],[34,35,"pl-pds"]],[],[[4,10,"pl-ent"]],[[8,12,"pl-ent"],[14,26,"pl-s"],[14,15,"pl-pds"],[25,26,"pl-pds"],[28,35,"pl-ent"],[39,48,"pl-ent"],[50,86,"pl-s"],[50,51,"pl-pds"],[85,86,"pl-pds"],[90,105,"pl-ent"],[107,112,"pl-s"],[107,108,"pl-pds"],[111,112,"pl-pds"]],[],[],[],[[2,12,"pl-ent"]],[[4,14,"pl-ent"]],[[6,16,"pl-ent"]],[[8,14,"pl-ent"]],[[10,21,"pl-ent"],[23,32,"pl-s"],[23,24,"pl-pds"],[31,32,"pl-pds"]],[[10,22,"pl-ent"],[25,32,"pl-s"],[25,26,"pl-pds"],[31,32,"pl-pds"]],[[10,28,"pl-ent"],[30,34,"pl-c1"]],[[10,17,"pl-ent"],[19,33,"pl-s"],[19,20,"pl-pds"],[32,33,"pl-pds"]],[],[],[],[[4,13,"pl-ent"]],[[6,16,"pl-ent"]],[[8,14,"pl-ent"]],[[10,17,"pl-ent"],[19,31,"pl-s"],[19,20,"pl-pds"],[30,31,"pl-pds"]],[[10,20,"pl-ent"],[22,29,"pl-s"],[22,23,"pl-pds"],[28,29,"pl-pds"]],[[10,22,"pl-ent"],[25,32,"pl-s"],[25,26,"pl-pds"],[31,32,"pl-pds"]],[[10,22,"pl-ent"],[24,29,"pl-c1"]],[],[],[],[[4,9,"pl-ent"]],[[6,16,"pl-ent"]],[[8,14,"pl-ent"]],[[10,16,"pl-ent"],[18,35,"pl-s"],[18,19,"pl-pds"],[34,35,"pl-pds"]],[[10,16,"pl-ent"],[18,22,"pl-c1"]],[[10,16,"pl-ent"],[18,28,"pl-s"],[18,19,"pl-pds"],[27,28,"pl-pds"]],[[10,20,"pl-ent"],[23,34,"pl-s"],[23,24,"pl-pds"],[33,34,"pl-pds"]],[[10,15,"pl-ent"],[17,21,"pl-c1"]],[[10,22,"pl-ent"],[25,32,"pl-s"],[25,26,"pl-pds"],[31,32,"pl-pds"]],[],[[8,19,"pl-ent"]],[[10,16,"pl-ent"],[18,37,"pl-s"],[18,19,"pl-pds"],[36,37,"pl-pds"]],[[10,16,"pl-ent"],[18,22,"pl-c1"]],[[10,16,"pl-ent"],[18,28,"pl-s"],[18,19,"pl-pds"],[27,28,"pl-pds"]],[[10,20,"pl-ent"],[23,32,"pl-s"],[23,24,"pl-pds"],[31,32,"pl-pds"]],[[10,15,"pl-ent"],[17,21,"pl-c1"]],[[10,29,"pl-ent"],[31,55,"pl-s"],[31,32,"pl-pds"],[54,55,"pl-pds"]],[[10,22,"pl-ent"],[25,28,"pl-s"],[25,26,"pl-pds"],[27,28,"pl-pds"]],[],[],[],[[4,11,"pl-ent"]],[[6,16,"pl-ent"]],[[8,14,"pl-ent"]],[[10,21,"pl-ent"],[23,33,"pl-s"],[23,24,"pl-pds"],[32,33,"pl-pds"]],[[10,21,"pl-ent"],[23,33,"pl-s"],[23,24,"pl-pds"],[32,33,"pl-pds"]],[[10,22,"pl-ent"],[25,32,"pl-s"],[25,26,"pl-pds"],[31,32,"pl-pds"]],[],[],[],[[4,11,"pl-ent"]],[[6,19,"pl-ent"],[21,31,"pl-s"],[21,22,"pl-pds"],[30,31,"pl-pds"]],[[6,20,"pl-ent"],[22,43,"pl-s"],[22,23,"pl-pds"],[42,43,"pl-pds"]],[[6,14,"pl-ent"],[17,39,"pl-s"],[17,18,"pl-pds"],[38,39,"pl-pds"],[41,56,"pl-s"],[41,42,"pl-pds"],[55,56,"pl-pds"],[58,82,"pl-s"],[58,59,"pl-pds"],[81,82,"pl-pds"]],[[6,26,"pl-ent"],[29,32,"pl-s"],[29,30,"pl-pds"],[31,32,"pl-pds"]],[[6,20,"pl-ent"],[22,32,"pl-s"],[22,23,"pl-pds"],[31,32,"pl-pds"]],[[6,13,"pl-ent"],[15,38,"pl-s"],[15,16,"pl-pds"],[37,38,"pl-pds"]],[[6,13,"pl-ent"],[15,40,"pl-s"],[15,16,"pl-pds"],[39,40,"pl-pds"]],[[6,13,"pl-ent"],[15,26,"pl-s"],[15,16,"pl-pds"],[25,26,"pl-pds"]],[],[],[],[[2,9,"pl-ent"]],[[4,11,"pl-ent"]],[[6,13,"pl-ent"]],[[8,17,"pl-ent"],[19,23,"pl-c1"]],[[8,18,"pl-ent"],[20,24,"pl-s"],[20,21,"pl-pds"],[23,24,"pl-pds"]],[[8,16,"pl-ent"],[21,31,"pl-ent"],[33,39,"pl-s"],[33,34,"pl-pds"],[38,39,"pl-pds"],[41,48,"pl-ent"],[50,68,"pl-s"],[50,51,"pl-pds"],[67,68,"pl-pds"]],[],[],[],[],[[2,15,"pl-ent"]],[[4,16,"pl-ent"]],[[6,17,"pl-ent"],[19,26,"pl-s"],[19,20,"pl-pds"],[25,26,"pl-pds"]],[[6,15,"pl-ent"],[17,22,"pl-s"],[17,18,"pl-pds"],[21,22,"pl-pds"]],[[6,12,"pl-ent"],[15,19,"pl-s"],[15,16,"pl-pds"],[18,19,"pl-pds"],[21,62,"pl-s"],[21,22,"pl-pds"],[61,62,"pl-pds"]],[[6,18,"pl-ent"],[20,25,"pl-c1"]],[],[[4,12,"pl-ent"]],[[6,17,"pl-ent"],[19,25,"pl-s"],[19,20,"pl-pds"],[24,25,"pl-pds"]],[[6,11,"pl-ent"],[13,42,"pl-s"],[13,14,"pl-pds"],[41,42,"pl-pds"]],[[6,18,"pl-ent"],[20,25,"pl-c1"]],[[6,15,"pl-ent"]],[[8,23,"pl-ent"],[25,47,"pl-s"],[25,26,"pl-pds"],[46,47,"pl-pds"]],[],[],[],[],[[2,10,"pl-ent"]],[[4,13,"pl-ent"],[15,23,"pl-s"],[15,16,"pl-pds"],[22,23,"pl-pds"]],[[4,15,"pl-ent"],[17,21,"pl-c1"]],[[4,24,"pl-ent"],[26,34,"pl-s"],[26,27,"pl-pds"],[33,34,"pl-pds"]],[[4,19,"pl-ent"],[21,24,"pl-c1"]],[[4,20,"pl-ent"],[22,25,"pl-c1"]],[],[],[[2,11,"pl-ent"]],[[4,10,"pl-ent"],[12,16,"pl-c1"]],[[4,21,"pl-ent"],[23,27,"pl-c1"]],[[4,23,"pl-ent"],[25,30,"pl-c1"]],[],[],[[2,12,"pl-ent"]],[[4,11,"pl-ent"],[13,25,"pl-s"],[13,14,"pl-pds"],[24,25,"pl-pds"]],[[4,20,"pl-ent"],[22,26,"pl-c1"]],[[4,26,"pl-ent"],[28,30,"pl-c1"]],[],[],[[2,11,"pl-ent"]],[[4,10,"pl-ent"],[12,20,"pl-s"],[12,13,"pl-pds"],[19,20,"pl-pds"]],[[4,12,"pl-ent"]],[[6,13,"pl-ent"],[15,28,"pl-s"],[15,16,"pl-pds"],[27,28,"pl-pds"]],[[6,15,"pl-ent"],[17,23,"pl-s"],[17,18,"pl-pds"],[22,23,"pl-pds"]],[[6,23,"pl-ent"],[25,28,"pl-c1"]],[[6,24,"pl-ent"],[26,30,"pl-c1"]],[],[],[],[],[[2,10,"pl-ent"],[14,24,"pl-ent"],[26,32,"pl-s"],[26,27,"pl-pds"],[31,32,"pl-pds"]],[[2,11,"pl-ent"],[15,24,"pl-ent"],[26,30,"pl-c1"]],[[2,12,"pl-ent"],[16,24,"pl-ent"],[26,36,"pl-s"],[26,27,"pl-pds"],[35,36,"pl-pds"]],[],[[2,12,"pl-ent"]],[[4,13,"pl-ent"],[17,26,"pl-ent"],[28,34,"pl-s"],[28,29,"pl-pds"],[33,34,"pl-pds"]],[[4,15,"pl-ent"],[19,34,"pl-ent"],[36,39,"pl-c1"],[41,58,"pl-ent"],[60,62,"pl-c1"]],[[4,11,"pl-ent"],[15,24,"pl-ent"],[26,30,"pl-c1"],[32,48,"pl-ent"],[50,52,"pl-c1"]],[],[],[[0,3,"pl-s"]],[],[[52,53,"pl-s"],[53,59,"pl-c1"],[59,60,"pl-s"],[68,69,"pl-s"],[69,80,"pl-c1"],[80,81,"pl-s"]],[],[[7,8,"pl-s"],[8,19,"pl-c1"],[19,20,"pl-s"]],[[4,5,"pl-s"],[5,15,"pl-c1"],[15,16,"pl-s"]],[],[],[],[],[[0,1,"pl-v"],[57,58,"pl-s"],[58,66,"pl-c1"],[66,67,"pl-s"],[80,81,"pl-s"],[81,98,"pl-c1"],[98,99,"pl-s"]],[[0,1,"pl-v"]],[[2,3,"pl-s"],[3,4,"pl-v"],[39,40,"pl-s"],[40,51,"pl-c1"],[51,52,"pl-s"]],[[2,3,"pl-s"],[3,4,"pl-v"]],[[2,3,"pl-s"],[3,4,"pl-v"],[9,10,"pl-s"],[10,23,"pl-c1"],[23,24,"pl-s"]],[[0,1,"pl-v"],[67,68,"pl-s"],[68,92,"pl-c1"],[92,93,"pl-s"],[125,126,"pl-s"],[126,155,"pl-c1"],[155,156,"pl-s"]],[[0,1,"pl-v"],[104,105,"pl-s"],[105,116,"pl-c1"],[116,117,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,14,"pl-c1"],[14,15,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,8,"pl-c1"],[8,9,"pl-s"],[28,29,"pl-s"],[29,39,"pl-c1"],[39,40,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"]],[[0,1,"pl-v"],[82,83,"pl-s"],[83,93,"pl-c1"],[93,94,"pl-s"]],[[0,1,"pl-v"],[31,32,"pl-s"],[32,37,"pl-c1"],[37,38,"pl-s"],[56,57,"pl-s"],[57,113,"pl-c1"],[113,114,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,12,"pl-ent"]],[],[[6,16,"pl-ent"],[18,25,"pl-s"],[18,19,"pl-pds"],[24,25,"pl-pds"]],[[6,13,"pl-ent"]],[[8,17,"pl-ent"],[19,29,"pl-s"],[19,20,"pl-pds"],[28,29,"pl-pds"]],[[8,20,"pl-ent"],[22,28,"pl-s"],[22,23,"pl-pds"],[27,28,"pl-pds"]],[[8,14,"pl-ent"],[18,24,"pl-ent"],[26,33,"pl-s"],[26,27,"pl-pds"],[32,33,"pl-pds"],[35,39,"pl-ent"],[41,67,"pl-s"],[41,42,"pl-pds"],[66,67,"pl-pds"]],[],[],[],[[6,16,"pl-ent"],[18,32,"pl-s"],[18,19,"pl-pds"],[31,32,"pl-pds"]],[[6,13,"pl-ent"]],[[8,17,"pl-ent"],[19,29,"pl-s"],[19,20,"pl-pds"],[28,29,"pl-pds"]],[[8,20,"pl-ent"],[22,28,"pl-s"],[22,23,"pl-pds"],[27,28,"pl-pds"]],[[8,14,"pl-ent"],[18,24,"pl-ent"],[26,33,"pl-s"],[26,27,"pl-pds"],[32,33,"pl-pds"],[35,39,"pl-ent"],[41,57,"pl-s"],[41,42,"pl-pds"],[56,57,"pl-pds"]],[],[],[],[],[[0,3,"pl-s"]],[],[[21,22,"pl-s"],[22,24,"pl-c1"],[24,25,"pl-s"],[36,37,"pl-s"],[37,42,"pl-c1"],[42,43,"pl-s"],[87,88,"pl-s"],[88,100,"pl-c1"],[100,101,"pl-s"]],[],[],[],[[56,57,"pl-s"],[57,85,"pl-c1"],[85,86,"pl-s"]],[[61,62,"pl-s"],[62,73,"pl-c1"],[73,74,"pl-s"],[164,165,"pl-s"],[165,181,"pl-c1"],[181,182,"pl-s"]],[[8,9,"pl-s"],[9,23,"pl-c1"],[23,24,"pl-s"],[42,43,"pl-s"],[43,56,"pl-c1"],[56,57,"pl-s"]],[[16,17,"pl-s"],[17,44,"pl-c1"],[44,45,"pl-s"],[47,48,"pl-s"],[48,77,"pl-c1"],[77,78,"pl-s"],[117,118,"pl-s"],[118,126,"pl-c1"],[126,127,"pl-s"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,10,"pl-ent"]],[[4,10,"pl-ent"]],[],[[8,12,"pl-ent"],[14,28,"pl-s"],[14,15,"pl-pds"],[27,28,"pl-pds"]],[[8,18,"pl-ent"],[20,32,"pl-s"],[20,21,"pl-pds"],[31,32,"pl-pds"]],[[8,15,"pl-ent"],[17,44,"pl-s"],[17,18,"pl-pds"],[43,44,"pl-pds"]],[],[],[[8,12,"pl-ent"],[14,21,"pl-s"],[14,15,"pl-pds"],[20,21,"pl-pds"]],[[8,18,"pl-ent"],[20,28,"pl-s"],[20,21,"pl-pds"],[27,28,"pl-pds"]],[[8,15,"pl-ent"],[17,36,"pl-s"],[17,18,"pl-pds"],[35,36,"pl-pds"]],[[8,23,"pl-ent"],[25,67,"pl-s"],[25,26,"pl-pds"],[66,67,"pl-pds"]],[],[],[],[[2,12,"pl-ent"]],[[4,14,"pl-ent"]],[[6,16,"pl-ent"]],[[8,14,"pl-ent"]],[[10,21,"pl-ent"],[23,38,"pl-s"],[23,24,"pl-pds"],[37,38,"pl-pds"]],[[10,22,"pl-ent"],[25,48,"pl-s"],[25,26,"pl-pds"],[47,48,"pl-pds"]],[[10,36,"pl-ent"],[38,42,"pl-c1"]],[[10,34,"pl-ent"],[36,40,"pl-c1"]],[[10,37,"pl-ent"],[39,43,"pl-c1"]],[[10,30,"pl-ent"],[32,40,"pl-s"],[32,33,"pl-pds"],[39,40,"pl-pds"]],[],[],[],[],[[2,12,"pl-ent"]],[],[[6,16,"pl-ent"],[18,32,"pl-s"],[18,19,"pl-pds"],[31,32,"pl-pds"]],[[6,13,"pl-ent"]],[[8,17,"pl-ent"],[19,29,"pl-s"],[19,20,"pl-pds"],[28,29,"pl-pds"]],[[8,20,"pl-ent"],[22,28,"pl-s"],[22,23,"pl-pds"],[27,28,"pl-pds"]],[[8,14,"pl-ent"],[18,24,"pl-ent"],[26,33,"pl-s"],[26,27,"pl-pds"],[32,33,"pl-pds"],[35,39,"pl-ent"],[41,57,"pl-s"],[41,42,"pl-pds"],[56,57,"pl-pds"]],[],[],[],[],[[0,3,"pl-s"]],[],[],[],[[0,1,"pl-v"],[7,8,"pl-s"],[8,19,"pl-c1"],[19,20,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[32,33,"pl-s"],[33,43,"pl-c1"],[43,44,"pl-s"],[54,55,"pl-s"],[55,78,"pl-c1"],[78,79,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[39,40,"pl-s"],[40,63,"pl-c1"],[63,64,"pl-s"],[69,70,"pl-s"],[70,75,"pl-c1"],[75,76,"pl-s"]],[],[[6,7,"pl-s"],[7,17,"pl-c1"],[17,18,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"]],[[0,1,"pl-v"],[15,16,"pl-s"],[16,42,"pl-c1"],[42,43,"pl-s"],[102,103,"pl-s"],[103,116,"pl-c1"],[116,117,"pl-s"],[124,125,"pl-s"],[125,144,"pl-c1"],[144,145,"pl-s"],[151,152,"pl-s"],[152,167,"pl-c1"],[167,168,"pl-s"],[175,176,"pl-s"],[176,197,"pl-c1"],[197,198,"pl-s"]],[[0,1,"pl-v"],[5,6,"pl-s"],[6,14,"pl-c1"],[14,15,"pl-s"],[17,18,"pl-s"],[18,34,"pl-c1"],[34,35,"pl-s"]],[[0,1,"pl-v"],[5,6,"pl-s"],[6,22,"pl-c1"],[22,23,"pl-s"]],[[0,1,"pl-v"]],[],[],[],[[0,1,"pl-v"]],[[0,1,"pl-v"],[25,26,"pl-s"],[26,36,"pl-c1"],[36,37,"pl-s"],[42,43,"pl-s"],[43,68,"pl-c1"],[68,69,"pl-s"],[104,105,"pl-s"],[105,136,"pl-c1"],[136,137,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[25,26,"pl-s"],[26,45,"pl-c1"],[45,46,"pl-s"],[62,63,"pl-s"],[63,81,"pl-c1"],[81,82,"pl-s"]],[],[[0,34,"pl-mh"],[4,34,"pl-en"]],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,16,"pl-ent"]],[[4,13,"pl-ent"],[15,19,"pl-c1"]],[[4,21,"pl-ent"],[23,50,"pl-s"],[23,24,"pl-pds"],[49,50,"pl-pds"]],[[4,21,"pl-ent"],[23,29,"pl-s"],[23,24,"pl-pds"],[28,29,"pl-pds"]],[[4,31,"pl-ent"],[34,40,"pl-s"],[34,35,"pl-pds"],[39,40,"pl-pds"],[42,54,"pl-s"],[42,43,"pl-pds"],[53,54,"pl-pds"]],[],[[2,12,"pl-ent"]],[[4,11,"pl-ent"],[13,19,"pl-s"],[13,14,"pl-pds"],[18,19,"pl-pds"]],[[4,22,"pl-ent"],[25,28,"pl-s"],[25,26,"pl-pds"],[27,28,"pl-pds"]],[[4,19,"pl-ent"],[22,25,"pl-s"],[22,23,"pl-pds"],[24,25,"pl-pds"]],[[4,38,"pl-ent"],[40,45,"pl-c1"]],[[4,32,"pl-ent"],[34,39,"pl-c1"]],[[4,30,"pl-ent"],[32,37,"pl-c1"]],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,31,"pl-c1"],[31,32,"pl-s"],[63,64,"pl-s"],[64,76,"pl-c1"],[76,77,"pl-s"],[101,102,"pl-s"],[102,121,"pl-c1"],[121,122,"pl-s"],[189,190,"pl-s"],[190,211,"pl-c1"],[211,212,"pl-s"],[216,217,"pl-s"],[217,248,"pl-c1"],[248,249,"pl-s"]],[[0,1,"pl-v"],[10,11,"pl-s"],[11,39,"pl-c1"],[39,40,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,31,"pl-c1"],[31,32,"pl-s"],[43,44,"pl-s"],[44,48,"pl-c1"],[48,49,"pl-s"],[51,52,"pl-s"],[52,59,"pl-c1"],[59,60,"pl-s"],[62,63,"pl-s"],[63,73,"pl-c1"],[73,74,"pl-s"],[76,77,"pl-s"],[77,80,"pl-c1"],[80,81,"pl-s"],[84,85,"pl-s"],[85,90,"pl-c1"],[90,91,"pl-s"],[93,94,"pl-s"],[94,103,"pl-c1"],[103,104,"pl-s"],[106,107,"pl-s"],[107,113,"pl-c1"],[113,114,"pl-s"],[116,117,"pl-s"],[117,127,"pl-c1"],[127,128,"pl-s"],[130,131,"pl-s"],[131,134,"pl-c1"],[134,135,"pl-s"],[137,138,"pl-s"],[138,142,"pl-c1"],[142,143,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,41,"pl-c1"],[41,42,"pl-s"]],[[0,1,"pl-v"],[21,22,"pl-s"],[22,35,"pl-c1"],[35,36,"pl-s"],[38,39,"pl-s"],[39,56,"pl-c1"],[56,57,"pl-s"],[59,60,"pl-s"],[60,74,"pl-c1"],[74,75,"pl-s"],[77,78,"pl-s"],[78,96,"pl-c1"],[96,97,"pl-s"],[99,100,"pl-s"],[100,111,"pl-c1"],[111,112,"pl-s"],[114,115,"pl-s"],[115,127,"pl-c1"],[127,128,"pl-s"],[140,141,"pl-s"],[141,159,"pl-c1"],[159,160,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,19,"pl-c1"],[19,20,"pl-s"],[37,38,"pl-s"],[38,43,"pl-c1"],[43,44,"pl-s"],[46,47,"pl-s"],[47,54,"pl-c1"],[54,55,"pl-s"],[61,62,"pl-s"],[62,65,"pl-c1"],[65,66,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[5,10,"pl-c1"],[10,11,"pl-s"],[16,17,"pl-s"],[17,24,"pl-c1"],[24,25,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[5,8,"pl-c1"],[8,9,"pl-s"]],[[0,1,"pl-v"],[85,86,"pl-s"],[86,119,"pl-c1"],[119,120,"pl-s"],[184,185,"pl-s"],[185,189,"pl-c1"],[189,190,"pl-s"],[191,192,"pl-s"],[192,196,"pl-c1"],[196,197,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,23,"pl-c1"],[23,24,"pl-s"]],[],[[0,26,"pl-mh"],[4,26,"pl-en"]],[],[[4,5,"pl-s"],[5,17,"pl-c1"],[17,18,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,12,"pl-ent"]],[[4,9,"pl-ent"]],[[6,16,"pl-ent"]],[[8,17,"pl-ent"]],[[10,21,"pl-ent"],[23,30,"pl-s"],[23,24,"pl-pds"],[29,30,"pl-pds"]],[[10,18,"pl-ent"],[20,31,"pl-s"],[20,21,"pl-pds"],[30,31,"pl-pds"]],[[10,16,"pl-ent"],[18,23,"pl-c1"]],[[10,16,"pl-ent"],[18,23,"pl-s"],[18,19,"pl-pds"],[22,23,"pl-pds"]],[[10,22,"pl-ent"],[24,56,"pl-s"],[24,25,"pl-pds"],[55,56,"pl-pds"]],[[10,29,"pl-ent"],[31,40,"pl-s"],[31,32,"pl-pds"],[39,40,"pl-pds"]],[[10,27,"pl-ent"],[30,53,"pl-s"],[30,31,"pl-pds"],[52,53,"pl-pds"],[55,93,"pl-s"],[55,56,"pl-pds"],[92,93,"pl-pds"]],[],[],[],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-v"],[14,15,"pl-s"],[15,36,"pl-c1"],[36,37,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[39,40,"pl-s"],[40,52,"pl-c1"],[52,53,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[5,14,"pl-c1"],[14,15,"pl-s"],[32,33,"pl-s"],[33,48,"pl-c1"],[48,49,"pl-s"],[59,60,"pl-s"],[60,74,"pl-c1"],[74,75,"pl-s"],[88,89,"pl-s"],[89,101,"pl-c1"],[101,102,"pl-s"],[112,113,"pl-s"],[113,125,"pl-c1"],[125,126,"pl-s"]],[[2,3,"pl-v"],[4,5,"pl-s"],[5,12,"pl-c1"],[12,13,"pl-s"],[46,47,"pl-s"],[47,57,"pl-c1"],[57,58,"pl-s"],[67,68,"pl-s"],[68,80,"pl-c1"],[80,81,"pl-s"],[91,92,"pl-s"],[92,104,"pl-c1"],[104,105,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"]],[[0,1,"pl-v"],[86,87,"pl-s"],[87,96,"pl-c1"],[96,97,"pl-s"],[143,144,"pl-s"],[144,147,"pl-c1"],[147,148,"pl-s"],[179,180,"pl-s"],[180,199,"pl-c1"],[199,200,"pl-s"],[204,205,"pl-s"],[205,239,"pl-c1"],[239,240,"pl-s"]],[[0,1,"pl-v"],[67,68,"pl-s"],[68,83,"pl-c1"],[83,84,"pl-s"],[94,95,"pl-s"],[95,115,"pl-c1"],[115,116,"pl-s"],[162,163,"pl-s"],[163,169,"pl-c1"],[169,170,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[35,36,"pl-s"],[36,41,"pl-c1"],[41,42,"pl-s"]],[[0,1,"pl-v"],[36,37,"pl-s"],[37,56,"pl-c1"],[56,57,"pl-s"],[97,98,"pl-s"],[98,124,"pl-c1"],[124,125,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[82,83,"pl-s"],[83,101,"pl-c1"],[101,102,"pl-s"],[104,105,"pl-s"],[105,127,"pl-c1"],[127,128,"pl-s"],[130,131,"pl-s"],[131,153,"pl-c1"],[153,154,"pl-s"]],[[0,1,"pl-v"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,12,"pl-ent"]],[[4,9,"pl-ent"]],[[6,16,"pl-ent"]],[[8,17,"pl-ent"]],[[10,21,"pl-ent"],[23,30,"pl-s"],[23,24,"pl-pds"],[29,30,"pl-pds"]],[[10,21,"pl-ent"],[23,57,"pl-s"],[23,24,"pl-pds"],[56,57,"pl-pds"]],[[10,26,"pl-ent"],[28,37,"pl-s"],[28,29,"pl-pds"],[36,37,"pl-pds"]],[[10,23,"pl-ent"],[25,51,"pl-s"],[25,26,"pl-pds"],[50,51,"pl-pds"]],[[10,32,"pl-ent"],[34,41,"pl-c1"]],[[10,39,"pl-ent"],[41,44,"pl-c1"]],[[10,35,"pl-ent"],[37,42,"pl-c1"]],[[10,30,"pl-ent"],[32,37,"pl-c1"]],[],[],[],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-v"],[37,38,"pl-s"],[38,49,"pl-c1"],[49,50,"pl-s"],[63,64,"pl-s"],[64,84,"pl-c1"],[84,85,"pl-s"],[105,106,"pl-s"],[106,128,"pl-c1"],[128,129,"pl-s"]],[[0,1,"pl-v"],[27,28,"pl-s"],[28,43,"pl-c1"],[43,44,"pl-s"],[59,60,"pl-s"],[60,72,"pl-c1"],[72,73,"pl-s"],[83,84,"pl-s"],[84,98,"pl-c1"],[98,99,"pl-s"],[108,109,"pl-s"],[109,121,"pl-c1"],[121,122,"pl-s"],[141,142,"pl-s"],[142,152,"pl-c1"],[152,153,"pl-s"]],[[0,1,"pl-v"],[8,9,"pl-s"],[9,21,"pl-c1"],[21,22,"pl-s"],[52,53,"pl-s"],[53,65,"pl-c1"],[65,66,"pl-s"],[81,82,"pl-s"],[82,102,"pl-c1"],[102,103,"pl-s"]],[[0,1,"pl-v"],[21,22,"pl-s"],[22,45,"pl-c1"],[45,46,"pl-s"],[129,130,"pl-s"],[130,141,"pl-c1"],[141,142,"pl-s"]],[[0,1,"pl-v"],[42,43,"pl-s"],[43,44,"pl-s"],[44,67,"pl-c1"],[67,68,"pl-s"],[68,69,"pl-s"],[69,70,"pl-s"],[70,93,"pl-corl"],[93,94,"pl-s"]],[],[[0,14,"pl-mh"],[3,14,"pl-en"]],[],[[0,1,"pl-ml"],[11,12,"pl-ml"],[20,21,"pl-ml"],[27,28,"pl-ml"],[41,42,"pl-ml"]],[[0,1,"pl-ml"],[11,12,"pl-ml"],[20,21,"pl-ml"],[27,28,"pl-ml"],[41,42,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[18,19,"pl-ml"],[25,26,"pl-ml"],[56,57,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,8,"pl-c1"],[8,9,"pl-s"],[10,11,"pl-ml"],[17,18,"pl-ml"],[19,20,"pl-s"],[20,34,"pl-c1"],[34,35,"pl-s"],[43,44,"pl-ml"],[85,86,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,11,"pl-c1"],[11,12,"pl-s"],[13,14,"pl-ml"],[20,21,"pl-ml"],[22,23,"pl-s"],[23,52,"pl-c1"],[52,53,"pl-s"],[54,55,"pl-ml"],[70,71,"pl-s"],[71,97,"pl-c1"],[97,98,"pl-s"],[99,100,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"],[22,23,"pl-ml"],[29,30,"pl-ml"],[31,32,"pl-s"],[32,61,"pl-c1"],[61,62,"pl-s"],[63,64,"pl-ml"],[76,77,"pl-s"],[77,89,"pl-c1"],[89,90,"pl-s"],[123,124,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,31,"pl-c1"],[31,32,"pl-s"],[33,34,"pl-ml"],[39,40,"pl-ml"],[46,47,"pl-ml"],[82,83,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,7,"pl-c1"],[7,8,"pl-s"],[9,10,"pl-ml"],[16,17,"pl-ml"],[18,19,"pl-s"],[19,48,"pl-c1"],[48,49,"pl-s"],[50,51,"pl-ml"],[120,121,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[14,15,"pl-ml"],[20,21,"pl-ml"],[35,36,"pl-ml"],[63,64,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[14,15,"pl-ml"],[21,22,"pl-ml"],[45,46,"pl-ml"],[81,82,"pl-ml"]],[],[[0,40,"pl-mh"],[4,40,"pl-en"]],[],[[29,30,"pl-s"],[42,43,"pl-s"],[43,44,"pl-s"],[44,73,"pl-corl"],[73,74,"pl-s"]],[],[[10,11,"pl-s"],[11,34,"pl-c1"],[34,35,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[],[[2,7,"pl-ent"]],[[4,13,"pl-ent"],[15,19,"pl-c1"]],[[4,10,"pl-ent"],[12,22,"pl-s"],[12,13,"pl-pds"],[21,22,"pl-pds"]],[[4,17,"pl-ent"],[19,49,"pl-s"],[19,20,"pl-pds"],[48,49,"pl-pds"]],[[4,9,"pl-ent"],[11,32,"pl-s"],[11,12,"pl-pds"],[31,32,"pl-pds"]],[[4,13,"pl-ent"],[15,22,"pl-s"],[15,16,"pl-pds"],[21,22,"pl-pds"]],[],[],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[12,14,"pl-s"]],[],[[0,1,"pl-ml"],[11,12,"pl-ml"],[18,19,"pl-ml"],[32,33,"pl-ml"]],[[0,1,"pl-ml"],[11,12,"pl-ml"],[18,19,"pl-ml"],[32,33,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,35,"pl-c1"],[35,36,"pl-s"],[37,38,"pl-ml"],[44,45,"pl-ml"],[76,77,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[14,15,"pl-ml"],[29,30,"pl-ml"],[53,54,"pl-ml"]],[],[[0,2,"pl-s"],[20,22,"pl-s"],[23,24,"pl-s"],[24,36,"pl-c1"],[36,37,"pl-s"],[39,40,"pl-s"],[40,54,"pl-c1"],[54,55,"pl-s"],[57,58,"pl-s"],[58,67,"pl-c1"],[67,68,"pl-s"],[70,71,"pl-s"],[71,83,"pl-c1"],[83,84,"pl-s"],[86,87,"pl-s"],[87,97,"pl-c1"],[97,98,"pl-s"],[100,101,"pl-s"],[101,118,"pl-c1"],[118,119,"pl-s"]],[],[[0,2,"pl-s"],[13,15,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,23,"pl-c"],[0,1,"pl-c"]],[[0,65,"pl-c"],[0,1,"pl-c"]],[[6,101,"pl-s"],[6,8,"pl-pds"],[27,58,"pl-s"],[27,28,"pl-pds"],[44,57,"pl-smi"],[57,58,"pl-pds"],[86,87,"pl-k"],[100,101,"pl-pds"]],[],[[0,23,"pl-c"],[0,1,"pl-c"]],[],[],[[0,19,"pl-c"],[0,1,"pl-c"]],[[16,46,"pl-s"],[16,17,"pl-pds"],[39,45,"pl-smi"],[45,46,"pl-pds"]],[[5,37,"pl-s"],[5,6,"pl-pds"],[36,37,"pl-pds"]],[[5,153,"pl-s"],[5,6,"pl-pds"],[152,153,"pl-pds"]],[],[[0,3,"pl-s"]],[],[[4,5,"pl-s"],[21,22,"pl-s"],[22,23,"pl-s"],[23,45,"pl-corl"],[45,46,"pl-s"]],[],[[0,23,"pl-mh"],[4,23,"pl-en"]],[],[[0,1,"pl-s"],[1,23,"pl-c1"],[23,24,"pl-s"],[43,44,"pl-s"],[44,56,"pl-c1"],[56,57,"pl-s"],[59,60,"pl-s"],[60,69,"pl-c1"],[69,70,"pl-s"],[72,73,"pl-s"],[73,79,"pl-c1"],[79,80,"pl-s"],[95,96,"pl-s"],[96,104,"pl-c1"],[104,105,"pl-s"],[120,121,"pl-s"],[121,135,"pl-c1"],[135,136,"pl-s"],[172,173,"pl-s"],[173,190,"pl-c1"],[190,191,"pl-s"],[243,244,"pl-s"],[244,271,"pl-c1"],[271,272,"pl-s"],[274,275,"pl-s"],[275,303,"pl-c1"],[303,304,"pl-s"],[310,311,"pl-s"],[311,348,"pl-c1"],[348,349,"pl-s"]],[],[[0,11,"pl-mh"],[3,11,"pl-en"]],[],[[0,1,"pl-ml"],[10,11,"pl-ml"],[24,25,"pl-ml"]],[[0,1,"pl-ml"],[10,11,"pl-ml"],[24,25,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,49,"pl-c1"],[49,50,"pl-s"],[51,52,"pl-ml"],[91,92,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,24,"pl-c1"],[24,25,"pl-s"],[26,27,"pl-ml"],[52,53,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,26,"pl-c1"],[26,27,"pl-s"],[28,29,"pl-ml"],[67,68,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[19,20,"pl-ml"],[41,42,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,6,"pl-c1"],[6,7,"pl-s"],[8,9,"pl-ml"],[83,84,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,8,"pl-c1"],[8,9,"pl-s"],[10,11,"pl-ml"],[34,35,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,10,"pl-c1"],[10,11,"pl-s"],[12,13,"pl-ml"],[51,52,"pl-s"],[52,66,"pl-c1"],[66,67,"pl-s"],[69,70,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,59,"pl-c1"],[59,60,"pl-s"],[61,62,"pl-ml"],[89,90,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,9,"pl-c1"],[9,10,"pl-s"],[11,12,"pl-ml"],[36,37,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"],[20,21,"pl-ml"],[92,93,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,49,"pl-c1"],[49,50,"pl-s"],[51,52,"pl-ml"],[118,119,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,96,"pl-c1"],[96,97,"pl-s"],[98,99,"pl-ml"],[123,124,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,37,"pl-c1"],[37,38,"pl-s"],[39,40,"pl-ml"],[71,72,"pl-s"],[72,94,"pl-c1"],[94,95,"pl-s"],[112,113,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,21,"pl-c1"],[21,22,"pl-s"],[23,24,"pl-ml"],[59,60,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,102,"pl-c1"],[102,103,"pl-s"],[104,105,"pl-ml"],[143,144,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,32,"pl-c1"],[32,33,"pl-s"],[34,35,"pl-ml"],[63,64,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,19,"pl-c1"],[19,20,"pl-s"],[22,23,"pl-s"],[23,69,"pl-c1"],[69,70,"pl-s"],[71,72,"pl-ml"],[132,133,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,27,"pl-c1"],[27,28,"pl-s"],[29,30,"pl-ml"],[75,76,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,24,"pl-c1"],[24,25,"pl-s"],[26,27,"pl-ml"],[63,64,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,29,"pl-c1"],[29,30,"pl-s"],[31,32,"pl-ml"],[61,62,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,47,"pl-c1"],[47,48,"pl-s"],[49,50,"pl-ml"],[96,97,"pl-ml"]],[[0,1,"pl-ml"],[2,3,"pl-s"],[3,27,"pl-c1"],[27,28,"pl-s"],[29,30,"pl-ml"],[61,62,"pl-ml"]],[],[[0,14,"pl-mh"],[3,14,"pl-en"]],[],[[30,32,"pl-s"],[42,44,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[35,46,"pl-c"],[35,36,"pl-c"]],[[35,59,"pl-c"],[35,36,"pl-c"]],[[10,14,"pl-c1"],[35,49,"pl-c"],[35,36,"pl-c"]],[[0,3,"pl-s"]],[],[[0,25,"pl-mh"],[4,25,"pl-en"]],[],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[3,26,"pl-c1"],[26,27,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[40,41,"pl-s"],[41,60,"pl-c1"],[60,61,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,18,"pl-c1"],[18,19,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,27,"pl-c1"],[27,28,"pl-s"],[30,31,"pl-s"],[31,58,"pl-c1"],[58,59,"pl-s"],[61,62,"pl-s"],[62,81,"pl-c1"],[81,82,"pl-s"],[84,85,"pl-s"],[85,108,"pl-c1"],[108,109,"pl-s"],[111,112,"pl-s"],[112,135,"pl-c1"],[135,136,"pl-s"],[138,139,"pl-s"],[139,160,"pl-c1"],[160,161,"pl-s"],[163,164,"pl-s"],[164,189,"pl-c1"],[189,190,"pl-s"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,24,"pl-c1"]],[[0,18,"pl-c1"]],[[0,23,"pl-c1"]],[[0,20,"pl-c1"]],[[0,35,"pl-c1"]],[[0,19,"pl-c1"]],[[0,35,"pl-c1"]],[[0,48,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,4,"pl-c1"]],[[0,58,"pl-c1"]],[[0,53,"pl-c1"]],[[0,66,"pl-c1"]],[[0,66,"pl-c1"]],[[0,66,"pl-c1"]],[[0,74,"pl-c1"]],[[0,151,"pl-c1"]],[[0,52,"pl-c1"]],[[0,85,"pl-c1"]],[[0,48,"pl-c1"]],[[0,86,"pl-c1"]],[[0,60,"pl-c1"]],[[0,49,"pl-c1"]],[[0,76,"pl-c1"]],[[0,81,"pl-c1"]],[[0,61,"pl-c1"]],[[0,73,"pl-c1"]],[[0,5,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,13,"pl-mh"],[3,13,"pl-en"]],[],[[14,16,"pl-s"],[22,24,"pl-s"],[26,27,"pl-s"],[27,35,"pl-c1"],[35,36,"pl-s"],[58,59,"pl-s"],[59,69,"pl-c1"],[69,70,"pl-s"]],[],[[0,1,"pl-v"],[2,4,"pl-s"],[15,17,"pl-s"],[18,19,"pl-s"],[19,28,"pl-c1"],[28,29,"pl-s"],[69,70,"pl-s"],[70,81,"pl-c1"],[81,82,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[67,69,"pl-s"],[71,72,"pl-s"],[72,76,"pl-c1"],[76,77,"pl-s"],[81,82,"pl-s"],[82,100,"pl-c1"],[100,101,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[34,35,"pl-s"],[35,38,"pl-c1"],[38,39,"pl-s"],[39,41,"pl-s"],[67,68,"pl-s"],[68,91,"pl-c1"],[91,92,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[31,33,"pl-s"]],[[0,1,"pl-v"],[2,4,"pl-s"],[4,5,"pl-s"],[5,23,"pl-c1"],[23,24,"pl-s"],[24,26,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[4,5,"pl-s"],[5,6,"pl-s"],[6,21,"pl-c1"],[21,22,"pl-s"],[22,23,"pl-s"],[23,24,"pl-s"],[24,39,"pl-corl"],[39,40,"pl-s"]],[],[],[],[[0,1,"pl-v"],[6,7,"pl-s"],[7,15,"pl-c1"],[15,16,"pl-s"],[20,21,"pl-s"],[21,35,"pl-c1"],[35,36,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,14,"pl-c1"],[14,15,"pl-s"],[19,20,"pl-s"],[20,33,"pl-c1"],[33,34,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,11,"pl-c1"],[11,12,"pl-s"],[16,17,"pl-s"],[17,27,"pl-c1"],[27,28,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,13,"pl-c1"],[13,14,"pl-s"],[26,27,"pl-s"],[27,38,"pl-c1"],[38,39,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,13,"pl-c1"],[13,14,"pl-s"],[18,19,"pl-s"],[19,33,"pl-c1"],[33,34,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,14,"pl-c1"],[14,15,"pl-s"],[27,28,"pl-s"],[28,41,"pl-c1"],[41,42,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,17,"pl-c1"],[17,18,"pl-s"],[22,23,"pl-s"],[23,42,"pl-c1"],[42,43,"pl-s"]],[[0,1,"pl-v"],[6,7,"pl-s"],[7,12,"pl-c1"],[12,13,"pl-s"],[17,18,"pl-s"],[18,54,"pl-c1"],[54,55,"pl-s"],[59,60,"pl-s"],[60,107,"pl-c1"],[107,108,"pl-s"]],[],[[0,22,"pl-mh"],[3,22,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[33,34,"pl-s"],[34,35,"pl-s"],[35,52,"pl-corl"],[52,53,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[28,29,"pl-s"],[29,30,"pl-s"],[30,53,"pl-corl"],[53,54,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[30,31,"pl-s"],[31,32,"pl-s"],[32,59,"pl-corl"],[59,60,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[29,30,"pl-s"],[30,31,"pl-s"],[31,55,"pl-corl"],[55,56,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[31,32,"pl-s"],[32,33,"pl-s"],[33,49,"pl-corl"],[49,50,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[31,32,"pl-s"],[32,33,"pl-s"],[33,56,"pl-corl"],[56,57,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[24,25,"pl-s"],[25,26,"pl-s"],[26,45,"pl-corl"],[45,46,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[19,20,"pl-s"],[20,21,"pl-s"],[21,43,"pl-corl"],[43,44,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[28,29,"pl-s"],[29,30,"pl-s"],[30,49,"pl-corl"],[49,50,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[27,28,"pl-s"],[28,29,"pl-s"],[29,51,"pl-corl"],[51,52,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[0,1,"pl-v"],[2,3,"pl-s"],[24,25,"pl-s"],[25,26,"pl-s"],[26,43,"pl-corl"],[43,44,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[15,16,"pl-s"],[16,17,"pl-s"],[17,40,"pl-corl"],[40,41,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[19,20,"pl-s"],[20,21,"pl-s"],[21,48,"pl-corl"],[48,49,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[16,17,"pl-s"],[17,18,"pl-s"],[18,42,"pl-corl"],[42,43,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[23,24,"pl-s"],[24,25,"pl-s"],[25,41,"pl-corl"],[41,42,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[15,16,"pl-s"],[16,17,"pl-s"],[17,40,"pl-corl"],[40,41,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[11,12,"pl-s"],[12,13,"pl-s"],[13,32,"pl-corl"],[32,33,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[14,15,"pl-s"],[15,16,"pl-s"],[16,38,"pl-corl"],[38,39,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[11,12,"pl-s"],[12,13,"pl-s"],[13,32,"pl-corl"],[32,33,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[14,15,"pl-s"],[15,16,"pl-s"],[16,38,"pl-corl"],[38,39,"pl-s"]],[],[[0,13,"pl-mh"],[3,13,"pl-en"]],[],[[56,58,"pl-s"],[139,141,"pl-s"]],[],[[0,10,"pl-mh"],[3,10,"pl-en"]],[],[[10,11,"pl-s"],[18,19,"pl-s"],[19,20,"pl-s"],[20,27,"pl-corl"],[27,28,"pl-s"]],[],[[0,3,"pl-ms"]],[],[[0,2,"pl-s"],[10,12,"pl-s"]],[],[[0,15,"pl-mh"],[3,15,"pl-en"]],[],[[0,1,"pl-s"],[1,3,"pl-s"],[21,22,"pl-s"],[22,23,"pl-s"],[23,105,"pl-corl"],[105,107,"pl-s"],[107,108,"pl-s"],[108,181,"pl-corl"],[181,182,"pl-s"]]],"colorizedLines":null}},"title":"nullclaw/README.md at main · nullclaw/nullclaw","appPayload":{},"meta":{"title":"nullclaw/README.md at main · nullclaw/nullclaw"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/nullclaw/nullclaw" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/nullclaw/nullclaw/tree/main" data-discover="true">nullclaw</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_1cpla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_1cpla9lik5_ _R_1cpla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_1cpla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7p9la9lik5_" id="_R_99la9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7p9la9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7pdla9lik5_" id="_R_9dla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7pdla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/nullclaw/nullclaw/commits/main/README.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/nullclaw/nullclaw/commits/main/README.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="41.4 KB" style="--truncate-max-width:100%"><span>976 lines (792 loc) · 41.4 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/nullclaw/nullclaw/tree/main" data-discover="true">nullclaw</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="41.4 KB" style="--truncate-max-width:100%"><span>976 lines (792 loc) · 41.4 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/nullclaw/nullclaw/raw/refs/heads/main/README.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><p dir="auto">Want a simpler way to install and configure nullclaw with a UI? Try <a href="https://github.com/nullclaw/nullhub">nullhub</a>! (currently in beta)</p>
<p dir="auto"><a href="https://github.com/nullclaw/nullhub">nullhub</a> provides a UI layer for the Null ecosystem: simpler nullclaw setup and configuration, orchestration from <a href="https://github.com/nullclaw/nullboiler">nullboiler</a>, observability from <a href="https://github.com/nullclaw/nullwatch">nullwatch</a>, and task tracking from <a href="https://github.com/nullclaw/nulltickets">nulltickets</a>.</p>
<p align="center" dir="auto">
  <a target="_blank" rel="noopener noreferrer" href="/nullclaw/nullclaw/blob/main/nullclaw.png"><img src="/nullclaw/nullclaw/raw/main/nullclaw.png" alt="nullclaw" width="200" style="max-width: 100%;"></a>
</p>
<div class="markdown-heading" dir="auto"><h1 align="center" tabindex="-1" class="heading-element" dir="auto">NullClaw</h1><a id="user-content-nullclaw" class="anchor" aria-label="Permalink: NullClaw" href="#nullclaw"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p align="center" dir="auto">
  <strong>Null overhead. Null compromise. 100% Zig. 100% Agnostic.</strong><br>
  <strong>678 KB binary. ~1 MB RAM. Boots in &lt;2 ms. Runs on anything with a CPU.</strong>
</p>
<p align="center" dir="auto">
  <a href="https://github.com/nullclaw/nullclaw/actions/workflows/ci.yml"><img src="https://github.com/nullclaw/nullclaw/actions/workflows/ci.yml/badge.svg" alt="CI" style="max-width: 100%;"></a>
  <a href="https://github.com/nullclaw/nullclaw/actions/workflows/nightly.yml"><img src="https://github.com/nullclaw/nullclaw/actions/workflows/nightly.yml/badge.svg" alt="Nightly" style="max-width: 100%;"></a>
  <a href="https://nullclaw.github.io" rel="nofollow"><img src="https://camo.githubusercontent.com/f6832e8695458d93bbf0f66febf111280effe2360a444fdc3427d187fb02432b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d6e756c6c636c61772e6769746875622e696f2d696e666f726d6174696f6e616c" alt="Documentation" data-canonical-src="https://img.shields.io/badge/docs-nullclaw.github.io-informational" style="max-width: 100%;"></a>
  <a href="https://discord.gg/Bfmdua22Ud" rel="nofollow"><img src="https://camo.githubusercontent.com/4514aff09ec21d0816fed58175d5505c84ee249249a3b5c669a42fa5ed43654d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646973636f72642d6a6f696e253230636f6d6d756e6974792d3538363546323f6c6f676f3d646973636f7264266c6f676f436f6c6f723d7768697465" alt="Discord" data-canonical-src="https://img.shields.io/badge/discord-join%20community-5865F2?logo=discord&amp;logoColor=white" style="max-width: 100%;"></a>
  <a href="/nullclaw/nullclaw/blob/main/LICENSE"><img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT" data-canonical-src="https://img.shields.io/badge/license-MIT-blue.svg" style="max-width: 100%;"></a>
</p>
<p dir="auto">The smallest fully autonomous AI assistant infrastructure — a static Zig binary that fits on any $5 board, boots in milliseconds, and requires nothing but libc.</p>
<p dir="auto">Docs: <a href="/nullclaw/nullclaw/blob/main/docs/en/README.md">English</a> · <a href="/nullclaw/nullclaw/blob/main/docs/zh/README.md">中文</a> · <a href="/nullclaw/nullclaw/blob/main/CONTRIBUTING.md">Contributing</a> · <a href="https://discord.gg/Bfmdua22Ud" rel="nofollow">Discord</a></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="678 KB binary · &lt;2 ms startup · 5,300+ tests · 50+ providers · 19 channels · Pluggable everything"><pre class="notranslate"><code>678 KB binary · &lt;2 ms startup · 5,300+ tests · 50+ providers · 19 channels · Pluggable everything
</code></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Features</h3><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Impossibly Small:</strong> 678 KB static binary — no runtime, no VM, no framework overhead.</li>
<li><strong>Near-Zero Memory:</strong> ~1 MB peak RSS. Runs comfortably on the cheapest ARM SBCs and microcontrollers.</li>
<li><strong>Instant Startup:</strong> &lt;2 ms on Apple Silicon, &lt;8 ms on a 0.8 GHz edge core.</li>
<li><strong>True Portability:</strong> Single self-contained binary across ARM, x86, and RISC-V. Drop it anywhere, it just runs.</li>
<li><strong>Feature-Complete:</strong> 50+ providers, 19 channels, 35+ tools, 10 memory engines, multi-layer sandbox, tunnels, hardware peripherals, MCP, subagents, streaming, voice — the full stack.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Why nullclaw</h3><a id="user-content-why-nullclaw" class="anchor" aria-label="Permalink: Why nullclaw" href="#why-nullclaw"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Lean by default:</strong> Zig compiles to a tiny static binary. No allocator overhead, no garbage collector, no runtime.</li>
<li><strong>Secure by design:</strong> pairing, strict sandboxing (landlock, firejail, bubblewrap, docker), explicit allowlists, workspace scoping, encrypted secrets.</li>
<li><strong>Fully swappable:</strong> core systems are vtable interfaces (providers, channels, tools, memory, tunnels, peripherals, observers, runtimes).</li>
<li><strong>No lock-in:</strong> OpenAI-compatible provider support + pluggable custom endpoints.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Benchmark Snapshot</h2><a id="user-content-benchmark-snapshot" class="anchor" aria-label="Permalink: Benchmark Snapshot" href="#benchmark-snapshot"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Local machine benchmark (macOS arm64, Feb 2026), normalized for 0.8 GHz edge hardware.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th><a href="https://github.com/openclaw/openclaw">OpenClaw</a></th>
<th><a href="https://github.com/HKUDS/nanobot">NanoBot</a></th>
<th><a href="https://github.com/sipeed/picoclaw">PicoClaw</a></th>
<th><a href="https://github.com/zeroclaw-labs/zeroclaw">ZeroClaw</a></th>
<th><strong><a href="https://github.com/nullclaw/nullclaw">🦞 NullClaw</a></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Language</strong></td>
<td>TypeScript</td>
<td>Python</td>
<td>Go</td>
<td>Rust</td>
<td><strong>Zig</strong></td>
</tr>
<tr>
<td><strong>RAM</strong></td>
<td>&gt; 1 GB</td>
<td>&gt; 100 MB</td>
<td>&lt; 10 MB</td>
<td>&lt; 5 MB</td>
<td><strong>~1 MB</strong></td>
</tr>
<tr>
<td><strong>Startup (0.8 GHz)</strong></td>
<td>&gt; 500 s</td>
<td>&gt; 30 s</td>
<td>&lt; 1 s</td>
<td>&lt; 10 ms</td>
<td><strong>&lt; 8 ms</strong></td>
</tr>
<tr>
<td><strong>Binary Size</strong></td>
<td>~28 MB (dist)</td>
<td>N/A (Scripts)</td>
<td>~8 MB</td>
<td>~8.8 MB</td>
<td><strong>678 KB</strong></td>
</tr>
<tr>
<td><strong>Tests</strong></td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>1,017</td>
<td><strong>5,300+</strong></td>
</tr>
<tr>
<td><strong>Source Files</strong></td>
<td>~400+</td>
<td>—</td>
<td>—</td>
<td>~120</td>
<td><strong>~230</strong></td>
</tr>
<tr>
<td><strong>Cost</strong></td>
<td>Mac Mini $599</td>
<td>Linux SBC ~$50</td>
<td>Linux Board $10</td>
<td>Any $10 hardware</td>
<td><strong>Any $5 hardware</strong></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<blockquote>
<p dir="auto">Measured with <code>/usr/bin/time -l</code> on ReleaseSmall builds. nullclaw is a static binary with zero runtime dependencies.</p>
</blockquote>
<p dir="auto">Reproduce locally:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="zig build -Doptimize=ReleaseSmall
ls -lh zig-out/bin/nullclaw

/usr/bin/time -l zig-out/bin/nullclaw --help
/usr/bin/time -l zig-out/bin/nullclaw status"><pre>zig build -Doptimize=ReleaseSmall
ls -lh zig-out/bin/nullclaw

/usr/bin/time -l zig-out/bin/nullclaw --help
/usr/bin/time -l zig-out/bin/nullclaw status</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Documentation</h2><a id="user-content-documentation" class="anchor" aria-label="Permalink: Documentation" href="#documentation"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Start here if you want the shortest path to install, configure, operate, or extend nullclaw.</p>
<p dir="auto">Localized documentation lives under <code>docs/en/</code> and <code>docs/zh/</code>. Use the links below to jump straight to the page you need.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Need</th>
<th>English</th>
<th>中文</th>
</tr>
</thead>
<tbody>
<tr>
<td>Start here</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/README.md"><code>docs/en/README.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/README.md"><code>docs/zh/README.md</code></a></td>
</tr>
<tr>
<td>Install</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/installation.md"><code>docs/en/installation.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/installation.md"><code>docs/zh/installation.md</code></a></td>
</tr>
<tr>
<td>Install Zig</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/zig-installation.md"><code>docs/en/zig-installation.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/zig-installation.md"><code>docs/zh/zig-installation.md</code></a></td>
</tr>
<tr>
<td>Configure</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/configuration.md"><code>docs/en/configuration.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/configuration.md"><code>docs/zh/configuration.md</code></a></td>
</tr>
<tr>
<td>Commands</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/commands.md"><code>docs/en/commands.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/commands.md"><code>docs/zh/commands.md</code></a></td>
</tr>
<tr>
<td>Development</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/development.md"><code>docs/en/development.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/development.md"><code>docs/zh/development.md</code></a></td>
</tr>
<tr>
<td>Operations</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/usage.md"><code>docs/en/usage.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/usage.md"><code>docs/zh/usage.md</code></a></td>
</tr>
<tr>
<td>Architecture</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/architecture.md"><code>docs/en/architecture.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/architecture.md"><code>docs/zh/architecture.md</code></a></td>
</tr>
<tr>
<td>Security</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/security.md"><code>docs/en/security.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/security.md"><code>docs/zh/security.md</code></a></td>
</tr>
<tr>
<td>Gateway API</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/gateway-api.md"><code>docs/en/gateway-api.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/gateway-api.md"><code>docs/zh/gateway-api.md</code></a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<ul dir="auto">
<li>Specialized guides: <a href="/nullclaw/nullclaw/blob/main/CONTRIBUTING.md"><code>CONTRIBUTING.md</code></a>, <a href="/nullclaw/nullclaw/blob/main/SECURITY.md"><code>SECURITY.md</code></a>, <a href="/nullclaw/nullclaw/blob/main/SIGNAL.md"><code>SIGNAL.md</code></a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Choose Your Path</h2><a id="user-content-choose-your-path" class="anchor" aria-label="Permalink: Choose Your Path" href="#choose-your-path"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Goal</th>
<th>Open this first</th>
<th>Then go to</th>
</tr>
</thead>
<tbody>
<tr>
<td>First run in English</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/README.md"><code>docs/en/README.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/installation.md"><code>docs/en/installation.md</code></a> → <a href="/nullclaw/nullclaw/blob/main/docs/en/configuration.md"><code>docs/en/configuration.md</code></a> → <a href="/nullclaw/nullclaw/blob/main/docs/en/usage.md"><code>docs/en/usage.md</code></a></td>
</tr>
<tr>
<td>Chinese Quick Start (中文快速上手)</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/README.md"><code>docs/zh/README.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/zh/installation.md"><code>docs/zh/installation.md</code></a> → <a href="/nullclaw/nullclaw/blob/main/docs/zh/configuration.md"><code>docs/zh/configuration.md</code></a> → <a href="/nullclaw/nullclaw/blob/main/docs/zh/usage.md"><code>docs/zh/usage.md</code></a></td>
</tr>
<tr>
<td>Find the right CLI command</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/commands.md"><code>docs/en/commands.md</code></a> / <a href="/nullclaw/nullclaw/blob/main/docs/zh/commands.md"><code>docs/zh/commands.md</code></a></td>
<td><code>nullclaw help</code> → task-specific subcommand page</td>
</tr>
<tr>
<td>Contribute code or docs</td>
<td><a href="/nullclaw/nullclaw/blob/main/CONTRIBUTING.md"><code>CONTRIBUTING.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/development.md"><code>docs/en/development.md</code></a> / <a href="/nullclaw/nullclaw/blob/main/docs/zh/development.md"><code>docs/zh/development.md</code></a> → relevant architecture page</td>
</tr>
<tr>
<td>Operate or secure a deployment</td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/usage.md"><code>docs/en/usage.md</code></a> / <a href="/nullclaw/nullclaw/blob/main/docs/zh/usage.md"><code>docs/zh/usage.md</code></a></td>
<td><a href="/nullclaw/nullclaw/blob/main/docs/en/security.md"><code>docs/en/security.md</code></a> / <a href="/nullclaw/nullclaw/blob/main/docs/zh/security.md"><code>docs/zh/security.md</code></a> → Gateway API</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">After This README</h2><a id="user-content-after-this-readme" class="anchor" aria-label="Permalink: After This README" href="#after-this-readme"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>New here: jump to <a href="/nullclaw/nullclaw/blob/main/docs/en/README.md"><code>docs/en/README.md</code></a> or <a href="/nullclaw/nullclaw/blob/main/docs/zh/README.md"><code>docs/zh/README.md</code></a> and follow the guided reading order.</li>
<li>Want commands fast: open <a href="/nullclaw/nullclaw/blob/main/docs/en/commands.md"><code>docs/en/commands.md</code></a> or <a href="/nullclaw/nullclaw/blob/main/docs/zh/commands.md"><code>docs/zh/commands.md</code></a>.</li>
<li>Want to submit a PR: start with <a href="/nullclaw/nullclaw/blob/main/CONTRIBUTING.md"><code>CONTRIBUTING.md</code></a>, then read <a href="/nullclaw/nullclaw/blob/main/docs/en/development.md"><code>docs/en/development.md</code></a> or <a href="/nullclaw/nullclaw/blob/main/docs/zh/development.md"><code>docs/zh/development.md</code></a>.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Quick Start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick Start" href="#quick-start"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">1) Recommended install (Homebrew)</h3><a id="user-content-1-recommended-install-homebrew" class="anchor" aria-label="Permalink: 1) Recommended install (Homebrew)" href="#1-recommended-install-homebrew"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The simplest path: install a ready-to-run binary with no extra runtime dependencies.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="brew install nullclaw
nullclaw --help"><pre>brew install nullclaw
nullclaw --help</pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">2) Build from source</h3><a id="user-content-2-build-from-source" class="anchor" aria-label="Permalink: 2) Build from source" href="#2-build-from-source"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<blockquote>
<p dir="auto"><strong>Prerequisite:</strong> use <strong>Zig 0.16.0</strong> (exact version).
Other Zig versions are currently unsupported and may fail to build.
Verify before building: <code>zig version</code> should print <code>0.16.0</code>.
Debian users who need Zig first can follow <a href="/nullclaw/nullclaw/blob/main/docs/en/zig-installation.md"><code>docs/en/zig-installation.md</code></a>.</p>
</blockquote>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/nullclaw/nullclaw.git
cd nullclaw
zig build -Doptimize=ReleaseSmall
zig build test --summary all"><pre>git clone https://github.com/nullclaw/nullclaw.git
<span class="pl-c1">cd</span> nullclaw
zig build -Doptimize=ReleaseSmall
zig build <span class="pl-c1">test</span> --summary all</pre></div>
<p dir="auto">Make <code>nullclaw</code> available on <code>PATH</code>:</p>
<p dir="auto">macOS/Linux (zsh/bash):</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="zig build -Doptimize=ReleaseSmall -p &quot;$HOME/.local&quot;
echo 'export PATH=&quot;$HOME/.local/bin:$PATH&quot;' &gt;&gt; ~/.zshrc
# or ~/.bashrc"><pre>zig build -Doptimize=ReleaseSmall -p <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$HOME</span>/.local<span class="pl-pds">"</span></span>
<span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">'</span>export PATH="$HOME/.local/bin:$PATH"<span class="pl-pds">'</span></span> <span class="pl-k">&gt;&gt;</span> <span class="pl-k">~</span>/.zshrc
<span class="pl-c"><span class="pl-c">#</span> or ~/.bashrc</span></pre></div>
<p dir="auto">Windows (PowerShell):</p>
<div class="highlight highlight-source-powershell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="zig build -Doptimize=ReleaseSmall -p &quot;$HOME\.local&quot;

$bin = &quot;$HOME\.local\bin&quot;
$user_path = [Environment]::GetEnvironmentVariable(&quot;Path&quot;, &quot;User&quot;)
if (-not ($user_path -split &quot;;&quot; | Where-Object { $_ -eq $bin })) {
  [Environment]::SetEnvironmentVariable(&quot;Path&quot;, &quot;$user_path;$bin&quot;, &quot;User&quot;)
}
$env:Path = &quot;$env:Path;$bin&quot;"><pre>zig build <span class="pl-k">-</span>Doptimize<span class="pl-k">=</span>ReleaseSmall <span class="pl-k">-</span>p <span class="pl-s"><span class="pl-pds">"</span><span class="pl-c1">$HOME</span>\.local<span class="pl-pds">"</span></span>

<span class="pl-smi">$bin</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-c1">$HOME</span>\.local\bin<span class="pl-pds">"</span></span>
<span class="pl-smi">$user_path</span> <span class="pl-k">=</span> [<span class="pl-k">Environment</span>]::GetEnvironmentVariable(<span class="pl-s"><span class="pl-pds">"</span>Path<span class="pl-pds">"</span></span><span class="pl-k">,</span> <span class="pl-s"><span class="pl-pds">"</span>User<span class="pl-pds">"</span></span>)
<span class="pl-k">if</span> (<span class="pl-k">-not</span> (<span class="pl-smi">$user_path</span> <span class="pl-k">-split</span> <span class="pl-s"><span class="pl-pds">"</span>;<span class="pl-pds">"</span></span> <span class="pl-k">|</span> <span class="pl-c1">Where-Object</span> { <span class="pl-c1">$_</span> <span class="pl-k">-eq</span> <span class="pl-smi">$bin</span> })) {
  [<span class="pl-k">Environment</span>]::SetEnvironmentVariable(<span class="pl-s"><span class="pl-pds">"</span>Path<span class="pl-pds">"</span></span><span class="pl-k">,</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$user_path</span>;<span class="pl-smi">$bin</span><span class="pl-pds">"</span></span><span class="pl-k">,</span> <span class="pl-s"><span class="pl-pds">"</span>User<span class="pl-pds">"</span></span>)
}
<span class="pl-smi">$<span class="pl-c1">env:</span>Path</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$<span class="pl-c1">env:</span>Path</span>;<span class="pl-smi">$bin</span><span class="pl-pds">"</span></span></pre></div>
<p dir="auto">Then:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="nullclaw --help"><pre>nullclaw --help</pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">3) Run with Docker Compose</h3><a id="user-content-3-run-with-docker-compose" class="anchor" aria-label="Permalink: 3) Run with Docker Compose" href="#3-run-with-docker-compose"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The repository includes a Makefile wrapper around Docker Compose for local
containerized runs.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="make build
make config
make up"><pre>make build
make config
make up</pre></div>
<p dir="auto"><code>make config</code> runs <code>nullclaw onboard --interactive</code> inside the agent container.
Pass only non-secret flags through <code>CONFIG_ARGS</code>:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="make config CONFIG_ARGS=&quot;--provider openrouter&quot;"><pre>make config CONFIG_ARGS=<span class="pl-s"><span class="pl-pds">"</span>--provider openrouter<span class="pl-pds">"</span></span></pre></div>
<p dir="auto">Avoid putting API keys or bot tokens in <code>CONFIG_ARGS</code>; command-line arguments
can be exposed through shell history and process listings.</p>
<p dir="auto">The compose gateway defaults to <code>NULLCLAW_PORT=3210</code>, binds inside the
container on <code>0.0.0.0</code>, and publishes to localhost on the host:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="curl http://127.0.0.1:3210/health"><pre>curl http://127.0.0.1:3210/health</pre></div>
<p dir="auto">Override the port or host bind address when needed:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="make up NULLCLAW_PORT=8080
make up NULLCLAW_BIND=0.0.0.0"><pre>make up NULLCLAW_PORT=8080
make up NULLCLAW_BIND=0.0.0.0</pre></div>
<p dir="auto">Operational shortcuts:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="make logs
make down
make shell"><pre>make logs
make down
make shell</pre></div>
<p dir="auto">Only set <code>NULLCLAW_BIND=0.0.0.0</code> on trusted networks with pairing, webhook
secrets, allowlists, and host firewall rules configured.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">4) Common commands</h3><a id="user-content-4-common-commands" class="anchor" aria-label="Permalink: 4) Common commands" href="#4-common-commands"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
# Quick setup
nullclaw onboard --api-key sk-... --provider openrouter

# Or interactive wizard
nullclaw onboard --interactive

# Chat
nullclaw agent -m &quot;Hello, nullclaw!&quot;

# Interactive mode
nullclaw agent

# Start gateway runtime (gateway + all configured channels/accounts + heartbeat + scheduler)
nullclaw gateway                # default: 127.0.0.1:3000
nullclaw gateway --port 8080    # custom port

# Check status
nullclaw status

# Run system diagnostics
nullclaw doctor

# Check channel health
nullclaw channel status

# Start specific channels
nullclaw channel start telegram
nullclaw channel start discord
nullclaw channel start signal

# Manage background service
# Linux supports systemd user services and OpenRC
nullclaw service install
nullclaw service status

# Optional secret injection hook for service mode:
# if ~/.nullclaw/service-env is executable, the installed service launcher runs it
# before starting `nullclaw gateway` (for example via dotenvx or sops)

# Migrate memory from OpenClaw
nullclaw migrate openclaw --dry-run
nullclaw migrate openclaw"><pre><span class="pl-c"><span class="pl-c">#</span> Quick setup</span>
nullclaw onboard --api-key sk-... --provider openrouter

<span class="pl-c"><span class="pl-c">#</span> Or interactive wizard</span>
nullclaw onboard --interactive

<span class="pl-c"><span class="pl-c">#</span> Chat</span>
nullclaw agent -m <span class="pl-s"><span class="pl-pds">"</span>Hello, nullclaw!<span class="pl-pds">"</span></span>

<span class="pl-c"><span class="pl-c">#</span> Interactive mode</span>
nullclaw agent

<span class="pl-c"><span class="pl-c">#</span> Start gateway runtime (gateway + all configured channels/accounts + heartbeat + scheduler)</span>
nullclaw gateway                <span class="pl-c"><span class="pl-c">#</span> default: 127.0.0.1:3000</span>
nullclaw gateway --port 8080    <span class="pl-c"><span class="pl-c">#</span> custom port</span>

<span class="pl-c"><span class="pl-c">#</span> Check status</span>
nullclaw status

<span class="pl-c"><span class="pl-c">#</span> Run system diagnostics</span>
nullclaw doctor

<span class="pl-c"><span class="pl-c">#</span> Check channel health</span>
nullclaw channel status

<span class="pl-c"><span class="pl-c">#</span> Start specific channels</span>
nullclaw channel start telegram
nullclaw channel start discord
nullclaw channel start signal

<span class="pl-c"><span class="pl-c">#</span> Manage background service</span>
<span class="pl-c"><span class="pl-c">#</span> Linux supports systemd user services and OpenRC</span>
nullclaw service install
nullclaw service status

<span class="pl-c"><span class="pl-c">#</span> Optional secret injection hook for service mode:</span>
<span class="pl-c"><span class="pl-c">#</span> if ~/.nullclaw/service-env is executable, the installed service launcher runs it</span>
<span class="pl-c"><span class="pl-c">#</span> before starting `nullclaw gateway` (for example via dotenvx or sops)</span>

<span class="pl-c"><span class="pl-c">#</span> Migrate memory from OpenClaw</span>
nullclaw migrate openclaw --dry-run
nullclaw migrate openclaw</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Edge MVP (Hybrid Host + WASM Logic)</h2><a id="user-content-edge-mvp-hybrid-host--wasm-logic" class="anchor" aria-label="Permalink: Edge MVP (Hybrid Host + WASM Logic)" href="#edge-mvp-hybrid-host--wasm-logic"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you want edge deployment (Cloudflare Worker) with Telegram + OpenAI while keeping agent policy in WASM, see:</p>
<p dir="auto"><code>examples/edge/cloudflare-worker/</code></p>
<p dir="auto">This pattern keeps networking/secrets in the edge host and lets you swap/update logic by replacing a tiny Zig WASM module.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Architecture</h2><a id="user-content-architecture" class="anchor" aria-label="Permalink: Architecture" href="#architecture"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Every subsystem is a <strong>vtable interface</strong> — swap implementations with a config change, zero code changes.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Subsystem</th>
<th>Interface</th>
<th>Ships with</th>
<th>Extend</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>AI Models</strong></td>
<td><code>Provider</code></td>
<td>50+ providers (OpenRouter, Anthropic, OpenAI, Azure OpenAI, Gemini, Vertex AI, Ollama, Venice, NEAR AI Cloud, Atlas Cloud, Evolink, Eden AI, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, and many OpenAI-compatible endpoints)</td>
<td><code>custom:https://your-api.com</code> — any OpenAI-compatible API</td>
</tr>
<tr>
<td><strong>Channels</strong></td>
<td><code>Channel</code></td>
<td>CLI, Telegram, Signal, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook, IRC, Lark/Feishu, OneBot, Line, DingTalk, Email, Nostr, QQ, MaixCam, Mattermost</td>
<td>Any messaging API</td>
</tr>
<tr>
<td><strong>Memory</strong></td>
<td><code>Memory</code></td>
<td>SQLite with hybrid search (FTS5 + vector cosine similarity), Markdown, ClickHouse, PostgreSQL, Redis, LanceDB, Lucid, LRU, API</td>
<td>Any persistence backend</td>
</tr>
<tr>
<td><strong>Tools</strong></td>
<td><code>Tool</code></td>
<td>shell, file_read, file_write, file_edit, file_edit_hashed, file_read_hashed, file_append, memory_store, memory_recall, memory_forget, memory_list, browser_open, screenshot, composio, http_request, web_fetch, web_search, delegate, schedule, hardware_info, hardware_memory, pushover, message, spawn, git, image, i2c, spi, and more</td>
<td>Any capability</td>
</tr>
<tr>
<td><strong>Observability</strong></td>
<td><code>Observer</code></td>
<td>Noop, Log, File, Multi</td>
<td>Prometheus, OTel</td>
</tr>
<tr>
<td><strong>Runtime</strong></td>
<td><code>RuntimeAdapter</code></td>
<td>Native, Docker (sandboxed), WASM (wasmtime)</td>
<td>Any runtime</td>
</tr>
<tr>
<td><strong>Security</strong></td>
<td><code>Sandbox</code></td>
<td>Landlock, Firejail, Bubblewrap, Docker, auto-detect</td>
<td>Any sandbox backend</td>
</tr>
<tr>
<td><strong>Identity</strong></td>
<td><code>IdentityConfig</code></td>
<td>OpenClaw (markdown), AIEOS v1.1 (JSON)</td>
<td>Any identity format</td>
</tr>
<tr>
<td><strong>Tunnel</strong></td>
<td><code>Tunnel</code></td>
<td>None, Cloudflare, Tailscale, ngrok, Custom</td>
<td>Any tunnel binary</td>
</tr>
<tr>
<td><strong>Heartbeat</strong></td>
<td>Engine</td>
<td>HEARTBEAT.md periodic tasks</td>
<td>—</td>
</tr>
<tr>
<td><strong>Skills</strong></td>
<td>Loader</td>
<td>TOML/JSON manifests or YAML frontmatter in <code>SKILL.md</code></td>
<td>Community skill packs</td>
</tr>
<tr>
<td><strong>Peripherals</strong></td>
<td><code>Peripheral</code></td>
<td>Serial, Arduino, Raspberry Pi GPIO, STM32/Nucleo</td>
<td>Any hardware interface</td>
</tr>
<tr>
<td><strong>Cron</strong></td>
<td>Scheduler</td>
<td>Cron expressions + one-shot timers with JSON persistence</td>
<td>—</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Memory System</h3><a id="user-content-memory-system" class="anchor" aria-label="Permalink: Memory System" href="#memory-system"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">All custom, zero external dependencies for the core path:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Layer</th>
<th>Implementation</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Vector DB</strong></td>
<td>Embeddings stored as BLOB in SQLite, cosine similarity search</td>
</tr>
<tr>
<td><strong>Keyword Search</strong></td>
<td>FTS5 virtual tables with BM25 scoring</td>
</tr>
<tr>
<td><strong>Hybrid Merge</strong></td>
<td>Weighted merge (configurable vector/keyword weights)</td>
</tr>
<tr>
<td><strong>Embeddings</strong></td>
<td><code>EmbeddingProvider</code> vtable — OpenAI, custom URL, or noop</td>
</tr>
<tr>
<td><strong>Hygiene</strong></td>
<td>Automatic archival + purge of stale memories</td>
</tr>
<tr>
<td><strong>Snapshots</strong></td>
<td>Export/import full memory state for migration</td>
</tr>
<tr>
<td><strong>Engines</strong></td>
<td>SQLite (default), Markdown, ClickHouse, PostgreSQL, Redis, LanceDB, Lucid, LRU, API, None</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;memory&quot;: {
    &quot;backend&quot;: &quot;sqlite&quot;,
    &quot;auto_save&quot;: true,
    &quot;embedding_provider&quot;: &quot;openai&quot;,
    &quot;vector_weight&quot;: 0.7,
    &quot;keyword_weight&quot;: 0.3,
    &quot;hygiene_enabled&quot;: true,
    &quot;snapshot_enabled&quot;: false
  }
}"><pre>{
  <span class="pl-ent">"memory"</span>: {
    <span class="pl-ent">"backend"</span>: <span class="pl-s"><span class="pl-pds">"</span>sqlite<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"auto_save"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"embedding_provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>openai<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"vector_weight"</span>: <span class="pl-c1">0.7</span>,
    <span class="pl-ent">"keyword_weight"</span>: <span class="pl-c1">0.3</span>,
    <span class="pl-ent">"hygiene_enabled"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"snapshot_enabled"</span>: <span class="pl-c1">false</span>
  }
}</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Security</h2><a id="user-content-security" class="anchor" aria-label="Permalink: Security" href="#security"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">nullclaw enforces security at <strong>every layer</strong>.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>#</th>
<th>Item</th>
<th>Status</th>
<th>How</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><strong>Gateway not publicly exposed</strong></td>
<td>Done</td>
<td>Binds <code>127.0.0.1</code> by default. Refuses <code>0.0.0.0</code> without tunnel or explicit <code>allow_public_bind</code>.</td>
</tr>
<tr>
<td>2</td>
<td><strong>Pairing required</strong></td>
<td>Done</td>
<td>6-digit one-time code on startup. Exchange via <code>POST /pair</code> for bearer token.</td>
</tr>
<tr>
<td>3</td>
<td><strong>Filesystem scoped</strong></td>
<td>Done</td>
<td><code>workspace_only = true</code> by default. Null byte injection blocked. Symlink escape detection.</td>
</tr>
<tr>
<td>4</td>
<td><strong>Access via tunnel only</strong></td>
<td>Done</td>
<td>Gateway refuses public bind without active tunnel. Supports Tailscale, Cloudflare, ngrok, or custom.</td>
</tr>
<tr>
<td>5</td>
<td><strong>Sandbox isolation</strong></td>
<td>Done</td>
<td>Auto-detects best backend: Landlock, Firejail, Bubblewrap, or Docker.</td>
</tr>
<tr>
<td>6</td>
<td><strong>Encrypted secrets</strong></td>
<td>Done</td>
<td>API keys encrypted with ChaCha20-Poly1305 using local key file.</td>
</tr>
<tr>
<td>7</td>
<td><strong>Resource limits</strong></td>
<td>Done</td>
<td>Configurable memory, CPU, disk, and subprocess limits.</td>
</tr>
<tr>
<td>8</td>
<td><strong>Audit logging</strong></td>
<td>Done</td>
<td>Signed event trail with configurable retention.</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Channel Allowlists</h3><a id="user-content-channel-allowlists" class="anchor" aria-label="Permalink: Channel Allowlists" href="#channel-allowlists"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Empty allowlist = <strong>deny all inbound messages</strong></li>
<li><code>"*"</code> = <strong>allow all</strong> (explicit opt-in)</li>
<li>Otherwise = exact-match allowlist</li>
</ul>
<p dir="auto">Nostr additionally: the <code>owner_pubkey</code> is <strong>always</strong> allowed regardless of <code>dm_allowed_pubkeys</code>. Private keys are encrypted at rest via SecretStore (<code>enc2:</code> prefix) and only decrypted into memory while the channel is running; zeroed on channel stop.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Nostr Channel Setup</h3><a id="user-content-nostr-channel-setup" class="anchor" aria-label="Permalink: Nostr Channel Setup" href="#nostr-channel-setup"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>nullclaw</code> speaks Nostr natively via NIP-17 (gift-wrapped private DMs) and NIP-04 (legacy DMs), using <a href="https://github.com/fiatjaf/nak"><code>nak</code></a>.</p>
<p dir="auto"><strong>Prerequisites:</strong> Install <code>nak</code> and ensure it's in your <code>$PATH</code>.</p>
<p dir="auto"><strong>Setup via onboarding wizard:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="nullclaw onboard --interactive   # Step 7 configures Nostr"><pre>nullclaw onboard --interactive   <span class="pl-c"><span class="pl-c">#</span> Step 7 configures Nostr</span></pre></div>
<p dir="auto">The wizard will:</p>
<ol dir="auto">
<li>Generate a new keypair for your bot or import a key &amp; encrypt it with ChaCha20-Poly1305</li>
<li>Ask for your (owner) pubkey (npub or hex) — always allowed through DM policy</li>
<li>Configure relays and DM relays (kind:10050 inbox)</li>
<li>Display the bot's pubkey</li>
</ol>
<p dir="auto">Or configure manually in the <a href="#configuration">config</a>.</p>
<p dir="auto"><strong>How it works:</strong> On startup, nullclaw announces its DM inbox relays (kind:10050), then listens for incoming NIP-17 gift wraps and NIP-04 encrypted DMs. Outbound messages mirror the sender's protocol. Multi-relay rumor deduplication prevents duplicate responses when the same message is delivered via multiple relays.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Configuration</h2><a id="user-content-configuration" class="anchor" aria-label="Permalink: Configuration" href="#configuration"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Config: <code>~/.nullclaw/config.json</code> (created by <code>onboard</code>)</p>
<blockquote>
<p dir="auto"><strong>OpenClaw compatible:</strong> nullclaw uses the same config structure as <a href="https://github.com/openclaw/openclaw">OpenClaw</a> (snake_case). Providers live under <code>models.providers</code>, the default model under <code>agents.defaults.model.primary</code>, and channels use <code>accounts</code> wrappers.
Top-level <code>default_provider</code> / <code>default_model</code> keys are not supported.</p>
<p dir="auto"><strong>Vertex AI note:</strong> <code>models.providers.vertex.api_key</code> supports either:</p>
<ol dir="auto">
<li>a bearer token (<code>ya29...</code>), or</li>
<li>a full Google service-account JSON object (same shape as Apps Script <code>GEMINI_KEY</code> with <code>project_id</code>, <code>client_email</code>, <code>private_key</code>).</li>
</ol>
<p dir="auto"><code>models.providers.vertex.base_url</code> can be set explicitly (<code>.../projects/&lt;id&gt;/locations/&lt;loc&gt;/publishers/google/models</code>), or omitted when service-account JSON is used (nullclaw will derive it from <code>project_id</code>, with <code>VERTEX_LOCATION</code> defaulting to <code>global</code>).
Service-account mode requires <code>openssl</code> available in <code>$PATH</code> for RS256 JWT signing.</p>
</blockquote>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;default_temperature&quot;: 0.7,

  &quot;models&quot;: {
    &quot;providers&quot;: {
      &quot;openrouter&quot;: { &quot;api_key&quot;: &quot;sk-or-...&quot; },
      &quot;nearai&quot;: { &quot;api_key&quot;: &quot;YOUR_NEARAI_API_KEY&quot; },
      &quot;atlas-cloud&quot;: { &quot;api_key&quot;: &quot;YOUR_ATLASCLOUD_API_KEY&quot; },
      &quot;evolink&quot;: { &quot;api_key&quot;: &quot;YOUR_EVOLINK_API_KEY&quot; },
      &quot;edenai&quot;: { &quot;api_key&quot;: &quot;YOUR_EDENAI_API_KEY&quot; },
      &quot;groq&quot;: { &quot;api_key&quot;: &quot;gsk_...&quot; },
      &quot;azure&quot;: { &quot;api_key&quot;: &quot;YOUR_AZURE_OPENAI_API_KEY&quot;, &quot;base_url&quot;: &quot;https://your-resource.openai.azure.com&quot; },
      &quot;vertex&quot;: {
        &quot;api_key&quot;: {
          &quot;type&quot;: &quot;service_account&quot;,
          &quot;project_id&quot;: &quot;your-project&quot;,
          &quot;client_email&quot;: &quot;svc@your-project.iam.gserviceaccount.com&quot;,
          &quot;private_key&quot;: &quot;-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n&quot;
        },
        &quot;base_url&quot;: &quot;https://aiplatform.googleapis.com/v1/projects/your-project/locations/global/publishers/google/models&quot;
      },
      &quot;anthropic&quot;: { &quot;api_key&quot;: &quot;sk-ant-...&quot; }
    }
  },

  &quot;agents&quot;: {
    &quot;defaults&quot;: {
      &quot;model&quot;: { &quot;primary&quot;: &quot;openrouter/anthropic/claude-sonnet-4&quot; },
      &quot;heartbeat&quot;: { &quot;every&quot;: &quot;30m&quot; }
    },
    &quot;list&quot;: [
      { &quot;id&quot;: &quot;researcher&quot;, &quot;model&quot;: { &quot;primary&quot;: &quot;openrouter/anthropic/claude-opus-4&quot; }, &quot;system_prompt&quot;: &quot;...&quot; }
    ]
  },

  &quot;channels&quot;: {
    &quot;telegram&quot;: {
      &quot;accounts&quot;: {
        &quot;main&quot;: {
          &quot;bot_token&quot;: &quot;123:ABC&quot;,
          &quot;allow_from&quot;: [&quot;user1&quot;],
          &quot;reply_in_private&quot;: true,
          &quot;proxy&quot;: &quot;socks5://...&quot;
        }
      }
    },
    &quot;discord&quot;: {
      &quot;accounts&quot;: {
        &quot;main&quot;: {
          &quot;token&quot;: &quot;disc-token&quot;,
          &quot;guild_id&quot;: &quot;12345&quot;,
          &quot;allow_from&quot;: [&quot;user1&quot;],
          &quot;allow_bots&quot;: false
        }
      }
    },
    &quot;irc&quot;: {
      &quot;accounts&quot;: {
        &quot;main&quot;: {
          &quot;host&quot;: &quot;irc.libera.chat&quot;,
          &quot;port&quot;: 6697,
          &quot;nick&quot;: &quot;nullclaw&quot;,
          &quot;channels&quot;: [&quot;#nullclaw&quot;],
          &quot;tls&quot;: true,
          &quot;allow_from&quot;: [&quot;user1&quot;]
        },
        &quot;meshrelay&quot;: {
          &quot;host&quot;: &quot;irc.meshrelay.xyz&quot;,
          &quot;port&quot;: 6697,
          &quot;nick&quot;: &quot;nullclaw&quot;,
          &quot;channels&quot;: [&quot;#agents&quot;],
          &quot;tls&quot;: true,
          &quot;nickserv_password&quot;: &quot;YOUR_NICKSERV_PASSWORD&quot;,
          &quot;allow_from&quot;: [&quot;*&quot;]
        }
      }
    },
    &quot;slack&quot;: {
      &quot;accounts&quot;: {
        &quot;main&quot;: {
          &quot;bot_token&quot;: &quot;xoxb-...&quot;,
          &quot;app_token&quot;: &quot;xapp-...&quot;,
          &quot;allow_from&quot;: [&quot;user1&quot;]
        }
      }
    },
    &quot;nostr&quot;: {
      &quot;private_key&quot;: &quot;enc2:...&quot;,
      &quot;owner_pubkey&quot;: &quot;hex-pubkey-of-owner&quot;,
      &quot;relays&quot;: [&quot;wss://relay.damus.io&quot;, &quot;wss://nos.lol&quot;, &quot;wss://relay.nostr.band&quot;],
      &quot;dm_allowed_pubkeys&quot;: [&quot;*&quot;],
      &quot;display_name&quot;: &quot;NullClaw&quot;,
      &quot;about&quot;: &quot;AI assistant on Nostr&quot;,
      &quot;nip05&quot;: &quot;nullclaw@yourdomain.com&quot;,
      &quot;lnurl&quot;: &quot;lnurl1...&quot;
    }
  },

  &quot;tools&quot;: {
    &quot;media&quot;: {
      &quot;audio&quot;: {
        &quot;enabled&quot;: true,
        &quot;language&quot;: &quot;ru&quot;,
        &quot;models&quot;: [{ &quot;provider&quot;: &quot;groq&quot;, &quot;model&quot;: &quot;whisper-large-v3&quot; }]
      }
    }
  },

  &quot;mcp_servers&quot;: {
    &quot;filesystem&quot;: {
      &quot;transport&quot;: &quot;stdio&quot;,
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [&quot;-y&quot;, &quot;@modelcontextprotocol/server-filesystem&quot;],
      &quot;timeout_ms&quot;: 10000
    },
    &quot;remote&quot;: {
      &quot;transport&quot;: &quot;http&quot;,
      &quot;url&quot;: &quot;https://mcp.example.com/rpc&quot;,
      &quot;timeout_ms&quot;: 10000,
      &quot;headers&quot;: {
        &quot;Authorization&quot;: &quot;Bearer example-token&quot;
      }
    }
  },

  &quot;memory&quot;: {
    &quot;backend&quot;: &quot;sqlite&quot;,
    &quot;auto_save&quot;: true,
    &quot;embedding_provider&quot;: &quot;openai&quot;,
    &quot;vector_weight&quot;: 0.7,
    &quot;keyword_weight&quot;: 0.3
  },

  &quot;gateway&quot;: {
    &quot;port&quot;: 3000,
    &quot;require_pairing&quot;: true,
    &quot;allow_public_bind&quot;: false
  },

  &quot;autonomy&quot;: {
    &quot;level&quot;: &quot;supervised&quot;,
    &quot;workspace_only&quot;: true,
    &quot;max_actions_per_hour&quot;: 20
  },

  &quot;runtime&quot;: {
    &quot;kind&quot;: &quot;native&quot;,
    &quot;docker&quot;: {
      &quot;image&quot;: &quot;alpine:3.24&quot;,
      &quot;network&quot;: &quot;none&quot;,
      &quot;memory_limit_mb&quot;: 512,
      &quot;read_only_rootfs&quot;: true
    }
  },


  &quot;tunnel&quot;: { &quot;provider&quot;: &quot;none&quot; },
  &quot;secrets&quot;: { &quot;encrypt&quot;: true },
  &quot;identity&quot;: { &quot;format&quot;: &quot;openclaw&quot; },

  &quot;security&quot;: {
    &quot;sandbox&quot;: { &quot;backend&quot;: &quot;auto&quot; },
    &quot;resources&quot;: { &quot;max_memory_mb&quot;: 512, &quot;max_cpu_percent&quot;: 80 },
    &quot;audit&quot;: { &quot;enabled&quot;: true, &quot;retention_days&quot;: 90 }
  }
}"><pre>{
  <span class="pl-ent">"default_temperature"</span>: <span class="pl-c1">0.7</span>,

  <span class="pl-ent">"models"</span>: {
    <span class="pl-ent">"providers"</span>: {
      <span class="pl-ent">"openrouter"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>sk-or-...<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"nearai"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>YOUR_NEARAI_API_KEY<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"atlas-cloud"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>YOUR_ATLASCLOUD_API_KEY<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"evolink"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>YOUR_EVOLINK_API_KEY<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"edenai"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>YOUR_EDENAI_API_KEY<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"groq"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>gsk_...<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"azure"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>YOUR_AZURE_OPENAI_API_KEY<span class="pl-pds">"</span></span>, <span class="pl-ent">"base_url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://your-resource.openai.azure.com<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"vertex"</span>: {
        <span class="pl-ent">"api_key"</span>: {
          <span class="pl-ent">"type"</span>: <span class="pl-s"><span class="pl-pds">"</span>service_account<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"project_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>your-project<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"client_email"</span>: <span class="pl-s"><span class="pl-pds">"</span>svc@your-project.iam.gserviceaccount.com<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"private_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>-----BEGIN PRIVATE KEY-----<span class="pl-cce">\n</span>...<span class="pl-cce">\n</span>-----END PRIVATE KEY-----<span class="pl-cce">\n</span><span class="pl-pds">"</span></span>
        },
        <span class="pl-ent">"base_url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://aiplatform.googleapis.com/v1/projects/your-project/locations/global/publishers/google/models<span class="pl-pds">"</span></span>
      },
      <span class="pl-ent">"anthropic"</span>: { <span class="pl-ent">"api_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>sk-ant-...<span class="pl-pds">"</span></span> }
    }
  },

  <span class="pl-ent">"agents"</span>: {
    <span class="pl-ent">"defaults"</span>: {
      <span class="pl-ent">"model"</span>: { <span class="pl-ent">"primary"</span>: <span class="pl-s"><span class="pl-pds">"</span>openrouter/anthropic/claude-sonnet-4<span class="pl-pds">"</span></span> },
      <span class="pl-ent">"heartbeat"</span>: { <span class="pl-ent">"every"</span>: <span class="pl-s"><span class="pl-pds">"</span>30m<span class="pl-pds">"</span></span> }
    },
    <span class="pl-ent">"list"</span>: [
      { <span class="pl-ent">"id"</span>: <span class="pl-s"><span class="pl-pds">"</span>researcher<span class="pl-pds">"</span></span>, <span class="pl-ent">"model"</span>: { <span class="pl-ent">"primary"</span>: <span class="pl-s"><span class="pl-pds">"</span>openrouter/anthropic/claude-opus-4<span class="pl-pds">"</span></span> }, <span class="pl-ent">"system_prompt"</span>: <span class="pl-s"><span class="pl-pds">"</span>...<span class="pl-pds">"</span></span> }
    ]
  },

  <span class="pl-ent">"channels"</span>: {
    <span class="pl-ent">"telegram"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"main"</span>: {
          <span class="pl-ent">"bot_token"</span>: <span class="pl-s"><span class="pl-pds">"</span>123:ABC<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"allow_from"</span>: [<span class="pl-s"><span class="pl-pds">"</span>user1<span class="pl-pds">"</span></span>],
          <span class="pl-ent">"reply_in_private"</span>: <span class="pl-c1">true</span>,
          <span class="pl-ent">"proxy"</span>: <span class="pl-s"><span class="pl-pds">"</span>socks5://...<span class="pl-pds">"</span></span>
        }
      }
    },
    <span class="pl-ent">"discord"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"main"</span>: {
          <span class="pl-ent">"token"</span>: <span class="pl-s"><span class="pl-pds">"</span>disc-token<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"guild_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>12345<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"allow_from"</span>: [<span class="pl-s"><span class="pl-pds">"</span>user1<span class="pl-pds">"</span></span>],
          <span class="pl-ent">"allow_bots"</span>: <span class="pl-c1">false</span>
        }
      }
    },
    <span class="pl-ent">"irc"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"main"</span>: {
          <span class="pl-ent">"host"</span>: <span class="pl-s"><span class="pl-pds">"</span>irc.libera.chat<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"port"</span>: <span class="pl-c1">6697</span>,
          <span class="pl-ent">"nick"</span>: <span class="pl-s"><span class="pl-pds">"</span>nullclaw<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"channels"</span>: [<span class="pl-s"><span class="pl-pds">"</span>#nullclaw<span class="pl-pds">"</span></span>],
          <span class="pl-ent">"tls"</span>: <span class="pl-c1">true</span>,
          <span class="pl-ent">"allow_from"</span>: [<span class="pl-s"><span class="pl-pds">"</span>user1<span class="pl-pds">"</span></span>]
        },
        <span class="pl-ent">"meshrelay"</span>: {
          <span class="pl-ent">"host"</span>: <span class="pl-s"><span class="pl-pds">"</span>irc.meshrelay.xyz<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"port"</span>: <span class="pl-c1">6697</span>,
          <span class="pl-ent">"nick"</span>: <span class="pl-s"><span class="pl-pds">"</span>nullclaw<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"channels"</span>: [<span class="pl-s"><span class="pl-pds">"</span>#agents<span class="pl-pds">"</span></span>],
          <span class="pl-ent">"tls"</span>: <span class="pl-c1">true</span>,
          <span class="pl-ent">"nickserv_password"</span>: <span class="pl-s"><span class="pl-pds">"</span>YOUR_NICKSERV_PASSWORD<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"allow_from"</span>: [<span class="pl-s"><span class="pl-pds">"</span>*<span class="pl-pds">"</span></span>]
        }
      }
    },
    <span class="pl-ent">"slack"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"main"</span>: {
          <span class="pl-ent">"bot_token"</span>: <span class="pl-s"><span class="pl-pds">"</span>xoxb-...<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"app_token"</span>: <span class="pl-s"><span class="pl-pds">"</span>xapp-...<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"allow_from"</span>: [<span class="pl-s"><span class="pl-pds">"</span>user1<span class="pl-pds">"</span></span>]
        }
      }
    },
    <span class="pl-ent">"nostr"</span>: {
      <span class="pl-ent">"private_key"</span>: <span class="pl-s"><span class="pl-pds">"</span>enc2:...<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"owner_pubkey"</span>: <span class="pl-s"><span class="pl-pds">"</span>hex-pubkey-of-owner<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"relays"</span>: [<span class="pl-s"><span class="pl-pds">"</span>wss://relay.damus.io<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>wss://nos.lol<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>wss://relay.nostr.band<span class="pl-pds">"</span></span>],
      <span class="pl-ent">"dm_allowed_pubkeys"</span>: [<span class="pl-s"><span class="pl-pds">"</span>*<span class="pl-pds">"</span></span>],
      <span class="pl-ent">"display_name"</span>: <span class="pl-s"><span class="pl-pds">"</span>NullClaw<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"about"</span>: <span class="pl-s"><span class="pl-pds">"</span>AI assistant on Nostr<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"nip05"</span>: <span class="pl-s"><span class="pl-pds">"</span>nullclaw@yourdomain.com<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"lnurl"</span>: <span class="pl-s"><span class="pl-pds">"</span>lnurl1...<span class="pl-pds">"</span></span>
    }
  },

  <span class="pl-ent">"tools"</span>: {
    <span class="pl-ent">"media"</span>: {
      <span class="pl-ent">"audio"</span>: {
        <span class="pl-ent">"enabled"</span>: <span class="pl-c1">true</span>,
        <span class="pl-ent">"language"</span>: <span class="pl-s"><span class="pl-pds">"</span>ru<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"models"</span>: [{ <span class="pl-ent">"provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>groq<span class="pl-pds">"</span></span>, <span class="pl-ent">"model"</span>: <span class="pl-s"><span class="pl-pds">"</span>whisper-large-v3<span class="pl-pds">"</span></span> }]
      }
    }
  },

  <span class="pl-ent">"mcp_servers"</span>: {
    <span class="pl-ent">"filesystem"</span>: {
      <span class="pl-ent">"transport"</span>: <span class="pl-s"><span class="pl-pds">"</span>stdio<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"command"</span>: <span class="pl-s"><span class="pl-pds">"</span>npx<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"args"</span>: [<span class="pl-s"><span class="pl-pds">"</span>-y<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>@modelcontextprotocol/server-filesystem<span class="pl-pds">"</span></span>],
      <span class="pl-ent">"timeout_ms"</span>: <span class="pl-c1">10000</span>
    },
    <span class="pl-ent">"remote"</span>: {
      <span class="pl-ent">"transport"</span>: <span class="pl-s"><span class="pl-pds">"</span>http<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://mcp.example.com/rpc<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"timeout_ms"</span>: <span class="pl-c1">10000</span>,
      <span class="pl-ent">"headers"</span>: {
        <span class="pl-ent">"Authorization"</span>: <span class="pl-s"><span class="pl-pds">"</span>Bearer example-token<span class="pl-pds">"</span></span>
      }
    }
  },

  <span class="pl-ent">"memory"</span>: {
    <span class="pl-ent">"backend"</span>: <span class="pl-s"><span class="pl-pds">"</span>sqlite<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"auto_save"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"embedding_provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>openai<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"vector_weight"</span>: <span class="pl-c1">0.7</span>,
    <span class="pl-ent">"keyword_weight"</span>: <span class="pl-c1">0.3</span>
  },

  <span class="pl-ent">"gateway"</span>: {
    <span class="pl-ent">"port"</span>: <span class="pl-c1">3000</span>,
    <span class="pl-ent">"require_pairing"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"allow_public_bind"</span>: <span class="pl-c1">false</span>
  },

  <span class="pl-ent">"autonomy"</span>: {
    <span class="pl-ent">"level"</span>: <span class="pl-s"><span class="pl-pds">"</span>supervised<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"workspace_only"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"max_actions_per_hour"</span>: <span class="pl-c1">20</span>
  },

  <span class="pl-ent">"runtime"</span>: {
    <span class="pl-ent">"kind"</span>: <span class="pl-s"><span class="pl-pds">"</span>native<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"docker"</span>: {
      <span class="pl-ent">"image"</span>: <span class="pl-s"><span class="pl-pds">"</span>alpine:3.24<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"network"</span>: <span class="pl-s"><span class="pl-pds">"</span>none<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"memory_limit_mb"</span>: <span class="pl-c1">512</span>,
      <span class="pl-ent">"read_only_rootfs"</span>: <span class="pl-c1">true</span>
    }
  },


  <span class="pl-ent">"tunnel"</span>: { <span class="pl-ent">"provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>none<span class="pl-pds">"</span></span> },
  <span class="pl-ent">"secrets"</span>: { <span class="pl-ent">"encrypt"</span>: <span class="pl-c1">true</span> },
  <span class="pl-ent">"identity"</span>: { <span class="pl-ent">"format"</span>: <span class="pl-s"><span class="pl-pds">"</span>openclaw<span class="pl-pds">"</span></span> },

  <span class="pl-ent">"security"</span>: {
    <span class="pl-ent">"sandbox"</span>: { <span class="pl-ent">"backend"</span>: <span class="pl-s"><span class="pl-pds">"</span>auto<span class="pl-pds">"</span></span> },
    <span class="pl-ent">"resources"</span>: { <span class="pl-ent">"max_memory_mb"</span>: <span class="pl-c1">512</span>, <span class="pl-ent">"max_cpu_percent"</span>: <span class="pl-c1">80</span> },
    <span class="pl-ent">"audit"</span>: { <span class="pl-ent">"enabled"</span>: <span class="pl-c1">true</span>, <span class="pl-ent">"retention_days"</span>: <span class="pl-c1">90</span> }
  }
}</pre></div>
<p dir="auto">Config values are literal. NullClaw does not expand <code>${VAR}</code> inside <code>config.json</code>
strings, including custom header values. If you need environment-based secrets,
render <code>config.json</code> ahead of time with your own deployment tooling.
MCP <code>timeout_ms</code> bounds each HTTP or stdio request; a timed-out stdio server is
terminated with its launcher process group so blocked child processes do not remain.</p>
<p dir="auto">Telegram forum topics:</p>
<ul dir="auto">
<li>Topic session isolation is automatic. You do not add a <code>topic_id</code> field under <code>channels.telegram</code>.</li>
<li>The easiest operator flow is:
<ol dir="auto">
<li>define named agent profiles under <code>agents.list</code></li>
<li>open the target Telegram chat or forum topic</li>
<li>run <code>/bind &lt;agent&gt;</code></li>
</ol>
</li>
<li>To bind a specific Telegram forum topic to a specific agent, use <code>bindings[].match.peer.id</code> with the canonical thread form <code>"&lt;chat_id&gt;:thread:&lt;topic_id&gt;"</code>.</li>
<li>To bind the whole Telegram group as a fallback for all other topics, keep a normal group binding with <code>"&lt;chat_id&gt;"</code>.</li>
<li><code>/bind status</code> shows the current effective route and the available agent ids.</li>
<li><code>/bind clear</code> removes only the exact binding for the current account/chat/topic and falls back to the broader route.</li>
<li><code>/bind</code> persists an exact <code>bindings[]</code> entry for the current Telegram account and peer.</li>
<li><code>/bind status</code> distinguishes an exact local override from an inherited broader fallback.</li>
<li>Topic-specific bindings win over group fallback by route priority; the order in <code>bindings[]</code> does not matter.</li>
<li>Telegram menu visibility for <code>/bind</code> is controlled by <code>channels.telegram.accounts.&lt;id&gt;.binding_commands_enabled</code>.</li>
</ul>
<p dir="auto">Example:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;bindings&quot;: [
    {
      &quot;agent_id&quot;: &quot;coder&quot;,
      &quot;match&quot;: {
        &quot;channel&quot;: &quot;telegram&quot;,
        &quot;account_id&quot;: &quot;main&quot;,
        &quot;peer&quot;: { &quot;kind&quot;: &quot;group&quot;, &quot;id&quot;: &quot;-1001234567890:thread:42&quot; }
      }
    },
    {
      &quot;agent_id&quot;: &quot;orchestrator&quot;,
      &quot;match&quot;: {
        &quot;channel&quot;: &quot;telegram&quot;,
        &quot;account_id&quot;: &quot;main&quot;,
        &quot;peer&quot;: { &quot;kind&quot;: &quot;group&quot;, &quot;id&quot;: &quot;-1001234567890&quot; }
      }
    }
  ]
}"><pre>{
  <span class="pl-ent">"bindings"</span>: [
    {
      <span class="pl-ent">"agent_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>coder<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"match"</span>: {
        <span class="pl-ent">"channel"</span>: <span class="pl-s"><span class="pl-pds">"</span>telegram<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"account_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>main<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"peer"</span>: { <span class="pl-ent">"kind"</span>: <span class="pl-s"><span class="pl-pds">"</span>group<span class="pl-pds">"</span></span>, <span class="pl-ent">"id"</span>: <span class="pl-s"><span class="pl-pds">"</span>-1001234567890:thread:42<span class="pl-pds">"</span></span> }
      }
    },
    {
      <span class="pl-ent">"agent_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>orchestrator<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"match"</span>: {
        <span class="pl-ent">"channel"</span>: <span class="pl-s"><span class="pl-pds">"</span>telegram<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"account_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>main<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"peer"</span>: { <span class="pl-ent">"kind"</span>: <span class="pl-s"><span class="pl-pds">"</span>group<span class="pl-pds">"</span></span>, <span class="pl-ent">"id"</span>: <span class="pl-s"><span class="pl-pds">"</span>-1001234567890<span class="pl-pds">"</span></span> }
      }
    }
  ]
}</pre></div>
<p dir="auto">In that setup, topic <code>42</code> routes to <code>coder</code>, while the rest of the forum falls back to <code>orchestrator</code>.</p>
<p dir="auto">Named agent profiles are configured separately from bindings. Bindings only choose which named agent handles a given chat/topic.</p>
<p dir="auto">If a named agent should run from its own workspace, set <code>agents.list[].workspace_path</code>.
Relative paths are resolved from the directory that contains <code>config.json</code>, the workspace is scaffolded on first use, and the agent gets a durable memory namespace <code>agent:&lt;agent-id&gt;</code>.
Setting <code>workspace_path</code> does not disable <code>system_prompt</code>: when both are configured, the named profile prompt is still applied and the workspace bootstrap files are loaded from that dedicated workspace.
This applies to <code>nullclaw agent --agent &lt;id&gt;</code>, <code>/subagents spawn --agent &lt;id&gt;</code>, and routed sessions resolved through <code>bindings</code>.</p>
<p dir="auto">Minimal end-to-end example:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;agents&quot;: {
    &quot;list&quot;: [
      {
        &quot;id&quot;: &quot;orchestrator&quot;,
        &quot;provider&quot;: &quot;openrouter&quot;,
        &quot;model&quot;: &quot;anthropic/claude-sonnet-4&quot;
      },
      {
        &quot;id&quot;: &quot;coder&quot;,
        &quot;provider&quot;: &quot;ollama&quot;,
        &quot;model&quot;: &quot;qwen2.5-coder:14b&quot;,
        &quot;system_prompt&quot;: &quot;You are the coding agent for this topic.&quot;
      }
    ]
  },
  &quot;channels&quot;: {
    &quot;telegram&quot;: {
      &quot;accounts&quot;: {
        &quot;main&quot;: {
          &quot;bot_token&quot;: &quot;123456:ABCDEF&quot;,
          &quot;allow_from&quot;: [&quot;YOUR_TELEGRAM_USER_ID&quot;],
          &quot;binding_commands_enabled&quot;: true,
          &quot;topic_commands_enabled&quot;: true,
          &quot;topic_map_command_enabled&quot;: true,
          &quot;commands_menu_mode&quot;: &quot;scoped&quot;
        }
      }
    }
  },
  &quot;bindings&quot;: [
    {
      &quot;agent_id&quot;: &quot;orchestrator&quot;,
      &quot;match&quot;: {
        &quot;channel&quot;: &quot;telegram&quot;,
        &quot;account_id&quot;: &quot;main&quot;,
        &quot;peer&quot;: { &quot;kind&quot;: &quot;group&quot;, &quot;id&quot;: &quot;-1001234567890&quot; }
      }
    }
  ]
}"><pre>{
  <span class="pl-ent">"agents"</span>: {
    <span class="pl-ent">"list"</span>: [
      {
        <span class="pl-ent">"id"</span>: <span class="pl-s"><span class="pl-pds">"</span>orchestrator<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>openrouter<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"model"</span>: <span class="pl-s"><span class="pl-pds">"</span>anthropic/claude-sonnet-4<span class="pl-pds">"</span></span>
      },
      {
        <span class="pl-ent">"id"</span>: <span class="pl-s"><span class="pl-pds">"</span>coder<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>ollama<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"model"</span>: <span class="pl-s"><span class="pl-pds">"</span>qwen2.5-coder:14b<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"system_prompt"</span>: <span class="pl-s"><span class="pl-pds">"</span>You are the coding agent for this topic.<span class="pl-pds">"</span></span>
      }
    ]
  },
  <span class="pl-ent">"channels"</span>: {
    <span class="pl-ent">"telegram"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"main"</span>: {
          <span class="pl-ent">"bot_token"</span>: <span class="pl-s"><span class="pl-pds">"</span>123456:ABCDEF<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"allow_from"</span>: [<span class="pl-s"><span class="pl-pds">"</span>YOUR_TELEGRAM_USER_ID<span class="pl-pds">"</span></span>],
          <span class="pl-ent">"binding_commands_enabled"</span>: <span class="pl-c1">true</span>,
          <span class="pl-ent">"topic_commands_enabled"</span>: <span class="pl-c1">true</span>,
          <span class="pl-ent">"topic_map_command_enabled"</span>: <span class="pl-c1">true</span>,
          <span class="pl-ent">"commands_menu_mode"</span>: <span class="pl-s"><span class="pl-pds">"</span>scoped<span class="pl-pds">"</span></span>
        }
      }
    }
  },
  <span class="pl-ent">"bindings"</span>: [
    {
      <span class="pl-ent">"agent_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>orchestrator<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"match"</span>: {
        <span class="pl-ent">"channel"</span>: <span class="pl-s"><span class="pl-pds">"</span>telegram<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"account_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>main<span class="pl-pds">"</span></span>,
        <span class="pl-ent">"peer"</span>: { <span class="pl-ent">"kind"</span>: <span class="pl-s"><span class="pl-pds">"</span>group<span class="pl-pds">"</span></span>, <span class="pl-ent">"id"</span>: <span class="pl-s"><span class="pl-pds">"</span>-1001234567890<span class="pl-pds">"</span></span> }
      }
    }
  ]
}</pre></div>
<p dir="auto">Operator flow:</p>
<ul dir="auto">
<li>Send <code>/bind coder</code> inside the target forum topic.</li>
<li><code>nullclaw</code> writes a new exact <code>bindings[]</code> entry to <code>~/.nullclaw/config.json</code> for that topic and Telegram account.</li>
<li>The next message in that topic uses the new routed agent profile.</li>
<li><code>nullclaw</code> must have write access to <code>~/.nullclaw/config.json</code> for <code>/bind</code> to persist changes.</li>
</ul>
<p dir="auto">About <code>account_id</code>:</p>
<ul dir="auto">
<li><code>account_id</code> identifies the configured Telegram account entry, not a topic and not an agent.</li>
<li>In the usual <code>channels.telegram.accounts</code> form, the object key becomes the account id. For example, <code>accounts.main</code> means <code>account_id = "main"</code>, and <code>accounts.backup</code> means <code>account_id = "backup"</code>.</li>
<li>In <code>bindings</code>, <code>match.account_id</code> limits that binding to one specific Telegram account.</li>
<li>If <code>match.account_id</code> is omitted, the binding can match any Telegram account for that channel.</li>
<li>Use different account ids only when you run multiple Telegram bot accounts/tokens in the same nullclaw instance.</li>
</ul>
<p dir="auto">Effect on delivery:</p>
<ul dir="auto">
<li>Incoming Telegram updates are processed by the account that received them.</li>
<li>Routing uses that same <code>account_id</code>, so <code>match.account_id = "main"</code> matches only messages received by <code>channels.telegram.accounts.main</code>.</li>
<li>Replies go back out through the same Telegram account/runtime that handled the message.</li>
<li>Setting one binding to <code>account_id = "main"</code> and another to <code>account_id = "sub"</code> does not split one chat across two agents automatically; it scopes each binding to a different configured Telegram account.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Full Web Search + Shell Access</h3><a id="user-content-full-web-search--shell-access" class="anchor" aria-label="Permalink: Full Web Search + Shell Access" href="#full-web-search--shell-access"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use this when you want full web-search provider control plus unrestricted shell command allowlist behavior:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;http_request&quot;: {
    &quot;enabled&quot;: true,
    &quot;search_base_url&quot;: &quot;https://searx.example.com&quot;,
    &quot;search_provider&quot;: &quot;auto&quot;,
    &quot;search_fallback_providers&quot;: [&quot;jina&quot;, &quot;duckduckgo&quot;]
  },
  &quot;autonomy&quot;: {
    &quot;level&quot;: &quot;full&quot;,
    &quot;allowed_commands&quot;: [&quot;*&quot;],
    &quot;allowed_paths&quot;: [&quot;*&quot;],
    &quot;require_approval_for_medium_risk&quot;: false,
    &quot;block_medium_risk_commands&quot;: false,
    &quot;block_high_risk_commands&quot;: false
  }
}"><pre>{
  <span class="pl-ent">"http_request"</span>: {
    <span class="pl-ent">"enabled"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"search_base_url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://searx.example.com<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"search_provider"</span>: <span class="pl-s"><span class="pl-pds">"</span>auto<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"search_fallback_providers"</span>: [<span class="pl-s"><span class="pl-pds">"</span>jina<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>duckduckgo<span class="pl-pds">"</span></span>]
  },
  <span class="pl-ent">"autonomy"</span>: {
    <span class="pl-ent">"level"</span>: <span class="pl-s"><span class="pl-pds">"</span>full<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"allowed_commands"</span>: [<span class="pl-s"><span class="pl-pds">"</span>*<span class="pl-pds">"</span></span>],
    <span class="pl-ent">"allowed_paths"</span>: [<span class="pl-s"><span class="pl-pds">"</span>*<span class="pl-pds">"</span></span>],
    <span class="pl-ent">"require_approval_for_medium_risk"</span>: <span class="pl-c1">false</span>,
    <span class="pl-ent">"block_medium_risk_commands"</span>: <span class="pl-c1">false</span>,
    <span class="pl-ent">"block_high_risk_commands"</span>: <span class="pl-c1">false</span>
  }
}</pre></div>
<ul dir="auto">
<li><code>http_request.search_base_url</code> accepts either instance root (<code>https://host</code>) or explicit endpoint (<code>https://host/search</code>); local/private SearXNG instances may also use plain HTTP such as <code>http://localhost:8888</code> or <code>http://192.168.1.10:8888/search</code>.</li>
<li>Invalid <code>http_request.search_base_url</code> now fails config validation at startup (no automatic fallback for malformed URL).</li>
<li><code>http_request.search_provider</code> supports: <code>auto</code>, <code>searxng</code>, <code>duckduckgo</code> (<code>ddg</code>), <code>brave</code>, <code>firecrawl</code>, <code>tavily</code>, <code>perplexity</code>, <code>exa</code>, <code>jina</code>.</li>
<li><code>http_request.search_fallback_providers</code> is optional and is tried in order when the primary provider fails.</li>
<li>Provider env vars: <code>BRAVE_API_KEY</code>, <code>FIRECRAWL_API_KEY</code>, <code>TAVILY_API_KEY</code>, <code>PERPLEXITY_API_KEY</code>, <code>EXA_API_KEY</code>, <code>JINA_API_KEY</code> (or shared <code>WEB_SEARCH_API_KEY</code> where supported). DuckDuckGo and SearXNG do not require API keys.</li>
<li><code>allowed_commands</code> entries support <code>"cmd"</code>, <code>"cmd *"</code>, and <code>"*"</code> formats.
<ul dir="auto">
<li><code>"cmd"</code> and <code>"cmd *"</code> both allow that command family at the allowlist stage.</li>
<li><code>"*"</code> allows any command at the allowlist stage.</li>
</ul>
</li>
<li>High-risk and medium-risk runtime gates still apply after the allowlist check; set <code>block_medium_risk_commands: false</code> when you intentionally allow network/transfer commands such as <code>curl</code>/<code>wget</code> or other medium-risk mutations.</li>
<li><code>allowed_paths: ["*"]</code> allows access outside workspace, except system-protected paths.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Web UI / Browser Relay</h3><a id="user-content-web-ui--browser-relay" class="anchor" aria-label="Permalink: Web UI / Browser Relay" href="#web-ui--browser-relay"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>channels.web</code> for browser UI events (WebChannel v1):</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;channels&quot;: {
    &quot;web&quot;: {
      &quot;accounts&quot;: {
        &quot;default&quot;: {
          &quot;transport&quot;: &quot;local&quot;,
          &quot;listen&quot;: &quot;127.0.0.1&quot;,
          &quot;port&quot;: 32123,
          &quot;path&quot;: &quot;/ws&quot;,
          &quot;auth_token&quot;: &quot;replace-with-long-random-token&quot;,
          &quot;message_auth_mode&quot;: &quot;pairing&quot;,
          &quot;allowed_origins&quot;: [&quot;http://localhost:5173&quot;, &quot;chrome-extension://your-extension-id&quot;]
        }
      }
    }
  }
}"><pre>{
  <span class="pl-ent">"channels"</span>: {
    <span class="pl-ent">"web"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"default"</span>: {
          <span class="pl-ent">"transport"</span>: <span class="pl-s"><span class="pl-pds">"</span>local<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"listen"</span>: <span class="pl-s"><span class="pl-pds">"</span>127.0.0.1<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"port"</span>: <span class="pl-c1">32123</span>,
          <span class="pl-ent">"path"</span>: <span class="pl-s"><span class="pl-pds">"</span>/ws<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"auth_token"</span>: <span class="pl-s"><span class="pl-pds">"</span>replace-with-long-random-token<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"message_auth_mode"</span>: <span class="pl-s"><span class="pl-pds">"</span>pairing<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"allowed_origins"</span>: [<span class="pl-s"><span class="pl-pds">"</span>http://localhost:5173<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>chrome-extension://your-extension-id<span class="pl-pds">"</span></span>]
        }
      }
    }
  }
}</pre></div>
<ul dir="auto">
<li>Local: keep <code>"listen": "127.0.0.1"</code>.</li>
<li><code>message_auth_mode</code> controls inbound <code>user_message</code> auth:
<ul dir="auto">
<li><code>"pairing"</code> (default): send <code>pairing_request</code>, receive <code>pairing_result</code>, include UI <code>access_token</code> in every <code>user_message</code>.</li>
<li><code>"token"</code> (local transport only): include <code>auth_token</code> in each <code>user_message</code> payload (<code>access_token</code> is also accepted for compatibility).</li>
</ul>
</li>
<li><code>auth_token</code> hardens the WebSocket upgrade and becomes required when binding non-loopback addresses.</li>
<li>Unauthenticated WebSocket upgrade is loopback-only. Pairing-first local UX works on <code>127.0.0.1</code>, but a public/LAN bind must authenticate the <code>/ws</code> upgrade on the first hop with <code>?token=&lt;auth_token&gt;</code> or <code>Authorization: Bearer &lt;auth_token&gt;</code>.</li>
<li>Local loopback pairing no longer depends on a fixed shared code. <code>pairing_request</code> may omit <code>payload.pairing_code</code>, and legacy loopback clients that still send <code>123456</code> remain compatible.</li>
<li><code>/ws</code> is the WebSocket endpoint. <code>/pair</code> belongs to the HTTP gateway API and is not part of the web channel handshake.</li>
<li>Remote/headless host: if you bind <code>"listen": "0.0.0.0"</code>, prefer a stable configured token plus <code>message_auth_mode: "token"</code> behind TLS/reverse proxy, or keep loopback bind and expose it through SSH tunnel/proxy.</li>
<li>UI/extension should live in a separate repository and connect via this WebSocket endpoint.</li>
<li>For orchestration, use local token mode with a stable token from config or env (<code>NULLCLAW_WEB_TOKEN</code>, <code>NULLCLAW_GATEWAY_TOKEN</code>, <code>OPENCLAW_GATEWAY_TOKEN</code>).</li>
<li>Relay transport (outbound agent socket) is configured via:</li>
</ul>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;channels&quot;: {
    &quot;web&quot;: {
      &quot;accounts&quot;: {
        &quot;default&quot;: {
          &quot;transport&quot;: &quot;relay&quot;,
          &quot;relay_url&quot;: &quot;wss://relay.nullclaw.io/ws/agent&quot;,
          &quot;relay_agent_id&quot;: &quot;default&quot;,
          &quot;relay_token&quot;: &quot;replace-with-relay-token&quot;,
          &quot;relay_token_ttl_secs&quot;: 2592000,
          &quot;relay_pairing_code_ttl_secs&quot;: 300,
          &quot;relay_ui_token_ttl_secs&quot;: 86400,
          &quot;relay_e2e_required&quot;: false
        }
      }
    }
  }
}"><pre>{
  <span class="pl-ent">"channels"</span>: {
    <span class="pl-ent">"web"</span>: {
      <span class="pl-ent">"accounts"</span>: {
        <span class="pl-ent">"default"</span>: {
          <span class="pl-ent">"transport"</span>: <span class="pl-s"><span class="pl-pds">"</span>relay<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"relay_url"</span>: <span class="pl-s"><span class="pl-pds">"</span>wss://relay.nullclaw.io/ws/agent<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"relay_agent_id"</span>: <span class="pl-s"><span class="pl-pds">"</span>default<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"relay_token"</span>: <span class="pl-s"><span class="pl-pds">"</span>replace-with-relay-token<span class="pl-pds">"</span></span>,
          <span class="pl-ent">"relay_token_ttl_secs"</span>: <span class="pl-c1">2592000</span>,
          <span class="pl-ent">"relay_pairing_code_ttl_secs"</span>: <span class="pl-c1">300</span>,
          <span class="pl-ent">"relay_ui_token_ttl_secs"</span>: <span class="pl-c1">86400</span>,
          <span class="pl-ent">"relay_e2e_required"</span>: <span class="pl-c1">false</span>
        }
      }
    }
  }
}</pre></div>
<ul dir="auto">
<li>Relay token lifecycle (dedicated): <code>relay_token</code> (config) -&gt; <code>NULLCLAW_RELAY_TOKEN</code> (env) -&gt; persisted <code>web-relay-&lt;account_id&gt;</code> credential -&gt; generated token.</li>
<li>Relay UI handshake: send <code>pairing_request</code> with one-time <code>pairing_code</code>, receive <code>pairing_result</code> with UI <code>access_token</code> JWT (and optional <code>set_cookie</code> string for relay HTTP layer).</li>
<li>Relay <code>user_message</code> must include valid UI JWT in <code>access_token</code> (top-level or <code>payload.access_token</code>).</li>
<li>If E2E is enabled (<code>relay_e2e_required=true</code>), UI and agent exchange X25519 keys during pairing and send encrypted payloads in <code>payload.e2e</code>.</li>
<li>WebChannel event envelope is defined in <a href="/nullclaw/nullclaw/blob/main/spec/webchannel_v1.json"><code>spec/webchannel_v1.json</code></a>.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Gateway API</h2><a id="user-content-gateway-api" class="anchor" aria-label="Permalink: Gateway API" href="#gateway-api"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Endpoint</th>
<th>Method</th>
<th>Auth</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>/health</code></td>
<td>GET</td>
<td>None</td>
<td>Health check (always public)</td>
</tr>
<tr>
<td><code>/pair</code></td>
<td>POST</td>
<td><code>X-Pairing-Code</code> header</td>
<td>Exchange one-time code for bearer token</td>
</tr>
<tr>
<td><code>/webhook</code></td>
<td>POST</td>
<td><code>Authorization: Bearer &lt;token&gt;</code></td>
<td>Send message: <code>{"message": "your prompt"}</code></td>
</tr>
<tr>
<td><code>/media/transcribe</code></td>
<td>POST</td>
<td><code>Authorization: Bearer &lt;token&gt;</code></td>
<td>Transcribe <code>audio_base64</code> payloads through configured STT</td>
</tr>
<tr>
<td><code>/.well-known/agent-card.json</code></td>
<td>GET</td>
<td>None</td>
<td>A2A Agent Card discovery (public)</td>
</tr>
<tr>
<td><code>/a2a</code></td>
<td>POST</td>
<td><code>Authorization: Bearer &lt;token&gt;</code></td>
<td>A2A JSON-RPC endpoint (canonical methods plus legacy slash aliases)</td>
</tr>
<tr>
<td><code>/whatsapp</code></td>
<td>GET</td>
<td>Query params</td>
<td>Meta webhook verification</td>
</tr>
<tr>
<td><code>/whatsapp</code></td>
<td>POST</td>
<td>None (Meta signature)</td>
<td>WhatsApp incoming message webhook</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">A2A (Agent-to-Agent Protocol v0.3.0)</h3><a id="user-content-a2a-agent-to-agent-protocol-v030" class="anchor" aria-label="Permalink: A2A (Agent-to-Agent Protocol v0.3.0)" href="#a2a-agent-to-agent-protocol-v030"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">NullClaw implements Google's <a href="https://github.com/google/A2A">A2A protocol</a> v0.3.0, allowing any A2A-compatible agent or client to discover, authenticate, and interact with your instance over JSON-RPC 2.0.</p>
<p dir="auto">Enable in <code>~/.nullclaw/config.json</code>:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;a2a&quot;: {
    &quot;enabled&quot;: true,
    &quot;name&quot;: &quot;nullclaw&quot;,
    &quot;description&quot;: &quot;General-purpose AI assistant&quot;,
    &quot;url&quot;: &quot;https://example.com&quot;,
    &quot;version&quot;: &quot;1.0.0&quot;
  }
}"><pre>{
  <span class="pl-ent">"a2a"</span>: {
    <span class="pl-ent">"enabled"</span>: <span class="pl-c1">true</span>,
    <span class="pl-ent">"name"</span>: <span class="pl-s"><span class="pl-pds">"</span>nullclaw<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"description"</span>: <span class="pl-s"><span class="pl-pds">"</span>General-purpose AI assistant<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://example.com<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"version"</span>: <span class="pl-s"><span class="pl-pds">"</span>1.0.0<span class="pl-pds">"</span></span>
  }
}</pre></div>
<p dir="auto"><strong>Endpoints:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Endpoint</th>
<th>Auth</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>GET /.well-known/agent-card.json</code></td>
<td>None</td>
<td>Agent Card discovery (public)</td>
</tr>
<tr>
<td><code>POST /a2a</code></td>
<td>Bearer token</td>
<td>JSON-RPC 2.0 dispatch</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Supported methods:</strong> <code>message/send</code>, <code>message/stream</code>, <code>tasks/get</code>, <code>tasks/cancel</code>, <code>tasks/list</code>, <code>tasks/resubscribe</code>.</p>
<p dir="auto"><strong>Quick test:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# 1. Get a bearer token
# Set PAIRING_CODE to the one-time code for this gateway session.
TOKEN=$(curl -s -X POST -H &quot;X-Pairing-Code: $PAIRING_CODE&quot; http://localhost:3000/pair | jq -r .token)

# 2. Discover the agent
curl http://localhost:3000/.well-known/agent-card.json

# 3. Send a message
curl -X POST -H &quot;Authorization: Bearer $TOKEN&quot; \
  -H &quot;Content-Type: application/json&quot; \
  -d '{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1,&quot;method&quot;:&quot;message/send&quot;,&quot;params&quot;:{&quot;message&quot;:{&quot;messageId&quot;:&quot;msg-1&quot;,&quot;role&quot;:&quot;user&quot;,&quot;parts&quot;:[{&quot;kind&quot;:&quot;text&quot;,&quot;text&quot;:&quot;Hello&quot;}]}}}' \
  http://localhost:3000/a2a"><pre><span class="pl-c"><span class="pl-c">#</span> 1. Get a bearer token</span>
<span class="pl-c"><span class="pl-c">#</span> Set PAIRING_CODE to the one-time code for this gateway session.</span>
TOKEN=<span class="pl-s"><span class="pl-pds">$(</span>curl -s -X POST -H <span class="pl-s"><span class="pl-pds">"</span>X-Pairing-Code: <span class="pl-smi">$PAIRING_CODE</span><span class="pl-pds">"</span></span> http://localhost:3000/pair <span class="pl-k">|</span> jq -r .token<span class="pl-pds">)</span></span>

<span class="pl-c"><span class="pl-c">#</span> 2. Discover the agent</span>
curl http://localhost:3000/.well-known/agent-card.json

<span class="pl-c"><span class="pl-c">#</span> 3. Send a message</span>
curl -X POST -H <span class="pl-s"><span class="pl-pds">"</span>Authorization: Bearer <span class="pl-smi">$TOKEN</span><span class="pl-pds">"</span></span> \
  -H <span class="pl-s"><span class="pl-pds">"</span>Content-Type: application/json<span class="pl-pds">"</span></span> \
  -d <span class="pl-s"><span class="pl-pds">'</span>{"jsonrpc":"2.0","id":1,"method":"message/send","params":{"message":{"messageId":"msg-1","role":"user","parts":[{"kind":"text","text":"Hello"}]}}}<span class="pl-pds">'</span></span> \
  http://localhost:3000/a2a</pre></div>
<p dir="auto">See <a href="/nullclaw/nullclaw/blob/main/docs/en/gateway-api.md">Gateway API docs</a> for full A2A reference including streaming, task lifecycle, and configuration details.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Media transcription</h3><a id="user-content-media-transcription" class="anchor" aria-label="Permalink: Media transcription" href="#media-transcription"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>POST /media/transcribe</code> accepts JSON with <code>audio_base64</code>, <code>mime_type</code>, <code>source</code>, and optional <code>language</code>, then returns <code>{"text":"..."}</code> plus metadata. Configure STT under <code>tools.media.audio</code>; remote custom STT endpoints must use HTTPS. Raise <code>gateway.max_body_size_bytes</code>, <code>gateway.request_timeout_secs</code>, and <code>gateway.webhook_rate_limit_per_minute</code> for live desktop audio chunking.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Commands</h2><a id="user-content-commands" class="anchor" aria-label="Permalink: Commands" href="#commands"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>onboard --api-key sk-... --provider openrouter</code></td>
<td>Quick setup with API key and provider</td>
</tr>
<tr>
<td><code>onboard --interactive</code></td>
<td>Full interactive wizard</td>
</tr>
<tr>
<td><code>onboard --channels-only</code></td>
<td>Reconfigure channels/allowlists only</td>
</tr>
<tr>
<td><code>agent -m "..."</code></td>
<td>Single message mode</td>
</tr>
<tr>
<td><code>acp</code></td>
<td>Start the Agent Client Protocol stdio adapter for ACP-compatible editors</td>
</tr>
<tr>
<td><code>agent</code></td>
<td>Interactive chat mode</td>
</tr>
<tr>
<td><code>gateway</code></td>
<td>Start long-running runtime (default: <code>127.0.0.1:3000</code>)</td>
</tr>
<tr>
<td><code>service install|start|stop|restart|status|uninstall</code></td>
<td>Manage background service</td>
</tr>
<tr>
<td><code>doctor</code></td>
<td>Diagnose system health</td>
</tr>
<tr>
<td><code>status [--json]</code></td>
<td>Show full system status or emit the machine-readable runtime snapshot</td>
</tr>
<tr>
<td><code>channel list|info|start|status|add|remove</code></td>
<td>Manage channels, including JSON account inventory for automation</td>
</tr>
<tr>
<td><code>cron list|status|add|add-agent|once|once-agent|remove|pause|resume|run|update|runs</code></td>
<td>Manage scheduled tasks</td>
</tr>
<tr>
<td><code>skills list|install|remove|info</code></td>
<td>Manage skill packs, including <code>install --name &lt;query&gt;</code> registry search</td>
</tr>
<tr>
<td><code>history list|show</code></td>
<td>View session conversation history</td>
</tr>
<tr>
<td><code>memory stats|count|reindex|search|get|list|export-jsonl|hygiene-report|drain-outbox|forget</code></td>
<td>Inspect, export, and maintain memory</td>
</tr>
<tr>
<td><code>hardware scan|flash|monitor</code></td>
<td>Hardware device management</td>
</tr>
<tr>
<td><code>config show|get</code>, <code>models list|summary|info|benchmark|refresh</code></td>
<td>Read config/model admin state and manage the model catalog</td>
</tr>
<tr>
<td><code>workspace edit|reset-md</code></td>
<td>Maintain workspace markdown/bootstrap files</td>
</tr>
<tr>
<td><code>capabilities [--json]</code></td>
<td>Show runtime capabilities manifest</td>
</tr>
<tr>
<td><code>auth login|status|logout</code></td>
<td>Manage OAuth authentication</td>
</tr>
<tr>
<td><code>migrate openclaw [--dry-run] [--source PATH]</code></td>
<td>Import memory + migrate config from OpenClaw</td>
</tr>
<tr>
<td><code>update [--check] [--yes]</code></td>
<td>Check for and install updates</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Development</h2><a id="user-content-development" class="anchor" aria-label="Permalink: Development" href="#development"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Build and tests are pinned to <strong>Zig 0.16.0</strong>.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="zig build                          # Dev build
zig build -Doptimize=ReleaseSmall  # Release build (678 KB)
zig build test --summary all       # 5,300+ tests"><pre>zig build                          <span class="pl-c"><span class="pl-c">#</span> Dev build</span>
zig build -Doptimize=ReleaseSmall  <span class="pl-c"><span class="pl-c">#</span> Release build (678 KB)</span>
zig build <span class="pl-c1">test</span> --summary all       <span class="pl-c"><span class="pl-c">#</span> 5,300+ tests</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Channel Flow Coverage</h3><a id="user-content-channel-flow-coverage" class="anchor" aria-label="Permalink: Channel Flow Coverage" href="#channel-flow-coverage"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Channel CJM coverage (ingress parsing/filtering, session key routing, account propagation, bus handoff) is validated by tests in:</p>
<ul dir="auto">
<li><code>src/channel_manager.zig</code> (runtime channel registration/start semantics + listener mode wiring)</li>
<li><code>src/config.zig</code> (OpenClaw-compatible <code>channels.*.accounts</code> parsing, multi-account selection/ordering, aliases)</li>
<li><code>src/gateway.zig</code> (Telegram/WhatsApp/LINE/Lark routed session keys from webhook payloads)</li>
<li><code>src/daemon.zig</code> (gateway-loop inbound route resolution for Discord/QQ/OneBot/Mattermost/MaixCam)</li>
<li><code>src/channels/discord.zig</code>, <code>src/channels/mattermost.zig</code>, <code>src/channels/qq.zig</code>, <code>src/channels/onebot.zig</code>, <code>src/channels/signal.zig</code>, <code>src/channels/line.zig</code>, <code>src/channels/whatsapp.zig</code> (per-channel inbound/outbound contracts)</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Project Stats</h3><a id="user-content-project-stats" class="anchor" aria-label="Permalink: Project Stats" href="#project-stats"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Language:     Zig 0.16.0
Source files: ~250
Lines of code: ~249,000
Tests:        5,300+
Binary:       678 KB (ReleaseSmall)
Peak RSS:     ~1 MB
Startup:      &lt;2 ms (Apple Silicon)
Dependencies: 0 (besides libc + optional SQLite)"><pre class="notranslate"><code>Language:     Zig 0.16.0
Source files: ~250
Lines of code: ~249,000
Tests:        5,300+
Binary:       678 KB (ReleaseSmall)
Peak RSS:     ~1 MB
Startup:      &lt;2 ms (Apple Silicon)
Dependencies: 0 (besides libc + optional SQLite)
</code></pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Source Layout</h3><a id="user-content-source-layout" class="anchor" aria-label="Permalink: Source Layout" href="#source-layout"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="src/
  main.zig              CLI entry point + argument parsing
  root.zig              Module hierarchy (public API)
  config.zig            JSON config loader + 30 sub-config structs
  agent.zig             Agent loop, auto-compaction, tool dispatch
  daemon.zig            Daemon supervisor with exponential backoff
  gateway.zig           HTTP gateway (rate limiting, idempotency, pairing)
  channels/             19 channel implementations (telegram, signal, discord, slack, nostr, matrix, whatsapp, line, lark, onebot, mattermost, qq, ...)
  providers/            50+ AI provider integrations
  memory/               SQLite backend, embeddings, vector search, hygiene, snapshots
  tools/                35+ tool implementations
  security/             Secrets (ChaCha20), sandbox backends (landlock, firejail, ...)
  cron.zig              Cron scheduler with JSON persistence
  health.zig            Component health registry
  tunnel.zig            Tunnel vtable (cloudflare, ngrok, tailscale, custom)
  peripherals.zig       Hardware peripheral vtable (serial, Arduino, RPi, Nucleo)
  runtime.zig           Runtime vtable (native, docker, WASM)
  skillforge.zig        Skill discovery (GitHub), evaluation, integration
  ..."><pre class="notranslate"><code>src/
  main.zig              CLI entry point + argument parsing
  root.zig              Module hierarchy (public API)
  config.zig            JSON config loader + 30 sub-config structs
  agent.zig             Agent loop, auto-compaction, tool dispatch
  daemon.zig            Daemon supervisor with exponential backoff
  gateway.zig           HTTP gateway (rate limiting, idempotency, pairing)
  channels/             19 channel implementations (telegram, signal, discord, slack, nostr, matrix, whatsapp, line, lark, onebot, mattermost, qq, ...)
  providers/            50+ AI provider integrations
  memory/               SQLite backend, embeddings, vector search, hygiene, snapshots
  tools/                35+ tool implementations
  security/             Secrets (ChaCha20), sandbox backends (landlock, firejail, ...)
  cron.zig              Cron scheduler with JSON persistence
  health.zig            Component health registry
  tunnel.zig            Tunnel vtable (cloudflare, ngrok, tailscale, custom)
  peripherals.zig       Hardware peripheral vtable (serial, Arduino, RPi, Nucleo)
  runtime.zig           Runtime vtable (native, docker, WASM)
  skillforge.zig        Skill discovery (GitHub), evaluation, integration
  ...
</code></pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Versioning</h2><a id="user-content-versioning" class="anchor" aria-label="Permalink: Versioning" href="#versioning"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">nullclaw uses <strong>CalVer</strong> (<code>YYYY.M.D</code>) for releases — e.g. <code>v2026.2.20</code>.</p>
<ul dir="auto">
<li><strong>Tag format:</strong> <code>vYYYY.M.D</code> (one release per day max; patch suffix <code>vYYYY.M.D.N</code> if needed)</li>
<li><strong>Release binaries derive their embedded version from the git tag</strong> (<code>v...</code> -&gt; <code>nullclaw --version</code>)</li>
<li><strong>Non-release builds default to <code>dev</code></strong> unless you override with <code>zig build -Dversion=...</code></li>
<li><strong>No stability guarantees yet</strong> — the project is pre-1.0, config and CLI may change between releases</li>
<li><strong><code>nullclaw --version</code></strong> prints the current version</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="/nullclaw/nullclaw/blob/main/CONTRIBUTING.md"><code>CONTRIBUTING.md</code></a> for development environment setup, workflow, validation commands, and the PR checklist.</p>
<p dir="auto">Implement a vtable interface, submit a PR:</p>
<ul dir="auto">
<li>New <code>Provider</code> -&gt; <code>src/providers/</code></li>
<li>New <code>Channel</code> -&gt; <code>src/channels/</code></li>
<li>New <code>Tool</code> -&gt; <code>src/tools/</code></li>
<li>New <code>Memory</code> backend -&gt; <code>src/memory/</code></li>
<li>New <code>Tunnel</code> -&gt; <code>src/tunnel.zig</code></li>
<li>New <code>Sandbox</code> backend -&gt; <code>src/security/</code></li>
<li>New <code>Peripheral</code> -&gt; <code>src/peripherals.zig</code></li>
<li>New <code>Skill</code> -&gt; <code>~/.nullclaw/workspace/skills/&lt;name&gt;/</code> or <code>~/.nullclaw/workspace/skills/&lt;category&gt;/&lt;name&gt;/</code></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Chinese Docs (中文文档)</h2><a id="user-content-chinese-docs-中文文档" class="anchor" aria-label="Permalink: Chinese Docs (中文文档)" href="#chinese-docs-中文文档"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/README.md">Chinese docs overview (中文文档总览)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/installation.md">Installation guide (安装指南)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/zig-installation.md">Zig installation (Zig 安装指南)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/configuration.md">Configuration guide (配置指南)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/usage.md">Usage and operations (使用与运维)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/architecture.md">Architecture overview (架构总览)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/security.md">Security model (安全机制)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/gateway-api.md">Gateway API (中文)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/commands.md">Commands reference (命令参考)</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/zh/development.md">Development guide (开发指南)</a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">English Docs</h2><a id="user-content-english-docs" class="anchor" aria-label="Permalink: English Docs" href="#english-docs"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/README.md">English docs overview</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/installation.md">Installation</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/zig-installation.md">Zig Installation</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/configuration.md">Configuration</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/usage.md">Usage and operations</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/architecture.md">Architecture</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/security.md">Security</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/gateway-api.md">Gateway API</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/commands.md">Commands</a></li>
<li><a href="/nullclaw/nullclaw/blob/main/docs/en/development.md">Development</a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Disclaimer</h2><a id="user-content-disclaimer" class="anchor" aria-label="Permalink: Disclaimer" href="#disclaimer"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">nullclaw is a pure open-source software project. It has <strong>no token, no cryptocurrency, no blockchain component, and no financial instrument</strong> of any kind. This project is not affiliated with any token or financial product.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT — see <a href="/nullclaw/nullclaw/blob/main/LICENSE">LICENSE</a></p>
<hr>
<p dir="auto"><strong>nullclaw</strong> — Null overhead. Null compromise. Deploy anywhere. Swap anything.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Star History</h2><a id="user-content-star-history" class="anchor" aria-label="Permalink: Star History" href="#star-history"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a href="https://www.star-history.com/#nullclaw/nullclaw&amp;type=date&amp;legend=top-left" rel="nofollow"><img src="https://camo.githubusercontent.com/6f6c8ccd4df24bf8571b31aad846a45109644fcf2459fa2af11765aaf1674723/68747470733a2f2f6170692e737461722d686973746f72792e636f6d2f7376673f7265706f733d6e756c6c636c61772f6e756c6c636c617726747970653d64617465266c6567656e643d746f702d6c656674" alt="Star History Chart" data-canonical-src="https://api.star-history.com/svg?repos=nullclaw/nullclaw&amp;type=date&amp;legend=top-left" style="max-width: 100%;"></a></p>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 p-responsive" role="contentinfo"  >
  <h2 class='sr-only'>Footer</h2>

  


  <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
    <div class="d-flex flex-items-center flex-shrink-0 mx-2">
      <a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
        <svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
    <path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
      <span>
        &copy; 2026 GitHub,&nbsp;Inc.
      </span>
    </div>

    <nav aria-label="Footer">
      <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>

      <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">


          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
          </li>


            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
            </li>

            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
            </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://github.community/" data-view-component="true" class="Link--secondary Link">Community</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
          </li>

          
<li class="mx-2" >
  <cookie-consent-link>
    <button
      type="button"
      class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
      data-action="click:cookie-consent-link#showConsentManagement"
      data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
    >
      Manage cookies
    </button>
  </cookie-consent-link>
</li>

  <li class="mx-2">
    <cookie-consent-link>
      <button
        type="button"
        class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
        data-action="click:cookie-consent-link#showConsentManagement"
        data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
      >
        Do not share my personal information
      </button>
    </cookie-consent-link>
  </li>

      </ul>
    </nav>
  </div>
</footer>



    <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
      data-locale="en"
      data-initial-cookie-consent-allowed=""
      data-cookie-consent-required="true"
    ></ghcc-consent>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    You can’t perform that action at this time.
  </div>

    <template id="site-details-dialog">
  <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
    <summary role="button" aria-label="Close dialog"></summary>
    <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
      <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
      </button>
      <div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
    </details-dialog>
  </details>
</template>

    <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
  <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
  </div>
</div>

    <template id="snippet-clipboard-copy-button">
  <div class="zeroclipboard-container position-absolute right-0 top-0">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
  <div class="zeroclipboard-container">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>




    </div>
    <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
    <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
  </body>
</html>

