Implement index.ts async factory + lifecycle with tests #143

Closed
opened 2026-08-31 22:06:07 +00:00 by david · 1 comment
Owner

Summary

Implement extensions/mongodb/index.ts — the extension entry point pi loads: resolve the env, create a lazy MongoClient, register the three tools, log a confirmation line, and close the client on session_shutdown. Tests cover configured and unconfigured behavior.

Background

Depends on: #136, #139, #140, #141, #142

This is the file referenced by "pi": { "extensions": ["./index.ts"] } in the package manifest and by the repo root pi.extensions array. It mirrors the structure of extensions/postgres/index.ts (factory pattern, registerDbTools-style exported registration for tests). Key behaviors: if no MONGODB_URI is configured, the extension registers zero tools and stays silent (absence of the mongo_* tools is the signal — no warning log); when configured, the client is created lazily (the driver opens no socket until the first operation, so pi startup never depends on the database being reachable).

Documentation Required

A separate process downloads these into the listed folders before this issue is implemented. Check the folders for the actual reference material before starting.

docs/reference/mongodb-driver/ — for MongoClient:

docs/reference/pi-coding-agent/ — for the pi runtime extension API used here:

  • /home/david/.bun/install/global/node_modules/@earendil-works/pi-coding-agent/README.md — pi main documentation (installed package docs on this machine).
  • /home/david/.bun/install/global/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md — extension authoring: pi.registerTool, the session_shutdown lifecycle event, extension factory conventions.

In-repo reference implementations: extensions/postgres/index.ts and extensions/victorialogs/index.ts (same factory/lifecycle pattern).

Implementation Details

index.ts (async factory, mirroring postgres):

  1. const envVars = loadEnvFile(); const uri = extractMongoUri(envVars);
  2. If uri is null → return early; register zero tools; no log output. (Silent by design.)
  3. If configured: const client = new MongoClient(uri)do NOT call connect() (lazy).
  4. Parse the URI with new URL(uri) for the confirmation log: host, port (default 27017 when absent), and db (pathname without the leading /; may be empty). For mongodb+srv:// use the SRV hostname. Log via console.log (deliberately, not ctx.ui.notify — matching postgres, it appears in pi's startup output and in non-TUI modes):
    MongoDB extension loaded: connected to <host>:<port>/<db>
  5. Register the three tools (mongo_find, mongo_count, mongo_list_collections from src/tools/) via pi.registerTool(...).
  6. pi.on("session_shutdown", async () => { await client.close(); }) — idempotent cleanup.
  7. Export registerMongoTools(pi, client) (accepts a MongoClient-like object) so tests can exercise tool execution against a fake client — the same pattern as postgres's registerDbTools(pi, pool).

