Two files, one repository
groupultra/telegram-search ships 3 formats across 13 indexed files. The question worth asking is whether the second one says anything the first does not.
| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 12 | 6 | 0% |
| Commands | 0 | 19 | 13 | 0% |
| Section tags | 3 | 11 | 0 | 21% |
What each file covers
Sections
0 shared · 12 only in A · 6 only in B- − Project Coded Agent Guide
- − Tech Stack (by surface)
- − Structure & Responsibilities
- − Key Path Index (what lives where)
- − Commands (pnpm with filters)
- − Dependency Management Rule
- − Styling & Conventions
- − Testing Practices
- − TypeScript / Tooling
- − Refactoring & Comments
- − PR / Workflow Tips
- − Docker + SQL Conventions
- + Copilot Instructions for telegram-search
- + Architecture essentials
- + Dev workflows
- + Conventions and patterns
- + Where to look for examples
- + Gotchas and edge cases
Commands
0 shared · 19 only in A · 13 only in B- − eslint.config.ts
- − pnpm-workspace.yaml
- − docker/
- − pnpm -F @tg-search/server dev
- − pnpm run web:dev
- − pnpm run server:dev
- − pnpm run start
- − pnpm run build
- − pnpm run server:build
- − pnpm run test:run
- − pnpm run test:coverage
- − pnpm run lint
- − pnpm run lint:fix
- − pnpm run typecheck
- − pnpm run db:generate
- − pnpm install
- − pnpm install -F <target> <dependency>
- − vitest
- − docker-compose.yml
- + pnpm dev
- + pnpm server:dev
- + pnpm web:dev
- + docker compose up -d pgvector
- + pnpm build
- + pnpm web:build
- + pnpm server:build
- + pnpm packages:build
- + pnpm typecheck
- + pnpm test
- + pnpm lint
- + pnpm lint:fix
- + pnpm db:generate
Section tags
3 shared · 11 only in A · 0 only in B- − setup
- − build
- − lint-format
- − architecture
- − types
- − testing-strategy
- − git-pr
- − database
- − ui
- − monorepo
- − docs
- test
- code-style
- agent-behaviour
Line diff
groupultra/telegram-search · AGENTS.md
@@ −1 @@
1# Project Coded Agent Guide
2
3Concise but detailed reference for contributors working in the `groupultra/telegram-search` monorepo. Improve code when you touch it; avoid one-off patterns.
4
5## Tech Stack (by surface)
6
7- **Server (`apps/server`)**: Node.js, TypeScript, Drizzle ORM, Postgres/pgvector, WebSocket + REST, dotenvx.
8- **Web (`apps/web`)**: Vue 3 + Vite, Pinia.
9- **Core/shared (`packages/*`)**: common types, client SDK, schema, core services, bot.
10- **Tooling**: pnpm workspaces, Vitest, ESLint, TypeScript 5.9, tsdown, Drizzle Kit.
11
12## Structure & Responsibilities
13
14- **Apps**
15 - `apps/server`: backend service (runtime entry in `apps/server/src/`).
16 - `apps/web`: web UI (source in `apps/web/src/`).
17- **Packages**
18 - `packages/`: shared libraries and domain logic used by apps.
19- **Root tooling**
20 - Linting: `eslint.config.ts`.
21 - DB tooling: `drizzle/`, `drizzle.config.ts`.
22 - Workspace: `pnpm-workspace.yaml`.
23
24## Key Path Index (what lives where)
25
26- `apps/server/src`: API, WebSocket, and session services.
27- `apps/web/src`: Vue UI and client-side logic.
28- `packages/core`: core domain/services.
29- `packages/schema`: shared types + DB schema.
30- `packages/client`: client SDKs for integration.
31- `docker/`: compose files + init scripts for local/dev.
32- `.env.example`: baseline env config.
33
34## Commands (pnpm with filters)
35
36> Use pnpm workspace filters to scope tasks, e.g. `pnpm -F @tg-search/server dev`.
37
38- **Dev (web only)**: `pnpm run web:dev`
39- **Dev (server only)**: `pnpm run server:dev`
40- **Dev (web + server)**: `pnpm run start`
41- **Build web**: `pnpm run build`
42- **Build server**: `pnpm run server:build`
43- **Run tests**: `pnpm run test:run`
44- **Coverage**: `pnpm run test:coverage`
45- **Lint**: `pnpm run lint` / `pnpm run lint:fix`
46- **Typecheck**: `pnpm run typecheck`
47- **DB generate**: `pnpm run db:generate`
48
49## Dependency Management Rule
50
51- Do not edit `package.json` directly to add/remove deps. Use `pnpm install` so lockfile and manifest stay in sync.
52- For workspace deps: `pnpm install -F <target> <dependency>` (add `-D` for dev deps).
53- Tooling like `typescript`, `vite`, `vitest`, `tsdown`, `@types/node` belongs at the workspace root (`-w`).
54
55## Styling & Conventions
56
57- Favor clear module boundaries; shared logic goes in `packages/`.
58- Keep runtime entrypoints lean; move heavy logic into services/modules.
59- Prefer functional patterns for testability; use DI where helpful. Avoid classes unless required by APIs.
60- Use Valibot for schema validation; keep schemas close to their consumers.
61- Use Eventa (`@moeru/eventa`) for structured IPC/RPC contracts where needed.
62- File names: `kebab-case`.
63- Do not add backward-compatibility guards. If extended support is required, write refactor docs and complete the change in a separate, well-scoped effort.
64- If the refactor scope is small, do a progressive refactor step by step.
65- When modifying code, look for small, safe refactors to reduce duplication or improve clarity.
66- If you need a workaround, add a `// NOTICE:` comment explaining why, the root cause, and any relevant context.
67
68## Testing Practices
69
70- Use Vitest for unit/integration tests.
71- Mock external services and Postgres where practical; keep tests deterministic.
72- When fixing a bug, add a Vitest test that documents the previous failure mode and include a short `//` comment about the cause.
73- For DB interactions, prefer migration-driven integration tests with env guards.
74
75## TypeScript / Tooling
76
77- Stay strict with types; avoid `any` unless absolutely necessary.
78- Prefer small, composable modules; keep exports minimal and intentional.
79
80## Refactoring & Comments
81
82- Prefer progressive, incremental refactors that keep behavior stable.
83- Keep existing comments with the code when moving/refactoring. If a comment becomes obsolete, replace it with a brief note about why it was removed.
84- Use markers consistently: `// TODO:`, `// REVIEW:`, `// NOTICE:`.
85- Add concise comments for complex logic, algorithms, OS-interaction, and shared utilities. Avoid obvious comments.
86
87## PR / Workflow Tips
88
89- Keep changes scoped; use workspace filters for commands.
90- Summarize changes, how tested (commands), and follow-ups.
91- Improve legacy when you touch it; avoid one-off patterns.
92- Maintain structured `README.md` documentation for each `packages/` and `apps/` entry.
93- Always run `pnpm run typecheck` and `pnpm run lint:fix` after finishing a task.
94- Use Conventional Commits (e.g., `feat(server): add session refresh`).
95
96## Docker + SQL Conventions
97
98- Use `docker-compose.yml` as the compose filename.
99- Do not write SQL migration files manually. Always use `drizzle-kit generate` to create migrations, which will be placed in `**/sql/` with descriptive, kebab-case names.
100- Avoid Postgres enums to keep migrations and imports flexible.
101
groupultra/telegram-search · .github/copilot-instructions.md
@@ +1 @@
1# Copilot Instructions for telegram-search
2
3This repo is a pnpm-powered monorepo for a Telegram search/export app. It uses an event-driven core with WebSocket bridging, Vue 3 frontend, and Drizzle ORM for storage (PostgreSQL + pgvector or in-browser PGlite).
4
5## Architecture essentials
6- Monorepo layout:
7 - `apps/web`: Vue 3 app (Pinia, TanStack Query). Can run standalone with `VITE_WITH_CORE=true` (browser-only mode with PGlite).
8 - `apps/server`: WebSocket server (h3) that hosts the Core for server mode.
9 - `packages/core`: Event-driven Core (EventEmitter3), services, DB models and resolvers.
10 - `packages/client`: Browser-side bridge + client event handlers and stores.
11 - `packages/common`: Shared config, logger wrapper, utils.
12- Core event bus: `packages/core/src/context.ts` creates `CoreContext` around EventEmitter3. All cross-layer comms use events:
13 - To Core (requests): `auth:*`, `message:*`, `dialog:*`, `entity:*`, `storage:*`, `takeout:*`, etc.
14 - From Core (results): e.g. `auth:connected`, `message:data`, `dialog:data`, `storage:search:messages:data`.
15 - Event types and contracts live in `packages/core/src/types/events.ts`. Follow `<domain>:<action>` naming.
16- Event handlers and services:
17 - Handlers: `packages/core/src/event-handlers/*.ts` map bus events to services.
18 - Services: `packages/core/src/services/*.ts` implement business logic and emit results.
19 - Message pipeline resolvers in `packages/core/src/message-resolvers/*` (embedding, jieba, link, media, user) operate independently and stream results.
20- Client bridge:
21 - `packages/client/src/adapters/core-bridge.ts` initializes config/logger, creates Core in browser mode, registers handlers, and forwards events between UI and Core (or WebSocket server).
22 - For server mode, the browser uses a WebSocket adapter; the server routes events to a per-connection Core instance.
23- Database:
24 - Drizzle ORM schemas/models under `packages/core/src/{schemas,models}`; migrations in `drizzle/`.
25 - Two modes: PostgreSQL+pgvector (server) and PGlite (browser). Code paths must support both.
26
27## Dev workflows
28- Node 24+ and pnpm required. Root scripts:
29 - Browser-only: `pnpm dev` (equivalent to `VITE_WITH_CORE=true pnpm -F @tg-search/web dev`).
30 - Server mode: `pnpm server:dev` and `pnpm web:dev` (two terminals). DB via `docker compose up -d pgvector`.
31 - Builds: `pnpm build`, `pnpm web:build`, `pnpm server:build`, `pnpm packages:build`.
32 - Types/tests/lint: `pnpm typecheck` (builds packages first), `pnpm test` (Vitest), `pnpm lint` / `pnpm lint:fix`.
33 - DB tools: `pnpm db:generate` (drizzle-kit).
34- Config:
35 - Browser mode uses `.env` (`VITE_TELEGRAM_API_ID`, `VITE_TELEGRAM_API_HASH`).
36 - Server mode uses environment variables (database, Telegram API, optional proxy) loaded via `.env` / `.env.local` and dotenvx. See `docs/ENVIRONMENT.md`.
37
38## Conventions and patterns
39- Events are the API. Don’t call services directly across layers; emit on `ctx.emitter` and listen for results. Use types from `packages/core/src/types/events.ts`.
40- Naming:
41 - Event names: `<domain>:<action>` (e.g. `message:fetch`, `storage:search:messages`). Avoid timestamps for ordering—prefer Telegram message IDs.
42 - Files: kebab-case; components: PascalCase; constants: UPPER_SNAKE_CASE.
43- Logging & errors:
44 - Use `@guiiai/logg` (`useLogger()`). Include `withFields` context and `withError` on failures.
45 - Use `ctx.withError(err, description)` to emit `core:error` and log uniformly. In dev, `CoreContext` tracks listener counts and warns on potential leaks; emit `core:cleanup` when tearing down a context.
46- Session isolation:
47 - Each browser tab/WS connection has its own `CoreContext` and event subscriptions. Avoid global singletons in core logic.
48- Storage/search specifics:
49 - Vector search via embeddings (OpenAI/Ollama). Resolvers live under `packages/core/src/message-resolvers/embedding-resolver.ts` etc.
50 - Storage/search events: `storage:search:messages` -> emits `storage:search:messages:data` with ranked results.
51
52## Where to look for examples
53- Event contracts: `packages/core/src/types/events.ts` (e.g., `MessageEventToCore`, `StorageEventFromCore`).
54- Handler -> service pattern: `packages/core/src/event-handlers/message.ts` and `packages/core/src/services/message.ts`.
55- Client event bridging: `packages/client/src/adapters/core-bridge.ts`.
56- DB schema and migrations: `packages/core/src/schemas/*`, `drizzle/*`.
57
58## Gotchas and edge cases
59- Message ordering: always use Telegram Message ID over timestamps.
60- Dual DB mode: ensure code paths work for both Postgres and PGlite; avoid vendor-specific SQL in core logic.
61- Avoid memory leaks: unsubscribe listeners on cleanup and prefer one-time listeners when appropriate.
62
@@ −1 +1 @@
1−# Project Coded Agent Guide
1+# Copilot Instructions for telegram-search
22
3−Concise but detailed reference for contributors working in the `groupultra/telegram-search` monorepo. Improve code when you touch it; avoid one-off patterns.
3+This repo is a pnpm-powered monorepo for a Telegram search/export app. It uses an event-driven core with WebSocket bridging, Vue 3 frontend, and Drizzle ORM for storage (PostgreSQL + pgvector or in-browser PGlite).
44
5−## Tech Stack (by surface)
5+## Architecture essentials
6+- Monorepo layout:
7+ - `apps/web`: Vue 3 app (Pinia, TanStack Query). Can run standalone with `VITE_WITH_CORE=true` (browser-only mode with PGlite).
8+ - `apps/server`: WebSocket server (h3) that hosts the Core for server mode.
9+ - `packages/core`: Event-driven Core (EventEmitter3), services, DB models and resolvers.
10+ - `packages/client`: Browser-side bridge + client event handlers and stores.
11+ - `packages/common`: Shared config, logger wrapper, utils.
12+- Core event bus: `packages/core/src/context.ts` creates `CoreContext` around EventEmitter3. All cross-layer comms use events:
13+ - To Core (requests): `auth:*`, `message:*`, `dialog:*`, `entity:*`, `storage:*`, `takeout:*`, etc.
14+ - From Core (results): e.g. `auth:connected`, `message:data`, `dialog:data`, `storage:search:messages:data`.
15+ - Event types and contracts live in `packages/core/src/types/events.ts`. Follow `<domain>:<action>` naming.
16+- Event handlers and services:
17+ - Handlers: `packages/core/src/event-handlers/*.ts` map bus events to services.
18+ - Services: `packages/core/src/services/*.ts` implement business logic and emit results.
19+ - Message pipeline resolvers in `packages/core/src/message-resolvers/*` (embedding, jieba, link, media, user) operate independently and stream results.
20+- Client bridge:
21+ - `packages/client/src/adapters/core-bridge.ts` initializes config/logger, creates Core in browser mode, registers handlers, and forwards events between UI and Core (or WebSocket server).
22+ - For server mode, the browser uses a WebSocket adapter; the server routes events to a per-connection Core instance.
23+- Database:
24+ - Drizzle ORM schemas/models under `packages/core/src/{schemas,models}`; migrations in `drizzle/`.
25+ - Two modes: PostgreSQL+pgvector (server) and PGlite (browser). Code paths must support both.
626
7−- **Server (`apps/server`)**: Node.js, TypeScript, Drizzle ORM, Postgres/pgvector, WebSocket + REST, dotenvx.
8−- **Web (`apps/web`)**: Vue 3 + Vite, Pinia.
9−- **Core/shared (`packages/*`)**: common types, client SDK, schema, core services, bot.
10−- **Tooling**: pnpm workspaces, Vitest, ESLint, TypeScript 5.9, tsdown, Drizzle Kit.
27+## Dev workflows
28+- Node 24+ and pnpm required. Root scripts:
29+ - Browser-only: `pnpm dev` (equivalent to `VITE_WITH_CORE=true pnpm -F @tg-search/web dev`).
30+ - Server mode: `pnpm server:dev` and `pnpm web:dev` (two terminals). DB via `docker compose up -d pgvector`.
31+ - Builds: `pnpm build`, `pnpm web:build`, `pnpm server:build`, `pnpm packages:build`.
32+ - Types/tests/lint: `pnpm typecheck` (builds packages first), `pnpm test` (Vitest), `pnpm lint` / `pnpm lint:fix`.
33+ - DB tools: `pnpm db:generate` (drizzle-kit).
34+- Config:
35+ - Browser mode uses `.env` (`VITE_TELEGRAM_API_ID`, `VITE_TELEGRAM_API_HASH`).
36+ - Server mode uses environment variables (database, Telegram API, optional proxy) loaded via `.env` / `.env.local` and dotenvx. See `docs/ENVIRONMENT.md`.
1137
12−## Structure & Responsibilities
38+## Conventions and patterns
39+- Events are the API. Don’t call services directly across layers; emit on `ctx.emitter` and listen for results. Use types from `packages/core/src/types/events.ts`.
40+- Naming:
41+ - Event names: `<domain>:<action>` (e.g. `message:fetch`, `storage:search:messages`). Avoid timestamps for ordering—prefer Telegram message IDs.
42+ - Files: kebab-case; components: PascalCase; constants: UPPER_SNAKE_CASE.
43+- Logging & errors:
44+ - Use `@guiiai/logg` (`useLogger()`). Include `withFields` context and `withError` on failures.
45+ - Use `ctx.withError(err, description)` to emit `core:error` and log uniformly. In dev, `CoreContext` tracks listener counts and warns on potential leaks; emit `core:cleanup` when tearing down a context.
46+- Session isolation:
47+ - Each browser tab/WS connection has its own `CoreContext` and event subscriptions. Avoid global singletons in core logic.
48+- Storage/search specifics:
49+ - Vector search via embeddings (OpenAI/Ollama). Resolvers live under `packages/core/src/message-resolvers/embedding-resolver.ts` etc.
50+ - Storage/search events: `storage:search:messages` -> emits `storage:search:messages:data` with ranked results.
1351
14−- **Apps**
15− - `apps/server`: backend service (runtime entry in `apps/server/src/`).
16− - `apps/web`: web UI (source in `apps/web/src/`).
17−- **Packages**
18− - `packages/`: shared libraries and domain logic used by apps.
19−- **Root tooling**
20− - Linting: `eslint.config.ts`.
21− - DB tooling: `drizzle/`, `drizzle.config.ts`.
22− - Workspace: `pnpm-workspace.yaml`.
52+## Where to look for examples
53+- Event contracts: `packages/core/src/types/events.ts` (e.g., `MessageEventToCore`, `StorageEventFromCore`).
54+- Handler -> service pattern: `packages/core/src/event-handlers/message.ts` and `packages/core/src/services/message.ts`.
55+- Client event bridging: `packages/client/src/adapters/core-bridge.ts`.
56+- DB schema and migrations: `packages/core/src/schemas/*`, `drizzle/*`.
2357
24−## Key Path Index (what lives where)
25−
26−- `apps/server/src`: API, WebSocket, and session services.
27−- `apps/web/src`: Vue UI and client-side logic.
28−- `packages/core`: core domain/services.
29−- `packages/schema`: shared types + DB schema.
30−- `packages/client`: client SDKs for integration.
31−- `docker/`: compose files + init scripts for local/dev.
32−- `.env.example`: baseline env config.
33−
34−## Commands (pnpm with filters)
35−
36−> Use pnpm workspace filters to scope tasks, e.g. `pnpm -F @tg-search/server dev`.
37−
38−- **Dev (web only)**: `pnpm run web:dev`
39−- **Dev (server only)**: `pnpm run server:dev`
40−- **Dev (web + server)**: `pnpm run start`
41−- **Build web**: `pnpm run build`
42−- **Build server**: `pnpm run server:build`
43−- **Run tests**: `pnpm run test:run`
44−- **Coverage**: `pnpm run test:coverage`
45−- **Lint**: `pnpm run lint` / `pnpm run lint:fix`
46−- **Typecheck**: `pnpm run typecheck`
47−- **DB generate**: `pnpm run db:generate`
48−
49−## Dependency Management Rule
50−
51−- Do not edit `package.json` directly to add/remove deps. Use `pnpm install` so lockfile and manifest stay in sync.
52−- For workspace deps: `pnpm install -F <target> <dependency>` (add `-D` for dev deps).
53−- Tooling like `typescript`, `vite`, `vitest`, `tsdown`, `@types/node` belongs at the workspace root (`-w`).
54−
55−## Styling & Conventions
56−
57−- Favor clear module boundaries; shared logic goes in `packages/`.
58−- Keep runtime entrypoints lean; move heavy logic into services/modules.
59−- Prefer functional patterns for testability; use DI where helpful. Avoid classes unless required by APIs.
60−- Use Valibot for schema validation; keep schemas close to their consumers.
61−- Use Eventa (`@moeru/eventa`) for structured IPC/RPC contracts where needed.
62−- File names: `kebab-case`.
63−- Do not add backward-compatibility guards. If extended support is required, write refactor docs and complete the change in a separate, well-scoped effort.
64−- If the refactor scope is small, do a progressive refactor step by step.
65−- When modifying code, look for small, safe refactors to reduce duplication or improve clarity.
66−- If you need a workaround, add a `// NOTICE:` comment explaining why, the root cause, and any relevant context.
67−
68−## Testing Practices
69−
70−- Use Vitest for unit/integration tests.
71−- Mock external services and Postgres where practical; keep tests deterministic.
72−- When fixing a bug, add a Vitest test that documents the previous failure mode and include a short `//` comment about the cause.
73−- For DB interactions, prefer migration-driven integration tests with env guards.
74−
75−## TypeScript / Tooling
76−
77−- Stay strict with types; avoid `any` unless absolutely necessary.
78−- Prefer small, composable modules; keep exports minimal and intentional.
79−
80−## Refactoring & Comments
81−
82−- Prefer progressive, incremental refactors that keep behavior stable.
83−- Keep existing comments with the code when moving/refactoring. If a comment becomes obsolete, replace it with a brief note about why it was removed.
84−- Use markers consistently: `// TODO:`, `// REVIEW:`, `// NOTICE:`.
85−- Add concise comments for complex logic, algorithms, OS-interaction, and shared utilities. Avoid obvious comments.
86−
87−## PR / Workflow Tips
88−
89−- Keep changes scoped; use workspace filters for commands.
90−- Summarize changes, how tested (commands), and follow-ups.
91−- Improve legacy when you touch it; avoid one-off patterns.
92−- Maintain structured `README.md` documentation for each `packages/` and `apps/` entry.
93−- Always run `pnpm run typecheck` and `pnpm run lint:fix` after finishing a task.
94−- Use Conventional Commits (e.g., `feat(server): add session refresh`).
95−
96−## Docker + SQL Conventions
97−
98−- Use `docker-compose.yml` as the compose filename.
99−- Do not write SQL migration files manually. Always use `drizzle-kit generate` to create migrations, which will be placed in `**/sql/` with descriptive, kebab-case names.
100−- Avoid Postgres enums to keep migrations and imports flexible.
58+## Gotchas and edge cases
59+- Message ordering: always use Telegram Message ID over timestamps.
60+- Dual DB mode: ensure code paths work for both Postgres and PGlite; avoid vendor-specific SQL in core logic.
61+- Avoid memory leaks: unsubscribe listeners on cleanup and prefer one-time listeners when appropriate.
10162
