# Contributing

> Local development with openclaw plugins install --link, build and test scripts, project layout, CI expectations, and contribution workflow from CONTRIBUTING.md.

- 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-5a33bbf5540a
- Complete Markdown: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-5a33bbf5540a/llms-full.txt

## Source Files

- `CONTRIBUTING.md`
- `package.json`
- `vitest.config.ts`
- `tsdown.config.ts`
- `.github/workflows/pr-ci.yml`
- `CHANGELOG.md`
- `LICENSE`

---

---
title: "Contributing"
description: "Local development with openclaw plugins install --link, build and test scripts, project layout, CI expectations, and contribution workflow from CONTRIBUTING.md."
---

Contributions to **TencentDB Agent Memory** (`@tencentdb-agent-memory/memory-tencentdb`) land as GitHub Issues/PRs against `main`, with DCO sign-off required on every commit. Local OpenClaw development uses `openclaw plugins install --link .` so the gateway loads TypeScript sources in place; packaging uses `tsdown` + script builds, and PR CI validates install, pack, plugin manifest metadata, and a 2 MB tarball size limit (it does not run Vitest).

## Prerequisites

| Requirement | Constraint | Source of truth |
| --- | --- | --- |
| Node.js | `>=22.16.0` | `package.json` `engines.node` |
| Package manager | npm or pnpm | `CONTRIBUTING.md` |
| OpenClaw (for plugin host work) | Plugin API / min gateway `>=2026.3.13` | `package.json` `openclaw.compat` |
| Peer `openclaw` (optional) | `>=2026.3.7` | `peerDependencies` |
| Peer `node-llama-cpp` (optional) | `^3.16.2` | `peerDependenciesMeta` (optional) |

OpenClaw is optional as a peer when you only build the published package or run the standalone Gateway / Hermes path. Linked plugin development and hook registration need a compatible OpenClaw install.

## Ways to contribute

| Kind | Where | Notes |
| --- | --- | --- |
| Bug reports | GitHub Issues (`bug_report.yml`) | Title prefix `[Bug]`, label `bug` |
| Feature requests | Issues (`feature_request.yml`) | Title prefix `[Feature]`, label `enhancement` |
| Questions | Issues (`question.yml`) | Title prefix `[Question]`, label `question` |
| Docs / examples | PR against `main` | Prefer README + `CHANGELOG.md` when behavior changes |
| Code | PR against `main` | Focused commits; run local tests before opening |

Security vulnerabilities: email **agentmemory@tencent.com** (do not open a public Issue for exploits).

## Local development (OpenClaw link)

OpenClaw loads the plugin from source when linked. Node 22.16+ type-stripping means **no build step is required** for edit → restart → verify on a linked checkout.

<Steps>
  <Step title="Clone and install">
```bash
git clone https://github.com/Tencent/TencentDB-Agent-Memory.git
cd TencentDB-Agent-Memory
npm install
```
  </Step>
  <Step title="Link into OpenClaw">
```bash
openclaw plugins install --link .
```
`install --link` registers the current directory as a local plugin. Edit TypeScript under the repo root; **restart the OpenClaw gateway** for changes to take effect.
  </Step>
  <Step title="Enable and exercise">
Enable `memory-tencentdb` in OpenClaw config, restart the gateway, and verify capture/recall or tools as needed. See related install and config pages for production-shaped setup.
  </Step>
</Steps>

<Note>
`npm install` runs `postinstall`: `scripts/openclaw-after-tool-call-messages.patch.sh` (errors ignored with `|| true`). CI installs with `npm install --ignore-scripts`, so postinstall is **not** exercised in PR CI.
</Note>

## Build scripts

Development against a linked tree does not need `dist/`. Publishing and `npm pack` do: `prepack` runs `npm run build`.

| Script | Command | Purpose |
| --- | --- | --- |
| `build` | `npm run build` | `build:plugin` then `build:scripts` |
| `build:plugin` | `tsdown` | Bundle plugin entry `./index.ts` → `./dist` (ESM) |
| `build:scripts` | three `tsc` projects | Compile migrate / export / read-local-memory CLIs |
| `prepack` | `npm run build` | Ensures pack/publish includes built artifacts |
| `migrate-sqlite-to-tcvdb` | `node ./bin/migrate-sqlite-to-tcvdb.mjs` | Offline SQLite → TCVDB migration CLI |
| `export-tencent-vdb` | `node ./bin/export-tencent-vdb.mjs` | Export TCVDB collections |
| `read-local-memory` | `node ./bin/read-local-memory.mjs` | Inspect local L0–L3 artifacts |

### Plugin bundle (`tsdown.config.ts`)

