init: 确定项目骨架

This commit is contained in:
李岩岩 2026-08-12 15:18:51 +08:00
parent 273750cd0d
commit e463772761
56 changed files with 1055 additions and 10 deletions

View File

@ -1,8 +1,8 @@
工作流: "idea-to-product"
项目: "Great Agent 2"
版本: "0.3.0"
当前阶段: "实施方案待确认"
更新时间: "2026-08-11"
当前阶段: "骨架待确认"
更新时间: "2026-08-12"
阻塞: null
阶段门:
@ -11,11 +11,11 @@
确认人: "用户"
确认时间: "2026-08-11"
实施方案:
状态: "确认"
确认人: null
确认时间: null
状态: "确认"
确认人: "用户"
确认时间: "2026-08-12"
项目骨架:
状态: "未开始"
状态: "待确认"
确认人: null
确认时间: null
功能验收:

10
.env.example Normal file
View File

@ -0,0 +1,10 @@
HOST=127.0.0.1
PORT=3000
DATA_DIR=./data
DEFAULT_WORKSPACE_ROOT=./workspace
DEEPSEEK_API_KEY=
DEEPSEEK_BASE_URL=https://api.deepseek.com
DEEPSEEK_MODEL=deepseek-v4-pro
DEEPSEEK_THINKING=enabled
MODEL_TIMEOUT_MS=120000
LOG_LEVEL=info

7
.gitignore vendored
View File

@ -2,6 +2,8 @@
dist
node_modules
data
workspace
.env
.env.local
.env.*.local
@ -10,6 +12,9 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
*.log
.temp
.cache
.cache
playwright-report/
test-results/

17
Dockerfile Normal file
View File

@ -0,0 +1,17 @@
FROM oven/bun:1.3.11 AS build
WORKDIR /app
COPY package.json bun.lock bunfig.toml tsconfig.base.json biome.json ./
COPY apps ./apps
COPY packages ./packages
COPY scripts ./scripts
RUN bun install --frozen-lockfile
RUN bun run build
FROM oven/bun:1.3.11 AS runtime
WORKDIR /app
ENV HOST=0.0.0.0 PORT=3000 DATA_DIR=/data DEFAULT_WORKSPACE_ROOT=/workspace
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/apps/web/dist ./apps/web/dist
COPY --from=build /app/apps/web-server/dist ./apps/web-server/dist
EXPOSE 3000
CMD ["bun", "apps/web-server/dist/index.js"]

View File

@ -0,0 +1,21 @@
{
"name": "@great-agent/web-server",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "bun --watch src/index.ts",
"typecheck": "tsc --noEmit",
"build": "bun build src/index.ts --outdir dist --target bun"
},
"dependencies": {
"@great-agent/agent-core": "workspace:*",
"@great-agent/local-data": "workspace:*",
"@great-agent/local-files": "workspace:*",
"@great-agent/model-deepseek": "workspace:*",
"@great-agent/web-contracts": "workspace:*",
"hono": "^4.9.0",
"pino": "^9.9.0",
"zod": "^4.1.0"
}
}

View File

@ -0,0 +1,14 @@
import { describe, expect, test } from "bun:test";
import pino from "pino";
import { healthResponseSchema } from "@great-agent/web-contracts";
import { createApp } from "./create-app";
describe("Web Server 骨架", () => {
test("健康检查返回约定格式和请求标识", async () => {
const app = createApp(pino({ enabled: false }));
const response = await app.request("/api/health");
expect(response.status).toBe(200);
expect(response.headers.get("X-Request-ID")).toBeTruthy();
expect(healthResponseSchema.parse(await response.json()).status).toBe("ok");
});
});

View File

@ -0,0 +1,13 @@
import { Hono } from "hono";
import type { Logger } from "pino";
import { createErrorHandler } from "../http/error-handler";
import { requestId } from "../http/request-id";
import { createHealthRoutes } from "../routes/health";
export function createApp(logger: Logger): Hono {
const app = new Hono();
app.use("*", requestId);
app.onError(createErrorHandler(logger));
app.route("/api", createHealthRoutes());
return app;
}

View File

@ -0,0 +1,8 @@
import pino, { type Logger } from "pino";
export function createLogger(level: string): Logger {
return pino({
level,
redact: ["deepSeekApiKey", "req.headers.authorization"],
});
}

View File

@ -0,0 +1,30 @@
import { afterEach, describe, expect, test } from "bun:test";
import { mkdtemp, rm } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { Hono } from "hono";
import { mountStaticWeb } from "./static-web";
let temporaryRoot: string | undefined;
afterEach(async () => {
if (temporaryRoot) await rm(temporaryRoot, { recursive: true, force: true });
temporaryRoot = undefined;
});
describe("静态 Web 挂载", () => {
test("返回构建后的首页", async () => {
temporaryRoot = await mkdtemp(join(tmpdir(), "great-agent2-web-"));
await Bun.write(join(temporaryRoot, "assets", "app.js"), "export {};");
await Bun.write(
join(temporaryRoot, "index.html"),
"<h1>Great Agent 2</h1>",
);
const app = new Hono();
mountStaticWeb(app, temporaryRoot);
const response = await app.request("/");
expect(response.status).toBe(200);
expect(await response.text()).toContain("Great Agent 2");
expect((await app.request("/assets/app.js")).status).toBe(200);
});
});

