Playground
This is the ContextKit packer running in your browser on a bundled sample repo — the same ranking, budgeting and stripping the CLI applies to yours. Tweak the knobs and watch the context file rebuild.
Sample repo
Token budget
4,000Options
Rank by
Equivalent command
$ npx contextkit --budget 4000 --rank hybrid12 of 12 files packed~1,239 / 4,000 tokens
# Repo: taskboard-api
> Express + Prisma REST API behind a kanban board
_Packed by ContextKit · 12 files scanned · rank: hybrid · budget: 4,000 tokens_
## File map
- src/routes/cards.ts (142 loc)
- src/services/cardService.ts (118 loc)
- src/types.ts (74 loc)
- src/db.ts (21 loc)
- src/server.ts (88 loc)
- src/routes/boards.ts (96 loc)
- src/middleware/auth.ts (43 loc)
- src/utils/logger.ts (18 loc)
- prisma/schema.prisma (67 loc)
- tests/cards.test.ts (130 loc)
- package-lock.json (9412 loc)
- README.md (52 loc)
## Recent git activity
- `e4f21c9` (2 days ago) fix: race when moving cards between columns
- `a90d3b1` (3 days ago) feat: cursor pagination on GET /cards
- `7c2e0f4` (6 days ago) chore: prisma 5 upgrade + schema cleanup
## Files (ranked)
### src/types.ts
<!-- loc: 74 · imported by 11 files · last touched 9d ago -->
> Shared zod schemas and inferred types for boards, columns, cards.
```ts
export const MoveCardSchema = z.object({
toColumnId: z.string().cuid(),
position: z.number().int().min(0),
});
export type MoveCard = z.infer<typeof MoveCardSchema>;
```
### src/db.ts
<!-- loc: 21 · imported by 7 files · last touched 30d ago -->
> Singleton PrismaClient with slow-query logging.
```ts
export const db = new PrismaClient({
log: [{ emit: "event", level: "query" }],
});
db.$on("query", (e) => e.duration > 200 && logger.warn("slow query", e));
```
### src/services/cardService.ts
<!-- loc: 118 · imported by 3 files · last touched 2d ago -->
> Card domain logic; moveCard runs in a transaction to avoid position races.
```ts
export async function moveCard(id: string, toColumnId: string, position: number) {
return db.$transaction(async (tx) => {
await tx.card.updateMany({
where: { columnId: toColumnId, position: { gte: position } },
data: { position: { increment: 1 } },
});
return tx.card.update({ where: { id }, data: { columnId: toColumnId, position } });
});
}
```
### src/routes/cards.ts
<!-- loc: 142 · imported by 1 file · last touched 1d ago -->
> REST handlers for cards: list with cursor pagination, create, move between columns.
```ts
router.post("/:id/move", async (req, res) => {
const { toColumnId, position } = MoveCardSchema.parse(req.body);
const card = await cardService.moveCard(req.params.id, toColumnId, position);
res.json(card);
});
```
### src/utils/logger.ts
<!-- loc: 18 · imported by 6 files · last touched 60d ago -->
> Pino logger, pretty in dev, JSON in prod.
```ts
export const logger = pino({
level: env.LOG_LEVEL ?? "info",
transport: env.NODE_ENV === "development" ? { target: "pino-pretty" } : undefined,
});
```
### tests/cards.test.ts
<!-- loc: 130 · imported by 0 files · last touched 1d ago -->
> Integration tests for the move endpoint, including the concurrent-move race.
```ts
it("keeps positions consistent under concurrent moves", async () => {
await Promise.all([moveCard(a.id, col2.id, 0), moveCard(b.id, col2.id, 0)]);
const cards = await getColumn(col2.id);
expect(cards.map((c) => c.position)).toEqual([0, 1, 2]);
});
```
### src/server.ts
<!-- loc: 88 · imported by 1 file · last touched 3d ago -->
> App entrypoint: express wiring, auth middleware, route mounting, error handler.
```ts
app.use("/api/boards", requireAuth, boardsRouter);
app.use("/api/cards", requireAuth, cardsRouter);
app.use(errorHandler);
app.listen(env.PORT, () => logger.info(`up on :${env.PORT}`));
```
### prisma/schema.prisma
<!-- loc: 67 · imported by 0 files · last touched 6d ago -->
> Board → Column → Card models; card position is unique per column.
```prisma
model Card {
id String @id @default(cuid())
title String
position Int
column Column @relation(fields: [columnId], references: [id])
columnId String
@@unique([columnId, position])
}
```
### package-lock.json (stubbed)
<!-- loc: 9412 · imported by 0 files · last touched 6d ago -->
> npm lockfile — 9,412 lines of resolved dependency metadata.
### src/routes/boards.ts
<!-- loc: 96 · imported by 1 file · last touched 12d ago -->
> Board CRUD plus column reordering endpoint.
```ts
router.get("/", async (req, res) => {
const boards = await db.board.findMany({
where: { ownerId: req.user.id },
include: { columns: { orderBy: { position: "asc" } } },
});
res.json(boards);
});
```
### src/middleware/auth.ts
<!-- loc: 43 · imported by 2 files · last touched 45d ago -->
> JWT bearer auth; attaches req.user or 401s.
```ts
export function requireAuth(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.replace("Bearer ", "");
if (!token) return res.status(401).json({ error: "missing token" });
req.user = verifyJwt(token);
next();
}
```
### README.md
<!-- loc: 52 · imported by 0 files · last touched 90d ago -->
> Setup, env vars, and route overview.
```md
## Running locally
```
cp .env.example .env
npm install && npx prisma migrate dev
npm run dev
```
```
| File | Score | Tokens | Status |
|---|---|---|---|
| src/types.ts | 0.78 | 82 | full |
| src/db.ts | 0.50 | 74 | full |
| src/services/cardService.ts | 0.49 | 139 | full |
| src/routes/cards.ts | 0.41 | 100 | full |
| src/utils/logger.ts | 0.40 | 74 | full |
| tests/cards.test.ts | 0.35 | 108 | full |
| src/server.ts | 0.34 | 90 | full |
| prisma/schema.prisma | 0.22 | 94 | full |
| package-lock.json | 0.22 | 40 | stubbed |
| src/routes/boards.ts | 0.21 | 88 | full |
| src/middleware/auth.ts | 0.17 | 102 | full |
| README.md | 0.03 | 57 | full |