The Problem

Developers building AI‑augmented applications need a persistent “brain” that can store conversational context, retrieve relevant episodes, and trigger actions across many tools. Without a unified store, each app maintains its own silo, forcing developers to duplicate memory logic and lose coherence when users switch between services.

What This Does

core implements a memory agent that persists “episodes” in Neo4j, indexes them in a vector store, and exposes a React‑based UI for exploration and management. The main server lives under apps/webapp/ and is bootstrapped by the Vite config apps/webapp/vite.config.ts. UI components such as apps/webapp/app/components/conversation/*.tsx render chat streams, while apps/webapp/app/components/graph/*.tsx visualise topic graphs. Integration adapters (e.g., integrations/github/, integrations/discord/) provide plug‑ins that push and pull episode data via the core services.

Key files:

  • apps/webapp/app/bullmq/queues/index.ts – registers background queues.
  • apps/webapp/app/bullmq/workers/index.ts – starts workers that ingest new messages.
  • apps/webapp/app/services/logger.service.ts – centralised logging used by most modules.
  • packages/providers/src/graph/neo4j/index.ts – thin wrapper around Neo4j driver used by the ingestion pipeline.

How It Is Wired

Execution starts when Vite launches the server defined in apps/webapp/app/entry.server.tsx. The server imports apps/webapp/app/bullmq/start-workers.ts, which in turn loads the queue definitions from apps/webapp/app/bullmq/queues/index.ts. Each queue enqueues a job that eventually reaches a worker defined in apps/webapp/app/bullmq/workers/index.ts.

A typical ingestion flow:

  1. API endpoint (apps/webapp/app/components/api/index.ts) receives a POST with a new message.
  2. It calls apps/webapp/app/trigger/ingest/ingest.ts (part of an import cycle; see health section).
  3. ingest.ts creates a BullMQ job via apps/webapp/app/bullmq/connection.ts.
  4. The worker (apps/webapp/app/bullmq/workers/index.ts) processes the job, invoking apps/webapp/app/lib/utils.ts for payload normalization and then packages/providers/src/graph/neo4j/core.ts to persist the episode.
  5. After storage, the worker pushes the episode’s embedding to the vector store (code located in packages/providers/src/vector-store/).

Blast‑radius hubs – modules with the highest inbound imports:

Hub moduleCa (importers)Ce (imports)Instability
apps/webapp/app/components/ui/index.ts2560.19
apps/webapp/app/lib/utils.ts2500
apps/webapp/app/components/icons/types.tsx2200

These files are touched by many downstream components; any change here will affect dozens of UI paths.

Circular imports – 11 modules participate in cycles; e.g., packages/emails/src/transports/index.ts ↔ apps/webapp/app/trigger/utils/queue.ts. Such cycles increase cognitive load and risk of runtime errors when refactoring.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/core
cd core

# Install dependencies (pnpm is the declared package manager)
pnpm install

# Copy example env and fill secrets
cp .env.example .env
# Edit .env (or hosting/docker/.env) with:
#   NEO4J_PASSWORD, POSTHOG_PROJECT_KEY, MAGIC_LINK_SECRET, etc.

# Run locally (Vite dev server)
pnpm dev   # starts the webapp on http://localhost:5173

# Or build and run the Docker image
docker build -t core .
docker run -p 3000:3000 --env-file .env core

The UI is reachable at the server’s root. API calls are routed through apps/webapp/app/components/api/ and background processing is handled by the BullMQ workers started automatically on server start.

Real‑World Use

A SaaS product that offers AI‑assisted customer support can embed the Core SDK (found under packages/providers/) in its backend. When a support ticket arrives, the service posts the ticket text to Core’s /api/v1/ingest endpoint. Core stores the episode in Neo4j, creates an embedding, and makes it searchable for future tickets. The product’s UI then uses apps/webapp/app/components/graph/graph-client.tsx to display related past tickets, enabling agents to surface prior resolutions instantly.

Code Health & Issues

Measured findings (static analysis)

  • HIGH/clarity – Hub modules (e.g., apps/webapp/app/components/ui/index.ts) have 25+ dependents; keep them stable.
  • HIGH/soundness – 11 import cycles (e.g., packages/emails/src/transports/index.ts). Break cycles by extracting shared types.
  • HIGH/cognitive_load – Deep nesting (max depth 6) in several components; refactor with early returns.
  • HIGH/cognitive_load – Oversized files (> 1 k lines) such as apps/webapp/app/components/onboarding/provider-config.tsx. Split by responsibility.
  • HIGH/clarity – Repeated 6‑line blocks across > 200 files; extract helpers.
  • MEDIUM/resilience – Empty catch {} blocks in two files; add logging or rethrow.
  • MEDIUM/cognitive_load – High branching density in three utility files; consider strategy tables.

Code‑health audit (severity‑ranked)

  • CRITICAL – Committed credentials in hosting/docker/.env (MAGIC_LINK_SECRET, NEO4J_PASSWORD, POSTHOG_PROJECT_KEY). Rotate and remove from repo.
  • HIGH – .env is tracked despite .gitignore; git rm --cached hosting/docker/.env and rotate keys.
  • HIGH – GitHub Actions use tag references; pin each action to a SHA.
  • HIGH – No test suite; add tests for each public entry point and run them in CI.
  • HIGH – Wildcard CORS ("*" in apps/webapp/server.ts); replace with explicit origins.
  • MEDIUM – GITHUB_TOKEN permissions not declared; add least‑privilege scopes.
  • MEDIUM – Dependabot not configured; add .github/dependabot.yml.
  • MEDIUM – No dependency‑vulnerability gate; add dependency-review-action or osv-scanner.
  • MEDIUM – No pre‑commit secret scan; install a hook (e.g., detect-secrets).

The Bottom Line

core provides a full‑stack memory‑agent with a React UI, Neo4j backing, and extensible integration points, making it a solid foundation for AI‑driven apps. However, the repository currently ships live credentials, lacks automated tests, and contains several high‑impact architectural smells (hub modules, import cycles). Addressing the health issues and adding a test suite should be priority steps before adopting it in production.