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.
@@ -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, dirname } from 'node:path'
11
- import { fileURLToPath } from 'node:url'
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(__dirname, '..', '..', '..', '..', 'dist')
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(__dirname, 'public', 'survey-form.html'), 'utf-8')
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 { join, dirname } = await import('node:path')
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(__dirname, 'public', 'survey-stats.html'), 'utf-8')
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, __dirname)
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, dirname } from 'node:path'
13
- import { fileURLToPath } from 'node:url'
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 { resolve, dirname } = await import('node:path')
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(dirname(fileURLToPath(import.meta.url)), '../../package.json'), 'utf-8')).version } catch { return 'dev' } })(), ts: new Date().toISOString() },
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 { resolve, dirname } = await import('node:path')
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, dirname } from 'node:path'
23
- import { fileURLToPath } from 'node:url'
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(__dirname, '../../dist/sandbox/sandbox-agent'),
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, join, dirname } from 'node:path'
13
- import { fileURLToPath, pathToFileURL } from 'node:url'
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
- const __dirname = dirname(fileURLToPath(import.meta.url))
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(__dirname, '..', 'ui', 'ssr-entry.ts')
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: 'weifuwu/client/vdom',
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)