Files
Codewalkers/.planning/research/STACK.md
Lukas May 0ff65b0b02 feat: Rename application from "Codewalk District" to "Codewalkers"
Update all user-facing strings (HTML title, manifest, header logo,
browser title updater), code comments, and documentation references.
Folder name retained as-is.
2026-03-05 12:05:08 +01:00

328 lines
12 KiB
Markdown

# Stack Research: TypeScript CLI with Embedded Server and SQLite
**Domain:** Multi-agent orchestration / Developer tooling
**Researched:** 2026-01-30
**Confidence:** HIGH (based on official docs, npm stats, GitHub activity, authoritative blog posts)
---
## Core Technologies
| Name | Version | Purpose | Why Recommended |
|------|---------|---------|-----------------|
| **Node.js** | v22+ LTS | Runtime | Native ESM support, `node:sqlite` experimental, stable LTS |
| **TypeScript** | 5.7+ | Type safety | Strict mode required for tRPC/Zod inference |
| **Commander.js** | 14.x | CLI framework | Lightweight, TypeScript types included, mature (9+ years), subcommand support |
| **tRPC** | 11.x | API layer | Type-safe RPC, standalone server adapter, SSE subscriptions, no codegen |
| **Drizzle ORM** | 0.44+ | Database ORM | Lightweight, TypeScript-first, SQL-centric, faster than raw better-sqlite3 with prepared statements |
| **better-sqlite3** | 11.x | SQLite driver | Synchronous API, fastest SQLite driver for Node.js, Drizzle's recommended driver |
| **Zod** | 3.24+ | Validation | tRPC's default validator, runtime + compile-time safety, Standard Schema compliant |
---
## Supporting Libraries
| Name | Version | Purpose | Notes |
|------|---------|---------|-------|
| **execa** | 9.6+ | Process spawning | Promise-based, auto-cleanup, cross-platform, graceful shutdown |
| **simple-git** | 3.27+ | Git operations | Wrapper around git CLI, worktree config support |
| **cors** | 2.8+ | CORS handling | For tRPC standalone server in dev mode |
| **nanoid** | 5.x | ID generation | URL-safe, small, fast |
| **consola** | 3.x | CLI logging | Pretty console output, log levels |
| **chalk** | 5.x | Terminal styling | ESM-native, color output |
---
## Development Tools
| Tool | Version | Purpose |
|------|---------|---------|
| **tsup** | 8.5+ | Build/bundle | esbuild-powered, zero-config, ESM+CJS output |
| **tsx** | 4.x | Dev execution | TypeScript execution without compilation, shebang support |
| **vitest** | 3.x | Testing | Vite-powered, native ESM/TS, fast, parallel |
| **drizzle-kit** | 0.31+ | Migrations | Schema migrations, introspection |
| **@types/better-sqlite3** | latest | Types | TypeScript definitions |
| **@types/node** | 22.x | Types | Node.js type definitions |
---
## Installation Commands
```bash
# Core dependencies
npm install commander @trpc/server drizzle-orm better-sqlite3 zod
# Supporting libraries
npm install execa simple-git nanoid consola chalk cors
# Development dependencies
npm install -D typescript tsup tsx vitest drizzle-kit @types/better-sqlite3 @types/node
```
---
## Project Structure (Hexagonal Architecture)
```
src/
├── cli/ # CLI entry points (commander)
│ ├── index.ts # Main CLI binary
│ └── commands/ # Subcommand handlers
├── server/ # tRPC server
│ ├── router.ts # tRPC router definitions
│ ├── context.ts # Request context
│ └── adapters/ # HTTP adapter config
├── core/ # Domain logic (hexagonal core)
│ ├── domain/ # Entities, value objects
│ ├── ports/ # Interfaces (inbound/outbound)
│ └── services/ # Application services
├── infrastructure/ # Adapters
│ ├── db/ # Drizzle schema, repositories
│ ├── git/ # Git worktree operations
│ └── agents/ # Claude Code process spawning
└── shared/ # Shared types, utils
├── schema.ts # Zod schemas (shared contracts)
└── types.ts # Inferred types
```
---
## Key Patterns
### tRPC Standalone Server Setup
```typescript
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import cors from 'cors';
const t = initTRPC.context<Context>().create();
const appRouter = t.router({
// procedures
});
const server = createHTTPServer({
middleware: cors(),
router: appRouter,
createContext,
});
server.listen(3000);
```
### Drizzle + better-sqlite3 Setup
```typescript
import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';
const sqlite = new Database('codewalk.db');
const db = drizzle(sqlite);
// Use prepared statements for performance
const prepared = db.select().from(tasks).where(eq(tasks.id, sql.placeholder('id'))).prepare();
const result = prepared.execute({ id: taskId });
```
### Process Spawning with execa
```typescript
import { execa } from 'execa';
// Spawn Claude Code agent
const subprocess = execa('claude', ['--worktree', worktreePath], {
cwd: worktreePath,
stdio: ['pipe', 'pipe', 'pipe'],
});
// Graceful cleanup
process.on('SIGTERM', () => subprocess.kill());
```
### Commander CLI with Subcommands
```typescript
import { Command } from 'commander';
const program = new Command();
program
.name('cw')
.description('Codewalkers - Multi-agent orchestration')
.version('0.1.0');
program
.command('serve')
.description('Start the orchestration server')
.option('-p, --port <number>', 'Port number', '3000')
.action(async (options) => {
// Start tRPC server
});
program
.command('task')
.description('Manage tasks')
.addCommand(new Command('create').action(createTask))
.addCommand(new Command('list').action(listTasks));
```
---
## Alternatives Considered
### CLI Frameworks
| Alternative | Why Not Chosen |
|-------------|----------------|
| **oclif** | Overkill for single developer, steeper learning curve, heavier |
| **yargs** | Less TypeScript-native, callback-heavy syntax |
| **clipanion** | Less ecosystem support than commander |
| **Ink** | React overhead unnecessary for this use case |
### Database
| Alternative | Why Not Chosen |
|-------------|----------------|
| **Prisma** | Heavy, slow cold starts, codegen complexity |
| **TypeORM** | Complex queries lose type safety |
| **node:sqlite** | Experimental, not production-ready |
| **libsql** | Unnecessary Turso features for local-only use |
### HTTP Server
| Alternative | Why Not Chosen |
|-------------|----------------|
| **Fastify** | tRPC standalone is simpler for this use case |
| **Express** | Slower, less modern |
| **Hono** | Better for edge, unnecessary complexity for Node CLI |
### Process Management
| Alternative | Why Not Chosen |
|-------------|----------------|
| **child_process** | Lower-level, manual cleanup required |
| **shelljs** | Less maintained, synchronous-focused |
| **cross-spawn** | execa wraps this with better DX |
---
## What NOT to Use
| Technology | Reason |
|------------|--------|
| **Express** | Slower than alternatives, less type-safe |
| **node-sqlite3** | Async API slower than better-sqlite3's sync API |
| **Prisma** | Too heavy for embedded CLI database |
| **GraphQL** | Overkill for internal API, tRPC is simpler |
| **Sequelize** | TypeScript support inferior to Drizzle |
| **npm link** | Use `tsx` for development instead |
| **ts-node** | tsx is faster, better ESM support |
| **Jest** | Vitest is faster, native ESM/TS support |
---
## Version Compatibility Notes
- **Node.js 22+** required for stable ESM, modern `child_process` features
- **TypeScript 5.7+** for `satisfies`, improved inference
- **tRPC v11** requires `"strict": true` in tsconfig
- **Drizzle 0.44+** for latest SQLite blob handling fixes
- **execa 9+** is ESM-only (no CommonJS)
- **chalk 5+** is ESM-only
- **better-sqlite3** requires native compilation (node-gyp)
### tsconfig.json Recommendations
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "dist",
"declaration": true,
"composite": true
}
}
```
### package.json Type Configuration
```json
{
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"bin": {
"cw": "./dist/cli/index.js"
}
}
```
---
## Sources
### CLI Frameworks
- [Commander.js GitHub](https://github.com/tj/commander.js) - Official repo, v14 docs
- [Commander.js npm](https://www.npmjs.com/package/commander) - Download stats, version history
- [Building TypeScript CLI with Commander](https://blog.logrocket.com/building-typescript-cli-node-js-commander/) - LogRocket guide
- [CLI Framework Comparison](https://npm-compare.com/commander,oclif,vorpal,yargs) - npm-compare analysis
- [Bloomberg Stricli Alternatives](https://bloomberg.github.io/stricli/docs/getting-started/alternatives) - Framework comparison
### tRPC
- [tRPC Standalone Adapter](https://trpc.io/docs/server/adapters/standalone) - Official docs (HIGH confidence)
- [tRPC v11 Announcement](https://trpc.io/blog/announcing-trpc-v11) - Official blog (HIGH confidence)
- [tRPC Migration Guide](https://trpc.io/docs/migrate-from-v10-to-v11) - v10 to v11 migration
- [tRPC npm](https://www.npmjs.com/package/@trpc/server) - Package info
- [tRPC + Zod Best Practices](https://betterstack.com/community/guides/scaling-nodejs/trpc-explained/) - Better Stack guide
### SQLite / Drizzle
- [better-sqlite3 GitHub](https://github.com/WiseLibs/better-sqlite3) - Official repo (HIGH confidence)
- [Drizzle ORM SQLite](https://orm.drizzle.team/docs/quick-sqlite/better-sqlite3) - Official docs (HIGH confidence)
- [Drizzle Releases](https://github.com/drizzle-team/drizzle-orm/releases) - Version history
- [Drizzle Getting Started](https://betterstack.com/community/guides/scaling-nodejs/drizzle-orm/) - Better Stack guide
- [TypeScript ORMs 2025](https://www.bytebase.com/blog/top-typescript-orm/) - Bytebase comparison
### Process Spawning
- [execa GitHub](https://github.com/sindresorhus/execa) - Official repo (HIGH confidence)
- [execa npm v9](https://www.npmjs.com/package/execa/v/9.0.0) - Package info
- [execa Guide](https://betterstack.com/community/guides/scaling-nodejs/execa-cli/) - Better Stack guide
- [Node.js child_process](https://nodejs.org/api/child_process.html) - Official Node docs (HIGH confidence)
### Git Libraries
- [simple-git npm](https://www.npmjs.com/package/simple-git) - Package info
- [isomorphic-git](https://isomorphic-git.org/) - Alternative for browser use
- [Git library comparison](https://npm-compare.com/isomorphic-git,nodegit,simple-git) - npm-compare
### Build Tools
- [tsup GitHub](https://github.com/egoist/tsup) - Official repo (HIGH confidence)
- [tsup Guide](https://generalistprogrammer.com/tutorials/tsup-npm-package-guide) - Usage guide
- [Vitest](https://vitest.dev/) - Official docs (HIGH confidence)
- [TypeScript ESM/CJS 2025](https://lirantal.com/blog/typescript-in-2025-with-esm-and-cjs-npm-publishing) - Liran Tal analysis
### Validation
- [Zod](https://zod.dev/) - Official docs (HIGH confidence)
- [tRPC Validators](https://trpc.io/docs/server/validators) - Input validation docs
---
## Confidence Assessment
| Area | Confidence | Reasoning |
|------|------------|-----------|
| CLI Framework | HIGH | Commander is battle-tested (13M weekly downloads), clear winner for simplicity |
| tRPC | HIGH | v11 officially released, standalone adapter well-documented |
| SQLite Stack | HIGH | better-sqlite3 + Drizzle is the recommended combination in official docs |
| Process Spawning | HIGH | execa is the de facto standard (150M+ weekly downloads) |
| Build Tooling | HIGH | tsup/tsx/vitest is the modern consensus for TypeScript libraries |
| Git Operations | MEDIUM | simple-git works but worktree support may need CLI fallback |
---
*Last updated: 2026-01-30*