初始化提交

This commit is contained in:
陈二狗 2026-05-21 09:08:59 +08:00
parent 7459416316
commit fdb4e439cf
25 changed files with 75 additions and 78 deletions

View File

@ -1,8 +1,8 @@
# Neta Monorepo 环境变量配置示例 # GPU Guard Monorepo 环境变量配置示例
# 注意:后端数据库配置在 packages/backend/src/config/config.local.ts 中 # 注意:后端数据库配置在 packages/backend/src/config/config.local.ts 中
# 后端端口 # 后端端口
NODE_ENV=local NODE_ENV=local
# AI 配置 (AI Flow 后端使用) # AI 配置 (GPU Guard 后端使用)
OPENAI_API_KEY=your_openai_key OPENAI_API_KEY=your_openai_key

5
.gitignore vendored
View File

@ -62,10 +62,7 @@ coverage/
.cache/ .cache/
.worktrees/ .worktrees/
# Claude Code # Agent tooling
.claude/settings.local.json
.claude/ .claude/
.husky/ .husky/
.superpowers/ .superpowers/
/.husky/
/.claude/

View File

@ -1,6 +1,6 @@
# Neta AI电商 - AI驱动的电商自动化运营平台 # GPU Guard - GPU 智能监控与防护平台
> 基于 Midway.js + Vue 3 + NetaClaw AI引擎 的智能电商运营平台Monorepo 架构 > 基于 Midway.js + Vue 3 + AI引擎 的智能 GPU 监控平台Monorepo 架构
## 技术架构 ## 技术架构
@ -8,7 +8,7 @@
|------|---------|------| |------|---------|------|
| **后端** | Midway.js 3.20 + TypeScript 5.9 + TypeORM + Cool Admin | 8003 | | **后端** | Midway.js 3.20 + TypeScript 5.9 + TypeORM + Cool Admin | 8003 |
| **前端** | Vue 3.5 + Vite 5.4 + Element Plus 2.9 + Pinia | 9001 | | **前端** | Vue 3.5 + Vite 5.4 + Element Plus 2.9 + Pinia | 9001 |
| **AI 引擎** | NetaClaw (ReAct 循环 + TypeBox Schema + WebSocket) | - | | **AI 引擎** | AI Agent 引擎 (ReAct 循环 + TypeBox Schema + WebSocket) | - |
| **数据库** | MySQL 8.0+ | 3306 | | **数据库** | MySQL 8.0+ | 3306 |
## 项目结构 ## 项目结构
@ -62,7 +62,7 @@ pnpm dev:frontend # 前端 http://localhost:9001
| 模块 | 路由前缀 | 用途 | | 模块 | 路由前缀 | 用途 |
|------|---------|------| |------|---------|------|
| **agent** | `/agent/*` | Agent 对话、Skill 管理、模型渠道管理 | | **agent** | `/agent/*` | 智能体对话、技能管理、模型渠道管理 |
| **base** | `/` | 登录、用户、角色、菜单、部门 | | **base** | `/` | 登录、用户、角色、菜单、部门 |
## 数据库 ## 数据库

View File