View File

@ -0,0 +1,19 @@
import { existsSync } from "node:fs";
import { join } from "node:path";
import type { Hono } from "hono";
export function mountStaticWeb(app: Hono, webRoot: string): void {
if (!existsSync(webRoot)) return;
app.get("/assets/*", async (context) => {
const relativePath = context.req.path.slice(1);
const asset = Bun.file(join(webRoot, relativePath));
if (!(await asset.exists())) return context.notFound();
return new Response(asset);
});
app.get("*", async () => {
const indexFile = Bun.file(join(webRoot, "index.html"));
return new Response(indexFile, {
headers: { "Content-Type": "text/html; charset=utf-8" },
});
});
}

View File

@ -0,0 +1,11 @@
import { describe, expect, test } from "bun:test";
import { loadEnvironment } from "./environment";
describe("环境配置", () => {
test("使用安全的本机开发默认值", () => {
const environment = loadEnvironment({});
expect(environment.host).toBe("127.0.0.1");
expect(environment.port).toBe(3000);
expect(environment.deepSeekApiKey).toBeUndefined();
});
});

View File

@ -0,0 +1,50 @@
import { resolve } from "node:path";
import { z } from "zod";
const environmentSchema = z.object({
HOST: z.string().default("127.0.0.1"),
PORT: z.coerce.number().int().min(1).max(65_535).default(3000),
DATA_DIR: z.string().min(1).default("./data"),
DEFAULT_WORKSPACE_ROOT: z.string().min(1).default("./workspace"),
DEEPSEEK_API_KEY: z.string().optional(),
DEEPSEEK_BASE_URL: z.url().default("https://api.deepseek.com"),
DEEPSEEK_MODEL: z.string().min(1).default("deepseek-v4-pro"),
DEEPSEEK_THINKING: z.enum(["enabled", "disabled"]).default("enabled"),
MODEL_TIMEOUT_MS: z.coerce.number().int().positive().default(120_000),
LOG_LEVEL: z
.enum(["trace", "debug", "info", "warn", "error", "fatal"])
.default("info"),
});
export type Environment = Readonly<{
host: string;
port: number;
dataDir: string;
defaultWorkspaceRoot: string;
deepSeekApiKey?: string;
deepSeekBaseUrl: string;
deepSeekModel: string;
deepSeekThinking: "enabled" | "disabled";
modelTimeoutMs: number;
logLevel: string;
}>;
export function loadEnvironment(
source: Record<string, string | undefined> = process.env,
): Environment {
const value = environmentSchema.parse(source);
return {
host: value.HOST,
port: value.PORT,
dataDir: resolve(value.DATA_DIR),
defaultWorkspaceRoot: resolve(value.DEFAULT_WORKSPACE_ROOT),
...(value.DEEPSEEK_API_KEY
? { deepSeekApiKey: value.DEEPSEEK_API_KEY }
: {}),
deepSeekBaseUrl: value.DEEPSEEK_BASE_URL,
deepSeekModel: value.DEEPSEEK_MODEL,
deepSeekThinking: value.DEEPSEEK_THINKING,
modelTimeoutMs: value.MODEL_TIMEOUT_MS,
logLevel: value.LOG_LEVEL,
};
}

View File

@ -0,0 +1,19 @@
import type { ErrorHandler } from "hono";
import type { Logger } from "pino";
export function createErrorHandler(logger: Logger): ErrorHandler {
return (error, context) => {
const requestId = context.get("requestId") ?? crypto.randomUUID();
logger.error({ error, requestId }, "请求处理失败");
return context.json(
{
error: {
code: "INTERNAL_ERROR",
message: "服务暂时不可用",
requestId,
},
},
500,
);
};
}

View File

@ -0,0 +1,8 @@
import type { MiddlewareHandler } from "hono";
export const requestId: MiddlewareHandler = async (context, next) => {
const id = context.req.header("X-Request-ID") ?? crypto.randomUUID();
context.set("requestId", id);
context.header("X-Request-ID", id);
await next();
};

View File

