# CLI reference

> openclaw memory-tdai seed flags, and package bins migrate-sqlite-to-tcvdb, export-tencent-vdb, read-local-memory including build prerequisites.

- 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

- `src/cli/index.ts`
- `src/cli/commands/seed.ts`
- `src/cli/README.md`
- `package.json`
- `bin/migrate-sqlite-to-tcvdb.mjs`
- `bin/export-tencent-vdb.mjs`
- `bin/read-local-memory.mjs`

---

---
title: "CLI reference"
description: "openclaw memory-tdai seed flags, and package bins migrate-sqlite-to-tcvdb, export-tencent-vdb, read-local-memory including build prerequisites."
---

The package `@tencentdb-agent-memory/memory-tencentdb` exposes two CLI surfaces: the OpenClaw plugin command namespace `openclaw memory-tdai` (currently `seed` only), and three npm `bin` entry points—`migrate-sqlite-to-tcvdb`, `export-tencent-vdb`, and `read-local-memory`—each a thin Node launcher over a TypeScript build product under `scripts/*/dist/`.

## CLI inventory

| Surface | How to invoke | Build / host requirement |
|---|---|---|
| `openclaw memory-tdai seed` | OpenClaw plugin CLI (`api.registerCli`) | Plugin installed/loaded; no separate script build |
| `migrate-sqlite-to-tcvdb` | Package bin or `npm run migrate-sqlite-to-tcvdb -- …` | `npm run build:migrate-sqlite-to-vdb` |
| `export-tencent-vdb` | Package bin or `npm run export-tencent-vdb -- …` | `npm run build:export-tencent-vdb` |
| `read-local-memory` | Package bin or `npm run read-local-memory -- …` | `npm run build:read-local-memory` |

```text
OpenClaw host                          Package bins (node)
─────────────────                      ───────────────────
openclaw memory-tdai seed              migrate-sqlite-to-tcvdb
  → registerMemoryTdaiCli              export-tencent-vdb
  → registerSeedCommand                read-local-memory
  → executeSeed (L0→L1, L2/L3 wired)     → scripts/*/dist/*.js
```

<Note>
`memory-tencentdb-ctl` and `export-diagnostic.sh` are shell ops tools under `scripts/`, not npm `bin` entries. See [Gateway control](/gateway-control) and [Export diagnostics](/export-diagnostics).
</Note>

## Build prerequisites

| Requirement | Value |
|---|---|
| Node | `>=22.16.0` (`package.json` `engines`) |
| TypeScript toolchain | Dev deps: `typescript`, `tsdown`, `@types/node` (for local builds) |
| Full scripts build | `npm run build:scripts` (runs all three script builds) |
| Full package build | `npm run build` → `build:plugin` + `build:scripts` |
| Publish path | `prepack` runs `npm run build`; published `files` include `bin/` and `scripts/*/dist/` |

### Per-bin compile targets

| Bin | npm script | Dist entry loaded by bin |
|---|---|---|
| `migrate-sqlite-to-tcvdb` | `build:migrate-sqlite-to-vdb` | `scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/cli-entry.js` |
| `export-tencent-vdb` | `build:export-tencent-vdb` | `scripts/export-tencent-vdb/dist/export-tencent-vdb.js` |
| `read-local-memory` | `build:read-local-memory` | `scripts/read-local-memory/dist/read-local-memory.js` |

```bash
# From package root (source checkout)
npm install
npm run build:scripts

# Or individually
npm run build:migrate-sqlite-to-vdb
npm run build:export-tencent-vdb
npm run build:read-local-memory
```

<Warning>
`export-tencent-vdb` and `read-local-memory` bins exit with code `1` if the dist file is missing and print the required `npm run build:…` command. `migrate-sqlite-to-tcvdb` does not preflight the dist path; a missing build fails on `import()`.
</Warning>

After a normal `npm install @tencentdb-agent-memory/memory-tencentdb`, bins resolve from the package and use published dist artifacts (no local `tsc` required).

---

## `openclaw memory-tdai seed`

Registers under the plugin CLI namespace `memory-tdai` via `api.registerCli` (both full runtime and `registrationMode === "cli-metadata"` discovery). Implementation: `src/cli/index.ts` → `registerSeedCommand` → `executeSeed`.

```bash
openclaw memory-tdai seed --input <file> [options]
```

### Flags

