PebbleOS is the operating system running on Pebble smartwatches.
docs: project documentationresources: firmware resources (icons, fonts, etc.)sdk: application SDK generation filessrc: firmware sourcesubsys: OS subsystems, e.g. loggingtests: teststhird_party: third-party code in git submodules, also includes glue codetools: a variety of tools or scripts used in multiple areas, from build system, tests, etc.tools/libs: Python packages used in multiple areas, e.g. log dehashing, console, etc.tools/libs/pbl-cli: thepbldeveloper CLItools/cmake: generators the CMake builds shell out tosdk/waftools: waf plugins bundled into the SDK app developers build with
Contributor documentation lives in docs/ (published at
https://pebbleos-core.readthedocs.io). Prefer pointing to or extending those
pages over duplicating knowledge here: docs/development/contributing.md
(DCO, commit and AI-usage rules), docs/development/pbl.md (the pbl
CLI, and how to extend it), docs/development/sdk_export.md (SDK export
machinery), docs/development/qemu.md (emulator workflow).
- clang-format for C code
- ruff for Python code
- Keep code comments short and concise. Extended descriptions can be kept in the Git commit message.
- Do not put references to issues in the code, only add those to the Git commit message.
PBL_LOG_WRN/PBL_LOG_ERRare for warnings and errors — use them as the names suggest.- Default to
PBL_LOG_DBGfor routine lifecycle / state-transition logs. ReservePBL_LOG_INFOfor events that genuinely warrant attention in a default-level log capture; if a code path can fire repeatedly under normal use (e.g. play/pause spam, frequent state changes), it must not log at INFO.
-
Configure:
pbl configure --board BOARD_NAME- Board names can be obtained from
pbl configure --help -DCONFIG_RELEASE=yenables release mode-DCONFIG_MFG=yenables manufacturing mode--variant=normal|prfselects build variant (default: normal)
- Board names can be obtained from
-
Build firmware:
pbl build -
Run tests:
pbl test
The submodules are large. In disposable or isolated agent workspaces, do not initialize every submodule recursively. Initialize only the submodule needed for the current build or task, using a shallow clone:
git submodule update --init --depth 1 -- path/to/submodule
Add --recursive only when that specific submodule requires its own nested
submodules. If a task needs submodule history, deepen only that submodule.
Workspace providers should reuse local Git object stores and copy-on-write
checkouts when available; agents must not symlink a writable submodule checkout
from another workspace because that breaks workspace isolation.
Exposing a function to third-party apps requires three coordinated changes
(applib wrapper + syscall, exported_symbols.json registration, SDK
revision bump) — the firmware build alone won't surface it to apps. Follow
docs/development/sdk_export.md whenever an applib/ function should
become callable from user apps.
Main rules:
- Commit using
-sgit option, so commits haveSigned-Off-By - Always indicate commit is co-authored by the current AI model
- Commit in small chunks, trying to preserve bisectability
- Commit format is
area: short description, with longer description in the body if necessary - Run
gitlinton every commit to verify rules are followed
Others:
- If fixing Linear or GitHub issues, include in the commit body a line with
Fixes XXX, where XXX is the issue number.