feat(P0-001): scaffold monorepo structure (#60)
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #60.
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1 +1,11 @@
|
|||||||
logs/
|
logs/
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.turbo
|
||||||
|
.next
|
||||||
|
coverage
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
*.tsbuildinfo
|
||||||
|
.pnpm-store
|
||||||
|
docs/reports/
|
||||||
|
|||||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npx lint-staged
|
||||||
4
.husky/pre-push
Executable file
4
.husky/pre-push
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
pnpm typecheck && pnpm lint && pnpm format:check
|
||||||
9
.lintstagedrc
Normal file
9
.lintstagedrc
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"**/*.{ts,tsx,js,jsx}": [
|
||||||
|
"prettier --write",
|
||||||
|
"eslint --fix"
|
||||||
|
],
|
||||||
|
"**/*.{json,md,yaml,yml}": [
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -14,9 +14,5 @@
|
|||||||
"timeout_seconds": 7200,
|
"timeout_seconds": 7200,
|
||||||
"max_attempts": 1
|
"max_attempts": 1
|
||||||
},
|
},
|
||||||
"quality_gates": [
|
"quality_gates": ["pnpm lint", "pnpm typecheck", "pnpm test"]
|
||||||
"pnpm lint",
|
|
||||||
"pnpm typecheck",
|
|
||||||
"pnpm test"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
1
.npmrc
Normal file
1
.npmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@mosaic:registry=https://git.mosaicstack.dev/api/packages/mosaic/npm/
|
||||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"semi": true,
|
||||||
|
"printWidth": 100
|
||||||
|
}
|
||||||
26
apps/gateway/package.json
Normal file
26
apps/gateway/package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/gateway",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"main": "dist/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"dev": "tsc --watch",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nestjs/common": "^11.0.0",
|
||||||
|
"@nestjs/core": "^11.0.0",
|
||||||
|
"@nestjs/platform-fastify": "^11.0.0",
|
||||||
|
"fastify": "^5.0.0",
|
||||||
|
"reflect-metadata": "^0.2.0",
|
||||||
|
"rxjs": "^7.8.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.0.0",
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
apps/gateway/src/app.module.ts
Normal file
7
apps/gateway/src/app.module.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { HealthController } from './health/health.controller.js';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [HealthController],
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
9
apps/gateway/src/health/health.controller.ts
Normal file
9
apps/gateway/src/health/health.controller.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Controller, Get } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Controller('health')
|
||||||
|
export class HealthController {
|
||||||
|
@Get()
|
||||||
|
check(): { status: string } {
|
||||||
|
return { status: 'ok' };
|
||||||
|
}
|
||||||
|
}
|
||||||
16
apps/gateway/src/main.ts
Normal file
16
apps/gateway/src/main.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import 'reflect-metadata';
|
||||||
|
import { NestFactory } from '@nestjs/core';
|
||||||
|
import { FastifyAdapter, type NestFastifyApplication } from '@nestjs/platform-fastify';
|
||||||
|
import { AppModule } from './app.module.js';
|
||||||
|
|
||||||
|
async function bootstrap(): Promise<void> {
|
||||||
|
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
|
||||||
|
|
||||||
|
await app.listen(4000, '0.0.0.0');
|
||||||
|
console.log('Gateway listening on port 4000');
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap().catch((err: unknown) => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
13
apps/gateway/tsconfig.json
Normal file
13
apps/gateway/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"module": "CommonJS",
|
||||||
|
"moduleResolution": "Node"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
apps/gateway/vitest.config.ts
Normal file
8
apps/gateway/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
6
apps/web/next-env.d.ts
vendored
Normal file
6
apps/web/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/image-types/global" />
|
||||||
|
import './.next/types/routes.d.ts';
|
||||||
|
|
||||||
|
// NOTE: This file should not be edited
|
||||||
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||||
7
apps/web/next.config.ts
Normal file
7
apps/web/next.config.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { NextConfig } from 'next';
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
output: 'standalone',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
26
apps/web/package.json
Normal file
26
apps/web/package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/web",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "next build",
|
||||||
|
"dev": "next dev",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run",
|
||||||
|
"start": "next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^16.0.0",
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-dom": "^19.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.0.0",
|
||||||
|
"@types/react": "^19.0.0",
|
||||||
|
"@types/react-dom": "^19.0.0",
|
||||||
|
"tailwindcss": "^4.0.0",
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
apps/web/src/app/layout.tsx
Normal file
14
apps/web/src/app/layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: 'Mosaic',
|
||||||
|
description: 'Mosaic Stack Dashboard',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({ children }: { children: ReactNode }): ReactNode {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body>{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
7
apps/web/src/app/page.tsx
Normal file
7
apps/web/src/app/page.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export default function HomePage(): React.ReactElement {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<h1>Mosaic Stack</h1>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
apps/web/tailwind.config.ts
Normal file
11
apps/web/tailwind.config.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import type { Config } from 'tailwindcss';
|
||||||
|
|
||||||
|
const config: Config = {
|
||||||
|
content: ['./src/**/*.{ts,tsx}'],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
16
apps/web/tsconfig.json
Normal file
16
apps/web/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "ES2022"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"jsx": "preserve",
|
||||||
|
"plugins": [{ "name": "next" }],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
8
apps/web/vitest.config.ts
Normal file
8
apps/web/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'jsdom',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
docker/gateway.Dockerfile
Normal file
22
docker/gateway.Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
FROM node:22-alpine AS base
|
||||||
|
ENV PNPM_HOME="/pnpm"
|
||||||
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
||||||
|
COPY apps/gateway/package.json ./apps/gateway/
|
||||||
|
COPY packages/ ./packages/
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
COPY . .
|
||||||
|
RUN pnpm --filter @mosaic/gateway build
|
||||||
|
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
COPY --from=builder /app/apps/gateway/dist ./dist
|
||||||
|
COPY --from=builder /app/apps/gateway/package.json ./package.json
|
||||||
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
|
EXPOSE 4000
|
||||||
|
CMD ["node", "dist/main.js"]
|
||||||
1
docker/init-db.sql
Normal file
1
docker/init-db.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CREATE EXTENSION IF NOT EXISTS vector;
|
||||||
22
docker/web.Dockerfile
Normal file
22
docker/web.Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
FROM node:22-alpine AS base
|
||||||
|
ENV PNPM_HOME="/pnpm"
|
||||||
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
|
RUN corepack enable
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
||||||
|
COPY apps/web/package.json ./apps/web/
|
||||||
|
COPY packages/ ./packages/
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
COPY . .
|
||||||
|
RUN pnpm --filter @mosaic/web build
|
||||||
|
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
COPY --from=builder /app/apps/web/.next/standalone ./
|
||||||
|
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
|
||||||
|
COPY --from=builder /app/apps/web/public ./apps/web/public
|
||||||
|
EXPOSE 3000
|
||||||
|
CMD ["node", "apps/web/server.js"]
|
||||||
@@ -25,12 +25,12 @@
|
|||||||
- [ ] AC-8: Multi-provider LLM — 3+ providers routing correctly
|
- [ ] AC-8: Multi-provider LLM — 3+ providers routing correctly
|
||||||
- [ ] AC-9: MCP — gateway MCP endpoint, brain + queue tools via MCP
|
- [ ] AC-9: MCP — gateway MCP endpoint, brain + queue tools via MCP
|
||||||
- [ ] AC-10: Deployment — `docker compose up` from clean state, CLI on bare metal
|
- [ ] AC-10: Deployment — `docker compose up` from clean state, CLI on bare metal
|
||||||
- [ ] AC-11: @mosaic/* packages — all 7 migrated packages build, test, integrate
|
- [ ] AC-11: @mosaic/\* packages — all 7 migrated packages build, test, integrate
|
||||||
|
|
||||||
## Milestones
|
## Milestones
|
||||||
|
|
||||||
| # | ID | Name | Status | Branch | Issue | Started | Completed |
|
| # | ID | Name | Status | Branch | Issue | Started | Completed |
|
||||||
|---|-----|------|--------|--------|-------|---------|-----------|
|
| --- | ------ | --------------------------------------- | ----------- | ------ | ----- | ------- | --------- |
|
||||||
| 0 | ms-157 | Phase 0: Foundation (v0.0.1) | not-started | — | — | — | — |
|
| 0 | ms-157 | Phase 0: Foundation (v0.0.1) | not-started | — | — | — | — |
|
||||||
| 1 | ms-158 | Phase 1: Core API (v0.0.2) | not-started | — | — | — | — |
|
| 1 | ms-158 | Phase 1: Core API (v0.0.2) | not-started | — | — | — | — |
|
||||||
| 2 | ms-159 | Phase 2: Agent Layer (v0.0.3) | not-started | — | — | — | — |
|
| 2 | ms-159 | Phase 2: Agent Layer (v0.0.3) | not-started | — | — | — | — |
|
||||||
@@ -43,14 +43,14 @@
|
|||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
| Target | URL | Method |
|
| Target | URL | Method |
|
||||||
|--------|-----|--------|
|
| -------------------- | --------- | -------------------------- |
|
||||||
| Docker Compose (dev) | localhost | docker compose up |
|
| Docker Compose (dev) | localhost | docker compose up |
|
||||||
| Production | TBD | Docker Swarm via Portainer |
|
| Production | TBD | Docker Swarm via Portainer |
|
||||||
|
|
||||||
## Token Budget
|
## Token Budget
|
||||||
|
|
||||||
| Metric | Value |
|
| Metric | Value |
|
||||||
|--------|-------|
|
| ------ | ------ |
|
||||||
| Budget | — |
|
| Budget | — |
|
||||||
| Used | 0 |
|
| Used | 0 |
|
||||||
| Mode | normal |
|
| Mode | normal |
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
## Session History
|
## Session History
|
||||||
|
|
||||||
| Session | Runtime | Started | Duration | Ended Reason | Last Task |
|
| Session | Runtime | Started | Duration | Ended Reason | Last Task |
|
||||||
|---------|---------|---------|----------|--------------|-----------|
|
| ------- | --------------- | -------------------- | -------- | ------------ | ------------- |
|
||||||
| 1 | claude-opus-4-6 | 2026-03-13 01:00 UTC | — | — | Planning gate |
|
| 1 | claude-opus-4-6 | 2026-03-13 01:00 UTC | — | — | Planning gate |
|
||||||
|
|
||||||
## Scratchpad
|
## Scratchpad
|
||||||
|
|||||||
107
docs/PRD.md
107
docs/PRD.md
@@ -8,7 +8,7 @@
|
|||||||
- **Best-Guess Mode:** true
|
- **Best-Guess Mode:** true
|
||||||
- Repo (target): `git.mosaicstack.dev/mosaic/mosaic-stack`
|
- Repo (target): `git.mosaicstack.dev/mosaic/mosaic-stack`
|
||||||
- Baseline: `~/src/jarvis-old` (jarvis v0.2.0)
|
- Baseline: `~/src/jarvis-old` (jarvis v0.2.0)
|
||||||
- Package source: `~/src/mosaic-mono-v0` (@mosaic/* packages)
|
- Package source: `~/src/mosaic-mono-v0` (@mosaic/\* packages)
|
||||||
- Agent harness: [pi](https://github.com/badlogic/pi-mono) (v0.57.1)
|
- Agent harness: [pi](https://github.com/badlogic/pi-mono) (v0.57.1)
|
||||||
- Remote control reference: [OpenClaw](https://github.com/openclaw/openclaw) (upstream, canonical)
|
- Remote control reference: [OpenClaw](https://github.com/openclaw/openclaw) (upstream, canonical)
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ Jarvis (v0.2.0) is a self-hosted AI assistant with a Python FastAPI backend and
|
|||||||
4. **Gateway orchestrator** — Central routing layer that dispatches tasks to appropriate agents based on capability, cost, and context
|
4. **Gateway orchestrator** — Central routing layer that dispatches tasks to appropriate agents based on capability, cost, and context
|
||||||
5. **Shared memory** — PostgreSQL canonical store + vector DB for semantic search + tiered log summarization to prevent context creep
|
5. **Shared memory** — PostgreSQL canonical store + vector DB for semantic search + tiered log summarization to prevent context creep
|
||||||
6. **Multi-user with SSO** — BetterAuth with Authentik/WorkOS/Keycloak SSO, RBAC for family/team/business use
|
6. **Multi-user with SSO** — BetterAuth with Authentik/WorkOS/Keycloak SSO, RBAC for family/team/business use
|
||||||
7. **Full @mosaic/* package integration** — brain, queue, coord, mosaic, prdy, quality-rails, cli all integrated
|
7. **Full @mosaic/\* package integration** — brain, queue, coord, mosaic, prdy, quality-rails, cli all integrated
|
||||||
8. **Extensible** — MCP capability, skill import interface, plugin architecture for LLM providers and remote channels
|
8. **Extensible** — MCP capability, skill import interface, plugin architecture for LLM providers and remote channels
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -129,7 +129,7 @@ Jarvis (v0.2.0) is a self-hosted AI assistant with a Python FastAPI backend and
|
|||||||
### Technology Decisions
|
### Technology Decisions
|
||||||
|
|
||||||
| Layer | Technology | Rationale |
|
| Layer | Technology | Rationale |
|
||||||
|-------|-----------|-----------|
|
| ------------------ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
|
||||||
| **Web Frontend** | Next.js 16 + React 19 + Tailwind CSS | SSR, RSC; design tokens from @mosaic/design-tokens (mosaic-stack-website) |
|
| **Web Frontend** | Next.js 16 + React 19 + Tailwind CSS | SSR, RSC; design tokens from @mosaic/design-tokens (mosaic-stack-website) |
|
||||||
| **API / Gateway** | NestJS + Fastify adapter | Module system, DI, guards/interceptors for complex gateway; Fastify performance underneath |
|
| **API / Gateway** | NestJS + Fastify adapter | Module system, DI, guards/interceptors for complex gateway; Fastify performance underneath |
|
||||||
| **Agent Runtime** | Pi SDK (embedded) | Extensible harness with tools, skills, session management |
|
| **Agent Runtime** | Pi SDK (embedded) | Extensible harness with tools, skills, session management |
|
||||||
@@ -139,7 +139,7 @@ Jarvis (v0.2.0) is a self-hosted AI assistant with a Python FastAPI backend and
|
|||||||
| **Vector DB** | pgvector + VectorStore interface | pgvector for v0.1.0; `VectorStore` abstraction in @mosaic/memory makes Qdrant a drop-in later |
|
| **Vector DB** | pgvector + VectorStore interface | pgvector for v0.1.0; `VectorStore` abstraction in @mosaic/memory makes Qdrant a drop-in later |
|
||||||
| **Cache / Queue** | Valkey 8 | Redis-compatible; proven in @mosaic/queue |
|
| **Cache / Queue** | Valkey 8 | Redis-compatible; proven in @mosaic/queue |
|
||||||
| **ORM** | Drizzle ORM | TypeScript-native, lightweight, good migration story |
|
| **ORM** | Drizzle ORM | TypeScript-native, lightweight, good migration story |
|
||||||
| **Validation** | Zod | Already used across @mosaic/* packages |
|
| **Validation** | Zod | Already used across @mosaic/\* packages |
|
||||||
| **Build** | pnpm workspaces + Turborepo | Proven in both jarvis-old and mosaic-mono-v0 |
|
| **Build** | pnpm workspaces + Turborepo | Proven in both jarvis-old and mosaic-mono-v0 |
|
||||||
| **Testing** | Vitest + Playwright | Unit/integration via Vitest, E2E via Playwright |
|
| **Testing** | Vitest + Playwright | Unit/integration via Vitest, E2E via Playwright |
|
||||||
| **Remote Control** | Discord.js + Telegraf | Inspired by OpenClaw plugin architecture |
|
| **Remote Control** | Discord.js + Telegraf | Inspired by OpenClaw plugin architecture |
|
||||||
@@ -245,6 +245,7 @@ mosaic-mono-v1/
|
|||||||
### Package Responsibilities
|
### Package Responsibilities
|
||||||
|
|
||||||
#### `apps/gateway` — @mosaic/gateway (NEW — critical path)
|
#### `apps/gateway` — @mosaic/gateway (NEW — critical path)
|
||||||
|
|
||||||
The central nervous system. All clients connect here. Built with NestJS (Fastify adapter).
|
The central nervous system. All clients connect here. Built with NestJS (Fastify adapter).
|
||||||
|
|
||||||
- **NestJS modules** — Each concern (chat, brain, agent, auth, queue, memory, plugins) is a module with clear boundaries
|
- **NestJS modules** — Each concern (chat, brain, agent, auth, queue, memory, plugins) is a module with clear boundaries
|
||||||
@@ -257,6 +258,7 @@ The central nervous system. All clients connect here. Built with NestJS (Fastify
|
|||||||
- **Auth middleware** — BetterAuth session validation, RBAC enforcement
|
- **Auth middleware** — BetterAuth session validation, RBAC enforcement
|
||||||
|
|
||||||
Key routes:
|
Key routes:
|
||||||
|
|
||||||
```
|
```
|
||||||
POST /api/chat Send message, get streamed response
|
POST /api/chat Send message, get streamed response
|
||||||
GET /api/conversations List conversations
|
GET /api/conversations List conversations
|
||||||
@@ -287,6 +289,7 @@ GET /mcp MCP endpoint (streamable HTTP)
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### `apps/web` — Next.js Web Dashboard
|
#### `apps/web` — Next.js Web Dashboard
|
||||||
|
|
||||||
Carried forward from jarvis-old with significant refactoring.
|
Carried forward from jarvis-old with significant refactoring.
|
||||||
|
|
||||||
- Chat/conversation UI (primary interaction surface)
|
- Chat/conversation UI (primary interaction surface)
|
||||||
@@ -301,7 +304,9 @@ Carried forward from jarvis-old with significant refactoring.
|
|||||||
- Auth pages (login, SSO redirect, registration)
|
- Auth pages (login, SSO redirect, registration)
|
||||||
|
|
||||||
#### `packages/types` — @mosaic/types
|
#### `packages/types` — @mosaic/types
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0. Extended with:
|
Migrated from mosaic-mono-v0. Extended with:
|
||||||
|
|
||||||
- Gateway types (routing, dispatch, agent pool)
|
- Gateway types (routing, dispatch, agent pool)
|
||||||
- Auth types (user, role, permission)
|
- Auth types (user, role, permission)
|
||||||
- Conversation/message types (from jarvis-old domain)
|
- Conversation/message types (from jarvis-old domain)
|
||||||
@@ -309,7 +314,9 @@ Migrated from mosaic-mono-v0. Extended with:
|
|||||||
- Plugin channel types (Discord, Telegram message mapping)
|
- Plugin channel types (Discord, Telegram message mapping)
|
||||||
|
|
||||||
#### `packages/brain` — @mosaic/brain
|
#### `packages/brain` — @mosaic/brain
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0. **Storage backend changes from JSON to PostgreSQL.**
|
Migrated from mosaic-mono-v0. **Storage backend changes from JSON to PostgreSQL.**
|
||||||
|
|
||||||
- REST API preserved (mounted as gateway sub-router or standalone)
|
- REST API preserved (mounted as gateway sub-router or standalone)
|
||||||
- MCP tools preserved
|
- MCP tools preserved
|
||||||
- Collections layer rewritten to use Drizzle ORM queries instead of JSON file I/O
|
- Collections layer rewritten to use Drizzle ORM queries instead of JSON file I/O
|
||||||
@@ -318,13 +325,17 @@ Migrated from mosaic-mono-v0. **Storage backend changes from JSON to PostgreSQL.
|
|||||||
- New: appreciation collection preserved for family use
|
- New: appreciation collection preserved for family use
|
||||||
|
|
||||||
#### `packages/queue` — @mosaic/queue
|
#### `packages/queue` — @mosaic/queue
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0 with minimal changes.
|
Migrated from mosaic-mono-v0 with minimal changes.
|
||||||
|
|
||||||
- Valkey-backed task queue with atomic WATCH/MULTI/EXEC
|
- Valkey-backed task queue with atomic WATCH/MULTI/EXEC
|
||||||
- MCP server with 8 tools
|
- MCP server with 8 tools
|
||||||
- Used by gateway for agent task dispatch and coordination
|
- Used by gateway for agent task dispatch and coordination
|
||||||
|
|
||||||
#### `packages/coord` — @mosaic/coord
|
#### `packages/coord` — @mosaic/coord
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0.
|
Migrated from mosaic-mono-v0.
|
||||||
|
|
||||||
- Mission lifecycle: init, run, resume, status, drain
|
- Mission lifecycle: init, run, resume, status, drain
|
||||||
- TASKS.md parsing and management
|
- TASKS.md parsing and management
|
||||||
- Session lock management
|
- Session lock management
|
||||||
@@ -332,14 +343,18 @@ Migrated from mosaic-mono-v0.
|
|||||||
- Integration with gateway for mission-driven orchestration
|
- Integration with gateway for mission-driven orchestration
|
||||||
|
|
||||||
#### `packages/db` — @mosaic/db (NEW)
|
#### `packages/db` — @mosaic/db (NEW)
|
||||||
|
|
||||||
Shared database package.
|
Shared database package.
|
||||||
|
|
||||||
- Drizzle ORM schema definitions (all tables)
|
- Drizzle ORM schema definitions (all tables)
|
||||||
- Migration management
|
- Migration management
|
||||||
- Connection pool configuration
|
- Connection pool configuration
|
||||||
- Shared by gateway, brain, auth, memory
|
- Shared by gateway, brain, auth, memory
|
||||||
|
|
||||||
#### `packages/auth` — @mosaic/auth (NEW)
|
#### `packages/auth` — @mosaic/auth (NEW)
|
||||||
|
|
||||||
Authentication and authorization.
|
Authentication and authorization.
|
||||||
|
|
||||||
- BetterAuth configuration
|
- BetterAuth configuration
|
||||||
- SSO adapters: Authentik, WorkOS, Keycloak
|
- SSO adapters: Authentik, WorkOS, Keycloak
|
||||||
- RBAC: roles (admin, member, viewer), permissions
|
- RBAC: roles (admin, member, viewer), permissions
|
||||||
@@ -347,7 +362,9 @@ Authentication and authorization.
|
|||||||
- Session management middleware
|
- Session management middleware
|
||||||
|
|
||||||
#### `packages/agent` — @mosaic/agent (NEW — critical path)
|
#### `packages/agent` — @mosaic/agent (NEW — critical path)
|
||||||
|
|
||||||
Pi SDK integration layer.
|
Pi SDK integration layer.
|
||||||
|
|
||||||
- Agent pool manager — spawns and manages Pi agent sessions
|
- Agent pool manager — spawns and manages Pi agent sessions
|
||||||
- Provider configuration — Anthropic, Codex, Z.ai, Ollama, LM Studio, llama.cpp
|
- Provider configuration — Anthropic, Codex, Z.ai, Ollama, LM Studio, llama.cpp
|
||||||
- Agent routing logic — selects provider/model based on task characteristics
|
- Agent routing logic — selects provider/model based on task characteristics
|
||||||
@@ -356,7 +373,9 @@ Pi SDK integration layer.
|
|||||||
- Session lifecycle — create, monitor, complete, fail, timeout
|
- Session lifecycle — create, monitor, complete, fail, timeout
|
||||||
|
|
||||||
#### `packages/memory` — @mosaic/memory (NEW)
|
#### `packages/memory` — @mosaic/memory (NEW)
|
||||||
|
|
||||||
Tiered memory system.
|
Tiered memory system.
|
||||||
|
|
||||||
- Preference store — learned user preferences, behaviors, defaults (PG)
|
- Preference store — learned user preferences, behaviors, defaults (PG)
|
||||||
- Insight store — distilled knowledge from agent interactions (PG + vector)
|
- Insight store — distilled knowledge from agent interactions (PG + vector)
|
||||||
- Semantic search — query across memory using pgvector embeddings
|
- Semantic search — query across memory using pgvector embeddings
|
||||||
@@ -364,7 +383,9 @@ Tiered memory system.
|
|||||||
- Memory API — used by gateway and agent sessions
|
- Memory API — used by gateway and agent sessions
|
||||||
|
|
||||||
#### `packages/log` — @mosaic/log (NEW)
|
#### `packages/log` — @mosaic/log (NEW)
|
||||||
|
|
||||||
Agent log service.
|
Agent log service.
|
||||||
|
|
||||||
- Log ingest — receives structured logs from agent sessions
|
- Log ingest — receives structured logs from agent sessions
|
||||||
- Log parsing — extracts decisions, learnings, tool usage patterns
|
- Log parsing — extracts decisions, learnings, tool usage patterns
|
||||||
- Tiered storage — hot (recent, full detail), warm (summarized), cold (archived)
|
- Tiered storage — hot (recent, full detail), warm (summarized), cold (archived)
|
||||||
@@ -372,31 +393,41 @@ Agent log service.
|
|||||||
- Retention policy — configurable TTLs per tier
|
- Retention policy — configurable TTLs per tier
|
||||||
|
|
||||||
#### `packages/mosaic` — @mosaic/mosaic
|
#### `packages/mosaic` — @mosaic/mosaic
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0, updated for v1.
|
Migrated from mosaic-mono-v0, updated for v1.
|
||||||
|
|
||||||
- Install wizard for Mosaic Stack setup
|
- Install wizard for Mosaic Stack setup
|
||||||
- Detects existing installations, offers upgrade path
|
- Detects existing installations, offers upgrade path
|
||||||
- Configures `~/.config/mosaic/` with guides, tools, runtime configs
|
- Configures `~/.config/mosaic/` with guides, tools, runtime configs
|
||||||
|
|
||||||
#### `packages/prdy` — @mosaic/prdy
|
#### `packages/prdy` — @mosaic/prdy
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0.
|
Migrated from mosaic-mono-v0.
|
||||||
|
|
||||||
- PRD generation wizard
|
- PRD generation wizard
|
||||||
- Template-based PRD creation with Zod validation
|
- Template-based PRD creation with Zod validation
|
||||||
- CLI integration via `mosaic prdy`
|
- CLI integration via `mosaic prdy`
|
||||||
|
|
||||||
#### `packages/quality-rails` — @mosaic/quality-rails
|
#### `packages/quality-rails` — @mosaic/quality-rails
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0.
|
Migrated from mosaic-mono-v0.
|
||||||
|
|
||||||
- TypeScript scaffolder for project quality config
|
- TypeScript scaffolder for project quality config
|
||||||
- Generates ESLint, tsconfig, Woodpecker, husky, lint-staged configs
|
- Generates ESLint, tsconfig, Woodpecker, husky, lint-staged configs
|
||||||
- Supports project types: monorepo, typescript-node, nextjs
|
- Supports project types: monorepo, typescript-node, nextjs
|
||||||
|
|
||||||
#### `packages/cli` — @mosaic/cli
|
#### `packages/cli` — @mosaic/cli
|
||||||
|
|
||||||
Migrated from mosaic-mono-v0, extended.
|
Migrated from mosaic-mono-v0, extended.
|
||||||
|
|
||||||
- Unified `mosaic` binary
|
- Unified `mosaic` binary
|
||||||
- Subcommands: `mosaic coord`, `mosaic prdy`, `mosaic queue`, `mosaic quality`, `mosaic gateway`, `mosaic brain`
|
- Subcommands: `mosaic coord`, `mosaic prdy`, `mosaic queue`, `mosaic quality`, `mosaic gateway`, `mosaic brain`
|
||||||
- Plugin discovery for installed @mosaic/* packages
|
- Plugin discovery for installed @mosaic/\* packages
|
||||||
|
|
||||||
#### `plugins/discord` — @mosaic/discord-plugin (NEW — high priority)
|
#### `plugins/discord` — @mosaic/discord-plugin (NEW — high priority)
|
||||||
|
|
||||||
Discord remote control channel. Architecture inspired by OpenClaw (https://github.com/openclaw/openclaw).
|
Discord remote control channel. Architecture inspired by OpenClaw (https://github.com/openclaw/openclaw).
|
||||||
|
|
||||||
- Channel plugin that registers with the gateway as a NestJS dynamic module
|
- Channel plugin that registers with the gateway as a NestJS dynamic module
|
||||||
- Single-guild binding only (v0.1.0) — prevents data leaks between servers
|
- Single-guild binding only (v0.1.0) — prevents data leaks between servers
|
||||||
- Receives Discord messages, dispatches through gateway routing
|
- Receives Discord messages, dispatches through gateway routing
|
||||||
@@ -406,7 +437,9 @@ Discord remote control channel. Architecture inspired by OpenClaw (https://githu
|
|||||||
- DM support for private conversations
|
- DM support for private conversations
|
||||||
|
|
||||||
#### `plugins/telegram` — @mosaic/telegram-plugin (NEW)
|
#### `plugins/telegram` — @mosaic/telegram-plugin (NEW)
|
||||||
|
|
||||||
Telegram remote control channel.
|
Telegram remote control channel.
|
||||||
|
|
||||||
- Same channel plugin pattern as Discord
|
- Same channel plugin pattern as Discord
|
||||||
- Telegraf-based bot
|
- Telegraf-based bot
|
||||||
- Message routing through gateway
|
- Message routing through gateway
|
||||||
@@ -417,42 +450,55 @@ Telegram remote control channel.
|
|||||||
## User/Stakeholder Requirements
|
## User/Stakeholder Requirements
|
||||||
|
|
||||||
### US-001 Multi-Channel Chat
|
### US-001 Multi-Channel Chat
|
||||||
|
|
||||||
**As a user**, I can chat with an AI assistant via web browser, terminal (Pi TUI), Discord, or Telegram and get consistent responses regardless of channel.
|
**As a user**, I can chat with an AI assistant via web browser, terminal (Pi TUI), Discord, or Telegram and get consistent responses regardless of channel.
|
||||||
|
|
||||||
### US-002 Task & Project Dashboard
|
### US-002 Task & Project Dashboard
|
||||||
|
|
||||||
**As a user**, I can manage my tasks, projects, and missions from the web dashboard with kanban and list views.
|
**As a user**, I can manage my tasks, projects, and missions from the web dashboard with kanban and list views.
|
||||||
|
|
||||||
### US-003 PRD Management
|
### US-003 PRD Management
|
||||||
|
|
||||||
**As a user**, I can view and edit PRDs for active missions from the web dashboard.
|
**As a user**, I can view and edit PRDs for active missions from the web dashboard.
|
||||||
|
|
||||||
### US-004 Agent Visibility
|
### US-004 Agent Visibility
|
||||||
|
|
||||||
**As a user**, I can see which agents are active, what they're working on, and their status in real-time.
|
**As a user**, I can see which agents are active, what they're working on, and their status in real-time.
|
||||||
|
|
||||||
### US-005 Provider Configuration
|
### US-005 Provider Configuration
|
||||||
|
|
||||||
**As a user**, I can configure which LLM providers to use and set routing preferences (cost vs capability).
|
**As a user**, I can configure which LLM providers to use and set routing preferences (cost vs capability).
|
||||||
|
|
||||||
### US-006 Skill Management
|
### US-006 Skill Management
|
||||||
|
|
||||||
**As a user**, I can install and manage agent skills through the web dashboard.
|
**As a user**, I can install and manage agent skills through the web dashboard.
|
||||||
|
|
||||||
### US-007 Persistent Memory
|
### US-007 Persistent Memory
|
||||||
|
|
||||||
**As a user**, the system remembers my preferences, learned behaviors, and past decisions across sessions.
|
**As a user**, the system remembers my preferences, learned behaviors, and past decisions across sessions.
|
||||||
|
|
||||||
### US-008 Semantic Search
|
### US-008 Semantic Search
|
||||||
|
|
||||||
**As a user**, I can search across my memory, conversations, and knowledge semantically.
|
**As a user**, I can search across my memory, conversations, and knowledge semantically.
|
||||||
|
|
||||||
### US-009 User Management
|
### US-009 User Management
|
||||||
|
|
||||||
**As an admin**, I can manage users, assign roles, and control access.
|
**As an admin**, I can manage users, assign roles, and control access.
|
||||||
|
|
||||||
### US-010 SSO Configuration
|
### US-010 SSO Configuration
|
||||||
|
|
||||||
**As an admin**, I can configure SSO via Authentik, WorkOS, or Keycloak.
|
**As an admin**, I can configure SSO via Authentik, WorkOS, or Keycloak.
|
||||||
|
|
||||||
### US-011 Self-Hosted Deployment
|
### US-011 Self-Hosted Deployment
|
||||||
|
|
||||||
**As a user**, I can run Mosaic Stack via Docker Compose or directly on bare metal.
|
**As a user**, I can run Mosaic Stack via Docker Compose or directly on bare metal.
|
||||||
|
|
||||||
### US-012 Intelligent Routing
|
### US-012 Intelligent Routing
|
||||||
|
|
||||||
**As an agent operator**, the gateway intelligently routes tasks to the cheapest capable model.
|
**As an agent operator**, the gateway intelligently routes tasks to the cheapest capable model.
|
||||||
|
|
||||||
### US-013 CLI Tooling
|
### US-013 CLI Tooling
|
||||||
|
|
||||||
**As a user**, I can use the `mosaic` CLI for PRD creation, quality rail setup, queue management, and mission coordination.
|
**As a user**, I can use the `mosaic` CLI for PRD creation, quality rail setup, queue management, and mission coordination.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -482,6 +528,7 @@ Telegram remote control channel.
|
|||||||
- FR-21: Skill Import from skills.sh
|
- FR-21: Skill Import from skills.sh
|
||||||
|
|
||||||
### FR-1: Chat System
|
### FR-1: Chat System
|
||||||
|
|
||||||
- Conversation CRUD (create, list, get with messages, delete)
|
- Conversation CRUD (create, list, get with messages, delete)
|
||||||
- Real-time streaming responses via WebSocket
|
- Real-time streaming responses via WebSocket
|
||||||
- Multi-provider support (route to configured LLM)
|
- Multi-provider support (route to configured LLM)
|
||||||
@@ -491,6 +538,7 @@ Telegram remote control channel.
|
|||||||
- Message rendering with markdown, code blocks, tool call display
|
- Message rendering with markdown, code blocks, tool call display
|
||||||
|
|
||||||
### FR-2: Gateway Orchestrator
|
### FR-2: Gateway Orchestrator
|
||||||
|
|
||||||
- Central API surface for all clients (web, TUI, Discord, Telegram)
|
- Central API surface for all clients (web, TUI, Discord, Telegram)
|
||||||
- Agent dispatch — receive task, select provider/model, spawn Pi session, return result
|
- Agent dispatch — receive task, select provider/model, spawn Pi session, return result
|
||||||
- Routing engine — cost/capability matrix, user preference overrides, task-type heuristics
|
- Routing engine — cost/capability matrix, user preference overrides, task-type heuristics
|
||||||
@@ -500,6 +548,7 @@ Telegram remote control channel.
|
|||||||
- Rate limiting and request validation
|
- Rate limiting and request validation
|
||||||
|
|
||||||
### FR-3: Agent Pool (@mosaic/agent)
|
### FR-3: Agent Pool (@mosaic/agent)
|
||||||
|
|
||||||
- Manage concurrent Pi SDK sessions
|
- Manage concurrent Pi SDK sessions
|
||||||
- Provider configuration: API key management, endpoint URLs, model lists
|
- Provider configuration: API key management, endpoint URLs, model lists
|
||||||
- Support providers: Anthropic (subscription + API), OpenAI/Codex (subscription + API), Z.ai, Ollama (local), LM Studio (local), llama.cpp (local)
|
- Support providers: Anthropic (subscription + API), OpenAI/Codex (subscription + API), Z.ai, Ollama (local), LM Studio (local), llama.cpp (local)
|
||||||
@@ -509,6 +558,7 @@ Telegram remote control channel.
|
|||||||
- Graceful shutdown — drain active sessions on shutdown
|
- Graceful shutdown — drain active sessions on shutdown
|
||||||
|
|
||||||
### FR-4: Task Management
|
### FR-4: Task Management
|
||||||
|
|
||||||
- Brain-backed task CRUD with full filter/sort
|
- Brain-backed task CRUD with full filter/sort
|
||||||
- Task statuses: backlog, scheduled, in-progress, blocked, done, cancelled
|
- Task statuses: backlog, scheduled, in-progress, blocked, done, cancelled
|
||||||
- Priority levels: critical, high, medium, low
|
- Priority levels: critical, high, medium, low
|
||||||
@@ -520,6 +570,7 @@ Telegram remote control channel.
|
|||||||
- Due date tracking with stale detection
|
- Due date tracking with stale detection
|
||||||
|
|
||||||
### FR-5: Project Management
|
### FR-5: Project Management
|
||||||
|
|
||||||
- Project CRUD with domain, status, priority
|
- Project CRUD with domain, status, priority
|
||||||
- Link to repository, branch, current/next milestone
|
- Link to repository, branch, current/next milestone
|
||||||
- Progress tracking
|
- Progress tracking
|
||||||
@@ -527,6 +578,7 @@ Telegram remote control channel.
|
|||||||
- Owner assignment
|
- Owner assignment
|
||||||
|
|
||||||
### FR-6: Mission System
|
### FR-6: Mission System
|
||||||
|
|
||||||
- Mission CRUD (linked to project and PRD)
|
- Mission CRUD (linked to project and PRD)
|
||||||
- Mission tasks with phases, dependencies, ordering
|
- Mission tasks with phases, dependencies, ordering
|
||||||
- Mission summary with computed progress
|
- Mission summary with computed progress
|
||||||
@@ -534,6 +586,7 @@ Telegram remote control channel.
|
|||||||
- Active mission dashboard in web UI
|
- Active mission dashboard in web UI
|
||||||
|
|
||||||
### FR-7: Memory System
|
### FR-7: Memory System
|
||||||
|
|
||||||
- **Preferences**: Key-value store for learned user preferences (e.g., "prefers tables over paragraphs", "timezone: America/Chicago")
|
- **Preferences**: Key-value store for learned user preferences (e.g., "prefers tables over paragraphs", "timezone: America/Chicago")
|
||||||
- **Insights**: Distilled knowledge from agent interactions, stored with embeddings
|
- **Insights**: Distilled knowledge from agent interactions, stored with embeddings
|
||||||
- **Semantic search**: Query across all memory using natural language
|
- **Semantic search**: Query across all memory using natural language
|
||||||
@@ -542,6 +595,7 @@ Telegram remote control channel.
|
|||||||
- **Decay**: Old, unused insights decay in relevance score over time
|
- **Decay**: Old, unused insights decay in relevance score over time
|
||||||
|
|
||||||
### FR-8: Authentication & Authorization
|
### FR-8: Authentication & Authorization
|
||||||
|
|
||||||
- BetterAuth integration with Next.js
|
- BetterAuth integration with Next.js
|
||||||
- Email/password registration and login
|
- Email/password registration and login
|
||||||
- SSO via OIDC/SAML: Authentik, WorkOS, Keycloak
|
- SSO via OIDC/SAML: Authentik, WorkOS, Keycloak
|
||||||
@@ -550,6 +604,7 @@ Telegram remote control channel.
|
|||||||
- Session management (web + API)
|
- Session management (web + API)
|
||||||
|
|
||||||
### FR-9: Remote Control — Discord
|
### FR-9: Remote Control — Discord
|
||||||
|
|
||||||
- Discord bot that connects to the gateway
|
- Discord bot that connects to the gateway
|
||||||
- Mention-based activation in channels
|
- Mention-based activation in channels
|
||||||
- DM support for private conversations
|
- DM support for private conversations
|
||||||
@@ -559,6 +614,7 @@ Telegram remote control channel.
|
|||||||
- Permission management (which Discord users/roles can interact)
|
- Permission management (which Discord users/roles can interact)
|
||||||
|
|
||||||
### FR-10: Remote Control — Telegram
|
### FR-10: Remote Control — Telegram
|
||||||
|
|
||||||
- Telegram bot via Telegraf
|
- Telegram bot via Telegraf
|
||||||
- Private and group chat support
|
- Private and group chat support
|
||||||
- Command-based interaction (`/ask`, `/task`, `/status`)
|
- Command-based interaction (`/ask`, `/task`, `/status`)
|
||||||
@@ -566,6 +622,7 @@ Telegram remote control channel.
|
|||||||
- Message routing through gateway
|
- Message routing through gateway
|
||||||
|
|
||||||
### FR-11: LLM Provider Management
|
### FR-11: LLM Provider Management
|
||||||
|
|
||||||
- Provider configuration UI in web dashboard
|
- Provider configuration UI in web dashboard
|
||||||
- Per-provider: API key/endpoint, enabled models, cost per token
|
- Per-provider: API key/endpoint, enabled models, cost per token
|
||||||
- Subscription-based providers: detect available models from subscription
|
- Subscription-based providers: detect available models from subscription
|
||||||
@@ -574,6 +631,7 @@ Telegram remote control channel.
|
|||||||
- Usage tracking per provider/model
|
- Usage tracking per provider/model
|
||||||
|
|
||||||
### FR-12: Agent Routing
|
### FR-12: Agent Routing
|
||||||
|
|
||||||
- Task-type to model-tier mapping (from AGENTS.md cost matrix)
|
- Task-type to model-tier mapping (from AGENTS.md cost matrix)
|
||||||
- User preference overrides (e.g., "always use Claude for code review")
|
- User preference overrides (e.g., "always use Claude for code review")
|
||||||
- Fallback chains (if primary provider unavailable, try next)
|
- Fallback chains (if primary provider unavailable, try next)
|
||||||
@@ -581,6 +639,7 @@ Telegram remote control channel.
|
|||||||
- Routing transparency — user can see why a particular model was chosen
|
- Routing transparency — user can see why a particular model was chosen
|
||||||
|
|
||||||
### FR-13: MCP Capability
|
### FR-13: MCP Capability
|
||||||
|
|
||||||
- Gateway exposes MCP server (streamable HTTP transport)
|
- Gateway exposes MCP server (streamable HTTP transport)
|
||||||
- Brain tools registered as MCP tools
|
- Brain tools registered as MCP tools
|
||||||
- Queue tools registered as MCP tools
|
- Queue tools registered as MCP tools
|
||||||
@@ -589,6 +648,7 @@ Telegram remote control channel.
|
|||||||
- External MCP server connectivity (agent can use third-party MCP servers)
|
- External MCP server connectivity (agent can use third-party MCP servers)
|
||||||
|
|
||||||
### FR-14: Skill Management
|
### FR-14: Skill Management
|
||||||
|
|
||||||
- Skill catalog — list available skills from configured sources
|
- Skill catalog — list available skills from configured sources
|
||||||
- Skill install — install skill to `~/.config/mosaic/skills/` or project-local
|
- Skill install — install skill to `~/.config/mosaic/skills/` or project-local
|
||||||
- Skill configuration — per-skill settings
|
- Skill configuration — per-skill settings
|
||||||
@@ -596,6 +656,7 @@ Telegram remote control channel.
|
|||||||
- Web UI for browsing and managing skills
|
- Web UI for browsing and managing skills
|
||||||
|
|
||||||
### FR-15: CLI Integration
|
### FR-15: CLI Integration
|
||||||
|
|
||||||
- `mosaic gateway start` — start the gateway server
|
- `mosaic gateway start` — start the gateway server
|
||||||
- `mosaic brain` — brain data management
|
- `mosaic brain` — brain data management
|
||||||
- `mosaic queue` — queue operations
|
- `mosaic queue` — queue operations
|
||||||
@@ -605,6 +666,7 @@ Telegram remote control channel.
|
|||||||
- `mosaic tui` — launch Pi TUI connected to gateway
|
- `mosaic tui` — launch Pi TUI connected to gateway
|
||||||
|
|
||||||
### FR-16: Log Service
|
### FR-16: Log Service
|
||||||
|
|
||||||
- Structured log ingest from agent sessions
|
- Structured log ingest from agent sessions
|
||||||
- Parse logs for: decisions made, tools used, errors encountered, learnings captured
|
- Parse logs for: decisions made, tools used, errors encountered, learnings captured
|
||||||
- Tier management: hot (7 days, full detail), warm (30 days, summarized), cold (90 days, key facts only)
|
- Tier management: hot (7 days, full detail), warm (30 days, summarized), cold (90 days, key facts only)
|
||||||
@@ -612,12 +674,14 @@ Telegram remote control channel.
|
|||||||
- Query interface for log search
|
- Query interface for log search
|
||||||
|
|
||||||
### FR-17: Gateway State Persistence
|
### FR-17: Gateway State Persistence
|
||||||
|
|
||||||
- Orchestration state persisted to Valkey (active sessions, pending dispatches, routing context)
|
- Orchestration state persisted to Valkey (active sessions, pending dispatches, routing context)
|
||||||
- On restart, gateway reads Valkey state and resumes — reconnects to active agent sessions
|
- On restart, gateway reads Valkey state and resumes — reconnects to active agent sessions
|
||||||
- `mosaic gateway restart --fresh` clears Valkey queue and all in-flight state (nuclear option)
|
- `mosaic gateway restart --fresh` clears Valkey queue and all in-flight state (nuclear option)
|
||||||
- Session recovery: detect orphaned agent sessions, offer reconnect or cleanup
|
- Session recovery: detect orphaned agent sessions, offer reconnect or cleanup
|
||||||
|
|
||||||
### FR-18: Multi-Session Agent Architecture
|
### FR-18: Multi-Session Agent Architecture
|
||||||
|
|
||||||
- Each agent has a distinct session with dedicated context
|
- Each agent has a distinct session with dedicated context
|
||||||
- Multiple input channels (TUI, web, Discord, Telegram) can connect to same agent session
|
- Multiple input channels (TUI, web, Discord, Telegram) can connect to same agent session
|
||||||
- Channel multiplexing at gateway level with proper authorization
|
- Channel multiplexing at gateway level with proper authorization
|
||||||
@@ -627,6 +691,7 @@ Telegram remote control channel.
|
|||||||
- `mosaic agent list` shows active sessions with connected channels
|
- `mosaic agent list` shows active sessions with connected channels
|
||||||
|
|
||||||
### FR-19: Cron Scheduler
|
### FR-19: Cron Scheduler
|
||||||
|
|
||||||
- Built-in cron scheduler in gateway for recurring tasks
|
- Built-in cron scheduler in gateway for recurring tasks
|
||||||
- Default schedules: log summarization, stale task detection, memory decay, provider health checks
|
- Default schedules: log summarization, stale task detection, memory decay, provider health checks
|
||||||
- Custom schedules: user-defined agent dispatches on cron expressions
|
- Custom schedules: user-defined agent dispatches on cron expressions
|
||||||
@@ -635,12 +700,14 @@ Telegram remote control channel.
|
|||||||
- Persistence: schedules stored in PG, survive gateway restart
|
- Persistence: schedules stored in PG, survive gateway restart
|
||||||
|
|
||||||
### FR-20: Web Search Tool
|
### FR-20: Web Search Tool
|
||||||
|
|
||||||
- DuckDuckGo web search via MCP server (primary — privacy-respecting, no API key)
|
- DuckDuckGo web search via MCP server (primary — privacy-respecting, no API key)
|
||||||
- Registered as standard MCP tool available to all agent sessions
|
- Registered as standard MCP tool available to all agent sessions
|
||||||
- Configurable: can swap to other search providers (Brave, SearXNG, Tavily)
|
- Configurable: can swap to other search providers (Brave, SearXNG, Tavily)
|
||||||
- Results formatted for agent consumption (title, snippet, URL)
|
- Results formatted for agent consumption (title, snippet, URL)
|
||||||
|
|
||||||
### FR-21: Skill Import from skills.sh
|
### FR-21: Skill Import from skills.sh
|
||||||
|
|
||||||
- Browse skills from https://skills.sh directory via API
|
- Browse skills from https://skills.sh directory via API
|
||||||
- Import skills into `~/.config/mosaic/skills/` or project-local `.mosaic/skills/`
|
- Import skills into `~/.config/mosaic/skills/` or project-local `.mosaic/skills/`
|
||||||
- Vetting workflow: imported skills marked as "unvetted" until admin approves
|
- Vetting workflow: imported skills marked as "unvetted" until admin approves
|
||||||
@@ -654,6 +721,7 @@ Telegram remote control channel.
|
|||||||
## Non-Functional Requirements
|
## Non-Functional Requirements
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
- No hardcoded secrets — all secrets via environment variables or vault
|
- No hardcoded secrets — all secrets via environment variables or vault
|
||||||
- API key rotation capability
|
- API key rotation capability
|
||||||
- RBAC enforcement at gateway level
|
- RBAC enforcement at gateway level
|
||||||
@@ -665,6 +733,7 @@ Telegram remote control channel.
|
|||||||
- Database connection encryption (SSL)
|
- Database connection encryption (SSL)
|
||||||
|
|
||||||
### Performance
|
### Performance
|
||||||
|
|
||||||
- Chat response streaming latency < 200ms TTFB (gateway overhead, not LLM latency)
|
- Chat response streaming latency < 200ms TTFB (gateway overhead, not LLM latency)
|
||||||
- Dashboard page loads < 2s
|
- Dashboard page loads < 2s
|
||||||
- Brain query responses < 100ms for filtered reads
|
- Brain query responses < 100ms for filtered reads
|
||||||
@@ -673,6 +742,7 @@ Telegram remote control channel.
|
|||||||
- WebSocket connection handling for 50+ concurrent users
|
- WebSocket connection handling for 50+ concurrent users
|
||||||
|
|
||||||
### Reliability
|
### Reliability
|
||||||
|
|
||||||
- Graceful degradation when LLM provider is unavailable (fallback chain)
|
- Graceful degradation when LLM provider is unavailable (fallback chain)
|
||||||
- Queue persistence — tasks survive gateway restart
|
- Queue persistence — tasks survive gateway restart
|
||||||
- Database connection pooling with retry
|
- Database connection pooling with retry
|
||||||
@@ -680,6 +750,7 @@ Telegram remote control channel.
|
|||||||
- Structured error responses with correlation IDs
|
- Structured error responses with correlation IDs
|
||||||
|
|
||||||
### Observability (Wide-Event Logging — Required from Phase 0)
|
### Observability (Wide-Event Logging — Required from Phase 0)
|
||||||
|
|
||||||
- **OpenTelemetry instrumentation** across all services from day one
|
- **OpenTelemetry instrumentation** across all services from day one
|
||||||
- `@opentelemetry/sdk-node` + `@opentelemetry/auto-instrumentations-node` for auto-instrumentation (HTTP, PG, Fastify/NestJS)
|
- `@opentelemetry/sdk-node` + `@opentelemetry/auto-instrumentations-node` for auto-instrumentation (HTTP, PG, Fastify/NestJS)
|
||||||
- NestJS interceptors for custom spans on agent dispatch, routing decisions, memory writes, summarization runs
|
- NestJS interceptors for custom spans on agent dispatch, routing decisions, memory writes, summarization runs
|
||||||
@@ -693,6 +764,7 @@ Telegram remote control channel.
|
|||||||
- Migrate to Grafana stack (Tempo + Loki + Grafana) post-beta if more customization is needed
|
- Migrate to Grafana stack (Tempo + Loki + Grafana) post-beta if more customization is needed
|
||||||
|
|
||||||
### Scalability (Multi-Tier Readiness)
|
### Scalability (Multi-Tier Readiness)
|
||||||
|
|
||||||
- Single-node deployment is the MVP target for v0.1.0
|
- Single-node deployment is the MVP target for v0.1.0
|
||||||
- Code structured with assumption that multi-tiered deployment will follow: dedicated gateway nodes, agent worker nodes, brain/DB nodes
|
- Code structured with assumption that multi-tiered deployment will follow: dedicated gateway nodes, agent worker nodes, brain/DB nodes
|
||||||
- Service boundaries communicate via HTTP/WS/MCP APIs, not in-process calls where avoidable
|
- Service boundaries communicate via HTTP/WS/MCP APIs, not in-process calls where avoidable
|
||||||
@@ -706,63 +778,74 @@ Telegram remote control channel.
|
|||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
|
|
||||||
### AC-1: Core Chat Flow
|
### AC-1: Core Chat Flow
|
||||||
|
|
||||||
- [ ] User can log in via web UI, send a message, and receive a streamed response
|
- [ ] User can log in via web UI, send a message, and receive a streamed response
|
||||||
- [ ] Conversation persists across page refreshes
|
- [ ] Conversation persists across page refreshes
|
||||||
- [ ] User can create, list, search, and delete conversations
|
- [ ] User can create, list, search, and delete conversations
|
||||||
- [ ] Conversations can be scoped to projects
|
- [ ] Conversations can be scoped to projects
|
||||||
|
|
||||||
### AC-2: TUI Integration
|
### AC-2: TUI Integration
|
||||||
|
|
||||||
- [ ] `mosaic tui` launches Pi interactive mode connected to gateway
|
- [ ] `mosaic tui` launches Pi interactive mode connected to gateway
|
||||||
- [ ] User can chat with same conversation context as web UI
|
- [ ] User can chat with same conversation context as web UI
|
||||||
- [ ] Agent has access to brain, queue, and memory tools
|
- [ ] Agent has access to brain, queue, and memory tools
|
||||||
|
|
||||||
### AC-3: Discord Remote Control
|
### AC-3: Discord Remote Control
|
||||||
|
|
||||||
- [ ] Discord bot connects and responds to mentions
|
- [ ] Discord bot connects and responds to mentions
|
||||||
- [ ] Messages route through gateway to agent pool
|
- [ ] Messages route through gateway to agent pool
|
||||||
- [ ] Responses stream back to Discord (chunked)
|
- [ ] Responses stream back to Discord (chunked)
|
||||||
- [ ] Thread creation for multi-turn conversations
|
- [ ] Thread creation for multi-turn conversations
|
||||||
|
|
||||||
### AC-4: Gateway Orchestration
|
### AC-4: Gateway Orchestration
|
||||||
|
|
||||||
- [ ] Gateway dispatches tasks to appropriate provider/model
|
- [ ] Gateway dispatches tasks to appropriate provider/model
|
||||||
- [ ] Routing decision logged and inspectable
|
- [ ] Routing decision logged and inspectable
|
||||||
- [ ] Fallback when primary provider unavailable
|
- [ ] Fallback when primary provider unavailable
|
||||||
- [ ] Multiple concurrent agent sessions managed correctly
|
- [ ] Multiple concurrent agent sessions managed correctly
|
||||||
|
|
||||||
### AC-5: Task & Project Management
|
### AC-5: Task & Project Management
|
||||||
|
|
||||||
- [ ] CRUD operations for tasks, projects, missions via web dashboard
|
- [ ] CRUD operations for tasks, projects, missions via web dashboard
|
||||||
- [ ] Kanban board view for tasks
|
- [ ] Kanban board view for tasks
|
||||||
- [ ] Mission progress tracking with computed stats
|
- [ ] Mission progress tracking with computed stats
|
||||||
- [ ] Brain MCP tools accessible from agent sessions
|
- [ ] Brain MCP tools accessible from agent sessions
|
||||||
|
|
||||||
### AC-6: Memory System
|
### AC-6: Memory System
|
||||||
|
|
||||||
- [ ] Agent sessions auto-capture decisions and learnings
|
- [ ] Agent sessions auto-capture decisions and learnings
|
||||||
- [ ] Semantic search returns relevant past context
|
- [ ] Semantic search returns relevant past context
|
||||||
- [ ] Learned preferences are applied in new sessions
|
- [ ] Learned preferences are applied in new sessions
|
||||||
- [ ] Log summarization runs on schedule, old logs compressed
|
- [ ] Log summarization runs on schedule, old logs compressed
|
||||||
|
|
||||||
### AC-7: Authentication & RBAC
|
### AC-7: Authentication & RBAC
|
||||||
|
|
||||||
- [ ] Email/password login works
|
- [ ] Email/password login works
|
||||||
- [ ] At least one SSO provider (Authentik) works end-to-end
|
- [ ] At least one SSO provider (Authentik) works end-to-end
|
||||||
- [ ] Admin can create users and assign roles
|
- [ ] Admin can create users and assign roles
|
||||||
- [ ] RBAC enforced on API endpoints
|
- [ ] RBAC enforced on API endpoints
|
||||||
|
|
||||||
### AC-8: Multi-Provider LLM Support
|
### AC-8: Multi-Provider LLM Support
|
||||||
|
|
||||||
- [ ] At least 3 providers configured and routing correctly (e.g., Anthropic + Ollama + Z.ai)
|
- [ ] At least 3 providers configured and routing correctly (e.g., Anthropic + Ollama + Z.ai)
|
||||||
- [ ] Agent routing selects appropriate model for task type
|
- [ ] Agent routing selects appropriate model for task type
|
||||||
- [ ] Provider configuration manageable from web UI
|
- [ ] Provider configuration manageable from web UI
|
||||||
|
|
||||||
### AC-9: MCP
|
### AC-9: MCP
|
||||||
|
|
||||||
- [ ] Gateway exposes MCP endpoint
|
- [ ] Gateway exposes MCP endpoint
|
||||||
- [ ] Brain and queue tools callable via MCP
|
- [ ] Brain and queue tools callable via MCP
|
||||||
- [ ] Agent sessions can connect to external MCP servers
|
- [ ] Agent sessions can connect to external MCP servers
|
||||||
|
|
||||||
### AC-10: Deployment
|
### AC-10: Deployment
|
||||||
|
|
||||||
- [ ] `docker compose up` starts full stack from clean state
|
- [ ] `docker compose up` starts full stack from clean state
|
||||||
- [ ] `mosaic` CLI installable and functional on bare metal
|
- [ ] `mosaic` CLI installable and functional on bare metal
|
||||||
- [ ] Database migrations run automatically on first start
|
- [ ] Database migrations run automatically on first start
|
||||||
- [ ] `.env.example` documents all required configuration
|
- [ ] `.env.example` documents all required configuration
|
||||||
|
|
||||||
### AC-11: @mosaic/* Packages
|
### AC-11: @mosaic/\* Packages
|
||||||
|
|
||||||
- [ ] All 7 migrated packages build, pass tests, and integrate with gateway
|
- [ ] All 7 migrated packages build, pass tests, and integrate with gateway
|
||||||
- [ ] `mosaic` CLI provides subcommands for each package
|
- [ ] `mosaic` CLI provides subcommands for each package
|
||||||
- [ ] Types package is the single source of shared interfaces
|
- [ ] Types package is the single source of shared interfaces
|
||||||
@@ -786,7 +869,7 @@ Telegram remote control channel.
|
|||||||
### Risks
|
### Risks
|
||||||
|
|
||||||
| Risk | Likelihood | Impact | Mitigation |
|
| Risk | Likelihood | Impact | Mitigation |
|
||||||
|------|-----------|--------|------------|
|
| -------------------------------------------------- | ---------- | ------ | ---------------------------------------------------------------------------------------- |
|
||||||
| Pi SDK API instability (pre-1.0) | Medium | High | Pin version, abstract behind @mosaic/agent interface |
|
| Pi SDK API instability (pre-1.0) | Medium | High | Pin version, abstract behind @mosaic/agent interface |
|
||||||
| Brain PG migration complexity | Medium | Medium | Preserve Brain REST/MCP API contract; only storage changes |
|
| Brain PG migration complexity | Medium | Medium | Preserve Brain REST/MCP API contract; only storage changes |
|
||||||
| Discord plugin complexity (OpenClaw has ~60 files) | Medium | Medium | Start minimal (DM + mention in channel), single-guild only; expand iteratively post-beta |
|
| Discord plugin complexity (OpenClaw has ~60 files) | Medium | Medium | Start minimal (DM + mention in channel), single-guild only; expand iteratively post-beta |
|
||||||
@@ -798,7 +881,7 @@ Telegram remote control channel.
|
|||||||
### Open Questions
|
### Open Questions
|
||||||
|
|
||||||
| # | Question | Priority | Status |
|
| # | Question | Priority | Status |
|
||||||
|---|----------|----------|--------|
|
| --- | ------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| 1 | Pi SDK version to pin for v0.1.0? | High | ✅ Resolved — Pin `@mariozechner/pi-coding-agent@~0.57.1` (current stable). Abstract behind `@mosaic/agent` interface to insulate from breaking changes. Bump deliberately after testing. |
|
| 1 | Pi SDK version to pin for v0.1.0? | High | ✅ Resolved — Pin `@mariozechner/pi-coding-agent@~0.57.1` (current stable). Abstract behind `@mosaic/agent` interface to insulate from breaking changes. Bump deliberately after testing. |
|
||||||
| 2 | Authentik vs WorkOS vs Keycloak — which SSO provider to implement first? | Medium | ✅ Resolved — Authentik first (already in Jason's infrastructure) |
|
| 2 | Authentik vs WorkOS vs Keycloak — which SSO provider to implement first? | Medium | ✅ Resolved — Authentik first (already in Jason's infrastructure) |
|
||||||
| 3 | Vector DB: pgvector sufficient or need Qdrant from the start? | Medium | ✅ Resolved — pgvector with VectorStore interface abstraction. Qdrant drops in later if needed. |
|
| 3 | Vector DB: pgvector sufficient or need Qdrant from the start? | Medium | ✅ Resolved — pgvector with VectorStore interface abstraction. Qdrant drops in later if needed. |
|
||||||
@@ -825,6 +908,7 @@ Telegram remote control channel.
|
|||||||
All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
||||||
|
|
||||||
### Phase 0: Foundation (v0.0.1)
|
### Phase 0: Foundation (v0.0.1)
|
||||||
|
|
||||||
- Scaffold monorepo (pnpm + turbo + tsconfig + eslint + vitest)
|
- Scaffold monorepo (pnpm + turbo + tsconfig + eslint + vitest)
|
||||||
- `@mosaic/types` — migrate and extend from v0
|
- `@mosaic/types` — migrate and extend from v0
|
||||||
- `@mosaic/db` — Drizzle schema, PG connection, migrations
|
- `@mosaic/db` — Drizzle schema, PG connection, migrations
|
||||||
@@ -835,6 +919,7 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
|||||||
- AGENTS.md, CLAUDE.md, README.md
|
- AGENTS.md, CLAUDE.md, README.md
|
||||||
|
|
||||||
### Phase 1: Core API (v0.0.2)
|
### Phase 1: Core API (v0.0.2)
|
||||||
|
|
||||||
- `apps/gateway` — NestJS server (Fastify adapter), auth middleware, health endpoints
|
- `apps/gateway` — NestJS server (Fastify adapter), auth middleware, health endpoints
|
||||||
- `@mosaic/brain` — migrate from v0, swap JSON store for PG via @mosaic/db
|
- `@mosaic/brain` — migrate from v0, swap JSON store for PG via @mosaic/db
|
||||||
- `@mosaic/queue` — migrate from v0 (minimal changes)
|
- `@mosaic/queue` — migrate from v0 (minimal changes)
|
||||||
@@ -843,6 +928,7 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
|||||||
- Basic agent dispatch (single provider, no routing)
|
- Basic agent dispatch (single provider, no routing)
|
||||||
|
|
||||||
### Phase 2: Agent Layer (v0.0.3)
|
### Phase 2: Agent Layer (v0.0.3)
|
||||||
|
|
||||||
- `@mosaic/agent` — Pi SDK integration, agent pool manager
|
- `@mosaic/agent` — Pi SDK integration, agent pool manager
|
||||||
- Multi-provider support (Anthropic + Ollama minimum)
|
- Multi-provider support (Anthropic + Ollama minimum)
|
||||||
- Agent routing engine (cost/capability matrix)
|
- Agent routing engine (cost/capability matrix)
|
||||||
@@ -850,6 +936,7 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
|||||||
- `@mosaic/coord` — migrate from v0, integrate with gateway
|
- `@mosaic/coord` — migrate from v0, integrate with gateway
|
||||||
|
|
||||||
### Phase 3: Web Dashboard (v0.0.4)
|
### Phase 3: Web Dashboard (v0.0.4)
|
||||||
|
|
||||||
- `apps/web` — Next.js app with BetterAuth
|
- `apps/web` — Next.js app with BetterAuth
|
||||||
- Chat UI (conversation list, message display, streaming input)
|
- Chat UI (conversation list, message display, streaming input)
|
||||||
- Task management (list + kanban)
|
- Task management (list + kanban)
|
||||||
@@ -858,6 +945,7 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
|||||||
- Admin panel (user management, RBAC)
|
- Admin panel (user management, RBAC)
|
||||||
|
|
||||||
### Phase 4: Memory & Intelligence (v0.0.5)
|
### Phase 4: Memory & Intelligence (v0.0.5)
|
||||||
|
|
||||||
- `@mosaic/memory` — preference store, insight store, semantic search
|
- `@mosaic/memory` — preference store, insight store, semantic search
|
||||||
- `@mosaic/log` — log ingest, parsing, tiered storage
|
- `@mosaic/log` — log ingest, parsing, tiered storage
|
||||||
- Summarization pipeline
|
- Summarization pipeline
|
||||||
@@ -865,12 +953,14 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
|||||||
- Skill management interface (web UI + CLI)
|
- Skill management interface (web UI + CLI)
|
||||||
|
|
||||||
### Phase 5: Remote Control (v0.0.6)
|
### Phase 5: Remote Control (v0.0.6)
|
||||||
|
|
||||||
- `@mosaic/discord-plugin` — Discord channel plugin
|
- `@mosaic/discord-plugin` — Discord channel plugin
|
||||||
- `@mosaic/telegram-plugin` — Telegram channel plugin
|
- `@mosaic/telegram-plugin` — Telegram channel plugin
|
||||||
- Plugin host in gateway
|
- Plugin host in gateway
|
||||||
- SSO configuration (Authentik)
|
- SSO configuration (Authentik)
|
||||||
|
|
||||||
### Phase 6: CLI & Tools (v0.0.7)
|
### Phase 6: CLI & Tools (v0.0.7)
|
||||||
|
|
||||||
- `@mosaic/cli` — unified CLI with all subcommands
|
- `@mosaic/cli` — unified CLI with all subcommands
|
||||||
- `@mosaic/prdy` — migrate from v0
|
- `@mosaic/prdy` — migrate from v0
|
||||||
- `@mosaic/quality-rails` — migrate from v0
|
- `@mosaic/quality-rails` — migrate from v0
|
||||||
@@ -878,6 +968,7 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
|||||||
- Pi TUI integration (`mosaic tui`)
|
- Pi TUI integration (`mosaic tui`)
|
||||||
|
|
||||||
### Phase 7: Polish & Beta (v0.0.8 → v0.1.0)
|
### Phase 7: Polish & Beta (v0.0.8 → v0.1.0)
|
||||||
|
|
||||||
- MCP endpoint hardening
|
- MCP endpoint hardening
|
||||||
- Additional SSO providers (WorkOS/Keycloak)
|
- Additional SSO providers (WorkOS/Keycloak)
|
||||||
- Additional LLM providers (Codex, Z.ai, LM Studio, llama.cpp)
|
- Additional LLM providers (Codex, Z.ai, LM Studio, llama.cpp)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
> Single-writer: orchestrator only. Workers read but never modify.
|
> Single-writer: orchestrator only. Workers read but never modify.
|
||||||
|
|
||||||
| id | status | milestone | description | pr | notes |
|
| id | status | milestone | description | pr | notes |
|
||||||
|----|--------|-----------|-------------|----|-------|
|
| ------ | ----------- | --------- | ------------------------------------------------------------ | --- | ----- |
|
||||||
| P0-001 | not-started | Phase 0 | Scaffold monorepo | — | #1 |
|
| P0-001 | not-started | Phase 0 | Scaffold monorepo | — | #1 |
|
||||||
| P0-002 | not-started | Phase 0 | @mosaic/types — migrate and extend shared types | — | #2 |
|
| P0-002 | not-started | Phase 0 | @mosaic/types — migrate and extend shared types | — | #2 |
|
||||||
| P0-003 | not-started | Phase 0 | @mosaic/db — Drizzle schema and PG connection | — | #3 |
|
| P0-003 | not-started | Phase 0 | @mosaic/db — Drizzle schema and PG connection | — | #3 |
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ User confirmed: start the planning gate.
|
|||||||
### Phase structure
|
### Phase structure
|
||||||
|
|
||||||
| Phase | Version | Tasks | Focus |
|
| Phase | Version | Tasks | Focus |
|
||||||
|-------|---------|-------|-------|
|
| ----- | ------- | ----- | ---------------------------------------------------------- |
|
||||||
| 0 | v0.0.1 | 9 | Foundation — monorepo, types, db, auth, OTEL, Docker, CI |
|
| 0 | v0.0.1 | 9 | Foundation — monorepo, types, db, auth, OTEL, Docker, CI |
|
||||||
| 1 | v0.0.2 | 9 | Core API — gateway, brain, queue, routes, WebSocket |
|
| 1 | v0.0.2 | 9 | Core API — gateway, brain, queue, routes, WebSocket |
|
||||||
| 2 | v0.0.3 | 7 | Agent Layer — Pi SDK, multi-provider, routing, coord |
|
| 2 | v0.0.3 | 7 | Agent Layer — Pi SDK, multi-provider, routing, coord |
|
||||||
@@ -38,7 +38,7 @@ User confirmed: start the planning gate.
|
|||||||
## Session Log
|
## Session Log
|
||||||
|
|
||||||
| Session | Date | Milestone | Tasks Done | Outcome |
|
| Session | Date | Milestone | Tasks Done | Outcome |
|
||||||
|---------|------|-----------|------------|---------|
|
| ------- | ---------- | --------- | ------------- | --------------------------------------------------------------------------- |
|
||||||
| 1 | 2026-03-13 | Planning | Planning gate | Milestones created, 59 issues created, TASKS.md populated, manifest updated |
|
| 1 | 2026-03-13 | Planning | Planning gate | Milestones created, 59 issues created, TASKS.md populated, manifest updated |
|
||||||
|
|
||||||
## Open Questions
|
## Open Questions
|
||||||
@@ -58,7 +58,7 @@ User confirmed: start the planning gate.
|
|||||||
**Revised execution sequence:**
|
**Revised execution sequence:**
|
||||||
|
|
||||||
| Step | Tasks (cross-phase) | What it proves |
|
| Step | Tasks (cross-phase) | What it proves |
|
||||||
|------|---------------------|----------------|
|
| ---- | -------------------------------------------------------------------- | ------------------------ |
|
||||||
| 1 | P0-001: Scaffold monorepo | Build system works |
|
| 1 | P0-001: Scaffold monorepo | Build system works |
|
||||||
| 2 | P0-005: Docker Compose (PG + Valkey) | Infrastructure runs |
|
| 2 | P0-005: Docker Compose (PG + Valkey) | Infrastructure runs |
|
||||||
| 3 | P0-002: @mosaic/types (minimal — gateway, agent, chat types) | Shared contracts |
|
| 3 | P0-002: @mosaic/types (minimal — gateway, agent, chat types) | Shared contracts |
|
||||||
|
|||||||
26
eslint.config.mjs
Normal file
26
eslint.config.mjs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import tseslint from 'typescript-eslint';
|
||||||
|
import tsPlugin from '@typescript-eslint/eslint-plugin';
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
{
|
||||||
|
ignores: ['**/dist/**', '**/node_modules/**', '**/.next/**', '**/coverage/**'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': tsPlugin,
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
parserOptions: {
|
||||||
|
projectService: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||||
|
'@typescript-eslint/no-explicit-any': 'warn',
|
||||||
|
'@typescript-eslint/consistent-type-imports': 'error',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "mosaic-stack",
|
||||||
|
"private": true,
|
||||||
|
"packageManager": "pnpm@10.6.2",
|
||||||
|
"scripts": {
|
||||||
|
"build": "turbo run build",
|
||||||
|
"dev": "turbo run dev",
|
||||||
|
"lint": "turbo run lint",
|
||||||
|
"typecheck": "turbo run typecheck",
|
||||||
|
"test": "turbo run test",
|
||||||
|
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
|
||||||
|
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"",
|
||||||
|
"prepare": "husky"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
|
"eslint": "^9.0.0",
|
||||||
|
"typescript-eslint": "^8.0.0",
|
||||||
|
"husky": "^9.0.0",
|
||||||
|
"lint-staged": "^15.0.0",
|
||||||
|
"prettier": "^3.0.0",
|
||||||
|
"turbo": "^2.0.0",
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
25
packages/agent/package.json
Normal file
25
packages/agent/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/agent",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mosaic/types": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/agent/src/index.ts
Normal file
1
packages/agent/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/agent/tsconfig.json
Normal file
9
packages/agent/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/agent/vitest.config.ts
Normal file
8
packages/agent/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/auth/package.json
Normal file
22
packages/auth/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/auth",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/auth/src/index.ts
Normal file
1
packages/auth/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/auth/tsconfig.json
Normal file
9
packages/auth/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/auth/vitest.config.ts
Normal file
8
packages/auth/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
25
packages/brain/package.json
Normal file
25
packages/brain/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/brain",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mosaic/types": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/brain/src/index.ts
Normal file
1
packages/brain/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/brain/tsconfig.json
Normal file
9
packages/brain/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/brain/vitest.config.ts
Normal file
8
packages/brain/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
25
packages/cli/package.json
Normal file
25
packages/cli/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/cli",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"bin": {
|
||||||
|
"mosaic": "dist/index.js"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/cli/src/index.ts
Normal file
1
packages/cli/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/cli/tsconfig.json
Normal file
9
packages/cli/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/cli/vitest.config.ts
Normal file
8
packages/cli/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
25
packages/coord/package.json
Normal file
25
packages/coord/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/coord",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mosaic/types": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/coord/src/index.ts
Normal file
1
packages/coord/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/coord/tsconfig.json
Normal file
9
packages/coord/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/coord/vitest.config.ts
Normal file
8
packages/coord/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/db/package.json
Normal file
22
packages/db/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/db",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/db/src/index.ts
Normal file
1
packages/db/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/db/tsconfig.json
Normal file
9
packages/db/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/db/vitest.config.ts
Normal file
8
packages/db/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/design-tokens/package.json
Normal file
22
packages/design-tokens/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/design-tokens",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/design-tokens/src/index.ts
Normal file
1
packages/design-tokens/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/design-tokens/tsconfig.json
Normal file
9
packages/design-tokens/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/design-tokens/vitest.config.ts
Normal file
8
packages/design-tokens/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/log/package.json
Normal file
22
packages/log/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/log",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/log/src/index.ts
Normal file
1
packages/log/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/log/tsconfig.json
Normal file
9
packages/log/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/log/vitest.config.ts
Normal file
8
packages/log/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
25
packages/memory/package.json
Normal file
25
packages/memory/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/memory",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mosaic/types": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/memory/src/index.ts
Normal file
1
packages/memory/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/memory/tsconfig.json
Normal file
9
packages/memory/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/memory/vitest.config.ts
Normal file
8
packages/memory/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/mosaic/package.json
Normal file
22
packages/mosaic/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/mosaic",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/mosaic/src/index.ts
Normal file
1
packages/mosaic/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/mosaic/tsconfig.json
Normal file
9
packages/mosaic/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/mosaic/vitest.config.ts
Normal file
8
packages/mosaic/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/prdy/package.json
Normal file
22
packages/prdy/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/prdy",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/prdy/src/index.ts
Normal file
1
packages/prdy/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/prdy/tsconfig.json
Normal file
9
packages/prdy/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/prdy/vitest.config.ts
Normal file
8
packages/prdy/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/quality-rails/package.json
Normal file
22
packages/quality-rails/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/quality-rails",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/quality-rails/src/index.ts
Normal file
1
packages/quality-rails/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/quality-rails/tsconfig.json
Normal file
9
packages/quality-rails/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/quality-rails/vitest.config.ts
Normal file
8
packages/quality-rails/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
25
packages/queue/package.json
Normal file
25
packages/queue/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/queue",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mosaic/types": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/queue/src/index.ts
Normal file
1
packages/queue/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/queue/tsconfig.json
Normal file
9
packages/queue/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/queue/vitest.config.ts
Normal file
8
packages/queue/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
packages/types/package.json
Normal file
22
packages/types/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/types",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/types/src/index.ts
Normal file
1
packages/types/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
packages/types/tsconfig.json
Normal file
9
packages/types/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
packages/types/vitest.config.ts
Normal file
8
packages/types/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
plugins/discord/package.json
Normal file
22
plugins/discord/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/discord-plugin",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
plugins/discord/src/index.ts
Normal file
1
plugins/discord/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
plugins/discord/tsconfig.json
Normal file
9
plugins/discord/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
plugins/discord/vitest.config.ts
Normal file
8
plugins/discord/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
22
plugins/telegram/package.json
Normal file
22
plugins/telegram/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@mosaic/telegram-plugin",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test": "vitest run"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.8.0",
|
||||||
|
"vitest": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
plugins/telegram/src/index.ts
Normal file
1
plugins/telegram/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const VERSION = '0.0.0';
|
||||||
9
plugins/telegram/tsconfig.json
Normal file
9
plugins/telegram/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
8
plugins/telegram/vitest.config.ts
Normal file
8
plugins/telegram/vitest.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
},
|
||||||
|
});
|
||||||
4658
pnpm-lock.yaml
generated
Normal file
4658
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
4
pnpm-workspace.yaml
Normal file
4
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
packages:
|
||||||
|
- 'apps/*'
|
||||||
|
- 'packages/*'
|
||||||
|
- 'plugins/*'
|
||||||
23
tsconfig.base.json
Normal file
23
tsconfig.base.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"strict": true,
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2022"],
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"incremental": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
26
turbo.json
Normal file
26
turbo.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://turbo.build/schema.json",
|
||||||
|
"ui": "tui",
|
||||||
|
"tasks": {
|
||||||
|
"build": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"inputs": ["$TURBO_DEFAULT$", ".env*"],
|
||||||
|
"outputs": ["dist/**"]
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"dependsOn": ["^lint"]
|
||||||
|
},
|
||||||
|
"typecheck": {
|
||||||
|
"dependsOn": ["^typecheck"]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"inputs": ["$TURBO_DEFAULT$"],
|
||||||
|
"outputs": ["coverage/**"]
|
||||||
|
},
|
||||||
|
"dev": {
|
||||||
|
"cache": false,
|
||||||
|
"persistent": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
vitest.workspace.ts
Normal file
7
vitest.workspace.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { defineWorkspace } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineWorkspace([
|
||||||
|
'packages/*/vitest.config.ts',
|
||||||
|
'apps/*/vitest.config.ts',
|
||||||
|
'plugins/*/vitest.config.ts',
|
||||||
|
]);
|
||||||
Reference in New Issue
Block a user