feat: package manager, build system, native cross-compilation, plugin system

Add three new crates and extend the compiler and CLI toolchain:

- el-manifest: el.toml manifest parser using serde + toml crate; supports
  package info, registry/path/version deps, build config with seal key
  sources, cross targets, and plugins; Manifest::find_manifest() walks up
  the directory tree

- el-registry: HTTP registry client (reqwest + tokio) for
  packages.neurontechnologies.ai; PackageMetadata, fetch/download/publish/
  search, BLAKE3 checksum verification, local cache at ~/.engram/packages/

- el-build: build orchestrator with incremental builds (BLAKE3 file hashes
  in .el/build-cache.json), cross-compilation target tagging, dep resolution,
  plugin registry with on_ast/on_typed_ast/on_bytecode hooks, test runner,
  fmt/check/clean commands

- CrossTarget and NativeTarget enums with triple() and artifact_extension()
  methods; NativeTarget::Host detects compile-time platform via cfg! macros

- Plugin system: CompilerPlugin trait + PluginRegistry; dynamic loading is
  a marked TODO with clear extension point for libloading

- CLI extended with: new, add, remove, update, build --cross, run, test,
  check, fmt, clean, publish, search, plugin add/remove/list; old
  single-file commands moved to build-file/seal/unseal subcommands

- Fix pre-existing debugger.rs borrow error (unwrap_or temporary lifetime)
- Fix checker.rs and codegen.rs to handle TestDef/Seed/Assert Stmt variants
- Add spec/language.md sections 12-14: package system, build system,
  plugin system, cross-compilation targets table

130 tests passing, zero warnings
This commit is contained in:
Will Anderson
2026-04-27 19:08:25 -05:00
parent 9ced941590
commit 48b72843e1
31 changed files with 4923 additions and 107 deletions
+41
View File
@@ -2,6 +2,36 @@
use el_lexer::Span;
// ── Test-specific nodes ───────────────────────────────────────────────────────
/// Which graph a test should execute against.
#[derive(Debug, Clone, PartialEq)]
pub enum TestTarget {
/// In-memory graph — default, zero external dependencies.
Unit,
/// Real Engram database pointed at by `ENGRAM_URL` / `ENGRAM_DB_PATH`.
E2e,
/// Run against both unit (in-memory) and e2e (real DB).
Both,
}
/// A `seed Node { ... }` or `seed Edge { ... }` statement inside a test block.
#[derive(Debug, Clone, PartialEq)]
pub enum SeedStmt {
Node {
node_type: String,
content: String,
importance: f32,
tier: Option<String>,
},
Edge {
from: String,
to: String,
relation: String,
weight: f32,
},
}
// ── Literals ──────────────────────────────────────────────────────────────────
#[derive(Debug, Clone, PartialEq)]
@@ -144,6 +174,17 @@ pub enum Stmt {
variants: Vec<Variant>,
span: Span,
},
/// `test "name" [target: unit|e2e|both] { body }`
TestDef {
name: String,
target: TestTarget,
body: Vec<Stmt>,
span: Span,
},
/// `seed Node { ... }` or `seed Edge { ... }`
Seed(SeedStmt, Span),
/// `assert <expr>`
Assert(Expr, Span),
}
// ── Top-level program ─────────────────────────────────────────────────────────