weifuwu 0.95.0 → 0.95.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/level5/client/layout/weifuwu-layout.css +37 -1
- package/dist/level6/apps/agent-platform/app-root.ts +15 -0
- package/dist/level6/apps/agent-platform/scripts/seed.mjs +18 -9
- package/dist/level6/apps/agent-platform/server.js +125 -125
- package/dist/level6/apps/agent-platform/src/bootstrap/routes-protected.ts +7 -17
- package/dist/level6/apps/agent-platform/src/bootstrap/routes-public.ts +4 -8
- package/dist/level6/apps/agent-platform/src/routes/role-templates.ts +3 -4
- package/dist/level6/apps/agent-platform/src/sandbox/docker.ts +3 -5
- package/dist/level6/apps/agent-platform/ui/ssr.ts +9 -5
- package/dist/level6/apps/showcase/server.js +22 -22
- package/dist/level6/apps/showcase/server.ts +1 -1
- package/dist/level6/client/layout/weifuwu-layout.css +1 -0
- package/dist/level6/index.js +9 -0
- package/dist/level6/server/user/index.js +1 -1
- package/dist/level6/server/user/index.ts +12 -0
- package/dist/server/index.js +9 -0
- package/dist/server/user/index.js +1 -1
- package/docs/client.md +2 -2
- package/docs/level.md +1 -1
- package/docs/migration.md +6 -1
- package/package.json +1 -1
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Router, errorResponse, workflowSystem, messager, ops, HttpError, email, ui, verifyPassword, hashPassword, WEIFUWU_WORKFLOW_SCHEMA, WEIFUWU_MESSAGER_SCHEMA, graphql } from '../../../../index.ts'
|
|
9
9
|
import type { Context } from '../../../../index.ts'
|
|
10
|
-
import { join, resolve
|
|
11
|
-
import {
|
|
10
|
+
import { join, resolve } from 'node:path'
|
|
11
|
+
import { APP_ROOT } from '../../app-root.ts'
|
|
12
12
|
import { handleWebhookMessage } from '../services/webhook.ts'
|
|
13
13
|
import type { AppCtx } from '../middleware/ctx.ts'
|
|
14
14
|
import type { PlatformDeps } from './deps.ts'
|
|
@@ -31,7 +31,6 @@ import { registerUiRoutes } from '../ui/routes.ts'
|
|
|
31
31
|
|
|
32
32
|
export async function registerProtectedRoutes(app: Router<AppCtx>, deps: PlatformDeps): Promise<void> {
|
|
33
33
|
const { pg, redisClient, eventsPg, currentCtx } = deps
|
|
34
|
-
const __dirname = dirname(fileURLToPath(import.meta.url)) + '/../..'
|
|
35
34
|
|
|
36
35
|
const protectedRoutes = new Router<AppCtx>()
|
|
37
36
|
// W0:受保护面错误链(与主 app 同面)
|
|
@@ -819,7 +818,7 @@ export async function registerProtectedRoutes(app: Router<AppCtx>, deps: Platfor
|
|
|
819
818
|
// 本地 CDN(问卷页——v2 面——dist/client/vdom/index.js;旧 ui-dom 产物已随
|
|
820
819
|
// v1 退役消失——问卷页 2027-09 迁移 vdom(S7 试点抓到:真实 LLM 打开问卷
|
|
821
820
|
// 页静态资源 500——页面运行面断链——角色浏览器渲染失败卡死))
|
|
822
|
-
const distRoot = join(
|
|
821
|
+
const distRoot = join(APP_ROOT, '..', '..', '..', '..', 'dist')
|
|
823
822
|
app.get('/static/ui-dom/index.js', async (): Promise<Response> => {
|
|
824
823
|
const { readFileSync } = await import('node:fs')
|
|
825
824
|
return new Response(readFileSync(join(distRoot, 'client', 'vdom', 'index.js'), 'utf-8'), { headers: { 'Content-Type': 'text/javascript; charset=utf-8', 'Cache-Control': 'no-store' } })
|
|
@@ -832,11 +831,8 @@ export async function registerProtectedRoutes(app: Router<AppCtx>, deps: Platfor
|
|
|
832
831
|
// ── 模拟数据收集问卷(客户 demo——多角色 AI 填写) ──────────
|
|
833
832
|
app.get('/demo-survey', async (): Promise<Response> => {
|
|
834
833
|
const { readFileSync } = await import('node:fs')
|
|
835
|
-
const { join, dirname } = await import('node:path')
|
|
836
|
-
const { fileURLToPath } = await import('node:url')
|
|
837
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
838
834
|
// CDN 模式(weifuwu 组件库 + 原生表单控件——AI 填写可靠)
|
|
839
|
-
const html = readFileSync(join(
|
|
835
|
+
const html = readFileSync(join(APP_ROOT, 'public', 'survey-form.html'), 'utf-8')
|
|
840
836
|
return new Response(html, { headers: { 'Content-Type': 'text/html; charset=utf-8' } })
|
|
841
837
|
})
|
|
842
838
|
|
|
@@ -890,10 +886,7 @@ export async function registerProtectedRoutes(app: Router<AppCtx>, deps: Platfor
|
|
|
890
886
|
|
|
891
887
|
app.get('/demo-survey/campaigns', async (): Promise<Response> => {
|
|
892
888
|
const { readFileSync } = await import('node:fs')
|
|
893
|
-
const
|
|
894
|
-
const { fileURLToPath } = await import('node:url')
|
|
895
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
896
|
-
const html = readFileSync(join(__dirname, 'public', 'survey-campaigns.html'), 'utf-8')
|
|
889
|
+
const html = readFileSync(join(APP_ROOT, 'public', 'survey-campaigns.html'), 'utf-8')
|
|
897
890
|
return new Response(html, { headers: { 'Content-Type': 'text/html; charset=utf-8' } })
|
|
898
891
|
})
|
|
899
892
|
|
|
@@ -913,17 +906,14 @@ export async function registerProtectedRoutes(app: Router<AppCtx>, deps: Platfor
|
|
|
913
906
|
|
|
914
907
|
app.get('/demo-survey/stats', async (): Promise<Response> => {
|
|
915
908
|
const { readFileSync } = await import('node:fs')
|
|
916
|
-
const { join, dirname } = await import('node:path')
|
|
917
|
-
const { fileURLToPath } = await import('node:url')
|
|
918
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
919
909
|
// CDN 模式(weifuwu 组件库渲染——Card/Badge/EmptyState)
|
|
920
|
-
const html = readFileSync(join(
|
|
910
|
+
const html = readFileSync(join(APP_ROOT, 'public', 'survey-stats.html'), 'utf-8')
|
|
921
911
|
return new Response(html, { headers: { 'Content-Type': 'text/html; charset=utf-8' } })
|
|
922
912
|
})
|
|
923
913
|
// ── UI / SPA ───────────────────────────────────────────
|
|
924
914
|
app.use(ui())
|
|
925
915
|
|
|
926
|
-
registerUiRoutes(app,
|
|
916
|
+
registerUiRoutes(app, APP_ROOT)
|
|
927
917
|
|
|
928
918
|
// ── 启动 ────────────────────────────────────────────────
|
|
929
919
|
|
|
@@ -9,12 +9,11 @@ import { HttpError, ops } from '../../../../index.ts'
|
|
|
9
9
|
import type { AppCtx } from '../middleware/ctx.ts'
|
|
10
10
|
import type { PlatformDeps } from './deps.ts'
|
|
11
11
|
import { readFileSync } from 'node:fs'
|
|
12
|
-
import { resolve, join
|
|
13
|
-
import {
|
|
12
|
+
import { resolve, join } from 'node:path'
|
|
13
|
+
import { APP_ROOT } from '../../app-root.ts'
|
|
14
14
|
|
|
15
15
|
export function registerPublicRoutes(app: Router<AppCtx>, deps: PlatformDeps): void {
|
|
16
16
|
const { pg, hasRedis, redisClient } = deps
|
|
17
|
-
const __dirname = dirname(fileURLToPath(import.meta.url)) + '/../..'
|
|
18
17
|
|
|
19
18
|
// ── 公开 API(无需登录) ───────────────────────────────
|
|
20
19
|
|
|
@@ -33,10 +32,7 @@ export function registerPublicRoutes(app: Router<AppCtx>, deps: PlatformDeps): v
|
|
|
33
32
|
// 可用技能列表(公开)+ C6 技能市场:?q= 搜索 + 全局评分聚合
|
|
34
33
|
app.get('/api/skills/available', async (req: Request, _ctx: AppCtx): Promise<Response> => {
|
|
35
34
|
const { discoverSkills } = await import('../services/skills.ts')
|
|
36
|
-
const
|
|
37
|
-
const { fileURLToPath } = await import('node:url')
|
|
38
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
39
|
-
const skillsDir = resolve(__dirname, 'skills', 'builtin')
|
|
35
|
+
const skillsDir = resolve(APP_ROOT, 'skills', 'builtin')
|
|
40
36
|
let skills = await discoverSkills(skillsDir)
|
|
41
37
|
|
|
42
38
|
// C6 搜索:name/description 匹配(大小写不敏感)
|
|
@@ -174,7 +170,7 @@ export function registerPublicRoutes(app: Router<AppCtx>, deps: PlatformDeps): v
|
|
|
174
170
|
const startTime = (globalThis as any).__platform_metrics?.startTime
|
|
175
171
|
const uptimeSec = startTime ? Math.round((Date.now() - startTime) / 1000) : 0
|
|
176
172
|
return Response.json(
|
|
177
|
-
{ status: healthy ? 'ok' : 'degraded', uptimeSec, deps, disk, version: (() => { try { return JSON.parse(readFileSync(join(
|
|
173
|
+
{ status: healthy ? 'ok' : 'degraded', uptimeSec, deps, disk, version: (() => { try { return JSON.parse(readFileSync(join(APP_ROOT, '..', '..', '..', '..', 'package.json'), 'utf-8')).version } catch { return 'dev' } })(), ts: new Date().toISOString() },
|
|
178
174
|
{ status: healthy ? 200 : 503 },
|
|
179
175
|
)
|
|
180
176
|
})
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import type { Router, Context } from '../../../../index.ts'
|
|
9
9
|
import { HttpError } from '../../../../index.ts'
|
|
10
|
+
import { resolve } from 'node:path'
|
|
11
|
+
import { APP_ROOT } from '../../app-root.ts'
|
|
10
12
|
import type { AppCtx } from '../middleware/ctx.ts'
|
|
11
13
|
import { BUILTIN_TOOL_DEFS } from './agents.ts'
|
|
12
14
|
|
|
@@ -222,10 +224,7 @@ export function registerRoleTemplateRoutes(app: Router<AppCtx>): void {
|
|
|
222
224
|
const defaultSkills: string[] = template.default_skills ?? []
|
|
223
225
|
for (const skillName of defaultSkills) {
|
|
224
226
|
try {
|
|
225
|
-
const
|
|
226
|
-
const { fileURLToPath } = await import('node:url')
|
|
227
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
228
|
-
const skillDir = resolve(__dirname, '..', '..', 'skills', 'builtin', skillName)
|
|
227
|
+
const skillDir = resolve(APP_ROOT, 'skills', 'builtin', skillName)
|
|
229
228
|
|
|
230
229
|
await ctx.orm.query.insert('agent_skills')
|
|
231
230
|
.values({ agent_id: String(agent.id), skill_name: skillName, skill_dir: skillDir })
|
|
@@ -19,14 +19,12 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { execFile, spawn } from 'node:child_process'
|
|
22
|
-
import { resolve
|
|
23
|
-
import {
|
|
22
|
+
import { resolve } from 'node:path'
|
|
23
|
+
import { APP_ROOT } from '../../app-root.ts'
|
|
24
24
|
import { sandboxEmit } from './events.ts'
|
|
25
25
|
import { type SandboxHost, HOST_ID } from './host.ts'
|
|
26
26
|
import { randomUUID } from 'node:crypto'
|
|
27
27
|
|
|
28
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
29
|
-
|
|
30
28
|
export interface SandboxOptions {
|
|
31
29
|
/** 默认容器镜像(ensure 时可按记录快照覆盖) */
|
|
32
30
|
image: string
|
|
@@ -76,7 +74,7 @@ const DEFAULT_OPTIONS: SandboxOptions = {
|
|
|
76
74
|
enabled: process.env.SANDBOX_DISABLE !== '1',
|
|
77
75
|
// Go agent(2027-09——挂载面而非烧入——镜像 ap-sandbox 保持不变——
|
|
78
76
|
// agent 升级 = 替换宿主二进制——回滚 = 换回旧文件)
|
|
79
|
-
agentPath: resolve(
|
|
77
|
+
agentPath: resolve(APP_ROOT, 'dist', 'sandbox', 'sandbox-agent'),
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
const CONTAINER_PREFIX = 'ap-sandbox-'
|
|
@@ -9,19 +9,23 @@
|
|
|
9
9
|
* - 只 SSR 登录/注册(无认证面——auth token 在 localStorage——其余页
|
|
10
10
|
* SPA 壳——ROADMAP A1 边界评估)
|
|
11
11
|
*/
|
|
12
|
-
import { resolve
|
|
13
|
-
import {
|
|
12
|
+
import { resolve } from 'node:path'
|
|
13
|
+
import { pathToFileURL } from 'node:url'
|
|
14
14
|
import { writeFile, rm } from 'node:fs/promises'
|
|
15
15
|
import { tmpdir } from 'node:os'
|
|
16
16
|
import { build as esbuild } from 'esbuild'
|
|
17
|
+
import { APP_ROOT } from '../app-root.ts'
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
// 框架根(src 或 dist)——APP_ROOT 上三层:agent-platform → apps → level6 → 根
|
|
20
|
+
// jsxImportSource 必须绝对路径:安装包 exports 已删——'weifuwu/client/vdom' 不可解析
|
|
21
|
+
// (0.95.0 安装包 SSR bundle 编译失败实证)
|
|
22
|
+
const fwRoot = resolve(APP_ROOT, '..', '..', '..')
|
|
19
23
|
|
|
20
24
|
/** 编译 + 加载 SSR bundle(无缓存——正确性优先——与 /app.js 同策略) */
|
|
21
25
|
let ssrMod: any = null
|
|
22
26
|
async function loadSsrApp(): Promise<any> {
|
|
23
27
|
if (ssrMod) return ssrMod
|
|
24
|
-
const entry = resolve(
|
|
28
|
+
const entry = resolve(APP_ROOT, 'ui', 'ssr-entry.ts')
|
|
25
29
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
26
30
|
try {
|
|
27
31
|
const result = await esbuild({
|
|
@@ -31,7 +35,7 @@ async function loadSsrApp(): Promise<any> {
|
|
|
31
35
|
format: 'esm',
|
|
32
36
|
write: false,
|
|
33
37
|
jsx: 'automatic',
|
|
34
|
-
jsxImportSource: '
|
|
38
|
+
jsxImportSource: resolve(fwRoot, 'level6', 'client', 'vdom'),
|
|
35
39
|
})
|
|
36
40
|
const tmp = resolve(tmpdir(), `wf-ap-ssr-${process.pid}-${Date.now()}.mjs`)
|
|
37
41
|
await writeFile(tmp, result.outputFiles[0].text)
|