---
title: Boot and runtime wiring
description: Order from app_main until subsystems are ready
---

import { Steps, FileTree, LinkCard } from '@astrojs/starlight/components';
import LinkToSource from '@/components/LinkToSource.astro';

This walkthrough uses sample app `application/edge_agent`, covering entry <LinkToSource relativePath="application/edge_agent/main/main.c" /> and wiring in <LinkToSource relativePath="components/common/app_claw/app_claw.c" />.

## `main.c` entry

<LinkToSource relativePath="application/edge_agent/main/main.c" /> initializes required system pieces and peripherals so the ESP-Claw Agent can run.

<Steps>
1. **Init NVS and load settings**

    On boot, `edge_agent` initializes the NVS partition (`nvs_flash_init`).
    Then `app_config_init` + `app_config_load` pull Wi‑Fi, LLM, IM, search, time zone, etc. into RAM.

2. **Init Board Manager and optional Emote**

    Call `esp_board_manager_init` to assemble board-level device handles.<br />
    If `CONFIG_APP_CLAW_ENABLE_EMOTE` is enabled, `app_claw_ui_start` is also invoked afterward to start the emote-display component and set the screen to an offline hint state.

3. **Mount FATFS**

    Mount FATFS at the virtual path `/fatfs`.<br />
    If mount fails, `ESP_ERROR_CHECK` triggers `abort` and the device reboots—a filesystem is required for ESP-Claw to run normally.

4. **Init Wi‑Fi and state callback**

    Attempt Wi‑Fi init (`wifi_manager_init` / `wifi_manager_start`): connect to configured SSID and start SoftAP for Web configuration and offline operations.<br />
    - After `wifi_manager_init`, `wifi_manager_register_state_callback` is registered: if emote is enabled, it updates emote and text status on Wi‑Fi connect/disconnect, and can display intermediate state such as current AP SSID.<br />
    - On failure, log and continue. Offline rules and Lua can still run without a Wi‑Fi link.

5. **Start HTTP server**

    Bring up the config HTTP server (`http_server_init` / `http_server_start`) for Web-based settings.
    Captive DNS (`captive_dns_start`) is started as well, so SoftAP provisioning can auto-redirect to the portal page.

6. **Start ESP-Claw Agent stack**

    Call `app_claw_start(&s_settings)` to bring up the Agent subsystems.

</Steps>

## `app_claw.c` Agent wiring

<LinkToSource relativePath="components/common/app_claw/app_claw.c" /> initializes the Agent stack in order, then launches the Console REPL.

<Steps>
1. **Init Session Manager and Event Router**

    Call `cap_session_mgr_set_session_root_dir` to set the session manager root, then
    `claw_event_router_init` loads the automation file (demo: `/fatfs/router_rules/router_rules.json`),
    sets timeouts talking to `claw_core`, and `default_route_messages_to_agent` (`true` when LLM settings are complete).
    The `run_agent` action uses asynchronous submission; Agent responses are published back to the Event Router as `out_message` events.

2. **Init scheduler**

    `cap_scheduler_init` sets the schedule file path (`/fatfs/scheduler/schedules.json`), check interval (`tick_ms`), max items, task stack size and priority, and binds publishing (`claw_event_router_publish`). The scheduler initializes here but does not start yet.

3. **Init Memory**

    `claw_memory_init` sets session history root (`/fatfs/sessions/`), long-term memory directory (`/fatfs/memory`), and per-message limits (`edge_agent` defaults to 1024 chars per message).
    If required structured-memory files are missing, they are created automatically.

4. **Init Skills**

    `claw_skill_init` sets the Skills root (`/fatfs/skills/`) and session state root for `activate_skill` and related flows.

5. **Init capabilities**

    `claw_cap_init`, then each cap module registers into groups:

    - **cap_files**: file root `/fatfs`.
    - **cap_lua**: Lua root `/fatfs/scripts/`.
    - **cap_im_platform**: when IM credentials exist, apply QQ / Feishu / Telegram / WeChat App ID, Secret, or Token fields, then configure the shared inbox path (`/fatfs/inbox/`) plus max attachment size. The component registers the per-platform groups (`cap_im_qq`, `cap_im_feishu`, `cap_im_tg`, `cap_im_wechat`).
    - **cap_web_search**: store Brave / Tavily keys when non-empty.
    - **cap_router_mgr**: register Event Router console commands (`event_router`).
    - **cap_system**: register the system information capability group (memory, CPU, Wi-Fi, IP, and restart action).
    - **cap_mcp_client / cap_mcp_server / cap_skill / cap_time / cap_llm_inspect / cap_session_mgr**, etc.: each `*_register_group` (Skill management sources live under `cap_skill_mgr`; the group id remains `cap_skill`).
    - In full structured-memory mode, the `claw_memory` capability group is also registered; in lightweight mode it is not.
    - `claw_cap_set_llm_visible_groups` seeds `cap_files`, `cap_skill`, `cap_system`, and `cap_lua` for the LLM; full structured-memory mode additionally includes `claw_memory`. Then `claw_cap_start_all` starts every group.

    <br />

6. **Bind outbound IM channels**

    `claw_event_router_register_outbound_binding` maps `qq`, `feishu`, `telegram`, `wechat` to their send caps (e.g. `qq_send_message`).

7. **Init claw_core (conditional)**

    When `llm_api_key`, `llm_model`, and `llm_profile` are all non-empty:
    - `claw_core_init` configures the LLM backend (key, profile, model, base_url, timeouts) and system prompt;
    - register context providers: `claw_memory_profile_provider`, a long-term provider (`claw_memory_long_term_provider` in full mode, `claw_memory_long_term_lightweight_provider` in lightweight mode), `claw_memory_session_history_provider`, `claw_skill_skills_list_provider`, and `claw_cap_tools_provider`;
    - `claw_core_start` launches the inference task.

    Otherwise `claw_core_init` / `claw_core_start` are skipped with a WARN—`ask`, default Agent routing, image inspect, and other core-dependent features stay unavailable until the LLM is configured and the device reboots.

8. **Start Event Router, time sync, scheduler, and Console REPL**

    `claw_event_router_start` begins processing inbound events, then `cap_time_sync_service_start` starts SNTP (first successful sync triggers `cap_scheduler_handle_time_sync` to rebase the scheduler), then `cap_scheduler_start` starts the scheduler task, then `app_claw_cli_start` opens the Console REPL—wiring complete.

</Steps>

## Filesystem layout

<FileTree>
- fatfs
  - sessions
    - ... session history
  - memory
    - MEMORY.md human-readable memory view (read-only)
    - memory_records.jsonl structured memory records
    - memory_index.json summary-tag and keyword index
    - memory_digest.log memory-operation digest log
    - user.md user profile
    - soul.md persona
    - identity.md identity
  - skills
    - skill_id
      - SKILL.md Skill metadata and body
      - scripts/ Skill-bundled scripts (optional)
  - scripts
    - ... Lua scripts
  - router_rules
    - router_rules.json automation rules
  - scheduler
    - schedules.json scheduler config
    - schedules.json.state scheduler runtime state
  - inbox
    - ... IM attachments
</FileTree>
