- Replace stale DD references (DD3, DD6, DD9, DD10) with proper ADR links - Fix 'Open Question 1' → OQ-01/OQ-03 cross-references - Rewrite metagraph-module.md 'Why TypeBox Modules' to describe capabilities directly instead of framing as SchemaBuilder replacement - Remove 'Transition from SchemaBuilder' section, replace with Source Structure - Clean up implementation path: strikethrough phases → status table - Fix data model diagram: remove non-existent nodeTypeId, fix EdgeType label - Align EdgeConstraints examples with actual code (add default values) - Clarify validateNode/validateEdge error behavior in docs - Align EncryptedDataSchema code example with actual implementation - Fix overview.md: correct dependency table, update current state, fix TypeBox URL - Fix forward-look.md garbled text about dbtype element migration - Fix open-questions.md: correct OQ count (4→7 open), add summary table - Update doc statuses: schema-evolution, encrypted-data, open-questions → reviewed - Update AGENTS.md to reflect current implementation state
6.1 KiB
6.1 KiB
AGENTS.md — @alkdev/storage
Project-specific guidance for agents working on this package.
Project Overview
@alkdev/storage is a deno-first TypeScript package providing typed graph
storage with dual database hosts (SQLite for spokes, PostgreSQL for the hub). It
uses the metagraph pattern (graphTypes → nodeTypes → edgeTypes → typed graph
instances) from the earlier @ade prototype.
Architecture Snapshot
@alkdev/storage/
├── mod.ts # Re-exports graphs/ only (zero db deps)
├── deno.json # JSR config, imports, tasks, lint rules
├── src/
│ ├── graphs/ # Metagraph Module + bridge functions (no db deps)
│ │ ├── modules/ # TypeBox Module definitions
│ │ │ ├── metagraph.ts # Base Metagraph Module (Config, BaseNode, BaseEdge)
│ │ │ ├── call-graph.ts # CallGraph reference Module
│ │ │ ├── secret-graph.ts # SecretGraph reference Module
│ │ │ └── index.ts # Barrel re-export
│ │ ├── bridge.ts # moduleToDbSchema, validateNode, validateEdge
│ │ ├── crypto.ts # encrypt, decrypt, generateEncryptionKey, EncryptedDataSchema
│ │ └── mod.ts # Re-exports all graphs exports
│ ├── sqlite/ # SQLite host (drizzle-orm/libsql)
│ │ ├── tables/ # Drizzle table definitions
│ │ ├── relations.ts # Drizzle relations
│ │ ├── schema.ts # Re-exports
│ │ └── client.ts # Injectable createSqliteDatabase()
│ └── pg/ # PostgreSQL host (NOT YET IMPLEMENTED)
└── test/
└── reference-modules.test.ts # Metagraph, bridge, crypto tests
Subpath Exports (JSR/npm)
@alkdev/storage→ Metagraph Module, graph type definitions (zero deps)@alkdev/storage/sqlite→ SQLite tables, relations, client (drizzle-orm + libsql)@alkdev/storage/pg→ PostgreSQL tables, relations, client (NOT YET IMPLEMENTED)
This design ensures consumers don't bundle database drivers they don't use.
Key Decisions
- Deno-first, npm-second via JSR: Package is published to JSR
(
deno publish). npm compatibility is automatic via JSR's npm layer (@jsr/alkdev__storage). No separate dnt build step. - No comments in code: Per project convention across @alkdev packages.
- JSR slow types excluded from lint: Drizzle's deeply inferred generics
(
sqliteTable,createInsertSchema,relations) make explicit type annotations impractical. We use--allow-slow-typeson publish and"exclude": ["no-slow-types"]in lint config. This is known technical debt — can be tightened iteratively. - Injectable clients:
createSqliteDatabase(client)takes a client, not env vars. Module-level side effects are forbidden. - Dependencies:
@alkdev/typeboxand@alkdev/drizzleboxare npm deps (not yet on JSR). This works fine — JSR handles npm dependencies natively.
Commands
deno check mod.ts src/graphs/mod.ts src/sqlite/mod.ts # Type check
deno lint # Lint (slow-types, verbatim-module-syntax excluded)
deno task lint:analyze # Analyze lint issues by code/file grouping
deno fmt # Format
deno test --allow-all test/ # Run tests
deno publish --allow-slow-types --dry-run # Dry-run publish
Source Heritage
The graphs/ and sqlite/ modules were adapted from
@ade/ade-v0/packages/core/graphs and @ade/ade-v0/packages/storage_sqlite.
The codebase has diverged significantly from the originals:
- All schemas use
Type.Module()construction (notSchemaBuilder) Metagraph,CallGraph,SecretGraphare TypeBox Modules composing viaImport()andType.Composite()- Bridge functions (
moduleToDbSchema,validateNode,validateEdge) project Modules to DB row values - Crypto utility ported from
@alkdev/hub/src/crypto/mod.tswithEncryptedDataSchemaas a TypeBox schema @sinclair/typebox→@alkdev/typebox,drizzle-typebox→@alkdev/drizzlebox- TypeScript enums replaced with
as constobjects (GRAPH_STATUS,ACTOR_TYPE) Type.Unknown()used for unvalidated fields (notType.Any())- Injectable client pattern (
createSqliteDatabase(client)takes a pre-created client) - No module-level side effects or state
File Conventions
- All source files use
.tsextension with explicit extensions in imports (Deno convention) - Entry points are
mod.tsfiles that re-export from subdirectories - TypeBox schemas are named with PascalCase (
NodeType,GraphConfig) - Drizzle table objects are named with camelCase (
graphTypes,nodeTypes) - Schema objects from drizzlebox are named with PascalCase (
InsertGraph,SelectGraph) - Enum constants use
SCREAMING_SNAKE_CASEobjects (GRAPH_STATUS,ACTOR_TYPE)
Architecture Docs
See docs/architecture/ for detailed specifications:
overview.md— Package purpose, exports, design decisions, open questionsmetagraph-module.md— Graph type definitions as TypeBox Modules, data model, naming conventions, implementation pathforward-look.md— Connections to dbtype, graph pointers, ujsx universal IR pipelineschema-evolution.md— How graph type schemas evolve, TypeBox Value.Diff/Patch/Cast for schema change detection and data migrationsqlite-host.md— SQLite tables, relations, client factory, porting notesencrypted-data.md— Encrypted data design, crypto utility, node type modeling
These docs describe what the package is AND what it's becoming. Items marked ⚠️ are not yet implemented.
What's Not Done Yet
src/pg/— PostgreSQL host (same table shapes,pgTable+jsonb+timestamp+pgEnum)- Repository/CRUD layer (currently only table definitions, no typed query functions)
- Hub-specific tables (sessions, messages, parts, call graphs, tasks, etc.)
- JSR publication setup (need to create scope/package on jsr.io first)