Tests (co-located index.test.ts):

  • Unconfigured (empty env record; missing .env; absent key) → zero tools registered.
  • Configured → the three tools registered + confirmation console.log emitted (spy on console.log and assert the connected to <host>:<port>/<db> shape; cover a URI with an explicit port, a URI without one → 27017, and mongodb+srv://).
  • session_shutdown invokes client.close() on a fake client.
  • tsc --noEmit clean.

Acceptance Criteria

  • Unconfigured (missing .env / absent / empty key) → extension returns early, registers zero tools, no log output.
  • Configured → all three tools registered and confirmation line MongoDB extension loaded: connected to <host>:<port>/<db> logged (port defaults to 27017; mongodb+srv:// uses the SRV hostname).
  • Client is created lazily — no connect() call at load time.
  • session_shutdown calls client.close() on the client.
  • registerMongoTools(pi, client) is exported and works against a fake client.
  • bun test in extensions/mongodb/ is green; tsc --noEmit is clean.

Test Plan

cd extensions/mongodb
bun test             # index tests green
bunx tsc --noEmit    # clean
## Summary Implement `extensions/mongodb/index.ts` — the extension entry point pi loads: resolve the env, create a lazy `MongoClient`, register the three tools, log a confirmation line, and close the client on `session_shutdown`. Tests cover configured and unconfigured behavior. ## Background **Depends on:** #136, #139, #140, #141, #142 This is the file referenced by `"pi": { "extensions": ["./index.ts"] }` in the package manifest and by the repo root `pi.extensions` array. It mirrors the structure of `extensions/postgres/index.ts` (factory pattern, `registerDbTools`-style exported registration for tests). Key behaviors: if no `MONGODB_URI` is configured, the extension registers **zero** tools and stays silent (absence of the `mongo_*` tools is the signal — no warning log); when configured, the client is created **lazily** (the driver opens no socket until the first operation, so pi startup never depends on the database being reachable). ## Documentation Required A separate process downloads these into the listed folders before this issue is implemented. Check the folders for the actual reference material before starting. **`docs/reference/mongodb-driver/`** — for `MongoClient`: - https://mongodb.github.io/node-mongodb-native/7.6/classes/MongoClient.html — API reference: `new MongoClient(uri, options?)` (lazy — connects on first operation), `client.db(name)` → `Db`, `await client.close()` (idempotent resource cleanup). - https://www.mongodb.com/docs/drivers/node/current/connect/ — connection guide: connection strings incl. `mongodb+srv://` (SRV) and TLS options. - https://mongodb.github.io/node-mongodb-native/7.6/ — TypeDoc API reference index. **`docs/reference/pi-coding-agent/`** — for the pi runtime extension API used here: - `/home/david/.bun/install/global/node_modules/@earendil-works/pi-coding-agent/README.md` — pi main documentation (installed package docs on this machine). - `/home/david/.bun/install/global/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md` — extension authoring: `pi.registerTool`, the `session_shutdown` lifecycle event, extension factory conventions. In-repo reference implementations: `extensions/postgres/index.ts` and `extensions/victorialogs/index.ts` (same factory/lifecycle pattern). ## Implementation Details `index.ts` (async factory, mirroring postgres): 1. `const envVars = loadEnvFile(); const uri = extractMongoUri(envVars);` 2. **If `uri` is `null`** → return early; register **zero** tools; no log output. (Silent by design.) 3. If configured: `const client = new MongoClient(uri)` — **do NOT call `connect()`** (lazy). 4. Parse the URI with `new URL(uri)` for the confirmation log: host, port (default `27017` when absent), and db (pathname without the leading `/`; may be empty). For `mongodb+srv://` use the SRV hostname. Log via `console.log` (deliberately, not `ctx.ui.notify` — matching postgres, it appears in pi's startup output and in non-TUI modes): `MongoDB extension loaded: connected to <host>:<port>/<db>` 5. Register the three tools (`mongo_find`, `mongo_count`, `mongo_list_collections` from `src/tools/`) via `pi.registerTool(...)`. 6. `pi.on("session_shutdown", async () => { await client.close(); })` — idempotent cleanup. 7. Export `registerMongoTools(pi, client)` (accepts a MongoClient-like object) so tests can exercise tool execution against a fake client — the same pattern as postgres's `registerDbTools(pi, pool)`. Tests (co-located `index.test.ts`): - Unconfigured (empty env record; missing `.env`; absent key) → **zero** tools registered. - Configured → the three tools registered + confirmation `console.log` emitted (spy on `console.log` and assert the `connected to <host>:<port>/<db>` shape; cover a URI with an explicit port, a URI without one → 27017, and `mongodb+srv://`). - `session_shutdown` invokes `client.close()` on a fake client. - `tsc --noEmit` clean. ## Acceptance Criteria - [ ] Unconfigured (missing `.env` / absent / empty key) → extension returns early, registers zero tools, no log output. - [ ] Configured → all three tools registered and confirmation line `MongoDB extension loaded: connected to <host>:<port>/<db>` logged (port defaults to 27017; `mongodb+srv://` uses the SRV hostname). - [ ] Client is created lazily — no `connect()` call at load time. - [ ] `session_shutdown` calls `client.close()` on the client. - [ ] `registerMongoTools(pi, client)` is exported and works against a fake client. - [ ] `bun test` in `extensions/mongodb/` is green; `tsc --noEmit` is clean. ## Test Plan ```bash cd extensions/mongodb bun test # index tests green bunx tsc --noEmit # clean ```
david closed this issue 2026-09-01 00:40:16 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #160

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/160
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-extensions-and-skills#143
No description provided.