# Export diagnostics

> Run export-diagnostic.sh to package redacted config, gateway logs, and memory-tdai data; privacy notes and local-only delivery expectations.

- Repository: TencentCloud/TencentDB-Agent-Memory
- GitHub: https://github.com/TencentCloud/TencentDB-Agent-Memory
- Human docs: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-14fefdd76c97
- Complete Markdown: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-14fefdd76c97/llms-full.txt

## Source Files

- `scripts/export-diagnostic.sh`
- `SKILL-DIAGNOSTIC-EXPORT.md`
- `scripts/bugfix-20260423/BUGFIX-20260423-SOP.md`
- `src/utils/openclaw-state-dir.ts`

---

---
title: "Export diagnostics"
description: "Run export-diagnostic.sh to package redacted config, gateway logs, and memory-tdai data; privacy notes and local-only delivery expectations."
---

`scripts/export-diagnostic.sh` packages a local OpenClaw + memory-tencentdb support bundle: environment inventory, gateway and rolling logs, the full `memory-tdai` data tree, a redacted `openclaw.json`, and installed plugin metadata. The script writes only under a user-chosen (or default) local path, creates `openclaw-diagnostic-<timestamp>.tar.gz`, and never uploads the archive.

<Warning>
The archive is **local-only**. There is no network transfer step. Review contents before sharing. `memory-tdai/` includes raw conversation text and other high-sensitivity memory data even when config secrets are redacted.
</Warning>

## Scope and constraints

| Item | Behavior |
|------|----------|
| Entry point | `bash scripts/export-diagnostic.sh [output_base_dir]` |
| Package surface | Not a `package.json` `bin`; run from a repo checkout that contains `scripts/export-diagnostic.sh` |
| Host focus | OpenClaw state directory and its `memory-tdai` plugin data |
| Not collected | `context-offload/`, Hermes/`MEMORY_TENCENTDB_ROOT` trees (`~/.memory-tencentdb/…`), remote VectorDB contents |
| Delivery | Manual only (copy/send archive after local review) |

Plugin package rename does not change the data path: `@tencentdb-agent-memory/memory-tencentdb` still stores under `<stateDir>/memory-tdai` (hardcoded in the plugin and the export script). Log tags remain `[memory-tdai]`.

## Prerequisites