@ -1,8 +1,8 @@
{ {
"name": "neta-monorepo", "name": "gpu-guard-monorepo",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"description": "Neta AI电商 - AI驱动的电商自动化运营平台", "description": "GPU Guard - GPU 智能监控与防护平台",
"pnpm": { "pnpm": {
"overrides": { "overrides": {
"@cool-midway/core": "8.0.7" "@cool-midway/core": "8.0.7"
@ -13,9 +13,9 @@
] ]
}, },
"scripts": { "scripts": {
"dev": "pnpm --parallel --filter @neta/backend --filter @neta/frontend dev", "dev": "pnpm --parallel --filter @gpu-guard/backend --filter @gpu-guard/frontend dev",
"dev:backend": "pnpm --filter @neta/backend dev", "dev:backend": "pnpm --filter @gpu-guard/backend dev",
"dev:frontend": "pnpm --filter @neta/frontend dev", "dev:frontend": "pnpm --filter @gpu-guard/frontend dev",
"build": "pnpm --filter './packages/*' build", "build": "pnpm --filter './packages/*' build",
"test": "pnpm --filter './packages/*' test", "test": "pnpm --filter './packages/*' test",
"lint": "pnpm --filter './packages/*' lint", "lint": "pnpm --filter './packages/*' lint",

View File

@ -1,8 +1,8 @@
# CLAUDE.md - Neta AI电商 后端 # CLAUDE.md - GPU Guard 后端
## 项目概述 ## 项目概述
Neta AI电商 后端 - 基于 Midway.js + Cool Admin 框架的 AI 电商运营平台后端。 GPU Guard 后端 - 基于 Midway.js + Cool Admin 框架的 GPU 智能监控平台后端。
**技术栈**: Midway.js 3.20 + TypeScript 5.9 + TypeORM + Cool Admin 8.x + MySQL 8+ **技术栈**: Midway.js 3.20 + TypeScript 5.9 + TypeORM + Cool Admin 8.x + MySQL 8+
**端口**: 8003 **端口**: 8003

View File

@ -4,10 +4,10 @@ const { resolveTraySecret } = require('./dist/comm/runtime-secret');
const traySecret = resolveTraySecret(process.argv, process.env); const traySecret = resolveTraySecret(process.argv, process.env);
if (traySecret) { if (traySecret) {
process.env.NETA_TRAY_SECRET = traySecret; process.env.GPU_GUARD_TRAY_SECRET = traySecret;
} }
if (process.argv.includes('--no-browser')) { if (process.argv.includes('--no-browser')) {
process.env.NETA_NO_BROWSER = 'true'; process.env.GPU_GUARD_NO_BROWSER = 'true';
} }
if (process.argv.includes('--version')) { if (process.argv.includes('--version')) {
@ -17,7 +17,7 @@ if (process.argv.includes('--version')) {
const configArgIndex = process.argv.indexOf('--config'); const configArgIndex = process.argv.indexOf('--config');
if (configArgIndex > -1 && process.argv[configArgIndex + 1]) { if (configArgIndex > -1 && process.argv[configArgIndex + 1]) {
process.env.NETA_CONFIG_PATH = process.argv[configArgIndex + 1]; process.env.GPU_GUARD_CONFIG_PATH = process.argv[configArgIndex + 1];
} }
try { try {

View File

@ -2,7 +2,7 @@ server:
port: 8003 port: 8003
data: data:
dir: "C:\\NetaData" dir: "C:\\GPUGuardData"
autoOpenBrowser: true autoOpenBrowser: true
@ -10,6 +10,6 @@ database:
type: mysql type: mysql
host: "120.48.5.80" host: "120.48.5.80"
port: 3306 port: 3306
username: "neta_test" username: "cpu_guard"
password: "m8FmsnnfJ3znPkdx" password: "m8FmsnnfJ3znPkdx"
database: "neta_test" database: "cpu_guard"

View File

@ -1,7 +1,7 @@
{ {
"name": "@neta/backend", "name": "@gpu-guard/backend",
"version": "8.0.0", "version": "8.0.0",
"description": "AI Flow 审核平台后端 - 基于 Midway.js + Cool Admin 的 AI 流程编排引擎", "description": "GPU Guard 平台后端 - 基于 Midway.js + Cool Admin 的 GPU 智能监控引擎",
"private": true, "private": true,
"overrides": { "overrides": {
"@cool-midway/core": "8.0.7" "@cool-midway/core": "8.0.7"

View File

@ -3,8 +3,8 @@
* *
* Cool Admin LocationUtil.getRunPath() 通过 Error stack trace 中的 * Cool Admin LocationUtil.getRunPath() 通过 Error stack trace 中的
* node_modules 位置反推项目根目录 pnpm monorepo node_modules * node_modules 位置反推项目根目录 pnpm monorepo node_modules
* 被提升到根目录导致解析到 Neta-monorepo/dist 而非 * 被提升到根目录导致解析到 GPU_GUARD_MONOREPO/dist 而非
* Neta-monorepo/packages/backend/dist(或src)使得模块配置无法加载 * GPU_GUARD_MONOREPO/packages/backend/dist(或src)使得模块配置无法加载
* *
* 本脚本通过 --require NODE_OPTIONS 在所有模块加载前修补 getRunPath * 本脚本通过 --require NODE_OPTIONS 在所有模块加载前修补 getRunPath
*/ */

View File

@ -12,9 +12,9 @@ export function acquireRuntimeLock(lockPath: string) {
const current = JSON.parse(fs.readFileSync(lockPath, 'utf8')) as { pid: number }; const current = JSON.parse(fs.readFileSync(lockPath, 'utf8')) as { pid: number };
try { try {
process.kill(current.pid, 0); process.kill(current.pid, 0);
throw new Error(`Neta 已在运行PID=${current.pid}`); throw new Error(`GPU Guard 已在运行PID=${current.pid}`);
} catch (e: any) { } catch (e: any) {
if (e.message?.includes('Neta 已在运行')) throw e; if (e.message?.includes('GPU Guard 已在运行')) throw e;
// Stale lock — remove and retry // Stale lock — remove and retry
fs.rmSync(lockPath, { force: true }); fs.rmSync(lockPath, { force: true });
fs.writeFileSync(lockPath, data, 'utf8'); fs.writeFileSync(lockPath, data, 'utf8');

View File

@ -16,7 +16,7 @@ export function validateRuntimeSecret(expected?: string, actual?: string | null)
export function resolveTraySecret(argv: string[], env: NodeJS.ProcessEnv) { export function resolveTraySecret(argv: string[], env: NodeJS.ProcessEnv) {
const index = argv.indexOf('--tray-secret'); const index = argv.indexOf('--tray-secret');
if (index > -1 && argv[index + 1]) return argv[index + 1]; if (index > -1 && argv[index + 1]) return argv[index + 1];
return env.NETA_TRAY_SECRET || ''; return env.GPU_GUARD_TRAY_SECRET || '';
} }
export function createRuntimeSecret() { export function createRuntimeSecret() {

View File

@ -109,15 +109,15 @@ export default {
}, },
}, },
autoOpenBrowser: autoOpenBrowser:
process.env.NETA_NO_BROWSER !== 'true' && process.env.GPU_GUARD_NO_BROWSER !== 'true' &&
((global as any).__NETA_EXTERNAL_CONFIG__?.autoOpenBrowser ?? false), ((global as any).__GPU_GUARD_EXTERNAL_CONFIG__?.autoOpenBrowser ?? false),
// NetaClaw Agent 引擎配置 // GPU Guard AI 引擎配置
netaclaw: { netaclaw: {
defaultModel: 'anthropic:claude-sonnet-4-20250514', defaultModel: 'anthropic:claude-sonnet-4-20250514',
apiKeys: { apiKeys: {
anthropic: process.env.NETACLAW_ANTHROPIC_KEY ?? '', anthropic: process.env.GPUCLAW_ANTHROPIC_KEY ?? '',
openai: process.env.NETACLAW_OPENAI_KEY ?? '', openai: process.env.GPUCLAW_OPENAI_KEY ?? '',
deepseek: process.env.NETACLAW_DEEPSEEK_KEY ?? '', deepseek: process.env.GPUCLAW_DEEPSEEK_KEY ?? '',
}, },
skillsDir: path.join(resolvedDataDir, 'skills'), skillsDir: path.join(resolvedDataDir, 'skills'),
dataDir: resolvedDataDir, dataDir: resolvedDataDir,

View File

@ -3,7 +3,7 @@ import { MidwayConfig } from '@midwayjs/core';
import { entities } from '../entities'; import { entities } from '../entities';
import { TenantSubscriber } from '../modules/base/db/tenant'; import { TenantSubscriber } from '../modules/base/db/tenant';
const external = (global as any).__NETA_EXTERNAL_CONFIG__; const external = (global as any).__GPU_GUARD_EXTERNAL_CONFIG__;
export default { export default {
typeorm: { typeorm: {

View File

@ -86,20 +86,20 @@ export class MainConfiguration {
ensureDpiAware(); ensureDpiAware();
const dataDir = pDataPath(); const dataDir = pDataPath();
const lockPath = path.join(dataDir, 'neta.lock'); const lockPath = path.join(dataDir, 'gpu-guard.lock');
const runtimeInfoPath = path.join(dataDir, 'runtime-info.json'); const runtimeInfoPath = path.join(dataDir, 'runtime-info.json');
const configDir = path.dirname(process.env.NETA_CONFIG_PATH || process.execPath); const configDir = path.dirname(process.env.GPU_GUARD_CONFIG_PATH || process.execPath);
const port = this.app.getConfig('koa.port'); const port = this.app.getConfig('koa.port');
const startedAt = new Date().toISOString(); const startedAt = new Date().toISOString();
(global as any).__NETA_RUNTIME_STARTED_AT__ = startedAt; (global as any).__GPU_GUARD_RUNTIME_STARTED_AT__ = startedAt;
(global as any).__NETA_RUNTIME_READY__ = false; (global as any).__GPU_GUARD_RUNTIME_READY__ = false;
acquireRuntimeLock(lockPath); acquireRuntimeLock(lockPath);
process.on('exit', () => releaseRuntimeLock(lockPath)); process.on('exit', () => releaseRuntimeLock(lockPath));
registerGracefulShutdown(async () => { registerGracefulShutdown(async () => {
(global as any).__NETA_RUNTIME_READY__ = false; (global as any).__GPU_GUARD_RUNTIME_READY__ = false;
clearRuntimeInfo(runtimeInfoPath); clearRuntimeInfo(runtimeInfoPath);
releaseRuntimeLock(lockPath); releaseRuntimeLock(lockPath);
setTimeout(() => process.exit(0), 50); setTimeout(() => process.exit(0), 50);
@ -122,7 +122,7 @@ export class MainConfiguration {
.getAsync(DesktopOpConfigBootstrap); .getAsync(DesktopOpConfigBootstrap);
await desktopOpBootstrap.ensureConfigAndLoad(); await desktopOpBootstrap.ensureConfigAndLoad();
(global as any).__NETA_RUNTIME_READY__ = true; (global as any).__GPU_GUARD_RUNTIME_READY__ = true;
writeRuntimeInfo(runtimeInfoPath, { writeRuntimeInfo(runtimeInfoPath, {
pid: process.pid, pid: process.pid,
ready: true, ready: true,

View File

@ -1,7 +1,7 @@
# 【开发】环境变量 # 【开发】环境变量
# 应用名称 # 应用名称
VITE_NAME = "AI Flow 智能审核平台" VITE_NAME = "GPU Guard 智能监控平台"
# 前端开发服务器端口 # 前端开发服务器端口
VITE_PORT = 9001 VITE_PORT = 9001

View File

@ -1,5 +1,5 @@
# 应用名称 # 应用名称
VITE_NAME = "AI Flow 智能审核平台" VITE_NAME = "GPU Guard 智能监控平台"
# 网络超时请求时间 # 网络超时请求时间
VITE_TIMEOUT = 30000 VITE_TIMEOUT = 30000

View File

@ -1,8 +1,8 @@
# CLAUDE.md - Neta AI电商 前端 # CLAUDE.md - GPU Guard 前端
## 项目概述 ## 项目概述
Neta AI电商 前端 - 基于 Vue 3 + Cool Admin UI 的 AI 电商运营平台前端。 GPU Guard 前端 - 基于 Vue 3 + Cool Admin UI 的 GPU 智能监控平台前端。
**技术栈**: Vue 3.5 + TypeScript 5.5 + Vite 5.4 + Element Plus 2.9 + Pinia **技术栈**: Vue 3.5 + TypeScript 5.5 + Vite 5.4 + Element Plus 2.9 + Pinia
**端口**: 9001 **端口**: 9001
@ -95,7 +95,7 @@ service.project.info.info({ id: 1 }) // GET /admin/project/info/i
| 模块 | 路由前缀 | 关键页面 | | 模块 | 路由前缀 | 关键页面 |
|------|---------|---------| |------|---------|---------|
| **base** | `/` | 登录(Canvas星河动画)、首页、用户管理、角色管理、菜单管理、部门管理 | | **base** | `/` | 登录(Canvas星河动画)、首页、用户管理、角色管理、菜单管理、部门管理 |
| **agent** | `/agent/*` | Agent对话(WebSocket)、Agent管理、Skill管理、模型渠道管理、检测结果 | | **agent** | `/agent/*` | 智能体对话(WebSocket)、智能体管理、技能管理、模型渠道管理、检测结果 |
| **project** | `/project/*` | 项目列表、项目详情(甘特图/日历/看板/列表四视图) | | **project** | `/project/*` | 项目列表、项目详情(甘特图/日历/看板/列表四视图) |
| **data** | `/data/*` | 商业健康险创新药、医保药品管理 | | **data** | `/data/*` | 商业健康险创新药、医保药品管理 |
| **dict** | `/dict/*` | 字典管理 | | **dict** | `/dict/*` | 字典管理 |

View File

@ -1,5 +1,5 @@
{ {
"name": "@neta/frontend", "name": "@gpu-guard/frontend",
"version": "8.0.0", "version": "8.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@ -3,27 +3,27 @@ import { type ModuleConfig } from '/@/cool';
export default (): ModuleConfig => { export default (): ModuleConfig => {
return { return {
name: 'agent', name: 'agent',
label: 'Agent 对话', label: 'AI 智能体',
order: 100, order: 100,
views: [ views: [
{ {
path: '/agent/chat', path: '/agent/chat',
meta: { label: 'Agent 对话' }, meta: { label: '智能体对话' },
component: () => import('./views/chat.vue') component: () => import('./views/chat.vue')
}, },
{ {
path: '/agent/agents', path: '/agent/agents',
meta: { label: 'Agent 管理' }, meta: { label: '智能体管理' },
component: () => import('./views/agent-list.vue') component: () => import('./views/agent-list.vue')
}, },
{ {
path: '/agent/tools', path: '/agent/tools',
meta: { label: 'Tool 管理' }, meta: { label: '工具管理' },
component: () => import('./views/tools.vue') component: () => import('./views/tools.vue')
}, },
{ {
path: '/agent/skills', path: '/agent/skills',
meta: { label: 'Skill 管理' }, meta: { label: '技能管理' },
component: () => import('./views/skills.vue') component: () => import('./views/skills.vue')
}, },
{ {
@ -43,7 +43,7 @@ export default (): ModuleConfig => {
}, },
{ {
path: '/agent/crew-editor', path: '/agent/crew-editor',
meta: { label: 'Agent 编排' }, meta: { label: '智能体编排' },
component: () => import('./views/crew-editor.vue') component: () => import('./views/crew-editor.vue')
}, },
{ {

View File

@ -3,7 +3,7 @@
<div class="channel-page__header"> <div class="channel-page__header">
<div class="channel-page__title"> <div class="channel-page__title">
<h2>频道管理</h2> <h2>频道管理</h2>
<p>支持两种模式<strong>ClawBot 私聊助手</strong>扫码登录独立 bot 账号用于一对一私聊<strong>微信本地代理 weixin-db</strong>从本机 PC 微信数据库读取消息用于群聊场景 Windows + 已登录 PC 微信</p> <p>支持两种模式<strong>微信私聊助手</strong>扫码登录独立 bot 账号用于一对一私聊<strong>微信本地代理 weixin-db</strong>从本机 PC 微信数据库读取消息用于群聊场景 Windows + 已登录 PC 微信</p>
</div> </div>
<div class="channel-page__actions"> <div class="channel-page__actions">
<el-select v-model="filters.loginStatus" clearable placeholder="连接状态" style="width: 140px"> <el-select v-model="filters.loginStatus" clearable placeholder="连接状态" style="width: 140px">
@ -96,7 +96,7 @@
<div class="channel-card__footer"> <div class="channel-card__footer">
<el-button link type="primary" @click="handleEdit(item)">编辑</el-button> <el-button link type="primary" @click="handleEdit(item)">编辑</el-button>
<el-button v-if="item.type === 'weixin'" link type="success" @click="openQrDialog(item)"> <el-button v-if="item.type === 'weixin'" link type="success" @click="openQrDialog(item)">
ClawBot 扫码登录 微信Bot 扫码登录
</el-button> </el-button>
<el-button <el-button
v-if="(item.type === 'weixin' && item.loginStatus === 'connected') || item.type === 'weixin-db'" v-if="(item.type === 'weixin' && item.loginStatus === 'connected') || item.type === 'weixin-db'"
@ -151,7 +151,7 @@
<el-select v-model="drawer.form.type" style="width: 100%" :disabled="drawer.isEdit"> <el-select v-model="drawer.form.type" style="width: 100%" :disabled="drawer.isEdit">
<el-option v-for="item in options.types" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in options.types" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
<div class="form-hint">微信本地代理 weixin-db 从本机 PC 微信数据库读取消息 Windows 可用ClawBot 通过扫码登录 iLink编辑后不可修改类型</div> <div class="form-hint">微信本地代理 weixin-db 从本机 PC 微信数据库读取消息 Windows 可用微信Bot 通过扫码登录 iLink编辑后不可修改类型</div>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="drawer.form.type === 'weixin'" v-if="drawer.form.type === 'weixin'"
@ -168,7 +168,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- ClawBot 专属字段 --> <!-- 微信Bot 专属字段 -->
<template v-if="drawer.form.type === 'weixin'"> <template v-if="drawer.form.type === 'weixin'">
<el-form-item label="机器人昵称" prop="botAlias"> <el-form-item label="机器人昵称" prop="botAlias">
<el-input <el-input
@ -283,7 +283,7 @@
</template> </template>
</el-drawer> </el-drawer>
<el-dialog v-model="qrDialog.visible" title="ClawBot 扫码登录(个人微信助手)" width="420px" @closed="stopQrPolling"> <el-dialog v-model="qrDialog.visible" title="微信Bot 扫码登录(个人微信助手)" width="420px" @closed="stopQrPolling">
<div class="qr-dialog" v-loading="qrDialog.loading"> <div class="qr-dialog" v-loading="qrDialog.loading">
<template v-if="qrDialog.qrcodeUrl"> <template v-if="qrDialog.qrcodeUrl">
<img class="qr-image" :src="qrImageSrc(qrDialog.qrcodeUrl)" alt="微信二维码" /> <img class="qr-image" :src="qrImageSrc(qrDialog.qrcodeUrl)" alt="微信二维码" />
@ -340,7 +340,7 @@ const desktopAgents = computed(() => allAgents.value);
const options = reactive({ const options = reactive({
types: [ types: [
{ value: 'weixin', label: '微信 ClawBot个人助手 · 仅私聊)' }, { value: 'weixin', label: '微信Bot个人助手 · 仅私聊)' },
{ value: 'weixin-db', label: '微信本地代理(群聊 · 需 Windows + PC 微信)' }, { value: 'weixin-db', label: '微信本地代理(群聊 · 需 Windows + PC 微信)' },
], ],
loginStatuses: [] as Array<{ value: string; label: string }>, loginStatuses: [] as Array<{ value: string; label: string }>,
@ -414,7 +414,7 @@ const rules = computed<FormRules>(() => ({
? [{ required: true, message: '请选择要绑定的 Agent', trigger: 'change' }] ? [{ required: true, message: '请选择要绑定的 Agent', trigger: 'change' }]
: [], : [],
botAlias: drawer.form.type === 'weixin' botAlias: drawer.form.type === 'weixin'
? [{ required: true, message: 'ClawBot 渠道必须填写机器人昵称', trigger: 'blur' }] ? [{ required: true, message: '微信Bot 渠道必须填写机器人昵称', trigger: 'blur' }]
: [], : [],
wxid: drawer.form.type === 'weixin-db' wxid: drawer.form.type === 'weixin-db'
? [{ required: true, message: 'weixin-db 渠道必须填写 wxid', trigger: 'blur' }] ? [{ required: true, message: 'weixin-db 渠道必须填写 wxid', trigger: 'blur' }]
@ -471,7 +471,7 @@ async function loadOptions() {
merged.push({ value: 'weixin-db', label: '微信本地代理(群聊 · 需 Windows + PC 微信)' }); merged.push({ value: 'weixin-db', label: '微信本地代理(群聊 · 需 Windows + PC 微信)' });
} }
if (!merged.find((t: any) => t.value === 'weixin')) { if (!merged.find((t: any) => t.value === 'weixin')) {
merged.unshift({ value: 'weixin', label: '微信 ClawBot个人助手 · 仅私聊)' }); merged.unshift({ value: 'weixin', label: '微信Bot个人助手 · 仅私聊)' });
} }
options.types = merged; options.types = merged;
options.loginStatuses = data.data.loginStatuses || []; options.loginStatuses = data.data.loginStatuses || [];
@ -535,7 +535,7 @@ function handleEdit(item: AgentChannelInfo) {
const normalizedType: 'weixin' | 'weixin-db' = const normalizedType: 'weixin' | 'weixin-db' =
allowedTypes.includes(item.type as any) ? (item.type as 'weixin' | 'weixin-db') : 'weixin'; allowedTypes.includes(item.type as any) ? (item.type as 'weixin' | 'weixin-db') : 'weixin';
if (item.type && !allowedTypes.includes(item.type as any)) { if (item.type && !allowedTypes.includes(item.type as any)) {
ElMessage.warning(`未知频道类型 "${item.type}",已退化为 ClawBot`); ElMessage.warning(`未知频道类型 "${item.type}",已退化为微信Bot`);
} }
const wr = (item.config as any)?.weixinReply; const wr = (item.config as any)?.weixinReply;
drawer.form = { drawer.form = {
@ -581,7 +581,7 @@ async function handleSave() {
try { try {
const trimmedAlias = (drawer.form.botAlias || '').trim(); const trimmedAlias = (drawer.form.botAlias || '').trim();
const existingConfig = drawer.form.config || {}; const existingConfig = drawer.form.config || {};
// :ClawBot credential, normalizePayload existing( iLink token) // :Bot credential, normalizePayload existing( iLink token)
// weixin-db wxid credential ( wxid PC ) // weixin-db wxid credential ( wxid PC )
const payload: Record<string, any> = { const payload: Record<string, any> = {
id: drawer.form.id, id: drawer.form.id,
@ -741,7 +741,7 @@ async function refreshQr() {
const data = await apiPost('/admin/netaclaw/agent_channel/weixin/qr', { id: qrDialog.channelId }); const data = await apiPost('/admin/netaclaw/agent_channel/weixin/qr', { id: qrDialog.channelId });
if (data.code === 1000) { if (data.code === 1000) {
qrDialog.qrcodeUrl = data.data.qrcodeUrl; qrDialog.qrcodeUrl = data.data.qrcodeUrl;
qrDialog.tip = '请使用个人微信扫码 ClawBot,扫码后页面会自动确认登录状态'; qrDialog.tip = '请使用个人微信扫码登录,扫码后页面会自动确认登录状态';
startQrPolling(); startQrPolling();
} else { } else {
ElMessage.error(data.message || '二维码获取失败'); ElMessage.error(data.message || '二维码获取失败');

View File

@ -23,7 +23,7 @@
/> />
<section class="conversation-panel"> <section class="conversation-panel">
<conversation-header <conversation-header
:title="currentAgent?.label || currentAgent?.name || 'Neta Runtime'" :title="currentAgent?.label || currentAgent?.name || 'GPU Guard Runtime'"
:entry-count="visibleConversationEntries.length" :entry-count="visibleConversationEntries.length"
:session-provider-label="sessionProviderLabel" :session-provider-label="sessionProviderLabel"
:session-cwd-label="sessionCwdLabel" :session-cwd-label="sessionCwdLabel"

View File

@ -12,7 +12,7 @@
<span>{{ app.info.name }}</span> <span>{{ app.info.name }}</span>
</div> </div>
<p class="desc">{{ $t('AI 智能审核与流程编排平台') }}</p> <p class="desc">{{ $t('GPU 智能监控与防护平台') }}</p>
<div class="form"> <div class="form">
<el-form label-position="top" class="form" :disabled="saving"> <el-form label-position="top" class="form" :disabled="saving">
@ -65,7 +65,7 @@
</div> </div>
</div> </div>
<span class="copyright">Copyright © 睿智毅行 v1.0</span> <span class="copyright">Copyright © GPU Guard v1.0</span>
</div> </div>
</template> </template>

View File

@ -1,7 +1,7 @@
{ {
"name": "@neta/netabrowser-cli", "name": "@gpu-guard/netabrowser-cli",
"version": "0.1.0", "version": "0.1.0",
"description": "Neta 反风控+拟人化浏览器自动化 CLI", "description": "GPU Guard 反检测浏览器自动化 CLI",
"private": true, "private": true,
"type": "module", "type": "module",
"bin": { "bin": {

View File

@ -1,5 +1,5 @@
{ {
"name": "@neta/shared", "name": "@gpu-guard/shared",
"version": "0.1.0", "version": "0.1.0",
"type": "module", "type": "module",
"main": "./index.ts", "main": "./index.ts",

View File

@ -6,18 +6,18 @@ const { exec } = require('child_process')
const services = [ const services = [
{ {
name: '后端', name: '后端',
title: 'Neta - 后端 (8003)', title: 'GPU Guard - 后端 (8003)',
command: 'pnpm --filter @neta/backend dev' command: 'pnpm --filter @gpu-guard/backend dev'
}, },
{ {
name: '前端', name: '前端',
title: 'Neta - 前端 (9001)', title: 'GPU Guard - 前端 (9001)',
command: 'pnpm --filter @neta/frontend dev' command: 'pnpm --filter @gpu-guard/frontend dev'
}, },
{ {
name: '桌面端', name: '桌面端',
title: 'Neta - 桌面端 (Tauri)', title: 'GPU Guard - 桌面端 (Tauri)',
command: 'pnpm --filter @neta/desktop dev' command: 'pnpm --filter @gpu-guard/desktop dev'
} }
] ]