<ParamField body="--input" type="string" required>
Path to input JSON file (Format A or Format B).
</ParamField>

<ParamField body="--output-dir" type="string">
Pipeline data directory. Default: `<stateDir>/memory-tdai-seed-<YYYYMMDD-HHmmss>` where `stateDir` is the OpenClaw state root (for example `~/.openclaw`).
</ParamField>

<ParamField body="--session-key" type="string">
Fallback session key when an input session omits `sessionKey`.
</ParamField>

<ParamField body="--config" type="string">
JSON config override path. Two-level deep-merged on top of the live plugin config from `openclaw.json`.
</ParamField>

<ParamField body="--strict-round-role" type="boolean" default="false">
Require every round to include both `user` and `assistant` messages.
</ParamField>

<ParamField body="--yes" type="boolean" default="false">
Skip interactive confirmations (timestamp auto-fill).
</ParamField>

### Behavior notes

| Topic | Behavior |
|---|---|
| Pipeline | Feeds L0 capture then L1 extraction; L2/L3 runners are wired, but seed currently waits only for L1 idle before destroy—L2/L3 artifacts may still be incomplete |
| Timestamps | All messages must have timestamps or none must; if all missing, prompts to fill with current time (or auto-fills with `--yes`) |
| Mixed timestamps | Fatal validation error |
| Output dir exists + non-empty | Fatal unless empty; checkpoint resume is **not** implemented (exit if `.metadata/checkpoint.json` exists) |
| Config merge | Object keys merge one level deep; non-objects are replaced |
| Progress | Stdout progress line per round; final box summary: sessions, rounds, messages, L0 recorded count, duration |

### Input formats

**Format A** — object wrapper:

```json
{
  "sessions": [
    {
      "sessionKey": "user-alice",
      "sessionId": "conv-001",
      "conversations": [
        [
          { "role": "user", "content": "Hello", "timestamp": 1711929600000 },
          { "role": "assistant", "content": "Hi!", "timestamp": 1711929601000 }
        ]
      ]
    }
  ]
}
```

**Format B** — top-level array of sessions:

```json
[
  {
    "sessionKey": "user-alice",
    "conversations": [
      [
        { "role": "user", "content": "Hello" },
        { "role": "assistant", "content": "Hi!" }
      ]
    ]
  }
]
```

| Field | Required | Notes |
|---|---|---|
| `sessionKey` | yes | Session identity |
| `sessionId` | no | Generated if omitted |
| `conversations` | yes | Array of rounds; each round is an array of messages |
| `role` | yes | Message role |
| `content` | yes | Message text |
| `timestamp` | no* | Epoch ms or ISO 8601; all-or-none across the file |

### Config override example

```json
{
  "pipeline": {
    "everyNConversations": 3,
    "enableWarmup": false,
    "l1IdleTimeoutSeconds": 2,
    "l2DelayAfterL1Seconds": 1,
    "l2MinIntervalSeconds": 1,
    "l2MaxIntervalSeconds": 10
  }
}
```

### Output layout

```text
<output-dir>/
├── conversations/       # L0 JSONL
├── records/             # L1 JSONL
├── scene_blocks/        # L2 scenes (if produced)
├── vectors.db           # SQLite store (sqlite backend)
├── .metadata/
│   ├── manifest.json
│   └── checkpoint.json
└── .backup/
```

### Examples

```bash
openclaw memory-tdai seed --input conversations.json
openclaw memory-tdai seed --input data.json --output-dir ./seed-output
openclaw memory-tdai seed --input data.json --config seed-config.json --yes
openclaw memory-tdai seed --input data.json --strict-round-role --yes
```

For workflow detail (verification of L0→L1→L2→L3 on disk), see [Seed historical conversations](/seed-conversations).

---

## `migrate-sqlite-to-tcvdb`

Offline migration from local SQLite (`vectors.db`) into Tencent VectorDB (TCVDB). Optionally rewrites `openclaw.json` plugin config (`storeBackend: "tcvdb"`) and `.metadata/manifest.json`.

### Invoke

```bash
# After build (or from installed package with published dist)
migrate-sqlite-to-tcvdb [options]
npm run migrate-sqlite-to-tcvdb -- [options]
node ./bin/migrate-sqlite-to-tcvdb.mjs [options]
```

