# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview HarmonyOS (鸿蒙) crash diagnostics demo app — `com.example.crashdiagnosticsdemo`. Targets HarmonyOS 6.1.0 (API 23), Stage Mode, phone devices only. Uses the Hvigor build system with DevEco Studio as the IDE. ## Build & Development Commands This is a HarmonyOS project; use the **deveco-cli skill** for all build, run, and device operations. - **Build (debug)**: `devecocli build` or via DevEco Studio - **Run on device/emulator**: DevEco Studio → Run, or `devecocli run` - **Lint ArkTS**: `code-linter` is configured via `code-linter.json5` (triggers on `.ets` files, enforces security rules like `@security/no-unsafe-aes`, `@security/no-unsafe-hash`, etc.) - **CLI docs lookup**: use the `deveco-cli` skill to fetch HarmonyOS API docs and samples ### Testing The project includes `@ohos/hypium` (test framework) and `@ohos/hamock` (mocking) as dev dependencies. Test targets are configured in `entry/build-profile.json5` under the `ohosTest` target. ## Architecture ### Entry Point & Page Routing ``` EntryAbility (entryability/EntryAbility.ets) └── loads pages/Index (main page) └── navigates to pages/CrashHistory (push route) ``` - `EntryAbility` initializes `CrashDiagnostics` on `onCreate`, sets color mode, and loads `pages/Index` on `onWindowStageCreate`. - Page routes are declared in `entry/src/main/resources/base/profile/main_pages.json`. ### Core Diagnostic Layer — `CrashDiagnostics` (diagnostics/CrashDiagnostics.ets) A **static utility class** (never instantiated) that is the backbone of the app. Key responsibilities: 1. **HiAppEvent subscription**: Registers an `hiAppEvent.Watcher` named `debugCrashWatcher` that listens for system `APP_CRASH` fault events. The watcher is created in `initialize()` — because it reuses the same name, it picks up un-consumed crash events from a previous process exit on the next launch. 2. **Persistent crash records**: Stores up to 10 crash record strings in `preferences` (key: `recent_hiappevent_crash_records`). New records are prepended; duplicates are filtered out. 3. **Dismiss-until-new-crash pattern**: Tracks which crash the user dismissed (key: `dismissed_hiappevent_crash_id`). `shouldShowLastCrashDialog()` returns `true` only when the current latest crash differs from the dismissed one. 4. **Listener callback**: `recordsUpdatedListener` — a single callback set by the active UI page; fires when cached records change. 5. **Caught error logging**: `recordCaughtError()` logs to hilog only — it does NOT mix caught exceptions into the APP_CRASH history. The history exclusively contains system-generated crash events. ### Pages - **`pages/Index`** — Main debug screen. Displays crash record count/status, buttons to simulate a caught error (logged only) and a native CPP crash (via NAPI, kills the app), and a button to view crash history. On `aboutToAppear`, sets itself as the `recordsUpdatedListener` and optionally shows an alert dialog for the last un-dismissed crash. - **`pages/CrashHistory`** — Lists crash records from `CrashDiagnostics.getRecentRecords()`, with detail view, clear-all, and export-to-ZIP (JSON inside ZIP, saved via `DocumentViewPicker`). ### Native Layer (NAPI) ``` entry/src/main/cpp/napi_init.cpp → libentry.so entry/src/main/cpp/types/libentry/index.d.ts → ArkTS type declarations ``` Exports a single function `simulateCppCrash()` that calls `std::abort()`. Used by `pages/Index` to demonstrate a native crash that gets picked up by HiAppEvent on the next launch. Built via CMake (`CMakeLists.txt`) targeting `arm64-v8a` only, linked against `libace_napi.z.so`. ### Key Data Flow ``` App crashes (native/JS) → HarmonyOS writes APP_CRASH event to HiAppEvent → Next app launch: EntryAbility.onCreate → CrashDiagnostics.initialize() → hiAppEvent.addWatcher("debugCrashWatcher") picks up events → collectFromHolder() formats and caches records to preferences → recordsUpdatedListener fires → Index page updates UI → Optionally shows AlertDialog for un-dismissed crash ``` ## Important Constraints - **ArkTS is NOT TypeScript**: ArkTS is a strict subset of TypeScript with its own compiler rules. Use the `arkts-grammar-standards` skill before writing `.ets` files. Key differences: no `any`/`unknown` types in certain contexts, restricted structural typing for `@Component` structs, specific decorator rules (`@State`, `@Entry`, `@Component`). - **Target ABI is arm64-v8a only** (no x86_64 emulator support in the build config). - **Obfuscation is disabled** even in release mode (`entry/build-profile.json5`). - **Strict mode enabled**: `caseSensitiveCheck: true`, `useNormalizedOHMUrl: true`.