feat(mindspace): enforce PostgreSQL user data delivery
This commit is contained in:
@@ -24,6 +24,7 @@ import { closePolicyDataset, normalizePageAccessPolicy } from './page-access-pol
|
||||
import { upsertPageDataPolicyIndex } from './page-data-policy-index.mjs';
|
||||
import { bindWorkspaceHtmlForPageData } from './page-data-workspace-bind.mjs';
|
||||
import { resolveMindSpaceStorageRoot } from './mindspace-runtime-config.mjs';
|
||||
import { assertNoProhibitedBrowserStorage } from './mindspace-browser-storage-policy.mjs';
|
||||
|
||||
const SANDBOX_ROOT = process.argv[2]?.trim() || process.env.SANDBOX_ROOT?.trim();
|
||||
if (!SANDBOX_ROOT) {
|
||||
@@ -215,7 +216,7 @@ const ALL_TOOLS = [
|
||||
{
|
||||
name: 'private_data_info',
|
||||
description:
|
||||
'查看当前用户“用户私有数据空间”的状态。每个用户只有一个私有 SQLite 数据库,适合保存问卷、表单、清单、调研数据和分析中间表;不要创建额外 SQLite 文件。',
|
||||
'查看当前用户“用户私有数据空间”的状态。每个用户只有一个由平台分配和隔离的数据空间,适合保存问卷、表单、清单、调研数据和分析中间表;不要创建额外数据库文件。',
|
||||
inputSchema: { type: 'object', properties: {} },
|
||||
},
|
||||
{
|
||||
@@ -504,6 +505,7 @@ async function callTool(name, args) {
|
||||
}
|
||||
case 'write_file': {
|
||||
const abs = resolveSandboxed(args.path);
|
||||
assertNoProhibitedBrowserStorage(args.content ?? '', { relativePath: args.path });
|
||||
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
||||
fs.writeFileSync(abs, args.content ?? '', 'utf8');
|
||||
return [{ type: 'text', text: `已写入 ${args.path}(${(args.content ?? '').length} 字节)` }];
|
||||
@@ -516,6 +518,7 @@ async function callTool(name, args) {
|
||||
throw new Error('edit_file: old_str 在文件中不存在,替换失败');
|
||||
}
|
||||
const updated = oldStr ? original.replace(oldStr, args.new_str ?? '') : (args.new_str ?? '');
|
||||
assertNoProhibitedBrowserStorage(updated, { relativePath: args.path });
|
||||
fs.writeFileSync(abs, updated, 'utf8');
|
||||
return [{ type: 'text', text: `已编辑 ${args.path}` }];
|
||||
}
|
||||
@@ -578,7 +581,9 @@ async function callTool(name, args) {
|
||||
{
|
||||
...info,
|
||||
rules: [
|
||||
'每个用户只能使用这个唯一 SQLite 数据库',
|
||||
info.backend === 'postgres'
|
||||
? '每个用户只能使用新 PG 中分配给自己的独立 schema'
|
||||
: '每个用户只能使用这个唯一 SQLite 数据库',
|
||||
'适合问卷、表单、清单、调研数据和分析中间表',
|
||||
'不要存账号、计费、权限、审计、公开平台数据或跨用户数据',
|
||||
'HTML 页面通过 Page Data API 访问 dataset,不要直接暴露 SQL',
|
||||
@@ -603,7 +608,9 @@ async function callTool(name, args) {
|
||||
return [
|
||||
{
|
||||
type: 'text',
|
||||
text: `已执行。当前数据空间大小 ${result.sizeBytes} 字节${result.quotaSynced ? `,已同步空间占用 ${result.deltaBytes} 字节` : ''}`,
|
||||
text: result.backend === 'postgres'
|
||||
? `已在用户专属 PG schema 中执行。命令 ${result.command ?? 'OK'},影响 ${result.affectedRows ?? 0} 行`
|
||||
: `已执行。当前数据空间大小 ${result.sizeBytes} 字节${result.quotaSynced ? `,已同步空间占用 ${result.deltaBytes} 字节` : ''}`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user