CLI entry: `scripts/migrate-sqlite-to-tcvdb/cli-entry.ts` → `runMigrationCli`. Stdout prints the migration summary as JSON; logs go to stderr with tag `[memory-tdai][migrate]`.

### Required options

<ParamField body="--plugin-data-dir" type="path" required>
Plugin data directory (for example `~/.openclaw/memory-tdai`).
</ParamField>

<ParamField body="--openclaw-config-path" type="path" required>
Path to `openclaw.json`.
</ParamField>

<ParamField body="--tcvdb-url" type="string" required>
TCVDB HTTP base URL.
</ParamField>

<ParamField body="--tcvdb-username" type="string" required>
TCVDB username.
</ParamField>

<ParamField body="--tcvdb-database" type="string" required>
Target TCVDB database name.
</ParamField>

<ParamField body="--tcvdb-embedding-model" type="string" required>
Embedding model name recorded for the target store.
</ParamField>

<ParamField body="--tcvdb-api-key" type="string">
API key in clear text. Mutually exclusive with `--tcvdb-api-key-env`.
</ParamField>

<ParamField body="--tcvdb-api-key-env" type="string">
Environment variable name holding the API key. Mutually exclusive with `--tcvdb-api-key`. One of the two is required.
</ParamField>

### Optional options

| Flag | Default | Description |
|---|---|---|
| `--sqlite-path` | `<plugin-data-dir>/vectors.db` | Source SQLite path |
| `--plugin-id` | `memory-tencentdb` | Plugin entry id written into `openclaw.json` |
| `--layers` | `l0,l1,l2,l3` | Comma-separated layer set |
| `--tcvdb-alias` | `""` | User alias |
| `--tcvdb-timeout-ms` | `10000` | Request timeout (ms) |
| `--tcvdb-ca-pem` | — | CA PEM path for HTTPS |
| `--bm25-language` | `zh` | `zh` or `en` |
| `--summary-json-path` | — | Write summary JSON to this path |
| `--job-id` | — | Optional job id for tracking |
| `--dry-run` | `false` | Preflight only; no writes |
| `--yes` | `false` | Skip interactive confirmation |
| `--no-apply-config` | apply on | Do not update `openclaw.json` |
| `--no-config-backup` | backup on | Skip config file backup before write |
| `--no-rewrite-manifest` | rewrite on | Do not rewrite manifest to `tcvdb` |
| `--no-fail-if-target-nonempty` | fail on | Allow non-empty target DB |
| `--no-verify-counts` | verify on | Skip post-migration count checks |
| `--no-bm25-enabled` | BM25 on | Disable BM25 sparse vectors |
| `-h, --help` | — | Print usage |

Boolean flags use Node `parseArgs` with `allowNegative: true` (so `--no-*` toggles the positive defaults).

### Config patch written on success

When `--apply-config` is true (default), the tool patches the plugin entry with:

```json
{
  "storeBackend": "tcvdb",
  "tcvdb": {
    "url": "…",
    "username": "…",
    "apiKey": "…",
    "database": "…",
    "alias": "…",
    "embeddingModel": "…",
    "timeout": 10000
  },
  "bm25": {
    "enabled": true,
    "language": "zh"
  }
}
```

### Empty source handling

If `plugin-data-dir` or `vectors.db` is missing, migration returns a zero-count summary (no hard failure)—useful for greenfield installs.

### Examples

```bash
# Dry-run preflight
migrate-sqlite-to-tcvdb \
  --plugin-data-dir ~/.openclaw/memory-tdai \
  --openclaw-config-path ~/.openclaw/openclaw.json \
  --tcvdb-url http://127.0.0.1:80 \
  --tcvdb-username root \
  --tcvdb-api-key-env TCVDB_API_KEY \
  --tcvdb-database agent_memory_prod \
  --tcvdb-embedding-model bge-large-zh \
  --dry-run

# Full migration
migrate-sqlite-to-tcvdb \
  --plugin-data-dir ~/.openclaw/memory-tdai \
  --openclaw-config-path ~/.openclaw/openclaw.json \
  --tcvdb-url http://127.0.0.1:80 \
  --tcvdb-username root \
  --tcvdb-api-key-env TCVDB_API_KEY \
  --tcvdb-database agent_memory_prod \
  --tcvdb-embedding-model bge-large-zh \
  --yes

# L1 only, no config rewrite
migrate-sqlite-to-tcvdb \
  --plugin-data-dir ~/.openclaw/memory-tdai \
  --openclaw-config-path ~/.openclaw/openclaw.json \
  --tcvdb-url http://127.0.0.1:80 \
  --tcvdb-username root \
  --tcvdb-api-key-env TCVDB_API_KEY \
  --tcvdb-database agent_memory_prod \
  --tcvdb-embedding-model bge-large-zh \
  --layers l1 \
  --no-apply-config \
  --no-rewrite-manifest \
  --yes
```