@ -0,0 +1,29 @@
import { resolve } from "node:path";
import { createDataLayout, ensureDataLayout } from "@great-agent/local-data";
import { createApp } from "./composition/create-app";
import { createLogger } from "./composition/create-logger";
import { mountStaticWeb } from "./composition/static-web";
import { loadEnvironment } from "./config/environment";
const environment = loadEnvironment();
const logger = createLogger(environment.logLevel);
const layout = createDataLayout(environment.dataDir);
await ensureDataLayout(layout);
const app = createApp(logger);
mountStaticWeb(app, resolve(import.meta.dir, "../../web/dist"));
logger.info(
{
host: environment.host,
port: environment.port,
dataDir: environment.dataDir,
},
"Great Agent 2 服务启动",
);
export default {
hostname: environment.host,
port: environment.port,
fetch: app.fetch,
};

View File

@ -0,0 +1,15 @@
import { Hono } from "hono";
import type { HealthResponse } from "@great-agent/web-contracts";
export function createHealthRoutes(): Hono {
const routes = new Hono();
routes.get("/health", (context) => {
const response: HealthResponse = {
status: "ok",
service: "great-agent2",
timestamp: new Date().toISOString(),
};
return context.json(response);
});
return routes;
}

View File

@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist-types" },
"include": ["src"]
}

12
apps/web/index.html Normal file
View File

@ -0,0 +1,12 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Great Agent 2</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

18
apps/web/package.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "@great-agent/web",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"typecheck": "tsc --noEmit",
"build": "vite build"
},
"dependencies": {
"@great-agent/web-contracts": "workspace:*",
"vanjs-core": "^1.5.5"
},
"devDependencies": {
"vite": "^7.1.0"
}
}

View File

@ -0,0 +1,11 @@
import van from "vanjs-core";
const { h1, main, p } = van.tags;
export function AppShell(): HTMLElement {
return main(
{ class: "app-shell" },
h1("Great Agent 2"),
p("项目骨架运行正常,产品界面将在纵向功能阶段实现。"),
);
}

8
apps/web/src/main.ts Normal file
View File

@ -0,0 +1,8 @@
import van from "vanjs-core";
import { AppShell } from "./app/app-shell";
import "./styles/global.css";
const mount = document.querySelector<HTMLElement>("#app");
if (!mount) throw new Error("缺少应用挂载节点 #app");
van.add(mount, AppShell());

View File

@ -0,0 +1,31 @@
:root {
color: #272522;
background: #f7f6f2;
font-family: ui-sans-serif, system-ui, sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.app-shell {
display: grid;
min-height: 100vh;
place-content: center;
padding: 2rem;
text-align: center;
}
.app-shell h1 {
margin: 0 0 0.75rem;
font-size: 2rem;
}
.app-shell p {
margin: 0;
color: #6b6760;
}

1
apps/web/src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

9
apps/web/tsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist-types",
"lib": ["ES2022", "DOM", "DOM.Iterable"]
},
"include": ["src"]
}

18
biome.json Normal file
View File

@ -0,0 +1,18 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.8/schema.json",
"files": {
"includes": ["**", "!**/dist", "!**/node_modules", "!data"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": { "preset": "recommended" }
},
"javascript": {
"formatter": { "quoteStyle": "double", "semicolons": "always" }
}
}

272
bun.lock Normal file
View File

