Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.

Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-06-15 15:04:43 -07:00
commit 2e14873f2d
272 changed files with 64133 additions and 0 deletions
+297
View File
@@ -0,0 +1,297 @@
import { resolveAgentGooseMode } from './policies.mjs';
export const CAPABILITY_CATALOG = [
{
key: 'shell',
label: 'Shell 命令',
description: '执行 bash/shell 命令(developer.shell',
risk: 'high',
category: 'developer',
},
{
key: 'static_publish',
label: '用户沙箱目录',
description:
'在 MindSpace/<用户ID>/ 内可使用 write、edit、shell、tree(不可越出该目录;由 static-page-publish 技能开通)',
risk: 'medium',
category: 'publisher',
},
{
key: 'filesystem',
label: '文件读写(全目录)',
description: '在工作区内任意读写文件(developer.write / edit),仅高级用户',
risk: 'high',
category: 'developer',
},
{
key: 'code_browse',
label: '代码浏览',
description: '目录树、代码结构分析(developer.tree、analyze',
risk: 'low',
category: 'developer',
},
{
key: 'image_read',
label: '图片读取',
description: '读取本地或网络图片(developer.read_image',
risk: 'low',
category: 'developer',
},
{
key: 'skills',
label: '技能加载',
description: '加载技能与知识(skills / summon.load',
risk: 'low',
category: 'knowledge',
},
{
key: 'subagent',
label: '子任务派发',
description: 'delegate 子 Agent 执行复杂任务(summon',
risk: 'high',
category: 'agent',
},
{
key: 'code_sandbox',
label: '沙箱脚本',
description: 'execute_typescript 在沙箱中批量调用工具(code_execution',
risk: 'high',
category: 'agent',
},
{
key: 'chat_recall',
label: '对话回溯',
description: '检索历史会话(chatrecall',
risk: 'low',
category: 'memory',
},
{
key: 'context_memory',
label: '项目记忆',
description: '会话级项目记忆注入(projectmemoryH5 引导用)',
risk: 'low',
category: 'memory',
},
{
key: 'memory_store',
label: '长期记忆',
description: '记住/检索用户偏好(memory 扩展)',
risk: 'medium',
category: 'memory',
},
{
key: 'extension_admin',
label: '扩展管理',
description: '搜索、启用、禁用扩展(extensionmanager',
risk: 'high',
category: 'admin',
},
{
key: 'apps',
label: '应用管理',
description: '创建与管理 TKMind 应用(apps',
risk: 'medium',
category: 'agent',
},
{
key: 'todo',
label: '待办事项',
description: '任务列表跟踪(todo',
risk: 'low',
category: 'productivity',
},
{
key: 'computer',
label: '电脑控制',
description: '自动化脚本、网页抓取、文档处理(computercontroller',
risk: 'high',
category: 'automation',
},
{
key: 'charts',
label: '数据可视化',
description: '图表与可视化(autovisualiser',
risk: 'low',
category: 'automation',
},
{
key: 'aider',
label: 'Aider 编码',
description: '多文件编码委托(aider',
risk: 'high',
category: 'developer',
},
];
/** Capabilities that must never be enabled for regular users, even via DB overrides. */
export const USER_NON_GRANTABLE_CAPABILITIES = new Set(['extension_admin']);
export function clampUserCapabilities(capabilities) {
const clamped = { ...capabilities };
for (const key of USER_NON_GRANTABLE_CAPABILITIES) {
clamped[key] = false;
}
return clamped;
}
export const DEFAULT_USER_CAPABILITIES = Object.fromEntries(
CAPABILITY_CATALOG.map(({ key }) => {
const defaults = {
shell: false,
static_publish: false,
filesystem: false,
code_browse: false,
image_read: true,
skills: false,
subagent: false,
code_sandbox: false,
chat_recall: false,
context_memory: true,
memory_store: false,
extension_admin: false,
apps: false,
todo: false,
computer: false,
charts: false,
aider: false,
};
return [key, defaults[key] ?? false];
}),
);
const CATALOG_KEYS = new Set(CAPABILITY_CATALOG.map((item) => item.key));
export function catalogKeys() {
return [...CATALOG_KEYS];
}
export function isValidCapabilityKey(key) {
return CATALOG_KEYS.has(key);
}
function makeExtension(type, name, tools = []) {
return {
type,
name,
description: '',
display_name: name,
bundled: true,
available_tools: tools,
};
}
export const SANDBOX_DEVELOPER_TOOLS = ['write', 'edit', 'shell', 'tree', 'read_image'];
/** static_publish sandbox: only file writes inside MindSpace/<userId>/ — no tree/shell by default */
export function sandboxDeveloperTools(capabilities) {
const tools = ['write', 'edit'];
if (capabilities.shell) {
tools.push('shell', 'tree');
} else if (capabilities.code_browse) {
tools.push('tree');
}
if (capabilities.image_read) tools.push('read_image');
return tools;
}
export function developerToolsFromPolicy(sessionPolicy) {
const developer = sessionPolicy?.extensionOverrides?.find((ext) => ext.name === 'developer');
return developer?.available_tools ?? [];
}
function mergeDeveloperTools(capabilities) {
const tools = [];
if (capabilities.shell) tools.push('shell');
if (capabilities.filesystem) tools.push('write', 'edit');
if (capabilities.code_browse) tools.push('tree');
if (capabilities.image_read) tools.push('read_image');
return tools;
}
/**
* Build goose agent/start extension_overrides from resolved capability flags.
* Returns null when the caller should use server defaults (admin / unrestricted).
*/
export function buildAgentExtensionPolicy(
capabilities,
{ unrestricted = false, policies = null } = {},
) {
if (unrestricted) {
return { extensionOverrides: null, enableContextMemory: true, gooseMode: 'auto' };
}
const extensions = [];
if (capabilities.static_publish) {
const sandboxTools = sandboxDeveloperTools(capabilities);
if (sandboxTools.length > 0) {
extensions.push(makeExtension('platform', 'developer', sandboxTools));
}
extensions.push(makeExtension('platform', 'skills', []));
extensions.push(makeExtension('platform', 'summon', ['load_skill']));
extensions.push(makeExtension('platform', 'projectmemory', []));
} else {
const developerTools = mergeDeveloperTools(capabilities);
if (developerTools.length > 0) {
extensions.push(makeExtension('platform', 'developer', developerTools));
}
if (capabilities.code_browse) {
extensions.push(makeExtension('platform', 'analyze', []));
}
if (capabilities.skills) {
extensions.push(makeExtension('platform', 'skills', []));
}
if (capabilities.skills || capabilities.subagent) {
const summonTools = [];
if (capabilities.skills) summonTools.push('load', 'load_skill');
if (capabilities.subagent) summonTools.push('delegate');
extensions.push(makeExtension('platform', 'summon', summonTools));
}
}
if (capabilities.code_sandbox) {
extensions.push(makeExtension('platform', 'code_execution', []));
}
if (capabilities.chat_recall) {
extensions.push(makeExtension('platform', 'chatrecall', []));
}
if (capabilities.context_memory) {
extensions.push(makeExtension('platform', 'projectmemory', []));
}
if (capabilities.memory_store) {
extensions.push(makeExtension('builtin', 'memory', []));
}
if (capabilities.extension_admin) {
extensions.push(makeExtension('platform', 'extensionmanager', []));
}
if (capabilities.apps) {
extensions.push(makeExtension('platform', 'apps', []));
}
if (capabilities.todo) {
extensions.push(makeExtension('platform', 'todo', []));
}
if (capabilities.computer) {
extensions.push(makeExtension('builtin', 'computercontroller', []));
}
if (capabilities.charts) {
extensions.push(makeExtension('builtin', 'autovisualiser', []));
}
if (capabilities.aider) {
extensions.push(makeExtension('platform', 'aider', []));
}
return {
extensionOverrides: extensions,
enableContextMemory: Boolean(
capabilities.context_memory || capabilities.chat_recall || capabilities.static_publish,
),
gooseMode: resolveAgentGooseMode(capabilities, policies),
};
}
export function normalizeCapabilityPatch(patch) {
const normalized = {};
for (const [key, value] of Object.entries(patch ?? {})) {
if (!isValidCapabilityKey(key)) continue;
normalized[key] = Boolean(value);
}
return normalized;
}