See also [Migrate SQLite to Tencent VectorDB](/migrate-sqlite-tcvdb) and [Configure storage backends](/configure-storage).

---

## `export-tencent-vdb`

HTTP export client for **Tencent VectorDB only**. Connects with CLI-supplied credentials (no `.env` file), lists collections, and writes JSONL plus schema/meta sidecars.

### Invoke

```bash
export-tencent-vdb --url <url> --username <user> --api-key <key> --database <db> [options]
npm run export-tencent-vdb -- …
node ./bin/export-tencent-vdb.mjs …
```

### Connection parameters (required)

<ParamField body="--url" type="string" required>
VDB instance HTTP base URL (for example `http://host:8100`).
</ParamField>

<ParamField body="--username" type="string" required>
Auth username (for example `root`).
</ParamField>

<ParamField body="--api-key" type="string" required>
Auth API key (sent as Bearer `account=…&api_key=…`).
</ParamField>

<ParamField body="--database" type="string" required>
Database name.
</ParamField>

### Export options

| Flag | Default | Description |
|---|---|---|
| `--timeout` | `30000` | Per-request timeout (ms) |
| `-o, --output` | `./vdb-export-YYYY-MM-DD` | Output directory |
| `-c, --collection` | all | Export one collection (full name match) |
| `-f, --filter` | — | VDB filter expression |
| `-l, --limit` | all | Max documents (`>= 1`) |
| `--offset` | `0` | Start offset (`>= 0`; must be a multiple of page size `100`) |
| `--include-vectors` | off | Include dense `vector` field (skipped by default) |
| `--probe` | off | Connectivity check + list collections, then exit |
| `-h, --help` | — | Help |

`sparse_vector` (BM25) is always exported; only dense `vector` is gated by `--include-vectors`.

### Output layout

```text
<outputDir>/
├── <collection>.jsonl    # one JSON document per line
├── schemas.json          # collection schemas / embedding config
└── export-meta.json      # export metadata
```

### Examples

```bash
export-tencent-vdb \
  --url "http://gz-vdb-xxx:8100" --username root --api-key "xxx" --database mydb \
  --probe

export-tencent-vdb \
  --url "http://gz-vdb-xxx:8100" --username root --api-key "xxx" --database mydb

export-tencent-vdb \
  --url "http://gz-vdb-xxx:8100" --username root --api-key "xxx" --database mydb \
  -c mydb_l0_conversations -o /tmp/backup

export-tencent-vdb \
  --url "http://gz-vdb-xxx:8100" --username root --api-key "xxx" --database mydb \
  -f 'role = "user"' --include-vectors
```

---

## `read-local-memory`

Read-only inspector for a **local sqlite** memory data directory. L0/L1 read from `vectors.db` via `node:sqlite` with `PRAGMA query_only = ON`. L2 reads `scene_blocks/`; L3 reads `persona.md`.

### Invoke

```bash
read-local-memory -d <data-dir> [options]
npm run read-local-memory -- -d <data-dir> [options]
node ./bin/read-local-memory.mjs -d <data-dir> [options]
```

### Options

<ParamField body="-d, --data-dir" type="path" required>
Local memory data directory; must exist. L0/L1 require `vectors.db` inside it.
</ParamField>

<ParamField body="-L, --level" type="L0|L1|L2|L3">
Query one layer. Omit to scan all layers (overview).
</ParamField>

<ParamField body="--since" type="string">
Start time: ISO string or relative `7d` / `24h` / `30m` / `60s` (relative is “now minus N”).
</ParamField>

<ParamField body="--until" type="string">
End time (same formats as `--since`).
</ParamField>

<ParamField body="-l, --limit" type="number" default="50">
Page size (`>= 1`).
</ParamField>

<ParamField body="--offset" type="number" default="0">
Page offset (`>= 0`).
</ParamField>