- Bash with `set -euo pipefail` (script uses strict mode)
- Readable OpenClaw state directory (see [State directory resolution](#state-directory-resolution))
- `tar` for packaging
- `node` recommended for config redaction (falls back to rough `grep`/`sed` redaction if Node fails)
- Optional: `openclaw` or `pnpm openclaw` for version capture in `env-info.txt`
- Optional: `json5` available to Node for non-strict JSON configs; otherwise plain `JSON.parse`

## State directory resolution

The script picks `STATE_DIR` in this order:

1. `OPENCLAW_STATE_DIR` if set
2. `$HOME/.openclaw` if that directory exists
3. `$HOME/.clawdbot` if that directory exists
4. Otherwise exit `1` with: OpenClaw work directory not found

Plugin runtime resolution (`resolveOpenClawStateDir`) prefers host `runtime.state.resolveStateDir()`, then `OPENCLAW_STATE_DIR`, then `~/.openclaw`. The export script additionally accepts legacy `~/.clawdbot` when present.

Plugin data path used by both runtime and export:

```text
$STATE_DIR/memory-tdai
```

Typical default: `~/.openclaw/memory-tdai`.

## Run the export

<Steps>
  <Step title="Confirm the OpenClaw state tree">
```bash
OPENCLAW_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
[ -d "$OPENCLAW_DIR" ] || OPENCLAW_DIR="$HOME/.clawdbot"
ls -la "$OPENCLAW_DIR/" 2>/dev/null
ls -la "$OPENCLAW_DIR/memory-tdai/" 2>/dev/null
```
  </Step>
  <Step title="Run export-diagnostic.sh from the repo root">
```bash
# Default output base: ~/Downloads
bash scripts/export-diagnostic.sh

# Custom output base directory
bash scripts/export-diagnostic.sh /tmp
```
  </Step>
  <Step title="Verify the archive">
The script prints the archive path and size. Confirm:

- `openclaw-diagnostic-<YYYYMMDD-HHMMSS>.tar.gz` exists under the output base
- Unpacked directory sibling: `openclaw-diagnostic-<timestamp>/`
- Expected members listed below are present (missing optional trees are non-fatal)
  </Step>
  <Step title="Review privacy before sharing">
Inspect `memory-tdai/` and logs. Redacted config is not a full privacy guarantee for conversation content. Share only what you intend to send.
  </Step>
</Steps>

### CLI parameters

<ParamField body="output_base_dir" type="string" default="~/Downloads">
Directory that will contain `openclaw-diagnostic-<timestamp>/` and the sibling `.tar.gz`. Pass as the first positional argument.
</ParamField>

### Environment inputs

| Variable | Effect |
|----------|--------|
| `OPENCLAW_STATE_DIR` | Forces the OpenClaw state root used for logs, config, extensions, and `memory-tdai` |

### Success output

On success the script prints a summary similar to:

```text
═══════════════════════════════════════════════════
  ✅ 诊断数据导出完成
═══════════════════════════════════════════════════

  📦 压缩包: <OUTPUT_BASE>/openclaw-diagnostic-<timestamp>.tar.gz
  📏 大小: <size>

  包含内容:
    - env-info.txt
    - logs/
    - memory-tdai/
    - openclaw-config-redacted.json
    - plugins-info.txt

  ⚠️ 安全提示:
    - 配置文件已自动脱敏（API Key、Token、Password 等已移除）
    - models/secrets/channels/env 等敏感配置块已整体替换
    - 记忆数据中可能包含用户对话内容，请确认后再发送

  📤 请手动检查后发送给研发团队
═══════════════════════════════════════════════════
```

Failure modes:

| Condition | Result |
|-----------|--------|
| No `~/.openclaw`, `~/.clawdbot`, or `OPENCLAW_STATE_DIR` | Exit `1` before packaging |
| Missing `memory-tdai` | Warning; export continues without that tree |
| Missing `openclaw.json` | Warning; no config artifact |
| Node redaction error | Falls back to line-based `grep`/`sed` redaction |
| Missing optional logs / subdirs | Skipped with `|| true` style handling |

## Archive layout

:::files
openclaw-diagnostic-&lt;timestamp&gt;/
├── env-info.txt
├── openclaw-config-redacted.json
├── plugins-info.txt
├── logs/
│   ├── gateway-logs/          # copy of $STATE_DIR/logs/
│   └── rolling-logs/          # up to 3 newest /tmp/openclaw/openclaw-*.log (tail 5000 lines each)
└── memory-tdai/
    ├── conversations/         # L0 JSONL
    ├── records/               # L1 JSONL
    ├── scene_blocks/          # L2 Markdown
    ├── persona.md             # L3 persona (if present)
    ├── vectors.db             # SQLite vector + FTS store (if present)
    ├── .metadata/             # checkpoints, scene_index, etc.
    └── .backup/               # optional; may be large
:::

### What each artifact is for

| Path in archive | Source | Privacy | Use in triage |
|-----------------|--------|---------|---------------|
| `env-info.txt` | Live probe | Low | OS, Node/pnpm, OpenClaw version, `STATE_DIR`, recursive `memory-tdai` listing, `du` sizes |
| `logs/gateway-logs/` | `$STATE_DIR/logs/` | Low–medium | Gateway stdout/stderr, config audit, command logs if present |
| `logs/rolling-logs/` | `/tmp/openclaw/openclaw-*.log` | Low–medium | Recent JSON Lines rolling logs (newest 3 files, last 5000 lines each) |
| `memory-tdai/` | `$STATE_DIR/memory-tdai/` | **High** | L0–L3 data, SQLite index, checkpoints, backups |
| `openclaw-config-redacted.json` | `$STATE_DIR/openclaw.json` after redact | Low | Plugin entries, store/embedding shape without secrets |
| `plugins-info.txt` | `$STATE_DIR/extensions/*` | Low | Installed extension dirs and package name/version when available |

### Log sources (OpenClaw)

| Kind | Typical path | Export behavior |
|------|--------------|-----------------|
| Gateway daemon logs | `$STATE_DIR/logs/` (e.g. `gateway.log`, `gateway.err.log`) | Full tree copy into `logs/gateway-logs/` |
| Rolling JSONL logs | `/tmp/openclaw/openclaw-YYYY-MM-DD.log` | Newest 3 files; each truncated to last 5000 lines |
| Config audit / commands | under `$STATE_DIR/logs/` | Included if present in that tree |

### memory-tdai subtrees copied

| Subpath | Layer / role |
|---------|----------------|
| `conversations/` | L0 raw conversations (daily JSONL) |
| `records/` | L1 structured memories (daily JSONL) |
| `scene_blocks/` | L2 scene Markdown |
| `persona.md` | L3 persona file |
| `.metadata/` | Checkpoints and indexes (e.g. recall checkpoint) |
| `vectors.db` | Local SQLite vector + FTS index |
| `.backup/` | Rolling backups (optional; can dominate size) |

## Config redaction

Redaction targets `$STATE_DIR/openclaw.json` and writes `openclaw-config-redacted.json`.

| Rule | Replacement |
|------|-------------|
| Key matches `api_?key\|token\|password\|secret\|credential` (case-insensitive) and value is a non-empty string | `***REDACTED(<N>chars)***` (empty string stays empty) |
| SecretRef-like object with `source`, `id`, and `provider` | Same shape with `id: "***REDACTED***"` |
| Top-level keys `models`, `secrets`, `channels`, `env` | `***REDACTED_SECTION(use openclaw config get <key> to inspect)***` |
| Under path `gateway.auth`, keys matching `token\|password` | `***REDACTED***` for strings |
| Other fields (including most of `plugins`) | Kept after recursive walk so non-secret plugin settings remain for debugging |

<Note>
Recursive redaction still strips nested `apiKey` / `token` / `password` / `secret` / `credential` string fields inside `plugins`. Provider, model, enable flags, and similar non-matching keys remain.
</Note>

If the Node path fails, the fallback strips lines that look like long secret string assignments and attempts a coarse section rewrite for `models` / `secrets` / `channels` / `env`. Prefer fixing Node rather than relying on the fallback before sharing.

## Privacy and delivery expectations

| Class | Handling |
|-------|----------|
| API keys, tokens, passwords, secrets, SecretRefs | Redacted in config export |
| Top-level models / secrets / channels / env | Section redacted |
| Plugin non-secret config | Retained for diagnosis |
| L0 conversations and other memory files | **Not redacted** — full local copy |
| Upload / telemetry | **None** — script only writes local files and `tar.gz` |

Recommended delivery workflow:

1. Keep the archive on the machine that produced it.
2. Unzip and spot-check `memory-tdai/conversations/`, `records/`, and logs for content you do not want shared.
3. Optionally remove `.backup/` or other large/sensitive subtrees and re-tar.
4. Send the archive through your approved channel (chat, email, ticket). The repository does not define an automated upload endpoint.

## Manual export fallback

When the script cannot run (for example Node redaction path unavailable and you prefer full control):

```bash
EXPORT_DIR=~/Downloads/openclaw-diagnostic-$(date +%Y%m%d-%H%M%S)
mkdir -p "$EXPORT_DIR"

cp -r "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/logs/" "$EXPORT_DIR/logs/" 2>/dev/null || true
cp /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log "$EXPORT_DIR/" 2>/dev/null || true
cp -r "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/memory-tdai/" "$EXPORT_DIR/memory-tdai/" 2>/dev/null || true

# Config must be redacted by hand before sharing
cp "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/openclaw.json" \
  "$EXPORT_DIR/openclaw-config-NEEDS-MANUAL-REDACTION.json"

cd "$(dirname "$EXPORT_DIR")"
tar -czf "${EXPORT_DIR}.tar.gz" "$(basename "$EXPORT_DIR")"
```

<Warning>
Manual config copies are **not** redacted. Remove `models` / `secrets` / `channels` / `env` blocks and all key/token values before sending.
</Warning>

## Agent skill hook

`SKILL-DIAGNOSTIC-EXPORT.md` defines skill `openclaw-diagnostic-export` for agents that should run this workflow when users ask to export diagnostics, package on-site data, or collect logs for support. The skill mirrors the script’s steps, privacy warnings, and post-export handoff guidance.

## Triage signals inside the bundle

| Question | Where to look |
|----------|----------------|
| Did the plugin load? | `logs/` → search `[memory-tdai]` |
| Is recall running? | `logs/` → search `[recall]` |
| Did L1/L2/L3 pipeline fire? | `logs/` → search `[pipeline]` |
| Embedding / store backend shape? | `openclaw-config-redacted.json` → `plugins.entries` |
| Disk pressure / empty store? | `env-info.txt` (`du`, listings) |
| Checkpoint / cursor state? | `memory-tdai/.metadata/` (e.g. recall checkpoint files) |

## Out of scope

- **Hermes / standalone Gateway data** under `MEMORY_TENCENTDB_ROOT` (default `~/.memory-tencentdb/memory-tdai`) is not collected by this script. Use host-specific log and data paths for those deployments.
- **Context offload** data under `context-offload/` is not part of the archive.
- **Tencent VectorDB remote collections** are not dumped; only local `vectors.db` when present under OpenClaw `memory-tdai`.
- **Automatic ticket upload** is not implemented.

## Related pages

<CardGroup>
  <Card title="Data directories" href="/data-directories">
    On-disk layout for `memory-tdai`, offload, and Hermes roots that the export may partially sample.
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    Source-backed failure modes and recovery probes that diagnostics packages support.
  </Card>
  <Card title="Configuration reference" href="/configuration-reference">
    Full plugin config schema fields retained (non-secret) in redacted exports.
  </Card>
  <Card title="Gateway control" href="/gateway-control">
    `memory-tencentdb-ctl` start/stop/status/logs for live probes alongside offline exports.
  </Card>
  <Card title="Package rename" href="/package-rename">
    Why the data dir remains `memory-tdai` after migrating to `@tencentdb-agent-memory/memory-tencentdb`.
  </Card>
  <Card title="CLI reference" href="/cli-reference">
    Other package bins and `openclaw memory-tdai` commands (export-diagnostic is a repo script, not a published bin).
  </Card>
</CardGroup>
