Files
dsh_ai1net_server/归档/poc-dsh-local/patch-seed-workspace.py
T
admin ce8e6ceed9 chore(工作区): 纳入版本控制基线(回收 411 MB 过程产物)
回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复:
- 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录)
- tmp/(32.4 M,按接续棒命名的过程临时区)
- .workbuddy/tmp/(39.5 M)
- 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物)
- tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留

入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与
接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、
.workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。

排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、
打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
2026-09-24 07:51:03 +08:00

89 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# 档案 24 后续:预置默认工作区(编辑器要求"必须选工作区"才能开会话 → 平台直接种 ws)
# 用法: python3 patch-seed-workspace.py /opt/dshs
import io
import os
import sys
root = sys.argv[1] if len(sys.argv) > 1 else '.'
p = os.path.join(root, 'src/supervisor/orchestrator.ts')
s = io.open(p, encoding='utf-8').read()
def sub(old, new, cnt=1):
global s
assert old in s, 'anchor not found:\n' + old[:200]
s = s.replace(old, new, cnt)
# 1) 补 fs 导入
sub(
"import { chmodSync, mkdirSync, writeFileSync } from 'node:fs'",
"import { chmodSync, chownSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'",
)
# 2) 在 spawnInstance 里对 main 预置工作区
sub(
""" const map = role === 'main' ? this.mains : this.watchdogs
map.set(userId, instance)""",
""" const map = role === 'main' ? this.mains : this.watchdogs
map.set(userId, instance)
// 档案 24 后续:main 启动前预置默认工作区(编辑器要求"必须选择工作区"才能开始会话;
// 平台直接把用户 ws 种进 workspace 存储 → 用户开箱即用、且 UI 只显示短标题而非完整路径)。
if (isMain) await this.seedDefaultWorkspace(userId)""",
)
# 3) 新增 seedDefaultWorkspace 方法(放在 writePatch 之前)
sub(
""" /** Materialize the rendered patch so the dsh CLI can `--patch <file>` it.""",
""" /**
* 预置默认工作区(幂等,仅在工作区列表为空时写入):
* 把 `<userRoot>/ws` 以短标题「我的工作区」写进 `<home>/storages/workspace.json`,
* 使新用户/清空后无需手动选择工作区即可开始会话;已有工作区时**不覆盖**用户现状。
* 失败不阻断启动(只记日志)。
*/
private async seedDefaultWorkspace(userId: string): Promise<void> {
const root = userRoot(this.config.dataRoot, userId)
const dir = join(homeRoot(root), 'storages')
const file = join(dir, 'workspace.json')
try {
mkdirSync(dir, { recursive: true })
let existing: { global?: { workspaceIds?: unknown } } | undefined
try {
existing = JSON.parse(readFileSync(file, 'utf8')) as { global?: { workspaceIds?: unknown } }
} catch {
existing = undefined
}
const ids = existing?.global?.workspaceIds
if (Array.isArray(ids) && ids.length > 0) return // 已有工作区 → 尊重用户现状
const ws = workspaceRoot(root)
const id = randomUUID()
const now = new Date().toISOString()
const seed = {
unit: { name: 'workspace', version: 2 },
global: { initialized: true, workspaceIds: [id], archivedSessionIds: [] },
tables: {
workspaces: {
[id]: { path: ws, title: '我的工作区', sessionIds: [], createdAt: now, updatedAt: now },
},
},
}
writeFileSync(file, JSON.stringify(seed, null, 2) + '\\n')
const uid = await this.resolveUid(userId)
chownSync(file, uid, uid) // 实例以该 uid 运行,需可读写
chownSync(dir, uid, uid)
process.stderr.write(`[seed-workspace] ${userId} → ${ws}\\n`)
} catch (err) {
process.stderr.write(
`[seed-workspace] failed for ${userId}: ${err instanceof Error ? err.message : String(err)}\\n`,
)
}
}
/** Materialize the rendered patch so the dsh CLI can `--patch <file>` it.""",
)
io.open(p, 'w', encoding='utf-8', newline='').write(s)
print('patched: fs import + spawnInstance 调用 + seedDefaultWorkspace 方法')