<ParamField body="--sort" type="asc|desc" default="desc">
Time sort: `desc` newest first, `asc` oldest first.
</ParamField>

<ParamField body="-f, --filter" type="string">
Column filters for L0/L1 SQLite tables. Operators: `=`, `!=`, `>`, `<`, `>=`, `<=`. Multiple conditions comma-separated. CamelCase field names map to snake_case columns.
</ParamField>

<ParamField body="--format" type="table|json|jsonl" default="table">
Output format.
</ParamField>

<ParamField body="--file" type="string">
L2 single-file detail: return full content for one scene file name.
</ParamField>

<ParamField body="-h, --help" type="boolean">
Print help and exit.
</ParamField>

### Filter column allowlists

| Level | Allowed columns |
|---|---|
| L0 | `record_id`, `session_key`, `session_id`, `role`, `message_text`, `recorded_at`, `timestamp` |
| L1 | `record_id`, `content`, `type`, `priority`, `scene_name`, `session_key`, `session_id`, `timestamp_str`, `timestamp_start`, `timestamp_end`, `created_time`, `updated_time`, `metadata_json` |

Unknown filter columns fail fast with the allowed list printed.

### Examples

```bash
# All-layer overview
read-local-memory -d ~/.openclaw/memory-tdai

# L0 last 7 days
read-local-memory -d ~/.openclaw/memory-tdai -L L0 --since 7d

# L1 persona-type atoms
read-local-memory -d ~/.openclaw/memory-tdai -L L1 -f 'type=persona'

# Page 2 of L0 (20 per page)
read-local-memory -d ~/.openclaw/memory-tdai -L L0 -l 20 --offset 20

# Machine-readable
read-local-memory -d ~/.openclaw/memory-tdai -L L0 --since 7d --format json
```

<Note>
`read-local-memory` targets the SQLite layout (`vectors.db`). It is not a TCVDB client; use `export-tencent-vdb` or Gateway search APIs for remote TCVDB inspection.
</Note>

---

## Common failure modes

| Symptom | Likely cause | Probe |
|---|---|---|
| `precompiled artifact missing` / import fail | Script not built | `npm run build:scripts` then re-run bin |
| `openclaw memory-tdai` missing | Plugin not installed or CLI metadata not registered | `openclaw plugins list`; reinstall package |
| Seed aborts on non-empty output dir | Existing dir or checkpoint | New `--output-dir` or clean directory |
| Seed validation errors | Bad Format A/B or mixed timestamps | Fix JSON; use `--strict-round-role` only when every round is paired |
| Migrate: missing API key | Neither `--tcvdb-api-key` nor `--tcvdb-api-key-env` | Set one (not both) |
| Migrate: both key flags | Mutually exclusive | Keep a single key source |
| `read-local-memory`: no `vectors.db` | Wrong dir or tcvdb-only data | Point `-d` at sqlite data root |
| Export: missing required connection flags | Incomplete CLI | Pass `--url --username --api-key --database` |

---

## Related pages

<CardGroup cols={2}>
  <Card title="Seed historical conversations" href="/seed-conversations">
    Format A/B workflows, config overrides, and L0→L1→L2→L3 verification signals for seed runs.
  </Card>
  <Card title="Migrate SQLite to Tencent VectorDB" href="/migrate-sqlite-tcvdb">
    Dry-run, layer selection, openclaw.json rewrites, and post-migration storeBackend checks.
  </Card>
  <Card title="Configure storage backends" href="/configure-storage">
    sqlite vs tcvdb fields, embedding quadruplets, BM25 language, store health.
  </Card>
  <Card title="Data directories" href="/data-directories">
    On-disk layout for OpenClaw memory-tdai, offload, and Hermes MEMORY_TENCENTDB_ROOT trees.
  </Card>
  <Card title="Gateway control" href="/gateway-control">
    memory-tencentdb-ctl start/stop/status/health/logs and config subcommands.
  </Card>
  <Card title="Gateway HTTP API" href="/gateway-http-api">
    Standalone Hermes sidecar endpoints including POST /seed and search routes.
  </Card>
  <Card title="Configuration reference" href="/configuration-reference">
    Full plugin config schema used by seed --config merges and migrate rewrites.
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    Source-backed failure modes for plugin, embedding, offload, and Gateway recovery probes.
  </Card>
</CardGroup>