@ -0,0 +1,272 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "great-agent2",
"devDependencies": {
"@biomejs/biome": "^2.2.0",
"@types/bun": "^1.3.0",
"typescript": "^5.9.0",
},
},
"apps/web": {
"name": "@great-agent/web",
"version": "0.1.0",
"dependencies": {
"@great-agent/web-contracts": "workspace:*",
"vanjs-core": "^1.5.5",
},
"devDependencies": {
"vite": "^7.1.0",
},
},
"apps/web-server": {
"name": "@great-agent/web-server",
"version": "0.1.0",
"dependencies": {
"@great-agent/agent-core": "workspace:*",
"@great-agent/local-data": "workspace:*",
"@great-agent/local-files": "workspace:*",
"@great-agent/model-deepseek": "workspace:*",
"@great-agent/web-contracts": "workspace:*",
"hono": "^4.9.0",
"pino": "^9.9.0",
"zod": "^4.1.0",
},
},
"packages/agent-core": {
"name": "@great-agent/agent-core",
"version": "0.1.0",
},
"packages/local-data": {
"name": "@great-agent/local-data",
"version": "0.1.0",
},
"packages/local-files": {
"name": "@great-agent/local-files",
"version": "0.1.0",
"dependencies": {
"@great-agent/agent-core": "workspace:*",
},
},
"packages/model-deepseek": {
"name": "@great-agent/model-deepseek",
"version": "0.1.0",
"dependencies": {
"@great-agent/agent-core": "workspace:*",
"openai": "^5.19.0",
},
},
"packages/web-contracts": {
"name": "@great-agent/web-contracts",
"version": "0.1.0",
"dependencies": {
"zod": "^4.1.0",
},
},
},
"packages": {
"@biomejs/biome": ["@biomejs/biome@2.5.8", "https://registry.npmmirror.com/@biomejs/biome/-/biome-2.5.8.tgz", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.8", "@biomejs/cli-darwin-x64": "2.5.8", "@biomejs/cli-linux-arm64": "2.5.8", "@biomejs/cli-linux-arm64-musl": "2.5.8", "@biomejs/cli-linux-x64": "2.5.8", "@biomejs/cli-linux-x64-musl": "2.5.8", "@biomejs/cli-win32-arm64": "2.5.8", "@biomejs/cli-win32-x64": "2.5.8" }, "bin": { "biome": "bin/biome" } }, "sha512-aeAeeJB9fSDc7Gq+2GqpQxA0qBj6gj1k2R6L1cYqGePKP/baIq1WX8y6B+D+nRsO5ViQL22K/8IwbqERW0q1nw=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.8.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-mk1QON9PHllvvLN5gU3f4rMxeh4syK5p9OvKyWH6/W8ueh04uaC8TUXXByhGufWf/y5mQc03ZLM45zU+cmqMjA=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.8.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-bsGwFMBNyHPyiLSsQcZJxdoRrg1V4JL+d7wEsvUBczlP9U9lwM+7mzQHxI4o1mhBsTmdOBbAb6fHU3Z3snN45w=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.8.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-XmFiA0WPYFC+uiUDC8WRFzAIH9bo7vwQLav38Uoq4ETC+T/+uBi0TsYGJECkugY3r8USl3jc+Ae2/irAF6F2lQ=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.8.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-VcJNbstduTHx83NGAdhp78/JOcP45BZHXL7yNsfI1uGzdUgegAz2s+mSoT7wK6PBNzLoqG0zDOXaz/RQYVtSiw=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.8.tgz", { "os": "linux", "cpu": "x64" }, "sha512-S5wcm9OBDvLHodD4PUaN488hCpco9QD/9ZxuYJiw4euWtr/oQvLR72z2ixItH8Wd5BCm6FZaeb+YNvOoM1xHtQ=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.8.tgz", { "os": "linux", "cpu": "x64" }, "sha512-kKmiyokeISRGq2FLwvr+TzsgBusfxaZ0FZNLcOYOpCK/78tRrEjeEBLvq3xLZMpqbANgJdRPI7vZX8ZL37u9/w=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.8", "https://registry.npmmirror.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.8.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-nILH0mzm3Hi3iEdd7o7GpB8kBR/mSQwfQG/tyBqyNrY2GFtcgwfV9nV8xLmbtUpMNY/Oi0Ml1XgfR4flOdq+AA=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.28.2", "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.28.2.tgz", { "os": "android", "cpu": "arm" }, "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", { "os": "android", "cpu": "arm64" }, "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.28.2.tgz", { "os": "android", "cpu": "x64" }, "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", { "os": "linux", "cpu": "arm" }, "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", { "os": "linux", "cpu": "ia32" }, "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", { "os": "linux", "cpu": "none" }, "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", { "os": "linux", "cpu": "none" }, "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", { "os": "linux", "cpu": "none" }, "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", { "os": "linux", "cpu": "x64" }, "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ=="],
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", { "os": "none", "cpu": "arm64" }, "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", { "os": "none", "cpu": "x64" }, "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw=="],
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", { "os": "openbsd", "cpu": "arm64" }, "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw=="],
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", { "os": "none", "cpu": "arm64" }, "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", { "os": "sunos", "cpu": "x64" }, "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.2", "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.2", "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="],
"@great-agent/agent-core": ["@great-agent/agent-core@workspace:packages/agent-core"],
"@great-agent/local-data": ["@great-agent/local-data@workspace:packages/local-data"],
"@great-agent/local-files": ["@great-agent/local-files@workspace:packages/local-files"],
"@great-agent/model-deepseek": ["@great-agent/model-deepseek@workspace:packages/model-deepseek"],
"@great-agent/web": ["@great-agent/web@workspace:apps/web"],
"@great-agent/web-contracts": ["@great-agent/web-contracts@workspace:packages/web-contracts"],
"@great-agent/web-server": ["@great-agent/web-server@workspace:apps/web-server"],
"@napi-rs/lzma-linux-x64-gnu": ["@napi-rs/lzma-linux-x64-gnu@1.5.1", "https://registry.npmmirror.com/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", { "os": "linux", "cpu": "x64" }, "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ=="],
"@pinojs/redact": ["@pinojs/redact@0.4.0", "https://registry.npmmirror.com/@pinojs/redact/-/redact-0.4.0.tgz", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", { "os": "android", "cpu": "arm" }, "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", { "os": "android", "cpu": "arm64" }, "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", { "os": "freebsd", "cpu": "arm64" }, "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", { "os": "linux", "cpu": "arm" }, "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", { "os": "linux", "cpu": "arm" }, "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g=="],
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", { "os": "linux", "cpu": "none" }, "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA=="],
"@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", { "os": "linux", "cpu": "none" }, "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ=="],
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w=="],
"@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", { "os": "linux", "cpu": "ppc64" }, "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", { "os": "linux", "cpu": "none" }, "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", { "os": "linux", "cpu": "none" }, "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", { "os": "linux", "cpu": "s390x" }, "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", { "os": "linux", "cpu": "x64" }, "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", { "os": "linux", "cpu": "x64" }, "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA=="],
"@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", { "os": "openbsd", "cpu": "x64" }, "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ=="],
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", { "os": "none", "cpu": "arm64" }, "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", { "os": "win32", "cpu": "ia32" }, "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ=="],
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", { "os": "win32", "cpu": "x64" }, "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.62.4", "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", { "os": "win32", "cpu": "x64" }, "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q=="],
"@types/bun": ["@types/bun@1.3.14", "https://registry.npmmirror.com/@types/bun/-/bun-1.3.14.tgz", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
"@types/estree": ["@types/estree@1.0.9", "https://registry.npmmirror.com/@types/estree/-/estree-1.0.9.tgz", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
"@types/node": ["@types/node@26.2.0", "https://registry.npmmirror.com/@types/node/-/node-26.2.0.tgz", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg=="],
"atomic-sleep": ["atomic-sleep@1.0.0", "https://registry.npmmirror.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
"bun-types": ["bun-types@1.3.14", "https://registry.npmmirror.com/bun-types/-/bun-types-1.3.14.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
"esbuild": ["esbuild@0.28.2", "https://registry.npmmirror.com/esbuild/-/esbuild-0.28.2.tgz", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.2", "@esbuild/android-arm": "0.28.2", "@esbuild/android-arm64": "0.28.2", "@esbuild/android-x64": "0.28.2", "@esbuild/darwin-arm64": "0.28.2", "@esbuild/darwin-x64": "0.28.2", "@esbuild/freebsd-arm64": "0.28.2", "@esbuild/freebsd-x64": "0.28.2", "@esbuild/linux-arm": "0.28.2", "@esbuild/linux-arm64": "0.28.2", "@esbuild/linux-ia32": "0.28.2", "@esbuild/linux-loong64": "0.28.2", "@esbuild/linux-mips64el": "0.28.2", "@esbuild/linux-ppc64": "0.28.2", "@esbuild/linux-riscv64": "0.28.2", "@esbuild/linux-s390x": "0.28.2", "@esbuild/linux-x64": "0.28.2", "@esbuild/netbsd-arm64": "0.28.2", "@esbuild/netbsd-x64": "0.28.2", "@esbuild/openbsd-arm64": "0.28.2", "@esbuild/openbsd-x64": "0.28.2", "@esbuild/openharmony-arm64": "0.28.2", "@esbuild/sunos-x64": "0.28.2", "@esbuild/win32-arm64": "0.28.2", "@esbuild/win32-ia32": "0.28.2", "@esbuild/win32-x64": "0.28.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA=="],
"fdir": ["fdir@6.5.0", "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
"fsevents": ["fsevents@2.3.3", "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"hono": ["hono@4.13.1", "https://registry.npmmirror.com/hono/-/hono-4.13.1.tgz", {}, "sha512-kdJoFVv2xmayw6cY09H7AbMJMt8Jn5jdlEdXsP7AGBdF2DIptVlKlOLKXP41yPip4/a3yQPv9gVcJYI8YY04dw=="],
"nanoid": ["nanoid@3.3.18", "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.18.tgz", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="],
"on-exit-leak-free": ["on-exit-leak-free@2.1.2", "https://registry.npmmirror.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="],
"openai": ["openai@5.23.2", "https://registry.npmmirror.com/openai/-/openai-5.23.2.tgz", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.23.8" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-MQBzmTulj+MM5O8SKEk/gL8a7s5mktS9zUtAkU257WjvobGc9nKcBuVwjyEEcb9SI8a8Y2G/mzn3vm9n1Jlleg=="],
"picocolors": ["picocolors@1.1.1", "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"picomatch": ["picomatch@4.0.5", "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.5.tgz", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="],
"pino": ["pino@9.14.0", "https://registry.npmmirror.com/pino/-/pino-9.14.0.tgz", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w=="],
"pino-abstract-transport": ["pino-abstract-transport@2.0.0", "https://registry.npmmirror.com/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="],
"pino-std-serializers": ["pino-std-serializers@7.1.0", "https://registry.npmmirror.com/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", {}, "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw=="],
"postcss": ["postcss@8.5.26", "https://registry.npmmirror.com/postcss/-/postcss-8.5.26.tgz", { "dependencies": { "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ=="],
"process-warning": ["process-warning@5.1.0", "https://registry.npmmirror.com/process-warning/-/process-warning-5.1.0.tgz", {}, "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw=="],
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "https://registry.npmmirror.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
"real-require": ["real-require@0.2.0", "https://registry.npmmirror.com/real-require/-/real-require-0.2.0.tgz", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="],
"rollup": ["rollup@4.62.4", "https://registry.npmmirror.com/rollup/-/rollup-4.62.4.tgz", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", "@rollup/rollup-android-arm-eabi": "4.62.4", "@rollup/rollup-android-arm64": "4.62.4", "@rollup/rollup-darwin-arm64": "4.62.4", "@rollup/rollup-darwin-x64": "4.62.4", "@rollup/rollup-freebsd-arm64": "4.62.4", "@rollup/rollup-freebsd-x64": "4.62.4", "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", "@rollup/rollup-linux-arm-musleabihf": "4.62.4", "@rollup/rollup-linux-arm64-gnu": "4.62.4", "@rollup/rollup-linux-arm64-musl": "4.62.4", "@rollup/rollup-linux-loong64-gnu": "4.62.4", "@rollup/rollup-linux-loong64-musl": "4.62.4", "@rollup/rollup-linux-ppc64-gnu": "4.62.4", "@rollup/rollup-linux-ppc64-musl": "4.62.4", "@rollup/rollup-linux-riscv64-gnu": "4.62.4", "@rollup/rollup-linux-riscv64-musl": "4.62.4", "@rollup/rollup-linux-s390x-gnu": "4.62.4", "@rollup/rollup-linux-x64-gnu": "4.62.4", "@rollup/rollup-linux-x64-musl": "4.62.4", "@rollup/rollup-openbsd-x64": "4.62.4", "@rollup/rollup-openharmony-arm64": "4.62.4", "@rollup/rollup-win32-arm64-msvc": "4.62.4", "@rollup/rollup-win32-ia32-msvc": "4.62.4", "@rollup/rollup-win32-x64-gnu": "4.62.4", "@rollup/rollup-win32-x64-msvc": "4.62.4", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg=="],
"safe-stable-stringify": ["safe-stable-stringify@2.5.0", "https://registry.npmmirror.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
"sonic-boom": ["sonic-boom@4.2.1", "https://registry.npmmirror.com/sonic-boom/-/sonic-boom-4.2.1.tgz", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q=="],
"source-map-js": ["source-map-js@1.2.1", "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"split2": ["split2@4.2.0", "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
"thread-stream": ["thread-stream@3.2.0", "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.2.0.tgz", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw=="],
"tinyglobby": ["tinyglobby@0.2.17", "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.17.tgz", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
"typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"undici-types": ["undici-types@8.3.0", "https://registry.npmmirror.com/undici-types/-/undici-types-8.3.0.tgz", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
"vanjs-core": ["vanjs-core@1.6.1", "https://registry.npmmirror.com/vanjs-core/-/vanjs-core-1.6.1.tgz", {}, "sha512-CPUteb4/iW3hB7TLTKI9A9YMRTAQFpPz5n1/+vfnPxNs2wOI9HvSg6K3B/9x+uycX8eefqopBcakr2vJeHgIgw=="],
"vite": ["vite@7.3.6", "https://registry.npmmirror.com/vite/-/vite-7.3.6.tgz", { "dependencies": { "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg=="],
"zod": ["zod@4.4.3", "https://registry.npmmirror.com/zod/-/zod-4.4.3.tgz", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
}
}

3
bunfig.toml Normal file
View File

@ -0,0 +1,3 @@
[test]
root = "."
coverage = false

View File

@ -1,10 +1,10 @@
# 实施方案
状态:待确认
状态:已确认,项目骨架待确认
方案版本0.4.0
需求版本0.3.0(已确认、已冻结)
确认人:
确认时间:
确认人:用户
确认时间:2026-08-12
## 1. 约束与关键默认值
@ -833,6 +833,25 @@ bun run test:visual
骨架阶段不得提前实现会话、模型调用、本地文件工具或完整 UI。
### 项目骨架验证记录2026-08-12
骨架已按本节范围生成,实际验证环境为 Bun `1.3.11`。以下命令均在项目根目录运行:
| 命令 | 结果 |
|---|---|
| `bun install` | 通过;安装 76 个包并生成 `bun.lock` |
| `bun run format:check` | 通过;检查 46 个文件,无需修改 |
| `bun run lint` | 通过;检查 47 个文件,无警告或错误 |
| `bun run typecheck` | 通过7 个 Workspace 包全部通过 |
| `bun run check:file-size` | 通过TypeScript 文件均不超过 400 行 |
| `bun run check:architecture` | 通过Core 与 Web 依赖方向符合约束 |
| `bun test` | 通过5 个测试、13 个断言0 失败 |
| `bun run build` | 通过VanJS/Vite 与 Hono/Bun 生产产物均生成成功 |
额外生产产物冒烟验证:使用 `PORT=3137` 和临时数据目录启动 `apps/web-server/dist/index.js``GET /api/health``GET /` 和构建后的 JavaScript 静态资源均返回 `200`;健康检查包含 `X-Request-ID`,并生成 `projects``conversations``runs``indexes``recovery` 五个数据目录。
当前未配置真实 `DEEPSEEK_API_KEY`、正式数据目录和正式默认工作区这是骨架阶段的预期状态。代码中尚未实现项目、会话、Agent Run、模型请求、本地文件工具或 Claude Desktop 业务界面。确认骨架后,第一个纵向功能仍为 F-001“应用外壳、首次状态与普通会话”进入该切片前先确定视觉参考截图包。
## 21. 有序纵向功能切片
### F-001 应用外壳、首次状态与普通会话

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "great-agent2",
"private": true,
"version": "0.1.0",
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"dev": "bun run --filter @great-agent/web --filter @great-agent/web-server dev",
"format": "biome format --write .",
"format:check": "biome format .",
"lint": "biome lint .",
"typecheck": "bun run --filter '*' typecheck",
"check:file-size": "bun run scripts/check-file-size.ts",
"check:architecture": "bun run scripts/check-architecture.ts",
"test": "bun test",
"build": "bun run --filter @great-agent/web build && bun run --filter @great-agent/web-server build",
"start": "bun apps/web-server/dist/index.js"
},
"devDependencies": {
"@biomejs/biome": "^2.2.0",
"@types/bun": "^1.3.0",
"typescript": "^5.9.0"
}
}

View File

@ -0,0 +1,11 @@
{
"name": "@great-agent/agent-core",
"version": "0.1.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
}
}

View File

@ -0,0 +1,10 @@
export class CoreError extends Error {
constructor(
readonly code: string,
message: string,
options?: ErrorOptions,
) {
super(message, options);
this.name = "CoreError";
}
}

View File

@ -0,0 +1,7 @@
export { CoreError } from "./errors/core-error";
export type { ModelEvent, ModelPort, ModelRequest } from "./ports/model-port";
export type {
ClockPort,
IdPort,
WorkspaceResolverPort,
} from "./ports/system-ports";

View File

@ -0,0 +1,13 @@
export type ModelRequest = Readonly<{
model: string;
messages: readonly unknown[];
}>;
export type ModelEvent = Readonly<{
type: string;
payload: unknown;
}>;
export interface ModelPort {
stream(request: ModelRequest, signal: AbortSignal): AsyncIterable<ModelEvent>;
}

View File

@ -0,0 +1,11 @@
export interface ClockPort {
now(): Date;
}
export interface IdPort {
create(): string;
}
export interface WorkspaceResolverPort {
resolve(conversationId: string): Promise<string>;
}

View File

@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist" },
"include": ["src"]
}

View File

@ -0,0 +1,11 @@
{
"name": "@great-agent/local-data",
"version": "0.1.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
}
}

View File

@ -0,0 +1,10 @@
import { dirname } from "node:path";
import { appendFile, mkdir } from "node:fs/promises";
export async function appendNdjson(
path: string,
value: unknown,
): Promise<void> {
await mkdir(dirname(path), { recursive: true });
await appendFile(path, `${JSON.stringify(value)}\n`, "utf8");
}

View File

@ -0,0 +1,12 @@
import { dirname } from "node:path";
import { mkdir, rename } from "node:fs/promises";
export async function writeJsonAtomically(
path: string,
value: unknown,
): Promise<void> {
await mkdir(dirname(path), { recursive: true });
const temporaryPath = `${path}.${crypto.randomUUID()}.tmp`;
await Bun.write(temporaryPath, `${JSON.stringify(value, null, 2)}\n`);
await rename(temporaryPath, path);
}

View File

@ -0,0 +1,8 @@
export { appendNdjson } from "./atomic-writes/append-ndjson";
export { writeJsonAtomically } from "./atomic-writes/write-json-atomically";
export {
createDataLayout,
DATA_FORMAT_VERSION,
ensureDataLayout,
type DataLayout,
} from "./layout/data-layout";

View File

@ -0,0 +1,37 @@
import { join } from "node:path";
import { mkdir } from "node:fs/promises";
export const DATA_FORMAT_VERSION = 1;
export type DataLayout = Readonly<{
root: string;
projects: string;
conversations: string;
runs: string;
indexes: string;
recovery: string;
}>;
export function createDataLayout(root: string): DataLayout {
return {
root,
projects: join(root, "projects"),
conversations: join(root, "conversations"),
runs: join(root, "runs"),
indexes: join(root, "indexes"),
recovery: join(root, "recovery"),
};
}
export async function ensureDataLayout(layout: DataLayout): Promise<void> {
await Promise.all(
[
layout.root,
layout.projects,
layout.conversations,
layout.runs,
layout.indexes,
layout.recovery,
].map((path) => mkdir(path, { recursive: true })),
);
}

View File

@ -0,0 +1,40 @@
import { afterEach, describe, expect, test } from "bun:test";
import { join } from "node:path";
import { mkdtemp, rm, stat } from "node:fs/promises";
import { tmpdir } from "node:os";
import {
appendNdjson,
createDataLayout,
ensureDataLayout,
writeJsonAtomically,
} from ".";
const temporaryRoots: string[] = [];
afterEach(async () => {
for (const path of temporaryRoots.splice(0)) {
await rm(path, { recursive: true, force: true });
}
});
describe("local-data 骨架", () => {
test("创建固定数据目录布局", async () => {
const root = await mkdtemp(join(tmpdir(), "great-agent2-data-"));
temporaryRoots.push(root);
const layout = createDataLayout(root);
await ensureDataLayout(layout);
expect((await stat(layout.projects)).isDirectory()).toBe(true);
expect((await stat(layout.recovery)).isDirectory()).toBe(true);
});
test("原子写入 JSON 并追加 NDJSON", async () => {
const root = await mkdtemp(join(tmpdir(), "great-agent2-write-"));
temporaryRoots.push(root);
const jsonPath = join(root, "entity.json");
const logPath = join(root, "events.ndjson");
await writeJsonAtomically(jsonPath, { schemaVersion: 1 });
await appendNdjson(logPath, { sequence: 1 });
expect(await Bun.file(jsonPath).json()).toEqual({ schemaVersion: 1 });
expect(await Bun.file(logPath).text()).toBe('{"sequence":1}\n');
});
});

View File

@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist" },
"include": ["src"]
}

View File

@ -0,0 +1,14 @@
{
"name": "@great-agent/local-files",
"version": "0.1.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@great-agent/agent-core": "workspace:*"
}
}

View File

@ -0,0 +1 @@
export const localFilesPackage = "@great-agent/local-files";

View File

@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist" },
"include": ["src"]
}

View File

@ -0,0 +1,15 @@
{
"name": "@great-agent/model-deepseek",
"version": "0.1.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@great-agent/agent-core": "workspace:*",
"openai": "^5.19.0"
}
}

View File

@ -0,0 +1 @@
export const deepSeekAdapterPackage = "@great-agent/model-deepseek";

View File

@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist" },
"include": ["src"]
}

View File

@ -0,0 +1,14 @@
{
"name": "@great-agent/web-contracts",
"version": "0.1.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"zod": "^4.1.0"
}
}

View File

@ -0,0 +1 @@
export { healthResponseSchema, type HealthResponse } from "./responses/health";

View File

@ -0,0 +1,9 @@
import { z } from "zod";
export const healthResponseSchema = z.object({
status: z.literal("ok"),
service: z.literal("great-agent2"),
timestamp: z.iso.datetime(),
});
export type HealthResponse = z.infer<typeof healthResponseSchema>;

View File

@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist" },
"include": ["src"]
}

View File

@ -0,0 +1,48 @@
const rules = [
{
root: "packages/agent-core/src",
forbidden: [
"hono",
"vanjs-core",
"openai",
"bun:",
"node:fs",
"@great-agent/",
],
},
{
root: "apps/web/src",
forbidden: [
"@great-agent/agent-core",
"@great-agent/local-data",
"@great-agent/local-files",
"@great-agent/model-deepseek",
],
},
];
const violations: string[] = [];
for (const rule of rules) {
const glob = new Bun.Glob("**/*.ts");
for await (const relative of glob.scan({ cwd: rule.root, onlyFiles: true })) {
const path = `${rule.root}/${relative}`;
const source = await Bun.file(path).text();
for (const forbidden of rule.forbidden) {
if (
source.includes(`from "${forbidden}`) ||
source.includes(`import("${forbidden}`)
) {
violations.push(`${path}: 禁止依赖 ${forbidden}`);
}
}
}
}
if (violations.length > 0) {
console.error(violations.join("\n"));
process.exit(1);
}
console.log("架构依赖检查通过。");
export {};

View File

@ -0,0 +1,21 @@
const roots = ["apps", "packages", "scripts"];
const limit = 400;
const oversized: string[] = [];
for (const root of roots) {
const glob = new Bun.Glob("**/*.ts");
for await (const relative of glob.scan({ cwd: root, onlyFiles: true })) {
const path = `${root}/${relative}`;
const lineCount = (await Bun.file(path).text()).split("\n").length;
if (lineCount > limit) oversized.push(`${path}: ${lineCount}`);
}
}
if (oversized.length > 0) {
console.error(`以下文件超过 ${limit} 行:\n${oversized.join("\n")}`);
process.exit(1);
}
console.log(`文件规模检查通过TypeScript 文件均不超过 ${limit} 行。`);
export {};

16
tsconfig.base.json Normal file
View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"types": ["bun"],
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}

8
tsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"noEmit": true
},
"include": ["scripts/**/*.ts"],
"exclude": ["node_modules", "dist", "apps", "packages"]
}