- **Entry:** `./index.ts`
- **Output:** `./dist`, format `esm`, platform `node`, `clean: true`, `fixedExtension: true`
- **Not bundled:** `openclaw` / `openclaw/*`, `node:` builtins, and all declared `dependencies`, `peerDependencies`, and `optionalDependencies`
- **DTS / sourcemaps:** off (`dts: false`, `sourcemap: false`)

Published package name: `@tencentdb-agent-memory/memory-tencentdb`. Plugin id in `openclaw.plugin.json`: `memory-tencentdb` (CLI aliases include `memory-tdai`).

## Tests

### Node (Vitest)

| Script | Behavior |
| --- | --- |
| `npm test` | `vitest run` (unit/integration config) |
| `npm run test:watch` | Vitest watch mode |
| `npm run test:coverage` | `vitest run --coverage` (v8; reporters `text`, `html`, `lcov`) |

Default config (`vitest.config.ts`):

- **Environment:** `node`, pool `forks`
- **Include:** `src/**/*.test.ts`, `__tests__/**/*.test.ts`
- **Exclude:** `dist/**`, `node_modules/**`, `**/*.e2e.test.ts`
- **Timeouts:** test and hook `120_000` ms
- **Isolation:** `clearMocks`, `restoreMocks`, `unstubEnvs`, `unstubGlobals`
- **Coverage include:** `src/**/*.ts`, `index.ts` (excludes `*.test.ts`)

E2E config (`vitest.e2e.config.ts`) includes only `**/*.e2e.test.ts` (separate from default `npm test`).

Existing co-located unit tests include (non-exhaustive):

- `src/utils/time.test.ts`
- `src/utils/sanitize.test.ts`
- `src/utils/no-think-fetch.test.ts`
- `src/offload/auth-profile-key.test.ts`

### Hermes (Python)

Provider recovery and gateway lifecycle tests live under:

`hermes-plugin/memory/memory_tencentdb/tests/`

Examples: `test_memory_tencentdb_recovery.py`, `test_gateway_shutdown_leak.py` (pytest + mocks; no real Node gateway required).

<Warning>
PR CI (`.github/workflows/pr-ci.yml`) does **not** invoke `vitest` or pytest. Run `npm test` (and Hermes tests when touching `hermes-plugin/`) locally before opening a PR.
</Warning>

## Project layout

`CONTRIBUTING.md` still shows a flat `src/conversation` tree. The implemented layout nests host-neutral memory under `src/core/`, with separate adapters, gateway, offload, and CLI surfaces:

:::files
.
├── index.ts                 # OpenClaw plugin shell (tools, hooks → TdaiCore)
├── openclaw.plugin.json     # Plugin id, configSchema, tool contracts
├── package.json             # Scripts, engines, openclaw.compat, exports
├── tsdown.config.ts         # Plugin ESM bundle
├── vitest.config.ts         # Unit tests
├── vitest.e2e.config.ts     # E2E Vitest include set
├── bin/                     # Packaged CLI entrypoints (.mjs)
├── src/
│   ├── config.ts            # Config parse / schema
│   ├── adapters/            # openclaw + standalone host adapters
│   ├── cli/                 # memory-tdai CLI (e.g. seed)
│   ├── core/
│   │   ├── tdai-core.ts     # Host-neutral facade
│   │   ├── conversation/    # L0 capture
│   │   ├── record/          # L1 extract / write / dedup
│   │   ├── scene/           # L2 scene blocks
│   │   ├── persona/         # L3 persona
│   │   ├── store/           # sqlite / tcvdb / embedding / BM25
│   │   ├── hooks/           # auto-capture / auto-recall
│   │   ├── prompts/         # LLM prompt templates
│   │   ├── tools/           # memory + conversation search
│   │   ├── seed/            # Historical seed path
│   │   └── report/          # Metrics / health reporting
│   ├── gateway/             # Standalone HTTP TdaiGateway
│   ├── offload/             # Context engine / compression
│   └── utils/               # Pipeline, cleaner, time, sanitize, …
├── hermes-plugin/           # Hermes memory_tencentdb provider (Python)
├── scripts/                 # ctl, install, patches, migrate/export sources
├── docker/opensource/       # Hermes Dockerfile + docs
├── CHANGELOG.md
├── CONTRIBUTING.md
└── LICENSE
:::

Useful scope tags for commits (from `CONTRIBUTING.md`): `store`, `hooks`, `persona`, `scene`, `record`, `conversation`, `gateway`, `hermes`. Additional practical scopes that match the tree: `offload`, `config`, `cli`, `adapters`.

## CI expectations

