diff --git a/.ai-project/state.yaml b/.ai-project/state.yaml
index 9896289..66bfc26 100644
--- a/.ai-project/state.yaml
+++ b/.ai-project/state.yaml
@@ -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
功能验收:
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..9784111
--- /dev/null
+++ b/.env.example
@@ -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
diff --git a/.gitignore b/.gitignore
index 4d05b34..f009b10 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
\ No newline at end of file
+.cache
+playwright-report/
+test-results/
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..bdbaca3
--- /dev/null
+++ b/Dockerfile
@@ -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"]
diff --git a/apps/web-server/package.json b/apps/web-server/package.json
new file mode 100644
index 0000000..e263603
--- /dev/null
+++ b/apps/web-server/package.json
@@ -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"
+ }
+}
diff --git a/apps/web-server/src/composition/create-app.test.ts b/apps/web-server/src/composition/create-app.test.ts
new file mode 100644
index 0000000..d6e7574
--- /dev/null
+++ b/apps/web-server/src/composition/create-app.test.ts
@@ -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");
+ });
+});
diff --git a/apps/web-server/src/composition/create-app.ts b/apps/web-server/src/composition/create-app.ts
new file mode 100644
index 0000000..a0d16be
--- /dev/null
+++ b/apps/web-server/src/composition/create-app.ts
@@ -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;
+}
diff --git a/apps/web-server/src/composition/create-logger.ts b/apps/web-server/src/composition/create-logger.ts
new file mode 100644
index 0000000..fddda13
--- /dev/null
+++ b/apps/web-server/src/composition/create-logger.ts
@@ -0,0 +1,8 @@
+import pino, { type Logger } from "pino";
+
+export function createLogger(level: string): Logger {
+ return pino({
+ level,
+ redact: ["deepSeekApiKey", "req.headers.authorization"],
+ });
+}
diff --git a/apps/web-server/src/composition/static-web.test.ts b/apps/web-server/src/composition/static-web.test.ts
new file mode 100644
index 0000000..03e2016
--- /dev/null
+++ b/apps/web-server/src/composition/static-web.test.ts
@@ -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"),
+ "
Great Agent 2
",
+ );
+ 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);
+ });
+});
diff --git a/apps/web-server/src/composition/static-web.ts b/apps/web-server/src/composition/static-web.ts
new file mode 100644
index 0000000..c07d392
--- /dev/null
+++ b/apps/web-server/src/composition/static-web.ts
@@ -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" },
+ });
+ });
+}
diff --git a/apps/web-server/src/config/environment.test.ts b/apps/web-server/src/config/environment.test.ts
new file mode 100644
index 0000000..3191fa7
--- /dev/null
+++ b/apps/web-server/src/config/environment.test.ts
@@ -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();
+ });
+});
diff --git a/apps/web-server/src/config/environment.ts b/apps/web-server/src/config/environment.ts
new file mode 100644
index 0000000..d22e5b1
--- /dev/null
+++ b/apps/web-server/src/config/environment.ts
@@ -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 = 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,
+ };
+}
diff --git a/apps/web-server/src/http/error-handler.ts b/apps/web-server/src/http/error-handler.ts
new file mode 100644
index 0000000..8bf92ff
--- /dev/null
+++ b/apps/web-server/src/http/error-handler.ts
@@ -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,
+ );
+ };
+}
diff --git a/apps/web-server/src/http/request-id.ts b/apps/web-server/src/http/request-id.ts
new file mode 100644
index 0000000..b547cc3
--- /dev/null
+++ b/apps/web-server/src/http/request-id.ts
@@ -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();
+};
diff --git a/apps/web-server/src/index.ts b/apps/web-server/src/index.ts
new file mode 100644
index 0000000..4e3c316
--- /dev/null
+++ b/apps/web-server/src/index.ts
@@ -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,
+};
diff --git a/apps/web-server/src/routes/health.ts b/apps/web-server/src/routes/health.ts
new file mode 100644
index 0000000..52d9fdf
--- /dev/null
+++ b/apps/web-server/src/routes/health.ts
@@ -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;
+}
diff --git a/apps/web-server/tsconfig.json b/apps/web-server/tsconfig.json
new file mode 100644
index 0000000..68f7819
--- /dev/null
+++ b/apps/web-server/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": { "rootDir": "src", "outDir": "dist-types" },
+ "include": ["src"]
+}
diff --git a/apps/web/index.html b/apps/web/index.html
new file mode 100644
index 0000000..327dce6
--- /dev/null
+++ b/apps/web/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Great Agent 2
+
+
+
+
+
+
diff --git a/apps/web/package.json b/apps/web/package.json
new file mode 100644
index 0000000..7cdcb46
--- /dev/null
+++ b/apps/web/package.json
@@ -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"
+ }
+}
diff --git a/apps/web/src/app/app-shell.ts b/apps/web/src/app/app-shell.ts
new file mode 100644
index 0000000..0a047dd
--- /dev/null
+++ b/apps/web/src/app/app-shell.ts
@@ -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("项目骨架运行正常,产品界面将在纵向功能阶段实现。"),
+ );
+}
diff --git a/apps/web/src/main.ts b/apps/web/src/main.ts
new file mode 100644
index 0000000..bae9ad9
--- /dev/null
+++ b/apps/web/src/main.ts
@@ -0,0 +1,8 @@
+import van from "vanjs-core";
+import { AppShell } from "./app/app-shell";
+import "./styles/global.css";
+
+const mount = document.querySelector("#app");
+if (!mount) throw new Error("缺少应用挂载节点 #app");
+
+van.add(mount, AppShell());
diff --git a/apps/web/src/styles/global.css b/apps/web/src/styles/global.css
new file mode 100644
index 0000000..5552612
--- /dev/null
+++ b/apps/web/src/styles/global.css
@@ -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;
+}
diff --git a/apps/web/src/vite-env.d.ts b/apps/web/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/apps/web/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
new file mode 100644
index 0000000..4db5d0b
--- /dev/null
+++ b/apps/web/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "outDir": "dist-types",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"]
+ },
+ "include": ["src"]
+}
diff --git a/biome.json b/biome.json
new file mode 100644
index 0000000..a95ae3f
--- /dev/null
+++ b/biome.json
@@ -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" }
+ }
+}
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..4ddb3eb
--- /dev/null
+++ b/bun.lock
@@ -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=="],
+ }
+}
diff --git a/bunfig.toml b/bunfig.toml
new file mode 100644
index 0000000..ffe9333
--- /dev/null
+++ b/bunfig.toml
@@ -0,0 +1,3 @@
+[test]
+root = "."
+coverage = false
diff --git a/docs/IMPLEMENTATION.md b/docs/IMPLEMENTATION.md
index 7e22ba5..ad6dc71 100644
--- a/docs/IMPLEMENTATION.md
+++ b/docs/IMPLEMENTATION.md
@@ -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 应用外壳、首次状态与普通会话
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..c5c1555
--- /dev/null
+++ b/package.json
@@ -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"
+ }
+}
diff --git a/packages/agent-core/package.json b/packages/agent-core/package.json
new file mode 100644
index 0000000..64b339e
--- /dev/null
+++ b/packages/agent-core/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@great-agent/agent-core",
+ "version": "0.1.0",
+ "type": "module",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "scripts": {
+ "typecheck": "tsc --noEmit"
+ }
+}
diff --git a/packages/agent-core/src/errors/core-error.ts b/packages/agent-core/src/errors/core-error.ts
new file mode 100644
index 0000000..8f5e469
--- /dev/null
+++ b/packages/agent-core/src/errors/core-error.ts
@@ -0,0 +1,10 @@
+export class CoreError extends Error {
+ constructor(
+ readonly code: string,
+ message: string,
+ options?: ErrorOptions,
+ ) {
+ super(message, options);
+ this.name = "CoreError";
+ }
+}
diff --git a/packages/agent-core/src/index.ts b/packages/agent-core/src/index.ts
new file mode 100644
index 0000000..648ac12
--- /dev/null
+++ b/packages/agent-core/src/index.ts
@@ -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";
diff --git a/packages/agent-core/src/ports/model-port.ts b/packages/agent-core/src/ports/model-port.ts
new file mode 100644
index 0000000..b03728c
--- /dev/null
+++ b/packages/agent-core/src/ports/model-port.ts
@@ -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;
+}
diff --git a/packages/agent-core/src/ports/system-ports.ts b/packages/agent-core/src/ports/system-ports.ts
new file mode 100644
index 0000000..b7a2162
--- /dev/null
+++ b/packages/agent-core/src/ports/system-ports.ts
@@ -0,0 +1,11 @@
+export interface ClockPort {
+ now(): Date;
+}
+
+export interface IdPort {
+ create(): string;
+}
+
+export interface WorkspaceResolverPort {
+ resolve(conversationId: string): Promise;
+}
diff --git a/packages/agent-core/tsconfig.json b/packages/agent-core/tsconfig.json
new file mode 100644
index 0000000..6fcd57f
--- /dev/null
+++ b/packages/agent-core/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": { "rootDir": "src", "outDir": "dist" },
+ "include": ["src"]
+}
diff --git a/packages/local-data/package.json b/packages/local-data/package.json
new file mode 100644
index 0000000..04db524
--- /dev/null
+++ b/packages/local-data/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@great-agent/local-data",
+ "version": "0.1.0",
+ "type": "module",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "scripts": {
+ "typecheck": "tsc --noEmit"
+ }
+}
diff --git a/packages/local-data/src/atomic-writes/append-ndjson.ts b/packages/local-data/src/atomic-writes/append-ndjson.ts
new file mode 100644
index 0000000..c0f51b8
--- /dev/null
+++ b/packages/local-data/src/atomic-writes/append-ndjson.ts
@@ -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 {
+ await mkdir(dirname(path), { recursive: true });
+ await appendFile(path, `${JSON.stringify(value)}\n`, "utf8");
+}
diff --git a/packages/local-data/src/atomic-writes/write-json-atomically.ts b/packages/local-data/src/atomic-writes/write-json-atomically.ts
new file mode 100644
index 0000000..475868c
--- /dev/null
+++ b/packages/local-data/src/atomic-writes/write-json-atomically.ts
@@ -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 {
+ 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);
+}
diff --git a/packages/local-data/src/index.ts b/packages/local-data/src/index.ts
new file mode 100644
index 0000000..885ede3
--- /dev/null
+++ b/packages/local-data/src/index.ts
@@ -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";
diff --git a/packages/local-data/src/layout/data-layout.ts b/packages/local-data/src/layout/data-layout.ts
new file mode 100644
index 0000000..6a4f6a0
--- /dev/null
+++ b/packages/local-data/src/layout/data-layout.ts
@@ -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 {
+ await Promise.all(
+ [
+ layout.root,
+ layout.projects,
+ layout.conversations,
+ layout.runs,
+ layout.indexes,
+ layout.recovery,
+ ].map((path) => mkdir(path, { recursive: true })),
+ );
+}
diff --git a/packages/local-data/src/local-data.test.ts b/packages/local-data/src/local-data.test.ts
new file mode 100644
index 0000000..daecbf9
--- /dev/null
+++ b/packages/local-data/src/local-data.test.ts
@@ -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');
+ });
+});
diff --git a/packages/local-data/tsconfig.json b/packages/local-data/tsconfig.json
new file mode 100644
index 0000000..6fcd57f
--- /dev/null
+++ b/packages/local-data/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": { "rootDir": "src", "outDir": "dist" },
+ "include": ["src"]
+}
diff --git a/packages/local-files/package.json b/packages/local-files/package.json
new file mode 100644
index 0000000..c0fdc3c
--- /dev/null
+++ b/packages/local-files/package.json
@@ -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:*"
+ }
+}
diff --git a/packages/local-files/src/index.ts b/packages/local-files/src/index.ts
new file mode 100644
index 0000000..e226c70
--- /dev/null
+++ b/packages/local-files/src/index.ts
@@ -0,0 +1 @@
+export const localFilesPackage = "@great-agent/local-files";
diff --git a/packages/local-files/tsconfig.json b/packages/local-files/tsconfig.json
new file mode 100644
index 0000000..6fcd57f
--- /dev/null
+++ b/packages/local-files/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": { "rootDir": "src", "outDir": "dist" },
+ "include": ["src"]
+}
diff --git a/packages/model-deepseek/package.json b/packages/model-deepseek/package.json
new file mode 100644
index 0000000..3d5f764
--- /dev/null
+++ b/packages/model-deepseek/package.json
@@ -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"
+ }
+}
diff --git a/packages/model-deepseek/src/index.ts b/packages/model-deepseek/src/index.ts
new file mode 100644
index 0000000..8d61db6
--- /dev/null
+++ b/packages/model-deepseek/src/index.ts
@@ -0,0 +1 @@
+export const deepSeekAdapterPackage = "@great-agent/model-deepseek";
diff --git a/packages/model-deepseek/tsconfig.json b/packages/model-deepseek/tsconfig.json
new file mode 100644
index 0000000..6fcd57f
--- /dev/null
+++ b/packages/model-deepseek/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": { "rootDir": "src", "outDir": "dist" },
+ "include": ["src"]
+}
diff --git a/packages/web-contracts/package.json b/packages/web-contracts/package.json
new file mode 100644
index 0000000..dfd1226
--- /dev/null
+++ b/packages/web-contracts/package.json
@@ -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"
+ }
+}
diff --git a/packages/web-contracts/src/index.ts b/packages/web-contracts/src/index.ts
new file mode 100644
index 0000000..bcda54c
--- /dev/null
+++ b/packages/web-contracts/src/index.ts
@@ -0,0 +1 @@
+export { healthResponseSchema, type HealthResponse } from "./responses/health";
diff --git a/packages/web-contracts/src/responses/health.ts b/packages/web-contracts/src/responses/health.ts
new file mode 100644
index 0000000..6296124
--- /dev/null
+++ b/packages/web-contracts/src/responses/health.ts
@@ -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;
diff --git a/packages/web-contracts/tsconfig.json b/packages/web-contracts/tsconfig.json
new file mode 100644
index 0000000..6fcd57f
--- /dev/null
+++ b/packages/web-contracts/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": { "rootDir": "src", "outDir": "dist" },
+ "include": ["src"]
+}
diff --git a/scripts/check-architecture.ts b/scripts/check-architecture.ts
new file mode 100644
index 0000000..6f7ebfa
--- /dev/null
+++ b/scripts/check-architecture.ts
@@ -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 {};
diff --git a/scripts/check-file-size.ts b/scripts/check-file-size.ts
new file mode 100644
index 0000000..b1805d1
--- /dev/null
+++ b/scripts/check-file-size.ts
@@ -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 {};
diff --git a/tsconfig.base.json b/tsconfig.base.json
new file mode 100644
index 0000000..07cbfed
--- /dev/null
+++ b/tsconfig.base.json
@@ -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
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..8f2a111
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "./tsconfig.base.json",
+ "compilerOptions": {
+ "noEmit": true
+ },
+ "include": ["scripts/**/*.ts"],
+ "exclude": ["node_modules", "dist", "apps", "packages"]
+}