repo-audit-tool 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +67 -0
- package/AUDIT.md +802 -0
- package/BEST-PRACTICES.md +268 -0
- package/CLAUDE.md +1 -0
- package/CONTRIBUTING.md +42 -0
- package/DEVELOPMENT.md +112 -0
- package/HANDOFF.md +124 -0
- package/LICENSE +21 -0
- package/PUBLISHING.md +66 -0
- package/README.en.md +71 -0
- package/README.md +71 -0
- package/REPO-AUDIT.md +107 -0
- package/REPO-CLASSIFICATION.md +137 -0
- package/SECURITY.md +19 -0
- package/docs/repo-audit/AGENT-GUIDE.md +474 -0
- package/docs/repo-audit/HUMAN-GUIDE.md +749 -0
- package/package.json +36 -0
- package/repo-audit.mjs +1507 -0
- package/rules/categories/archive.yaml +48 -0
- package/rules/categories/content.yaml +34 -0
- package/rules/categories/dsh-plugin.yaml +79 -0
- package/rules/categories/go-service.yaml +67 -0
- package/rules/categories/product-oss.yaml +75 -0
- package/rules/categories/python-app.yaml +60 -0
- package/rules/categories/sandbox.yaml +33 -0
- package/rules/domains/docs.yaml +105 -0
- package/rules/domains/git.yaml +52 -0
- package/rules/domains/quality.yaml +69 -0
- package/rules/domains/security.yaml +79 -0
- package/shim/repo-audit.cmd +7 -0
- package/shim/repo-audit.ps1 +4 -0
- package/shim/repo-audit.sh +5 -0
- package/templates/AGENT-GUIDE.md +331 -0
- package/templates/README.md +192 -0
- package/templates/UPDATE-MODEL.md +141 -0
- package/templates/UPDATE-PLAN.md +79 -0
- package/templates/categories/content/AGENTS-append.md +6 -0
- package/templates/categories/content/CATEGORY.md +26 -0
- package/templates/categories/content/README.en.md +12 -0
- package/templates/categories/content/README.md +14 -0
- package/templates/categories/content/gitignore-append.md +6 -0
- package/templates/categories/dsh-plugin/AGENTS-append.md +21 -0
- package/templates/categories/dsh-plugin/CATEGORY.md +9 -0
- package/templates/categories/dsh-plugin/CONTRIBUTING-append.md +22 -0
- package/templates/categories/dsh-plugin/DEVELOPMENT-append.md +71 -0
- package/templates/categories/dsh-plugin/PUBLISHING-append.md +53 -0
- package/templates/categories/dsh-plugin/README-append.md +28 -0
- package/templates/categories/dsh-plugin/README.en.md +44 -0
- package/templates/categories/dsh-plugin/gitignore-append.md +15 -0
- package/templates/categories/go-service/.githooks/pre-commit +13 -0
- package/templates/categories/go-service/.github/workflows/ci.yml +31 -0
- package/templates/categories/go-service/.github/workflows/release.yml +58 -0
- package/templates/categories/go-service/.goreleaser.yaml +86 -0
- package/templates/categories/go-service/AGENTS-append.md +7 -0
- package/templates/categories/go-service/CATEGORY.md +33 -0
- package/templates/categories/go-service/CONTRIBUTING-append.md +13 -0
- package/templates/categories/go-service/DEVELOPMENT-append.md +21 -0
- package/templates/categories/go-service/Makefile +21 -0
- package/templates/categories/go-service/PUBLISHING-append.md +48 -0
- package/templates/categories/go-service/PUBLISHING.md +59 -0
- package/templates/categories/go-service/README-append.md +26 -0
- package/templates/categories/go-service/README.en.md +43 -0
- package/templates/categories/go-service/gitignore-append.md +13 -0
- package/templates/categories/product-oss/.github/CODEOWNERS +6 -0
- package/templates/categories/product-oss/.github/ISSUE_TEMPLATE/bug_report.yml +52 -0
- package/templates/categories/product-oss/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/templates/categories/product-oss/.github/dependabot.yml +28 -0
- package/templates/categories/product-oss/.github/workflows/dependency-review.yml +18 -0
- package/templates/categories/product-oss/.github/workflows/release-please.yml +39 -0
- package/templates/categories/product-oss/.release-please-manifest.json +3 -0
- package/templates/categories/product-oss/CATEGORY.md +27 -0
- package/templates/categories/product-oss/CHANGELOG.md +14 -0
- package/templates/categories/product-oss/PULL_REQUEST_TEMPLATE.md +15 -0
- package/templates/categories/product-oss/SUPPORT.md +71 -0
- package/templates/categories/product-oss/release-please-config.json +10 -0
- package/templates/categories/python-app/.githooks/pre-commit +13 -0
- package/templates/categories/python-app/.github/workflows/ci.yml +33 -0
- package/templates/categories/python-app/.github/workflows/publish.yml +112 -0
- package/templates/categories/python-app/AGENTS-append.md +18 -0
- package/templates/categories/python-app/CATEGORY.md +34 -0
- package/templates/categories/python-app/CONTRIBUTING-append.md +13 -0
- package/templates/categories/python-app/DEVELOPMENT-append.md +21 -0
- package/templates/categories/python-app/PUBLISHING-append.md +52 -0
- package/templates/categories/python-app/PUBLISHING.md +61 -0
- package/templates/categories/python-app/README-append.md +27 -0
- package/templates/categories/python-app/README.en.md +44 -0
- package/templates/categories/python-app/gitignore-append.md +19 -0
- package/templates/categories/python-app/pyproject.toml +41 -0
- package/templates/categories/python-app/scripts/verify.py +39 -0
- package/templates/categories/sandbox/AGENTS-append.md +7 -0
- package/templates/categories/sandbox/CATEGORY.md +31 -0
- package/templates/categories/sandbox/README.en.md +24 -0
- package/templates/categories/sandbox/README.md +23 -0
- package/templates/check-single-source.mjs +107 -0
- package/templates/common/AGENTS-core.md +28 -0
- package/templates/common/CONTRIBUTING-core.md +21 -0
- package/templates/common/DEVELOPMENT-core.md +45 -0
- package/templates/common/PUBLISHING-core.md +31 -0
- package/templates/common/README-core.md +60 -0
- package/templates/common/SECURITY-core.md +19 -0
- package/templates/common/copilot-instructions.md +5 -0
- package/templates/common/gitignore-core.md +11 -0
- package/templates/repo-root/.githooks/pre-commit +20 -0
- package/templates/repo-root/.github/workflows/ci.yml +45 -0
- package/templates/repo-root/.github/workflows/publish.yml +77 -0
- package/templates/repo-root/CLAUDE.md +3 -0
- package/templates/repo-root/LICENSE +21 -0
- package/templates/repo-root/package.json +71 -0
- package/templates/repo-root/scripts/build.mjs +24 -0
- package/templates/repo-root/scripts/check-deploy.mjs +176 -0
- package/templates/repo-root/scripts/verify.mjs +52 -0
- package/templates/repo-root/src/config.ts +25 -0
- package/templates/repo-root/src/index.ts +40 -0
- package/templates/repo-root/tsconfig.build.json +22 -0
- package/templates/repo-root/tsconfig.json +23 -0
- package/templates/scaffold.mjs +793 -0
- package/templates/skill/SKILL.md +47 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- id: SEC-001
|
|
3
|
+
title: "无硬编码密钥"
|
|
4
|
+
severity: critical
|
|
5
|
+
domain: security
|
|
6
|
+
applies_to: ["*"]
|
|
7
|
+
check: grep
|
|
8
|
+
params:
|
|
9
|
+
patterns:
|
|
10
|
+
- "(?i)(api[_-]?key|secret|password|token)\\s*[:=]\\s*['\"][^'\"]{8,}"
|
|
11
|
+
exclude:
|
|
12
|
+
- ".git/"
|
|
13
|
+
- "node_modules/"
|
|
14
|
+
- ".scaffold/"
|
|
15
|
+
- "audit-report/"
|
|
16
|
+
- "templates/"
|
|
17
|
+
max_match: 0
|
|
18
|
+
description: "源代码中不应包含硬编码密钥或凭证(AGENTS-core 机密红线第 3 条)"
|
|
19
|
+
fix_hint: "使用环境变量或密钥管理服务"
|
|
20
|
+
|
|
21
|
+
- id: SEC-002
|
|
22
|
+
title: "Workflow 使用 SHA 固定"
|
|
23
|
+
severity: major
|
|
24
|
+
domain: security
|
|
25
|
+
applies_to: ["dsh-plugin", "python-app", "go-service", "javascript", "npm-package"]
|
|
26
|
+
check: grep
|
|
27
|
+
params:
|
|
28
|
+
patterns:
|
|
29
|
+
- "@[a-f0-9]{40}"
|
|
30
|
+
exclude:
|
|
31
|
+
- ".git/"
|
|
32
|
+
- "node_modules/"
|
|
33
|
+
- ".scaffold/"
|
|
34
|
+
- "audit-report/"
|
|
35
|
+
- "templates/"
|
|
36
|
+
max_match: 1
|
|
37
|
+
description: "GitHub Actions workflow 应使用 SHA 固定而非 tag(BEST-PRACTICES §6.1)"
|
|
38
|
+
fix_hint: "将 actions/checkout@v4 改为 actions/checkout@<SHA>"
|
|
39
|
+
note: "无 workflow 文件的仓库豁免"
|
|
40
|
+
|
|
41
|
+
- id: SEC-003
|
|
42
|
+
title: "无本机绝对路径"
|
|
43
|
+
severity: minor
|
|
44
|
+
domain: security
|
|
45
|
+
applies_to: ["*"]
|
|
46
|
+
check: grep
|
|
47
|
+
params:
|
|
48
|
+
patterns:
|
|
49
|
+
- "/home/[a-z]"
|
|
50
|
+
- "/Users/[a-z]"
|
|
51
|
+
- "/mnt/[a-z]"
|
|
52
|
+
exclude:
|
|
53
|
+
- ".git/"
|
|
54
|
+
- "node_modules/"
|
|
55
|
+
- ".scaffold/"
|
|
56
|
+
- "audit-report/"
|
|
57
|
+
- "templates/"
|
|
58
|
+
- "CHANGELOG.md"
|
|
59
|
+
- "HANDOFF.md"
|
|
60
|
+
- "HANDOFF-ARCHIVE/"
|
|
61
|
+
- ".agents/"
|
|
62
|
+
max_match: 0
|
|
63
|
+
description: "源代码不应包含本机绝对路径(AGENTS-core 机密红线第 3 条);CHANGELOG/HANDOFF 等交接文档豁免"
|
|
64
|
+
note: "severity=minor:描述性路径文本(如 CHANGELOG 中的扫描描述)容忍;硬编码密钥仍由 SEC-001 覆盖"
|
|
65
|
+
|
|
66
|
+
- id: SEC-004
|
|
67
|
+
title: "publish workflow 含 id-token write"
|
|
68
|
+
severity: critical
|
|
69
|
+
domain: security
|
|
70
|
+
applies_to: ["dsh-plugin", "python-app"]
|
|
71
|
+
check: yaml_field
|
|
72
|
+
params:
|
|
73
|
+
path: ".github/workflows/publish.yml"
|
|
74
|
+
field: "permissions.id-token"
|
|
75
|
+
expected: "write"
|
|
76
|
+
skip_if_no_file: ".github/workflows/publish.yml"
|
|
77
|
+
description: "publish workflow 必须请求 id-token: write 权限(OIDC Trusted Publishing)"
|
|
78
|
+
template_ref: "templates/repo-root/.github/workflows/publish.yml"
|
|
79
|
+
fix_hint: "在 workflow 顶部添加 permissions: id-token: write"
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
# scaffold init/update 操作手册(agent 用)
|
|
2
|
+
|
|
3
|
+
## §A 开始之前
|
|
4
|
+
|
|
5
|
+
### 1. 适用对象与前提
|
|
6
|
+
|
|
7
|
+
- 使用对象:AI coding agent(DSH agent、Claude Code、Copilot 等以编程方式调用 scaffold 的场景)。人也可以参考,但本手册假设调用方是 agent——所有输出都可 grep/parse,所有异常都有明确退出码。
|
|
8
|
+
- 前置条件:git 可用;node 可用(≥18);模板集路径可达。
|
|
9
|
+
- 反馈路径(绝对路径,写反馈前先确认可达):
|
|
10
|
+
`./feedback/`
|
|
11
|
+
- 参考文档:[UPDATE-MODEL.md](UPDATE-MODEL.md)(机制设计)· [UPDATE-PLAN.md](UPDATE-PLAN.md)(分阶段实施)
|
|
12
|
+
|
|
13
|
+
### 2. 速查
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
S="/path/to/templates/scaffold.mjs"
|
|
17
|
+
|
|
18
|
+
# 新建仓库(五分类 + overlay)
|
|
19
|
+
node $S --type <分类> --name <短名> --org <org> --desc "<一句话>" --target <目录>
|
|
20
|
+
|
|
21
|
+
# 更新已有仓库(自动探测元数据;可显式覆盖)
|
|
22
|
+
node $S --update <仓库路径> [--type <分类>] [--name/--org/--desc/--legal/--surface ...]
|
|
23
|
+
|
|
24
|
+
# 预览(不写任何文件)
|
|
25
|
+
node $S --update <仓库路径> --dry-run
|
|
26
|
+
|
|
27
|
+
# 回滚最近一次 update
|
|
28
|
+
node $S --rollback <仓库路径>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 3. 分类选择
|
|
32
|
+
|
|
33
|
+
| --type | 适用 | 产物 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `dsh-plugin`(默认) | dsh 宿主插件 | TS 骨架 + npm 发布链 + 部署纪律 |
|
|
36
|
+
| `python-app` | Python 应用/研究 | pyproject + PyPI TP 发布链 |
|
|
37
|
+
| `go-service` | Go 服务 | Makefile + GoReleaser 发布链 |
|
|
38
|
+
| `sandbox` | 本地实验/dogfood | 最小集(无 CI/发布) |
|
|
39
|
+
| `content` | 内容/写作 | 最小集(正文 + review 分离) |
|
|
40
|
+
| + `--overlay product-oss` | 上述任一 + 多人协作 | 额外叠加 release-please/PR/issue/CODEOWNERS/dependabot |
|
|
41
|
+
|
|
42
|
+
判断规则:写代码挂到 dsh 宿主 → dsh-plugin;pyproject 项目 → python-app;go.mod → go-service;一次性实验 → sandbox;文档即制品 → content;会多人协作 → 加 `--overlay product-oss`。
|
|
43
|
+
|
|
44
|
+
## §B 操作
|
|
45
|
+
|
|
46
|
+
### 4. init(新建仓库)操作流程
|
|
47
|
+
|
|
48
|
+
#### 步骤 1:契约预检(写代码之前)
|
|
49
|
+
|
|
50
|
+
1. `cordis_inspect_list` / `cordis_inspect_query` 查清用到的 Service/Event/Builtin/Slot 精确签名——**不猜 API**
|
|
51
|
+
2. 记录宿主包清单 → 决定 package.json peer/devDeps
|
|
52
|
+
3. 确认分类:host half only 还是 host+client 双 half(影响 dsh.client.inject 与 build-client.mjs)
|
|
53
|
+
|
|
54
|
+
#### 步骤 2:出库
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
node $S --type dsh-plugin --name myplugin --org NinjaSln-labs \
|
|
58
|
+
--desc "一句话描述" --surface "宿主能力面" --target /path/to/dsh-myplugin
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- `--name` 不带 dsh- 前缀(自动剥除并告警);包名/仓库名派生为 `dsh-<name>`
|
|
62
|
+
- 产物:全套治理文件(AGENTS/README×2/CONTRIBUTING/DEVELOPMENT/PUBLISHING/SECURITY/LICENSE/CLAUDE.md/.gitignore)+ 工程骨架(package.json/tsconfig/src/scripts/.github/.githooks)
|
|
63
|
+
- git init + hooksPath 自动完成
|
|
64
|
+
|
|
65
|
+
#### 步骤 3:按产物 AGENTS.md 与 TODO 清单执行
|
|
66
|
+
|
|
67
|
+
出库末尾打印分类专属 TODO(含精确命令)。关键必做项:
|
|
68
|
+
|
|
69
|
+
1. package.json 填 peer/devDeps(占位符不是合法包名,直接 install 会报 EINVALIDPACKAGENAME)——**dsh-plugin 专属**
|
|
70
|
+
2. `npm install --legacy-peer-deps` → `package-lock.json` **必须入库**——**dsh-plugin 专属**
|
|
71
|
+
3. `npm run build` → `dsh plugin --profile web install`(file: 接线)→ `npm run check:deploy`——**dsh-plugin 专属**
|
|
72
|
+
4. workflow 的 `<commit-SHA>`:从参照库(dsh-context-compass)同名文件抄当前锁定值
|
|
73
|
+
5. GitHub 建库:`gh repo create <org>/<repo> --public --source . --description "..." --push`
|
|
74
|
+
6. **所有分类通用:出库后必须 `git add -A && git commit`**(工作区脏会阻塞后续 update;pre-commit 钩子因工具链缺失 FAIL 时可用 `--no-verify` 应急)
|
|
75
|
+
|
|
76
|
+
#### init 后的验证清单(agent 自检,全绿才算完成)
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
cd <产物目录>
|
|
80
|
+
grep -rn '模板说明' . --include='*.md' | wc -l # 期望 0
|
|
81
|
+
# 依赖占位检查:dsh-plugin 查 package.json;python-app 查 pyproject.toml;go-service 查 go.mod
|
|
82
|
+
# 期望 0(依赖占位已填)
|
|
83
|
+
# 验证链按分类:dsh-plugin=node scripts/verify.mjs / python-app=python3 scripts/verify.py / go-service=make verify
|
|
84
|
+
# (期望"验证链全绿"或 SKIP——工具未装时 exit 2 不阻塞)
|
|
85
|
+
git add -A && git commit # init 产物必须 commit(否则 update 的 clean 检查拒绝)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 5. update(已有仓库)操作流程
|
|
89
|
+
|
|
90
|
+
#### 何时用 update
|
|
91
|
+
|
|
92
|
+
> **硬性要求:update 时始终显式传 `--type <分类>`**——不传时 lock.template 优先(二次 update 安全),
|
|
93
|
+
> 但首次 adopt(无 lock)会 fallback 为 dsh-plugin,可能对非 dsh 仓库产生错误分类的文件。
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
- 存量仓库要接入模板治理(首次 adopt)
|
|
98
|
+
- 已接入的仓库要吸收模板升级(lock 存在时全自动)
|
|
99
|
+
- 仓库缺失模板管辖文件(CI/hooks/AGENTS 等)需要补齐
|
|
100
|
+
|
|
101
|
+
#### 首次 update(adopt 模式)——仓库无 .scaffold/lock/ 时
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
# 先 dry-run 看会改什么(不写任何文件)
|
|
105
|
+
node $S --update /path/to/repo --type <分类> --dry-run
|
|
106
|
+
|
|
107
|
+
# 确认后正式执行
|
|
108
|
+
node $S --update /path/to/repo --type <分类>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**adopt 行为**:
|
|
112
|
+
|
|
113
|
+
- 建立状态层:`.scaffold/lock/`(base 快照 + manifest)+ `last-update.json`
|
|
114
|
+
- 仓库**缺失**的模板文件 → ADDED 直拷(写仓库)
|
|
115
|
+
- 仓库**已有**的文件 → 不覆盖!模板版写入 `.scaffold-merge/<相对路径>` 供比对采纳
|
|
116
|
+
- git 自动 commit(回滚点)+ `.gitignore` 增补过程目录
|
|
117
|
+
|
|
118
|
+
**agent 必做的 adopt 收尾**:
|
|
119
|
+
|
|
120
|
+
1. 逐个查看 `.scaffold-merge/` 的 diff(`diff <仓库文件> <merge文件>`),决定采纳策略
|
|
121
|
+
2. 采纳 = 用模板版覆盖仓库文件(或人工合并两边内容)
|
|
122
|
+
3. `git add -A && git commit`(收口 adopt,否则下次 update 会被 clean 检查拒绝)
|
|
123
|
+
4. 确认 `.scaffold/lock/` 已入库(回滚连带状态)
|
|
124
|
+
|
|
125
|
+
#### 后续 update(lock 存在时)——全自动
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
node $S --update /path/to/repo
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**状态机**(对每个模板管辖文件):
|
|
132
|
+
|
|
133
|
+
| 判定 | 处置 | agent 需要做 |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| 仓库缺失 | ADDED 直拷 | 无(自动 commit) |
|
|
136
|
+
| ours == lock.base | FAST-FORWARD 采纳模板新版 | 无(自动 commit)——用户未改过,安全 |
|
|
137
|
+
| 模板未变 | UNCHANGED 保持 | 无 |
|
|
138
|
+
| ours ≠ base ≠ new | 三方合并(git merge-file --zdiff3)| 见下方冲突处理 |
|
|
139
|
+
|
|
140
|
+
**冲突处理(QUARANTINED)**:三方合并无法自动解决时,冲突文件(含 zdiff3 markers)落盘到 `.scaffold/conflicts/<路径>.rej`,不阻塞其他文件。
|
|
141
|
+
|
|
142
|
+
agent 裁决步骤:
|
|
143
|
+
|
|
144
|
+
1. 读 `.rej` 文件(zdiff3 格式:current/base/template 三段)
|
|
145
|
+
2. 结合上下文决定保留/合并——**保留用户已填的占位值与自定义段,吸收模板新条款**
|
|
146
|
+
3. 把裁决结果写回仓库文件(替换含 markers 的原文件)
|
|
147
|
+
4. `git add -A && git commit`
|
|
148
|
+
5. 删除 `.scaffold/conflicts/` 对应文件
|
|
149
|
+
6. 下次 update 该文件将走 UNCHANGED 或正常合并(lock 已吸收裁决)
|
|
150
|
+
|
|
151
|
+
#### update 后收口(agent 必做)
|
|
152
|
+
|
|
153
|
+
- 全部 UNCHANGED/FAST-FORWARD/MERGED-CLEAN → 工具已自动 commit,无需操作
|
|
154
|
+
- 有 MERGE-REVIEW → 查看 .scaffold-merge/ 并采纳(或忽略),然后 `git add -A && git commit`
|
|
155
|
+
- 有 QUARANTINED → 按"冲突裁决 6 步"处理,然后 commit + 删 .scaffold/conflicts/
|
|
156
|
+
- **update 后不收口会阻塞下一次 update**(clean 检查拒绝)
|
|
157
|
+
|
|
158
|
+
#### update 输出解读
|
|
159
|
+
|
|
160
|
+
每个文件的状态标记:
|
|
161
|
+
|
|
162
|
+
| 标记 | 含义 | agent 动作 |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| `ADDED` | 新文件已写入 | 无 |
|
|
165
|
+
| `FAST-FORWARD` | 仓库未改→采纳模板新版 | 无 |
|
|
166
|
+
| `UNCHANGED` | 与模板一致或模板未变 | 无 |
|
|
167
|
+
| `MERGED-CLEAN` | 三方合并干净 | 无 |
|
|
168
|
+
| `MERGE-REVIEW` | adopt 首见差异→.scaffold-merge/ | **人工/agent 比对采纳** |
|
|
169
|
+
| `QUARANTINED` | 三方合并冲突→.scaffold/conflicts/ | **agent 裁决(见上)** |
|
|
170
|
+
| `SKIP` | 用户在 --skip 清单中 | 无 |
|
|
171
|
+
|
|
172
|
+
#### update 后的验证清单(agent 自检)
|
|
173
|
+
|
|
174
|
+
```sh
|
|
175
|
+
cd <仓库>
|
|
176
|
+
# 按分类选验证链:dsh-plugin=node scripts/verify.mjs / python-app=python3 scripts/verify.py / go-service=make verify
|
|
177
|
+
git status --porcelain | wc -l # 期望 0(全部已 commit)
|
|
178
|
+
grep -rn '<<<<<<<\|>>>>>>>' <管辖文件> 2>/dev/null | wc -l # 期望 0(无残留 marker)
|
|
179
|
+
test -f .scaffold/lock/manifest.json && echo "lock ✓"
|
|
180
|
+
test -f .scaffold/last-update.json && echo "更新记录 ✓"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### 各分类自动探测源差异(update 模式元数据探测)
|
|
184
|
+
|
|
185
|
+
| 分类 | name 来源 | desc 来源 | org 来源 | 限制 |
|
|
186
|
+
|---|---|---|---|---|
|
|
187
|
+
| dsh-plugin | package.json(剥 dsh-)→ 目录名 | package.json description | git remote origin | 探测最完整 |
|
|
188
|
+
| python-app | pyproject.toml name → 目录名 | pyproject description | git remote origin | 需显式传 desc(探测可能为空) |
|
|
189
|
+
| go-service | 目录名 | **无自动探测**(必须显式传 --desc) | git remote origin | 需显式传 --desc/--surface |
|
|
190
|
+
| sandbox/content | 目录名 | **无自动探测** | 默认 NinjaSln-labs | 最小集,建议全显式传参 |
|
|
191
|
+
|
|
192
|
+
#### update 后收口(agent 必做)
|
|
193
|
+
|
|
194
|
+
- 全部 UNCHANGED/FAST-FORWARD/MERGED-CLEAN → 工具已自动 commit,无需操作
|
|
195
|
+
- 有 MERGE-REVIEW → 查看 .scaffold-merge/ 并采纳(或忽略),然后 `git add -A && git commit`
|
|
196
|
+
- 有 QUARANTINED → 按"冲突裁决 6 步"处理,然后 commit + 删 .scaffold/conflicts/
|
|
197
|
+
- **update 后不收口会阻塞下一次 update**(clean 检查拒绝)
|
|
198
|
+
|
|
199
|
+
## §C 安全网
|
|
200
|
+
|
|
201
|
+
### 6. 使用前备份(agent 必做)
|
|
202
|
+
|
|
203
|
+
> 实测覆盖不可能穷尽所有仓库状态;使用反馈尚不足以确认所有边界安全。**update 前的备份是 agent 的责任,不是工具的责任。**
|
|
204
|
+
|
|
205
|
+
#### update 前必须做的备份(按仓库状态选择)
|
|
206
|
+
|
|
207
|
+
| 仓库状态 | 备份命令 | 恢复方式 |
|
|
208
|
+
|---|---|---|
|
|
209
|
+
| **git 仓且工作区 clean**(标准场景) | 无需额外备份——前置 clean + 自动 commit 已构成回滚点 | `git revert <sha>` 或 `git reset --hard <preUpdateHEAD>` |
|
|
210
|
+
| **git 仓但有未提交改动** | `git stash push -m "scaffold update 前备份"`(update 拒绝 dirty,先 stash 后再跑) | `git stash pop` |
|
|
211
|
+
| **非 git 目录** | `cp -r <目录> <目录>.bak.<日期>` | `rm -rf <目录> && mv <目录>.bak.<日期> <目录>` |
|
|
212
|
+
| **不确定 / 首次接触该仓** | `git tag scaffold-pre-update-$(date +%s)` + `cp -r <目录> <目录>.bak.<日期>` | tag: `git reset --hard <tag>`;目录:同上 |
|
|
213
|
+
|
|
214
|
+
#### agent 备份自检(update 前逐条过)
|
|
215
|
+
|
|
216
|
+
1. `git status --porcelain` 是否为空?→ 空则安全(git 可回滚)
|
|
217
|
+
2. 仓库是否有 `.scaffold/lock/`?→ 有则走自动模式(比 adopt 安全)
|
|
218
|
+
3. 仓库是否有大量非模板管辖的自定义文件?→ 有则**额外** `cp -r` 目录备份
|
|
219
|
+
4. 是否为首次接触该仓库?→ 是则**额外** `cp -r` 目录备份(不信任探测结果)
|
|
220
|
+
|
|
221
|
+
#### 备份完成后才允许调用 update
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
# 标准场景(git clean):跳过额外备份
|
|
225
|
+
node $S --update <仓库路径>
|
|
226
|
+
|
|
227
|
+
# 非标准场景(有自定义内容 / 首次接触):先备份
|
|
228
|
+
cp -r <仓库目录> <仓库目录>.bak.$(date +%Y%m%d%H%M%S)
|
|
229
|
+
# 确认备份存在后才执行 update
|
|
230
|
+
ls <仓库目录>.bak.* >/dev/null && node $S --update <仓库路径>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 7. 回滚
|
|
234
|
+
|
|
235
|
+
```sh
|
|
236
|
+
node $S --rollback /path/to/repo
|
|
237
|
+
# 等价于:git reset --hard <preUpdateHEAD>(回到 update 前状态)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
前置:工作区必须 clean。回滚后审计历史保留(revert 生成新 commit;update 的 last-update.json 记录 preUpdateHEAD)。
|
|
241
|
+
紧急情况(revert 失败):`git reset --hard <preUpdateHEAD>`(last-update.json 有记录)。
|
|
242
|
+
|
|
243
|
+
#### 回滚能力边界(agent 必知)
|
|
244
|
+
|
|
245
|
+
| 能力 | 机制 | 限制 |
|
|
246
|
+
|---|---|---|
|
|
247
|
+
| 撤销最近一次 update 的全部改动 | `--rollback`(git reset --hard preUpdateHEAD) | **只保留最近一次**(last-update.json 每次覆盖) |
|
|
248
|
+
| 回到 update 前的精确状态 | `git reset --hard <preUpdateHEAD>` | 同上;且会连 lock 一起回退 |
|
|
249
|
+
| 撤销最近一次 update 的全部改动 | `--rollback`(git reset --hard preUpdateHEAD) | **只保留最近一次**(last-update.json 每次覆盖) |
|
|
250
|
+
| 回到 update 前的精确状态 | `git reset --hard <preUpdateHEAD>` | 同上;且会连 lock 一起回退 |
|
|
251
|
+
| 恢复单个文件 | `git log --oneline -- <file>` 找到 commit → `git checkout <sha> -- <file>` | 手动操作(**不要用 last-update.json 的 commitSha**——amend 后 SHA 可能变化) |
|
|
252
|
+
| 两次前的 update | 不支持(lock 只有一层) | 如需多次回滚:update 前手动打 tag |
|
|
253
|
+
| 恢复"update 前工作区未提交改动" | 不存在此场景 | update 前置 clean 检查已保证 |
|
|
254
|
+
|
|
255
|
+
**不是备份系统**:`--rollback` = git reset --hard preUpdateHEAD(回到 update 前状态),不是文件快照恢复。update 的安全模型 = 前置 clean + 自动 commit(回滚点)+ revert(撤销)。多次 update 需多次回滚时,建议 update 前手动打 tag(`git tag pre-update-<N>`)。
|
|
256
|
+
|
|
257
|
+
## §D 排障
|
|
258
|
+
|
|
259
|
+
### 8. 异常与退出码
|
|
260
|
+
|
|
261
|
+
| 退出码 | 场景 | agent 处置 |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| 0 | 成功 | 按 TODO/report 继续 |
|
|
264
|
+
| 1 | 拒绝执行(非 git 仓/脏工作区/lock 损坏/未知旗标/参数缺失) | 读 stderr 修复调用条件后重试 |
|
|
265
|
+
| 2 | verify.py 工具未安装(SKIP 语义) | 不阻塞 update;建议 `pip install -e ".[dev]"` 后重跑 |
|
|
266
|
+
| 129 | git merge-file usage 错误 | 更新模式下自动降级 MERGE-REVIEW;如复现报 issue |
|
|
267
|
+
|
|
268
|
+
### 9. 注意事项(硬性)
|
|
269
|
+
|
|
270
|
+
1. **不要手改 `.scaffold/lock/`**:manifest/base 是三方合并的 base,手改会欺骗算法
|
|
271
|
+
2. **不要手改 `last-update.json`**:rollback 依赖它
|
|
272
|
+
3. **不要把 `.scaffold/lock/` 加入 .gitignore**:lock 必须入库(Copier/buf 惯例)
|
|
273
|
+
4. **update 前必须 commit/stash**:工作区不干净时拒绝执行(回滚点唯一性)
|
|
274
|
+
5. **每次 update 后立即 commit**:未 commit 状态会阻塞下一次 update
|
|
275
|
+
6. **非模板管辖文件 update 永远不碰**:src 实现、data、用户手写文件不在管辖集内
|
|
276
|
+
7. **`--skip <path>` 让文件退出自动更新域**:对"这个文件我手管"的文件使用(可多次)
|
|
277
|
+
8. **update 前做备份(见 §C"使用前备份")**:实测覆盖不可能穷尽,agent 自己兜底
|
|
278
|
+
9. **lock 损坏(非法 JSON)→ 自动降级为 adopt 模式**:仍安全,但失去三方合并能力;修复=删除 .scaffold/lock/ 后重跑 update 重建快照
|
|
279
|
+
10. **类型不可中途切换**:update 时 --type 与 lock.template 不一致会被拒绝;切换分类需删 .scaffold/lock/ 重新 adopt
|
|
280
|
+
|
|
281
|
+
## §E 参考
|
|
282
|
+
|
|
283
|
+
### 10. 完整参数参考
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
--type <分类> 分类(默认 dsh-plugin)
|
|
287
|
+
--name <短名> 名称(不带 dsh- 前缀,自动剥除+告警)
|
|
288
|
+
--org <org> GitHub 组织(默认 NinjaSln-labs)
|
|
289
|
+
--desc "<一句话>" 一句话描述(与 GitHub about 一致)
|
|
290
|
+
--surface "<能力面>" 宿主能力面(默认=desc)
|
|
291
|
+
--legal "<版权主体>" LICENSE 版权行(默认=org)
|
|
292
|
+
--target <目录> 目标目录(generate 模式;默认 ../dsh-<name>)
|
|
293
|
+
--force 空目录复用(含 .git 时仍拒绝)
|
|
294
|
+
--update <仓库路径> 更新模式(自动探测元数据)
|
|
295
|
+
--overlay <名> 叠加 overlay(product-oss)
|
|
296
|
+
--dry-run 只对比不写文件(update 模式)
|
|
297
|
+
--skip <path> 退出自动更新域(update 模式,可多次)
|
|
298
|
+
--rollback <仓库路径> 回滚最近一次 update
|
|
299
|
+
--help 帮助
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 11. 反馈通道
|
|
303
|
+
|
|
304
|
+
模板集仍在实测阶段,以下情况请记录并反馈给模板维护者:
|
|
305
|
+
|
|
306
|
+
| 类型 | 示例 | 反馈内容 |
|
|
307
|
+
|---|---|---|
|
|
308
|
+
| **误覆盖** | update 后仓库文件内容丢失/被改 | 仓库路径 + .scaffold/lock/manifest.json + 丢失前后的 diff |
|
|
309
|
+
| **误判分类** | 某仓库用 A 分类出库但行为不符 | 仓库名 + 使用的 --type + 期望 vs 实际 |
|
|
310
|
+
| **merge-file 失败** | exit 129/负数/空输出 | .scaffold/conflicts/ 的 .rej 文件 + stderr |
|
|
311
|
+
| **探测错误** | name/desc/org 自动探测结果不对 | 仓库元数据文件(package.json 等)+ 探测输出 |
|
|
312
|
+
| **模板内容错误** | 产物中的规范/命令与实际不符 | 具体文件 + 正确做法 |
|
|
313
|
+
|
|
314
|
+
#### 反馈存放路径(agent 必读)
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
./feedback/
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
#### agent 写反馈的执行步骤
|
|
321
|
+
|
|
322
|
+
1. **确认路径可达**:`test -d "./feedback/"` → 不存在则 `mkdir -p`
|
|
323
|
+
2. **确认可写**:`test -w` 同路径 → 不可写则**用 ask_user 向用户确认正确的反馈存放路径**,不要猜
|
|
324
|
+
3. 路径确认后写入:`<feedback路径>/<YYYY-MM-DD>-<主题>.md`
|
|
325
|
+
|
|
326
|
+
#### 反馈文件内容要求
|
|
327
|
+
|
|
328
|
+
- 仓库绝对路径
|
|
329
|
+
- 使用的完整命令(含全部旗标)
|
|
330
|
+
- 期望 vs 实际(附相关文件 diff 或报错原文)
|
|
331
|
+
- 如涉及 update:附 .scaffold/lock/manifest.json 快照副本
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# 个人仓库模板集(templates/)
|
|
2
|
+
|
|
3
|
+
> 依据上级目录 `../BEST-PRACTICES.md` 的调研结论整理,dsh 插件基类(repo-root/)
|
|
4
|
+
> 以已跑通发布的 `dsh-context-compass` / `dsh-subagent-router` 单库实底文件为蓝本,不是凭空设计。
|
|
5
|
+
> 适用两条路线:**A. 从零新建库**(主路线)与 **B. 从 dsh-plugins monorepo 迁移**(增量路线,另见
|
|
6
|
+
> `../../DSH-PLUGIN-STANDALONE-MIGRATION.md`)。
|
|
7
|
+
> **分类体系**:全仓 23 个 git 仓库按模板差异分 7 类(见 `../REPO-CLASSIFICATION.md`),
|
|
8
|
+
> `scaffold.mjs --type <分类>` 路由;`categories/` 为各分类 delta 与说明。
|
|
9
|
+
|
|
10
|
+
## 分类与脚手架路由
|
|
11
|
+
|
|
12
|
+
| --type | 分类 | 覆盖仓库(实证数) | 产物 |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| `dsh-plugin`(默认) | A · dsh 插件单库 | dsh-* 6 库 | repo-root 基类全量 |
|
|
15
|
+
| (overlay) | B · 产品/多人 OSS | qingfu-envoy / neonforge / fuyao-nomad / Voyage | 语言基类 + `categories/product-oss/` 叠加(`--overlay product-oss`):release-please v5 版本晋升自动化 / YAML issue forms / CODEOWNERS / dependabot / dependency-review / SUPPORT.md 升级检查清单 |
|
|
16
|
+
| `python-app` | C · Python 应用/研究 | chumen / shisui / shuijing-v2 / vertical-small-model | 基类换 pyproject/verify.py/ruff+pytest CI |
|
|
17
|
+
| `go-service` | D · Go 服务 | jinteng | 基类换 Makefile 四件套/go CI |
|
|
18
|
+
| `sandbox` | E · 本地实验/dogfood | fuyao-* 11 库 + weather-outfit-assistant | 最小集(README+AGENTS,无 CI/发布) |
|
|
19
|
+
| `content` | F · 内容/写作 | rsi-unit-of-evolution / part-time-job | 最小集(正文+review 分离) |
|
|
20
|
+
| (不套模板) | G · 存档只读 | dsh-plugins(封版) | 遵守仓内封版纪律 |
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
node scaffold.mjs --type python-app --name chumen2 --desc "..." # 例
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 单源原则(AGENTS / CONTRIBUTING / .gitignore / README / DEVELOPMENT / PUBLISHING / SECURITY)
|
|
27
|
+
|
|
28
|
+
- 共性内容**只存在于 `common/*-core.md` 一份**:
|
|
29
|
+
- `AGENTS-core.md`——概览/提交规范/**「AI 协作守则」7 条**(不猜契约 / 完成的定义 = 验证链全绿 /
|
|
30
|
+
机密红线 / 不静默绕过门禁 / 改动最小化 / 文档同步 / 冲突处理)/ 安全考虑
|
|
31
|
+
- `CONTRIBUTING-core.md` · `gitignore-core.md` · `README-core.md`(标题/简介/文档/贡献/License)
|
|
32
|
+
- `DEVELOPMENT-core.md`(核心循环/Backlog/Sprint 契约预检/DoD 三段/回顾/速查表机制)
|
|
33
|
+
- `PUBLISHING-core.md`(发布状态/版本历史/发布后验证)· `SECURITY-core.md`(通用,无分类差异)
|
|
34
|
+
- 分类差异只写 `categories/<type>/*-append.md`(npm/PyPI/GoReleaser 的安装段与发布通道、
|
|
35
|
+
dsh 部署纪律全文等);scaffold 拼装生成,产物内**不要手改**拼装段
|
|
36
|
+
- **双语 README 标配**:各分类均提供 `README.en.md` 模板;语言切换行在 README-core(单源),
|
|
37
|
+
英文镜像回链 `README.md` 并声明中文权威;英文镜像与中文同步更新(DoD 文档项)
|
|
38
|
+
- 改规则 → 改 common/append 源 → 重新 scaffold;**漂移由 `check-single-source.mjs` 把守**
|
|
39
|
+
(core 指纹扫描 / append 命名 / 基类残留,CI/审计可挂,发现多源 exit 1)
|
|
40
|
+
|
|
41
|
+
## 更新模式(--update,v2.1 设计定稿)
|
|
42
|
+
|
|
43
|
+
已初始化仓库可通过 `scaffold --update <仓库路径>` 吸收模板更新:生成-对比(Copier 同款语义)→
|
|
44
|
+
状态机(快进/三方合并 git merge-file --diff3)→ 冲突分级裁决(机械自动 / agent 裁决 + 确定性验证
|
|
45
|
+
门禁 / QUARANTINED `.rej` 兜底)→ 自动 commit(回滚点)→ 报告与回滚(`--rollback`)。
|
|
46
|
+
状态层 `.scaffold/lock/`(base 快照 + manifest)入库。**完整设计:[UPDATE-MODEL.md](UPDATE-MODEL.md)(机制 v2.1)· [UPDATE-PLAN.md](UPDATE-PLAN.md)(分阶段实施方案)——已实施,agent 操作手册:[AGENT-GUIDE.md](AGENT-GUIDE.md)。**
|
|
47
|
+
|
|
48
|
+
## Agent 参与优化
|
|
49
|
+
|
|
50
|
+
所有工程分类的 AGENTS.md 内置「AI 协作守则」;AI 入口三桥接——`CLAUDE.md`(`@AGENTS.md` 导入)、
|
|
51
|
+
`.github/copilot-instructions.md`(工程分类自动配,sandbox/content 最小集不带)、AGENTS.md 本体
|
|
52
|
+
(DSH 实证有效)。pre-commit 验证链前门即 agent 防呆:FAIL 修根因,`--no-verify` 必须留痕。
|
|
53
|
+
|
|
54
|
+
## 占位符约定
|
|
55
|
+
|
|
56
|
+
| 占位符 | 含义 | 示例 |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `<name>` | 插件短名(不带 dsh- 前缀) | `context-compass` |
|
|
59
|
+
| `<repo>` | 仓库名,scaffold 按分类派生:dsh-plugin = `dsh-<name>`,其余 = `<name>` | `dsh-context-compass` / `chumen` |
|
|
60
|
+
| `dsh-<name>` | npm 包名(A 类专属派生) | `dsh-context-compass` |
|
|
61
|
+
| `<org>` | GitHub 组织 | `NinjaSln-labs` |
|
|
62
|
+
| `<一句话描述>` | repo description / README 首句 / package.json description | `DSH 上下文占用罗盘` |
|
|
63
|
+
| `<year>` / `<org 法律名>` | LICENSE 版权行 | `2026 ninjasln` |
|
|
64
|
+
| `<宿主能力面>` | 插件挂在 dsh 的哪一层(工具/命令/设置页/Slot UI…) | `多会话上下文健康面板` |
|
|
65
|
+
| `<用到的宿主包>` 等 | package.json peer/devDeps 占位 | 按 `cordis_inspect_query` 契约预检结果填 |
|
|
66
|
+
|
|
67
|
+
模板内的 **HTML 注释 `<!-- 模板说明:… -->` 与引用块说明在使用时删除**;正文是可保留的成文。
|
|
68
|
+
|
|
69
|
+
## 文件 → 单库目标路径映射
|
|
70
|
+
|
|
71
|
+
> **七份文档(README/README.en/CONTRIBUTING/DEVELOPMENT/PUBLISHING/SECURITY/AGENTS)+ .gitignore
|
|
72
|
+
> 已迁单源拼装**:源在 `common/*-core.md` + `categories/<type>/*-append.md`,由 scaffold 拼装生成
|
|
73
|
+
> (见上方「单源原则」)——**repo-root 已无这些文件**,勿在此表找复制路径。
|
|
74
|
+
|
|
75
|
+
### 文档与仓库治理(拼装生成 / 分类提供)
|
|
76
|
+
|
|
77
|
+
| 模板 | 产物 | 作用 | 拼装后必改 |
|
|
78
|
+
|---|---|---|---|
|
|
79
|
+
| `common/README-core.md` + `<type>/README-append.md` | 根 `README.md` | 通用骨架(Standard Readme 三档 + 状态/非目标节)+ 分类徽章/安装/使用/配置 | 标题/描述/安装命令/配置项 |
|
|
80
|
+
| `categories/<type>/README.en.md` | 根 `README.en.md` | 英文镜像(双语标配,各分类提供,回链中文);结构为 Standard Readme 核心节(Features/Install/Usage/Configuration/Docs/Contributing/License)——状态/非目标两节仅中文版提供(中文权威的扩展节) | 同步中文版对应节 |
|
|
81
|
+
| `common/CONTRIBUTING-core.md` + append | 根 `CONTRIBUTING.md` | 分支/提交规范/机密红线 + 分类开发环境命令 | 验证链命令按本库改 |
|
|
82
|
+
| `common/DEVELOPMENT-core.md` + append | 根 `DEVELOPMENT.md` | 通用开发→验证→构建→发布流程 + 分类纪律/DoD/速查表 | 验证链/插件名 |
|
|
83
|
+
| `common/PUBLISHING-core.md` + append | 根 `PUBLISHING.md` | 发布状态 + 版本历史 + 分类发布通道(npm OIDC/PyPI TP/GoReleaser) | 发布状态表填实际值 |
|
|
84
|
+
| `common/SECURITY-core.md` | 根 `SECURITY.md` | 通用安全策略(无分类差异) | 支持面描述 |
|
|
85
|
+
| `common/AGENTS-core.md` + append | 根 `AGENTS.md` | AI 协作守则 7 条 + 分类纪律(agent/humen 双入口) | 包名 |
|
|
86
|
+
| `common/gitignore-core.md` + append | 根 `.gitignore` | 机密/编辑器通用段 + 语言忽略段 | 视库增删 |
|
|
87
|
+
| `common/copilot-instructions.md` | `.github/copilot-instructions.md` | Copilot 桥接(指向 AGENTS.md) | 无 |
|
|
88
|
+
| `categories/dsh-plugin/CLAUDE.md`(基类 `repo-root/CLAUDE.md`) | 根 `CLAUDE.md` | Claude Code 桥接(`@AGENTS.md` 导入) | 无(原样复制) |
|
|
89
|
+
| `skill/SKILL.md` | `~/.agents/skills/<skill-name>/SKILL.md`(已验证);项目级分发 Claude Code 用 `.claude/skills/`,DSH 项目级未验证 | 跨仓库可复用流程的 skill 骨架 | name/description(description 写法见模板内注释) |
|
|
90
|
+
|
|
91
|
+
### 工程与发布
|
|
92
|
+
|
|
93
|
+
| 模板 | 复制到单库 | 作用 | 复制后必改 |
|
|
94
|
+
|---|---|---|---|
|
|
95
|
+
| `repo-root/package.json` | 根 | 字段骨架(type: module / exports / **dsh 字段**(client half 必需:bundle.patch + client.inject + platform)/ peer/devDeps 规范,对齐两实践库) | 全部占位符 + 真实 peer/devDeps(见实践报告 §5.2);纯 host 插件删除 `dsh` 字段;`test` 已指向 verify.mjs 单源 |
|
|
96
|
+
| `repo-root/tsconfig.json` | 根 | IDE/typecheck 配置(noEmit) | 无(可选调 target/lib) |
|
|
97
|
+
| `repo-root/tsconfig.build.json` | 根 | 构建配置(outDir lib + declaration) | 无 |
|
|
98
|
+
| `repo-root/src/index.ts` | `src/index.ts` | host half 入口骨架(OBJECT form 默认导出 + 生命周期注释) | 替换为本插件能力;**OBJECT form 注释保留** |
|
|
99
|
+
| `repo-root/src/config.ts` | `src/config.ts` | schemastery Config + resolveConfig 骨架 | 配置项(编译依赖 schemastery/@types/node 已预置在 devDeps) |
|
|
100
|
+
| `repo-root/scripts/verify.mjs` | `scripts/verify.mjs` | **验证链单源入口**:build→typecheck→探测式 smoke/vitest/mount/client-mount | 无(探测式,接入即自动进链;visual 留作本地发布前门) |
|
|
101
|
+
| `repo-root/scripts/build.mjs` | `scripts/build.mjs` | build 链探测包装:tsc 后按存在性跑 build-client.mjs(无 client 的库不再死在缺失脚本) | 无 |
|
|
102
|
+
| `repo-root/scripts/check-deploy.mjs` | `scripts/check-deploy.mjs` | 部署纪律装后自检(单库/多包自适应) | 只核对默认 profile 名(脚本头部注释) |
|
|
103
|
+
| `repo-root/.github/workflows/ci.yml` | `.github/workflows/ci.yml` | push(main)/PR 验证链(坏提交拦在进 main 当下,不等打 tag) | 无(与 publish.yml 同调 verify.mjs;action SHA 同步更新) |
|
|
104
|
+
| `repo-root/.github/workflows/publish.yml` | `.github/workflows/publish.yml` | OIDC Trusted Publishing 发布流水线 | tag pattern、node 版本、可选 environment 审批门 |
|
|
105
|
+
| `repo-root/.githooks/pre-commit` | `.githooks/pre-commit` | 部署纪律硬拦截 | 无(原样复制后 `git config core.hooksPath .githooks`) |
|
|
106
|
+
| `scaffold.mjs` | **不随库分发**(模板集工具) | 一条命令完成阶段 2:复制 + 占位符替换 + 删模板注释 + git init/hooks + TODO 清单 | — |
|
|
107
|
+
|
|
108
|
+
> 从零新建且有 client half 时需 `scripts/build-client.mjs`(client bundle)——与 client 格式
|
|
109
|
+
> 强耦合,**从 `dsh-context-compass/scripts/build-client.mjs` 复制适配**,模板不固化;
|
|
110
|
+
> `package.json` 的 build 经 `scripts/build.mjs` 探测包装,接入即生效,无 client 的库不受影响。
|
|
111
|
+
> 纯 host 插件删除 package.json 的 `dsh` 字段;cordis.patch.yml 仅 client half 插件需要。
|
|
112
|
+
|
|
113
|
+
## 明确不模板化的项
|
|
114
|
+
|
|
115
|
+
| 项 | 处理方式 |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `scripts/build-client.mjs` / smoke/mount 测试脚本 | **从参照库复制适配**(与 client bundle 格式、验证策略强耦合);路由 A 第 8 步 |
|
|
118
|
+
| `.githooks/commit-msg` | **本机私有,禁止入库**——只留本地 + `.gitignore` 已忽略 |
|
|
119
|
+
| `cordis.patch.yml` | profile 自有但**随发布物分发**(package.json files 已引用)——按本 profile 实况填写,不模板化 |
|
|
120
|
+
| `lib/`、`visual/baselines/` | 构建产物/实机基线,非模板 |
|
|
121
|
+
|
|
122
|
+
## 已知限制(诚实标注)
|
|
123
|
+
|
|
124
|
+
- `typecheck` 模板用严格版(`tsc -p tsconfig.json --noEmit`);实践库实际带 `|| true` 宽松后缀(消化 SlotMap augmentation 双副本类报错的实战 hack)——从零起步建议先严格,遇到 augmentation 报错再按实践库放宽并注释原因
|
|
125
|
+
- `tsconfig.build.json` 的 `allowImportingTsExtensions` + `declaration` 组合要求 TypeScript ≥ 5.7(模板 devDeps 已钉 `^5.7.0`)
|
|
126
|
+
- DSH harness 的项目级 skills 目录机制未经验证(见 skill 模板注释);agent 读取的 AGENTS.md 已由本会话实证有效
|
|
127
|
+
- 首版 bootstrap 描述基于 2025-12 npm 新规的公开报道,发布当日以 npm 官方文档为准
|
|
128
|
+
- 模板骨架未含 lockfile——脚手架产物首次 `npm install` 后**必须把 package-lock.json 入库**(CI npm ci 依赖;scaffold TODO 第 5 步与 ci.yml 头注释均有提示)
|
|
129
|
+
- 客户端 bundle 格式(`__ModuleLoader__` 工厂)与宿主强耦合,build-client.mjs 不模板化;client half 插件的 `dsh` 字段值需按本库宿主包实际填写
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 路线 A:从零新建插件库(通用步骤)
|
|
134
|
+
|
|
135
|
+
> 前提:宿主 dsh 可运行(本机 profile)、GitHub org 有建库权限、npm org 可发包。
|
|
136
|
+
> 阶段划分的原则来自实践报告:**先跑通最小闭环,再补发布面;每版一个关注点**。
|
|
137
|
+
|
|
138
|
+
### 阶段 1:契约预检(写代码之前)
|
|
139
|
+
|
|
140
|
+
1. 明确插件要挂在 dsh 的哪一层(工具/命令/投影/设置页/Slot UI),列 host/client 各自做什么(两个 half 都想清楚)
|
|
141
|
+
2. `cordis_inspect_list` → `cordis_inspect_query` 查清用到的 Service/Event/Builtin/Slot **精确签名**——不猜 API
|
|
142
|
+
3. 记录要依赖的宿主包清单(决定 package.json 的 peer/devDeps)
|
|
143
|
+
|
|
144
|
+
### 阶段 2:仓库脚手架(一条命令)
|
|
145
|
+
|
|
146
|
+
4. **首选脚手架**:`node templates/scaffold.mjs --name <name> --org <org> --desc "<一句话>"`(缺省参数且 TTY 时交互问答;非 TTY 必须全旗标)——自动完成第 5-7 步的**本地部分**并打印手工 TODO 清单(**GitHub 建库、npm install 等远端/网络操作不在其中**,见 TODO 第 5/7 步)
|
|
147
|
+
5. (手动替代)`gh repo create <org>/dsh-<name> --public`(public:provenance 需要;`--description "<一句话>"`)→ 本地 init → 复制 `repo-root/` 全部文件 → 逐文件替换占位符 → 删模板说明注释
|
|
148
|
+
6. `package.json`:按阶段 1 的契约清单填 peerDependencies(宽 caret + 预发布下界)、peerDependenciesMeta、devDependencies(peer 同范围复制 + 运行时可达宿主包全量)
|
|
149
|
+
7. `git config core.hooksPath .githooks` 启用 pre-commit;首次 `git grep` 机密自查后 commit
|
|
150
|
+
|
|
151
|
+
### 阶段 3:最小实现闭环(先跑通再补齐)
|
|
152
|
+
|
|
153
|
+
8. 复制适配 `scripts/build-client.mjs`(不做 client 的插件跳过)→ 写 `src/`(入口骨架 + config 骨架起步)→ `npm install --legacy-peer-deps` → build/typecheck 全绿
|
|
154
|
+
9. 按 DEVELOPMENT.md 核心循环开发:Backlog → Sprint(契约预检)→ 实现 → **DoD 三段**;部署纪律遵守:`file:` 安装 + `check:deploy` PASS 才算改过源码
|
|
155
|
+
10. 每个"类发布"节点跑完整验证链(build → typecheck → 测试 → mount;有 client 加 client-mount/visual)
|
|
156
|
+
|
|
157
|
+
### 阶段 4:发布面补齐(首个公开版之前)
|
|
158
|
+
|
|
159
|
+
11. 文档定稿:README 双语同步、DEVELOPMENT 速查表已积累、SECURITY 支持面写实
|
|
160
|
+
12. `gh repo edit` 设 description + topics;GitHub community profile 检查(LICENSE/README/CONTRIBUTING/SECURITY)
|
|
161
|
+
13. npmjs.com 配 Trusted Publisher(org/repo/`publish.yml` 文件名逐字段一致);granular token 选不到未发布包 → **首版手动 `npm publish` bootstrap**,随后立即切 OIDC
|
|
162
|
+
14. 首发验证:`npm view dsh-<name> dist-tags` + npm 页 provenance 徽章 + `npm audit signatures`
|
|
163
|
+
|
|
164
|
+
### 阶段 5:例行发版(此后每版)
|
|
165
|
+
|
|
166
|
+
15. `npm version <semver>` → push tag → CI 验证链 → (environment 审批门)→ 自动发布;灰度走 `--preid=next` 的 canary 通道(PUBLISHING.md 模板)
|
|
167
|
+
16. 每版在 PUBLISHING.md 记一行(做了什么 + 为什么 + 怎么验证);新坑进速查表
|
|
168
|
+
|
|
169
|
+
## 路线 B:从 dsh-plugins monorepo 迁移(增量,在路线 A 基础上)
|
|
170
|
+
|
|
171
|
+
前置与切库步骤(subtree split、拉历史、推仓库)**见 `DSH-PLUGIN-STANDALONE-MIGRATION.md` §3**,
|
|
172
|
+
本模板集只覆盖迁移后的"规范化"增量:
|
|
173
|
+
|
|
174
|
+
1. 迁移后仓库已有 src/lib/package.json —— 复制本模板集**文档与治理文件**(README/LICENSE/CONTRIBUTING/DEVELOPMENT/PUBLISHING/SECURITY/AGENTS/CLAUDE/.gitignore)
|
|
175
|
+
2. 对照模板补工程文件:`.github/workflows/publish.yml`(monorepo 时代的已在封版仓删除)、`tsconfig*.json`、`.githooks/pre-commit`、`scripts/check-deploy.mjs`(参照库复制或用本模板,核对 `localSrcFor()` 单库分支)
|
|
176
|
+
3. 全局 `grep -rn "dsh-plugins"` 清旧引用(src 默认数据 URL **发版前必改**;package.json repository/homepage/bugs 指向新库——OIDC/provenance 依赖)
|
|
177
|
+
4. rebuild lib → 验证链全绿 → `git grep` 机密自查 → npm 配 Trusted Publisher → tag 发布
|
|
178
|
+
5. 迁移后按迁移文档 §9 分版本推进(v+1 宿主适配/URL 修正,v+2 规范化,v+3+ 功能)
|
|
179
|
+
|
|
180
|
+
## 两路线共同的红线(模板已内建,勿删)
|
|
181
|
+
|
|
182
|
+
- **OBJECT form 默认导出**(`src/index.ts` 模板注释)——工厂写法被静默忽略
|
|
183
|
+
- **部署纪律**(AGENTS.md 5 条 + DEVELOPMENT.md 全文 + pre-commit + check-deploy)——同版本号不同内容事故的唯一拦截链
|
|
184
|
+
- **机密不入库**——`.gitignore` 模板已忽略 HANDOFF/commit-msg;提交前 `git grep -nE '/home/[a-z]|/mnt/[a-z]|/Users/[a-z]'`
|
|
185
|
+
- **验证链单源**——package.json `test`、ci.yml 与 publish.yml 都只调 `scripts/verify.mjs`(结构保证,非纪律约束);链内增删步骤只改 verify.mjs
|
|
186
|
+
|
|
187
|
+
## 将来可选:GitHub template repo
|
|
188
|
+
|
|
189
|
+
模板集成熟(≥2 个插件用 scaffold.mjs 建库跑通)后,可把 `templates/repo-root/` 推成独立
|
|
190
|
+
GitHub 仓库并勾选 Settings → "Template repository",即可用 "Use this template" 一键建库;
|
|
191
|
+
scaffold.mjs 的占位符替换则由 GitHub 变量或首次 commit 后的 sed 替代。本步为可选项,
|
|
192
|
+
当前双文件模板(templates/ + scaffold.mjs)已够用。
|