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:
admin committed 2026-10-10 23:13:22 +08:00
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 方法')