chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
This commit is contained in:
1 parent
30b46dbd0c
commit
c1b5e4d966
735 files changed
+153192
-2415
No files matched your search
@@ -0,0 +1,88 @@
|
||||
#!/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 方法')
|
||||
Reference in new issue
Block a user