Workflow: `.github/workflows/pr-ci.yml`  
**Trigger:** `pull_request` → `main`  
**Concurrency:** `ci-${{ github.ref }}` with `cancel-in-progress: true`  
**Node:** `22` (`actions/setup-node@v4`)

| Job | Depends on | What it checks |
| --- | --- | --- |
| **Install** | — | Cache `node_modules` keyed by OS + `package.json` hash; on miss, `npm install --ignore-scripts` |
| **Pack** | Install | `npm pack --dry-run`, then `npm pack`; upload `*.tgz` artifact (7-day retention) |
| **Manifest** | — (independent) | `openclaw.plugin.json` exists, valid JSON, has string `id`; if `configSchema` present it must be an object; `package.json` `openclaw.extensions`, `openclaw.compat.pluginApi`, `openclaw.build.openclawVersion` required |
| **Size Guard** | Pack | Tarball size ≤ **2048 KB** |

Because `prepack` runs `npm run build`, `npm pack` in CI exercises the tsdown + script TypeScript builds. Failures common on PRs:

- Broken `openclaw.plugin.json` or missing `package.json` `openclaw.*` metadata
- Accidental large files bloating the tarball over 2 MB
- Build breakage under `prepack` / `tsdown` / script `tsc` projects

What CI does **not** currently enforce: unit coverage, e2e, Hermes pytest, lint/format gates, or DCO bot automation (DCO is still a merge policy in `CONTRIBUTING.md`).

## Pull request workflow

1. **Fork** and branch from `main` (default PR target).
2. **Change** in focused, atomic commits.
3. **Test** locally (`npm test`; Hermes tests if applicable).
4. **Docs** — update README / `CHANGELOG.md` when user-facing behavior changes (Keep a Changelog + SemVer in `CHANGELOG.md`).
5. **Open a PR** using `.github/PULL_REQUEST_TEMPLATE.md`: description, related issue, change type, self-test checklist.

### PR change types (template)

- Bug fix  
- New feature  
- Documentation update  
- Code optimization  

### Commit messages

```
<type>(<scope>): <short summary>

<optional body>

Closes #123
Signed-off-by: Your Name <your-email@example.com>
```

| Type | Meaning | Maps to PR checkbox |
| --- | --- | --- |
| `fix` | Bug fix | Bug fix |
| `feat` | New feature | New feature |
| `docs` | Documentation | Documentation update |
| `perf` | Performance | Code optimization |
| `refactor` | No behavior change | Code optimization |
| `test` | Tests | — |
| `chore` | Build / tooling / deps | — |

### Developer Certificate of Origin (DCO)

Every commit must include a valid `Signed-off-by` line (Developer Certificate of Origin). Commits without it will not be merged.

```bash
git commit -s -m "feat(store): add batch insert support"
```

## Code style

- Match existing TypeScript style in the tree.
- Prefer clear English identifiers.
- Comment **why** at non-obvious logic, not restatements of **what**.
- Import order: Node built-ins → third-party → internal modules.

## License

Contributions are accepted under the **MIT** license (`LICENSE`). Copyright notice: Tencent, 2026.

## Local self-check before PR

| Check | Command / action |
| --- | --- |
| Unit tests | `npm test` |
| Coverage (optional) | `npm run test:coverage` |
| Full package build | `npm run build` |
| Pack dry-run (mirrors CI) | `npm pack --dry-run` |
| Manifest sanity | Confirm `openclaw.plugin.json` `id` and `package.json` `openclaw` block still valid |
| Linked plugin smoke | `openclaw plugins install --link .`, restart gateway, exercise change |
| Hermes changes | Run pytest under `hermes-plugin/memory/memory_tencentdb/tests/` |
| DCO | `git commit -s` on each commit |
| Changelog | Update `[Unreleased]` / version notes when behavior ships |

## Next

<CardGroup>
  <Card title="Installation" href="/installation">
    Node/OpenClaw prerequisites, npm and plugin install, postinstall patch behavior.
  </Card>
  <Card title="Overview" href="/overview">
    Host surfaces (OpenClaw plugin, Hermes Gateway) and first routes through the system.
  </Card>
  <Card title="CLI reference" href="/cli-reference">
    Bin commands and memory-tdai namespace used while developing tooling changes.
  </Card>
  <Card title="Gateway lifecycle" href="/gateway-ops">
    memory-tencentdb-ctl start/stop/status for standalone and Hermes gateway work.
  </Card>
  <Card title="Plugin configuration reference" href="/plugin-config-reference">
    Full memory-tencentdb config schema when extending config or openclaw.plugin.json.
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    Source-backed failure modes useful when local link or gateway smoke checks fail.
  </Card>
</CardGroup>
