dsh-crwu-workbench 0.0.13 → 0.0.14
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/CHANGELOG.md +166 -0
- package/README.en.md +33 -4
- package/README.md +34 -5
- package/common/skills/crwu-dws/SKILL.md +4 -4
- package/common/skills/crwu-h3yun-login/SKILL.md +3 -3
- package/common/skills/crwu-h3yun-query/SKILL.md +5 -5
- package/lib/client.js +193 -18
- package/lib/index.js +1040 -583
- package/package.json +17 -9
- package/scripts/lib/cli-entry.mjs +112 -0
- package/scripts/prepare.mjs +56 -16
- package/skills/crwu/crwu-audit/references/14-orchestration-workflow.md +15 -0
- package/skills/crwu/crwu-audit/scripts/README.md +2 -2
- package/skills/crwu/crwu-dev-audit-optimize/references/03-AI/344/272/272/345/267/245/345/267/256/350/267/235/345/210/206/346/236/220/346/265/201/347/250/213.md +1 -1
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/01-kb-source-discovery.md +1 -1
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/02-child-skill-contract.md +1 -1
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/04-registry-and-mapping-update.md +1 -1
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/05-validation-and-delivery.md +2 -2
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/06-live-routing-reconciliation.md +1 -1
- package/skills/crwu/crwu-dev-audit-skill-maintainer/scripts/README.md +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-crwu-workbench",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "中瑞世联工作台 / CRWU audit workbench for DeepSeek Harness: pick a pending audit report, dispatch one AI audit subagent, watch and stop/restart it, auto-upload deliverables to Aliyun OSS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"lib/index.js",
|
|
33
33
|
"lib/client.js",
|
|
34
34
|
"scripts/prepare.mjs",
|
|
35
|
+
"scripts/lib/cli-entry.mjs",
|
|
35
36
|
"config/crwu-workbench.yml",
|
|
36
37
|
"cordis.patch.yml",
|
|
37
38
|
"bin/",
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
],
|
|
48
49
|
"engines": {
|
|
49
50
|
"node": "^22.19.0 || >=24.0.0",
|
|
50
|
-
"dsh": "^0.1.7-rc.2"
|
|
51
|
+
"dsh": "^0.1.7-rc.2 || ^0.2.0-rc.1"
|
|
51
52
|
},
|
|
52
53
|
"publishConfig": {
|
|
53
54
|
"access": "public",
|
|
@@ -65,6 +66,7 @@
|
|
|
65
66
|
"check": "npm run version:check && npm run config:check && npm run skills:check && npm run skills:cli-guard && npm run dws:check && npm run typecheck && npm test && npm run build && npm run smoke:built",
|
|
66
67
|
"config:check": "node scripts/check-config.mjs",
|
|
67
68
|
"pack:assert": "node scripts/assert-pack.mjs",
|
|
69
|
+
"compat:dsh": "node scripts/check-dsh-compat.mjs",
|
|
68
70
|
"pack:assert:strict": "node scripts/assert-pack.mjs --strict",
|
|
69
71
|
"prepublishOnly": "npm run check && npm run pack:assert:strict",
|
|
70
72
|
"smoke:built": "node scripts/smoke-built.mjs",
|
|
@@ -72,6 +74,7 @@
|
|
|
72
74
|
"skills:check": "node scripts/sync-common-skills.mjs --check",
|
|
73
75
|
"skills:cli-guard": "node scripts/check-skill-cli-guard.mjs",
|
|
74
76
|
"bin:check": "node scripts/sync-binaries.mjs --check",
|
|
77
|
+
"bin:smoke": "node scripts/smoke-windows-binaries.mjs",
|
|
75
78
|
"dws:sync": "node scripts/sync-dws-skills.mjs",
|
|
76
79
|
"dws:check": "node scripts/sync-dws-skills.mjs --check"
|
|
77
80
|
},
|
|
@@ -90,13 +93,13 @@
|
|
|
90
93
|
},
|
|
91
94
|
"peerDependencies": {
|
|
92
95
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
93
|
-
"@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2",
|
|
94
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.2",
|
|
95
|
-
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2",
|
|
96
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2",
|
|
97
|
-
"@deepseek-ai/dsh-plugin-manager": "^0.1.7-rc.2",
|
|
98
|
-
"@deepseek-ai/dsh-skill-filesystem": "^0.1.7-rc.2",
|
|
99
|
-
"@deepseek-ai/dsh-tools": "^0.1.7-rc.2",
|
|
96
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
97
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
98
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
99
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
100
|
+
"@deepseek-ai/dsh-plugin-manager": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
101
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
100
103
|
"react": "^18.2.0"
|
|
101
104
|
},
|
|
102
105
|
"dependencies": {
|
|
@@ -106,13 +109,18 @@
|
|
|
106
109
|
},
|
|
107
110
|
"devDependencies": {
|
|
108
111
|
"@deepseek-ai/dsh-agent": "^0.1.7-rc.2",
|
|
112
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.1.7-rc.2",
|
|
109
113
|
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.2",
|
|
114
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.7-rc.2",
|
|
110
115
|
"@deepseek-ai/dsh-fs": "^0.1.7-rc.2",
|
|
116
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2",
|
|
111
117
|
"@deepseek-ai/dsh-plugin-manager": "^0.1.7-rc.2",
|
|
112
118
|
"@deepseek-ai/dsh-session": "^0.1.7-rc.2",
|
|
113
119
|
"@deepseek-ai/dsh-shell": "^0.1.7-rc.2",
|
|
120
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.1.7-rc.2",
|
|
114
121
|
"@deepseek-ai/dsh-subagent": "^0.1.7-rc.2",
|
|
115
122
|
"@deepseek-ai/dsh-tools": "^0.1.7-rc.2",
|
|
123
|
+
"@deepseek-ai/dsh-util-values": "^0.1.7-rc.2",
|
|
116
124
|
"@types/node": "^22.20.0",
|
|
117
125
|
"@types/react": "~18.3.1",
|
|
118
126
|
"@types/semver": "^7.8.0",
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 解析一个 npm 包的 **JS CLI 入口**,并用**当前这个 node** 直接执行它。
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么不能 `spawn('tsdown', …, { shell: true })`
|
|
5
|
+
*
|
|
6
|
+
* Windows 上包的可执行文件是 `node_modules/.bin/tsdown.cmd`(外加 `.ps1`),
|
|
7
|
+
* `CreateProcess` 既不认无扩展名的 `tsdown`,Node ≥ 20.12 还会直接拒绝 spawn `.cmd`;
|
|
8
|
+
* 于是只能开 `shell: true` —— 而一旦过 shell,**项目路径里的空格就会被第二套解析规则改写**
|
|
9
|
+
* (`C:\Users\张三\Case's Work\...` 每次都踩),而且退出码与 stderr 还可能被 shell 自己吃掉。
|
|
10
|
+
*
|
|
11
|
+
* 做法与 `exec.mjs` 对 npm 的做法一致:解析出包的 JS 入口文件,用 `process.execPath` 起它。
|
|
12
|
+
* 没有 shell,就没有第二次解析。
|
|
13
|
+
*
|
|
14
|
+
* ## 解析顺序
|
|
15
|
+
*
|
|
16
|
+
* 1. `createRequire(<from>/package.json).resolve('<pkg>/package.json')` —— 走 Node 自己的
|
|
17
|
+
* node_modules 解析(npm / pnpm / yarn 布局都认,软链接也认);
|
|
18
|
+
* 2. 读该 package.json 的 `bin`,按 `binName` 取出入口相对路径;
|
|
19
|
+
* 3. 只接受**真实存在的 .js / .mjs / .cjs**:命中 `.cmd` / `.ps1` / shell 脚本一律报错,
|
|
20
|
+
* 绝不退回「让 shell 去跑它」—— 那正是本模块要消灭的形态。
|
|
21
|
+
*
|
|
22
|
+
* 解析不到就**抛错**(带可读原因),由调用方决定是失败还是降级;不静默换一种执行方式。
|
|
23
|
+
*/
|
|
24
|
+
import { createRequire } from 'node:module'
|
|
25
|
+
import { existsSync, statSync } from 'node:fs'
|
|
26
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path'
|
|
27
|
+
import { pathToFileURL } from 'node:url'
|
|
28
|
+
|
|
29
|
+
/** 可执行入口必须是 JS,不能是 Windows 的 `.cmd` / `.ps1` shim。 */
|
|
30
|
+
const JS_ENTRY = /\.(?:mjs|cjs|js)$/i
|
|
31
|
+
|
|
32
|
+
function isFile(path) {
|
|
33
|
+
try {
|
|
34
|
+
return existsSync(path) && statSync(path).isFile()
|
|
35
|
+
} catch (error) {
|
|
36
|
+
// 权限 / 断链:都只意味着「这个候选不可用」。
|
|
37
|
+
void error
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `bin` 字段既可能是字符串,也可能是 `{ 名字: 相对路径 }`。 */
|
|
43
|
+
function binEntryOf(bin, binName, packageName) {
|
|
44
|
+
if (typeof bin === 'string') return bin
|
|
45
|
+
if (bin !== null && typeof bin === 'object') {
|
|
46
|
+
const table = bin
|
|
47
|
+
const wanted = binName !== '' ? binName : packageName.split('/').pop() ?? ''
|
|
48
|
+
const direct = table[wanted]
|
|
49
|
+
if (typeof direct === 'string') return direct
|
|
50
|
+
// 只有一个入口时按它走(包名与命令名不一致的包,例如 `@scope/tool` → `tool-cli`)。
|
|
51
|
+
const values = Object.values(table).filter((value) => typeof value === 'string')
|
|
52
|
+
if (values.length === 1) return values[0]
|
|
53
|
+
}
|
|
54
|
+
return ''
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 解析 `<packageName>` 的 CLI 入口绝对路径。
|
|
59
|
+
*
|
|
60
|
+
* @param {string} packageName 包名,例如 `tsdown`
|
|
61
|
+
* @param {{ from?: string, binName?: string }} [options] `from` = 解析起点目录(默认本文件所属插件根)
|
|
62
|
+
* @returns {string} 入口文件的绝对路径(一定是 JS 文件)
|
|
63
|
+
* @throws 解析不到、或只找到非 JS shim 时
|
|
64
|
+
*/
|
|
65
|
+
export function resolvePackageCli(packageName, options = {}) {
|
|
66
|
+
const from = options.from ?? process.cwd()
|
|
67
|
+
const binName = options.binName ?? ''
|
|
68
|
+
const require_ = createRequire(pathToFileURL(join(from, 'package.json')).href)
|
|
69
|
+
|
|
70
|
+
let manifestPath = ''
|
|
71
|
+
try {
|
|
72
|
+
manifestPath = require_.resolve(`${packageName}/package.json`)
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throw new Error(`找不到 ${packageName}:${error instanceof Error ? error.message : String(error)}`)
|
|
75
|
+
}
|
|
76
|
+
let manifest
|
|
77
|
+
try {
|
|
78
|
+
manifest = require_(manifestPath)
|
|
79
|
+
} catch (error) {
|
|
80
|
+
throw new Error(`${packageName} 的 package.json 读不出来:${error instanceof Error ? error.message : String(error)}`)
|
|
81
|
+
}
|
|
82
|
+
const relative = binEntryOf(manifest?.bin, binName, packageName)
|
|
83
|
+
const candidates = []
|
|
84
|
+
if (relative !== '') {
|
|
85
|
+
candidates.push(isAbsolute(relative) ? relative : resolve(dirname(manifestPath), relative))
|
|
86
|
+
}
|
|
87
|
+
// 少数包不写 `bin` 或写法不规范:按常见入口名兜底(仍然只接受 JS 文件)。
|
|
88
|
+
const packageDir = dirname(manifestPath)
|
|
89
|
+
const name = packageName.split('/').pop() ?? packageName
|
|
90
|
+
candidates.push(
|
|
91
|
+
join(packageDir, 'dist', `${name}.mjs`),
|
|
92
|
+
join(packageDir, 'dist', `${name}.js`),
|
|
93
|
+
join(packageDir, 'dist', 'run.mjs'),
|
|
94
|
+
join(packageDir, 'bin', `${name}.mjs`),
|
|
95
|
+
join(packageDir, 'bin', `${name}.js`),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
for (const candidate of candidates) {
|
|
99
|
+
if (JS_ENTRY.test(candidate) && isFile(candidate)) return candidate
|
|
100
|
+
}
|
|
101
|
+
const shim = join(from, 'node_modules', '.bin', binName !== '' ? binName : name)
|
|
102
|
+
if (existsSync(shim)) {
|
|
103
|
+
throw new Error(`${packageName} 只找到了 ${shim}(Windows 上是 .cmd/.ps1 shim)—— 不要用 shell 去跑它,` +
|
|
104
|
+
'请在 package.json 里为该包声明 JS 入口,或让上游补上规范入口')
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`${packageName} 没有可用的 JS 入口(试过:${candidates.join(', ')})`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** 把入口包成「用当前 node 执行」的 argv。 */
|
|
110
|
+
export function nodeCommand(entryPath, args = []) {
|
|
111
|
+
return { command: process.execPath, args: [entryPath, ...args] }
|
|
112
|
+
}
|
package/scripts/prepare.mjs
CHANGED
|
@@ -12,46 +12,86 @@
|
|
|
12
12
|
* - **npm 安装已发布产物**:源码不在 → 跳过(`lib/` 已随包提供)。
|
|
13
13
|
*
|
|
14
14
|
* 发布路径不允许静默出一个没有 `lib/` 的包:`prepack` 用 `--force`,源码不在即失败。
|
|
15
|
+
*
|
|
16
|
+
* ## 为什么不再 `spawnSync('tsdown', { shell: process.platform === 'win32' })`
|
|
17
|
+
*
|
|
18
|
+
* 那条命令在 Windows 上只能靠 shell 才能找到 `tsdown.cmd`,而**一旦过 shell,项目路径里的
|
|
19
|
+
* 空格与单引号就会被第二套解析规则改写**(`C:\Users\张三\Case's Work\…` 必踩),
|
|
20
|
+
* 退出码与 stderr 也可能被 shell 自己吃掉。现在解析出 tsdown 的 **JS 入口**、用
|
|
21
|
+
* `process.execPath` 直接执行(`scripts/lib/cli-entry.mjs`):没有 shell,就没有第二次解析。
|
|
15
22
|
*/
|
|
16
23
|
import { spawnSync } from 'node:child_process'
|
|
17
24
|
import { existsSync } from 'node:fs'
|
|
18
25
|
import { dirname, join } from 'node:path'
|
|
19
26
|
import { fileURLToPath } from 'node:url'
|
|
27
|
+
import { nodeCommand, resolvePackageCli } from './lib/cli-entry.mjs'
|
|
20
28
|
|
|
21
29
|
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)))
|
|
22
30
|
const SOURCE_MARKERS = ['tsconfig.json', 'tsdown.config.ts', join('src', 'index.ts'), join('src', 'client', 'index.ts')]
|
|
23
31
|
|
|
24
32
|
/** 源码是否齐备(齐备 = 我们在 git 克隆里,可以构建)。 */
|
|
25
|
-
export function missingSources() {
|
|
26
|
-
return SOURCE_MARKERS.filter((marker) => !existsSync(join(
|
|
33
|
+
export function missingSources(root = ROOT) {
|
|
34
|
+
return SOURCE_MARKERS.filter((marker) => !existsSync(join(root, marker)))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 这一次构建要跑的**精确 argv**(不含 shell)。
|
|
39
|
+
*
|
|
40
|
+
* 导出它是为了让测试能直接断言「命令位置是当前 node + tsdown 的 JS 入口」,
|
|
41
|
+
* 而不是靠跑一遍构建去间接猜。tsdown 没装时抛错,由 `build()` 翻成退出码 1。
|
|
42
|
+
*/
|
|
43
|
+
export function buildPlan(root = ROOT) {
|
|
44
|
+
const entry = resolvePackageCli('tsdown', { from: root, binName: 'tsdown' })
|
|
45
|
+
return { ...nodeCommand(entry), cwd: root }
|
|
27
46
|
}
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
/**
|
|
49
|
+
* 真构建。
|
|
50
|
+
*
|
|
51
|
+
* 进度日志一律走 **stderr**:stdout 留给机器可读输出。npm 10(Node 22 自带)在
|
|
52
|
+
* `npm pack --dry-run --json --ignore-scripts` 下仍然会执行 prepare,这些日志一旦混进
|
|
53
|
+
* stdout,消费 `--json` 的脚本 `JSON.parse` 就炸了(CI 的 ubuntu/node22 就是这么红的)。
|
|
54
|
+
* 子进程的 stdout 也转去 stderr('inherit' 会让 tsdown 的 ℹ 行落进我们的 stdout)。
|
|
55
|
+
*
|
|
56
|
+
* @param {{ root?: string, spawn?: typeof spawnSync, log?: (message: string) => void }} [options]
|
|
57
|
+
*/
|
|
58
|
+
export function build(options = {}) {
|
|
59
|
+
const root = options.root ?? ROOT
|
|
60
|
+
const spawn = options.spawn ?? spawnSync
|
|
61
|
+
const log = options.log ?? ((message) => console.error(message))
|
|
62
|
+
log('[build] tsdown 构建 lib/ …')
|
|
63
|
+
|
|
64
|
+
let plan
|
|
65
|
+
try {
|
|
66
|
+
plan = buildPlan(root)
|
|
67
|
+
} catch (error) {
|
|
68
|
+
log(`[build] 构建失败:${error instanceof Error ? error.message : String(error)}`)
|
|
69
|
+
return 1
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// **没有 shell**:argv 原样交给 CreateProcess / posix_spawn,路径里的空格与引号不参与解析。
|
|
73
|
+
const result = spawn(plan.command, plan.args, { cwd: plan.cwd, stdio: ['inherit', 2, 'inherit'] })
|
|
36
74
|
if (result.error) {
|
|
37
|
-
|
|
75
|
+
log(`[build] 构建失败:${result.error.message}`)
|
|
38
76
|
return 1
|
|
39
77
|
}
|
|
40
78
|
return result.status ?? 1
|
|
41
79
|
}
|
|
42
80
|
|
|
43
81
|
/** 供测试使用:按给定模式决定跳过还是构建。 */
|
|
44
|
-
export function run(
|
|
45
|
-
const
|
|
82
|
+
export function run(options = {}) {
|
|
83
|
+
const root = options.root ?? ROOT
|
|
84
|
+
const log = options.log ?? ((message) => console.error(message))
|
|
85
|
+
const missing = missingSources(root)
|
|
46
86
|
if (missing.length > 0) {
|
|
47
|
-
if (force) {
|
|
48
|
-
|
|
87
|
+
if (options.force === true) {
|
|
88
|
+
log(`[build] 缺少构建所需文件:${missing.join(', ')}`)
|
|
49
89
|
return 1
|
|
50
90
|
}
|
|
51
|
-
|
|
91
|
+
log(`[build] 跳过构建:这是已发布的预构建产物(缺 ${missing.join(', ')}),lib/ 已随包提供。`)
|
|
52
92
|
return 0
|
|
53
93
|
}
|
|
54
|
-
return build()
|
|
94
|
+
return build({ ...options, root, log })
|
|
55
95
|
}
|
|
56
96
|
|
|
57
97
|
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
@@ -24,6 +24,21 @@
|
|
|
24
24
|
|
|
25
25
|
下面流程里出现的 `python3 scripts/<文件>` 一律按本节解析出的解释器路径执行。
|
|
26
26
|
|
|
27
|
+
### 1.1 命令块按**当前平台 shell** 执行
|
|
28
|
+
|
|
29
|
+
本技能与各 reference 里的命令块只描述**要跑什么**,不承诺某一种 shell:
|
|
30
|
+
|
|
31
|
+
- Windows 上 DSH 挂的是 **PowerShell**(整串命令作为一个 argv 元素交给 `pwsh -Command`),
|
|
32
|
+
macOS / Linux 上是 POSIX shell;
|
|
33
|
+
- 不要假设某一种 shell 一定存在,也不要用另一种方言的语法(PowerShell 里没有
|
|
34
|
+
`mkdir -p` / `chmod` / `rm -f`,POSIX 里也没有 `Get-Location` / `New-Item`);
|
|
35
|
+
- 命令块里的 `python3` 一律换成上面解析出的**绝对解释器路径**;文件路径直接作为参数传递,
|
|
36
|
+
引用交给宿主 shell 的规则,不要自己拼引号或分隔符;
|
|
37
|
+
- 需要「当前在哪个目录」时**问宿主 shell**(POSIX `pwd` / Windows `Get-Location`),不要猜。
|
|
38
|
+
|
|
39
|
+
Windows 上审核链路的命令全部由插件的平台适配器生成(`src/host/platform/shell.ts`),
|
|
40
|
+
技能正文里的命令只用于人工复现与排障。
|
|
41
|
+
|
|
27
42
|
## 2. 路由流程(步骤 1–15)
|
|
28
43
|
|
|
29
44
|
1. **消费 Host 已准备的输入快照(不要再定位、不要重复取数)**:报告已由 Host 按精确 ObjectId 定位并取数一次,结果落在案例目录的 `输入快照/` 下——完整记录 `报告记录.json`、附件清单 `附件清单.json`、元数据 `快照元数据.json`。`schemaCode` 是 Host 的基础设施状态:**核验记录事实一律以 `报告记录.json` 为准**,不要提交、不要猜测 `schemaCode`,也不要再调 `records list` / 搜表单 / 重新取记录。仅在启动指令明确说明「输入快照缺失」时,才允许**一次**兜底:调 `crwu_h3yun_record_get({objectId,caseDir})`(它由 Host 自己解析 `schemaCode`)。附件元数据直接读 `附件清单.json`(字段:附件字段、文件名、类型、大小、`fileId`)并分类;只有快照缺失时才对同一 `objectId` 调一次 `crwu_h3yun_files_list({objectId,caseDir})`;附件名只用于隔离决策和待抽验提示。(工具**不返回**带会话鉴权的下载 URL,也不需要。)
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
## 用法
|
|
33
33
|
|
|
34
|
-
```
|
|
34
|
+
```text
|
|
35
35
|
# 阶段一冻结指纹(写入 AuditResult.phaseControl.phase1Digest)
|
|
36
36
|
python3 scripts/audit_delivery.py digest <冻结快照.json>
|
|
37
37
|
|
|
@@ -66,7 +66,7 @@ python3 scripts/test_audit_delivery.py
|
|
|
66
66
|
| `media_extract.py` | 媒体抽取库:xlsx 绘图锚点 / docx·doc 正文图(段落序)/ PDF 内嵌图 / 独立图片;H0 与 fail-closed | 同上 §非单元格证据 |
|
|
67
67
|
| `test_prepare_materials.py`、`test_media_extract.py` | 上述两脚本的契约测试 | — |
|
|
68
68
|
|
|
69
|
-
```
|
|
69
|
+
```text
|
|
70
70
|
# 阶段一:盘点 + 工作版 + 媒体证据(产出 材料盘点.json / 媒体索引.json / 提取/ / 工作版/ / 媒体证据/)
|
|
71
71
|
python3 scripts/prepare_materials.py --case <案例目录>
|
|
72
72
|
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
|
|
78
78
|
结构化结果遵循 `scripts/gap_analysis.schema.json`,先校验再渲染:
|
|
79
79
|
|
|
80
|
-
```
|
|
80
|
+
```text
|
|
81
81
|
python3 scripts/gap_analysis_delivery.py validate --input <gap-analysis.json>
|
|
82
82
|
python3 scripts/gap_analysis_delivery.py render --input <gap-analysis.json> --output <gap-analysis.html>
|
|
83
83
|
```
|
|
@@ -26,7 +26,7 @@ crwu-audit-asset-<name>/
|
|
|
26
26
|
|
|
27
27
|
**公共规则:一个规范源 + 各叶子本地副本(不是多个事实源)**。轴边界、输入、一级根装配、二级选择返回、执行顺序(一级共用层→命中二级条目)、必检项/历史问题状态字段、来源优先级、证据出处与 capability gap,维护在**一个规范源** `crwu-audit/references/12-leaf-common-contract.md`,由确定性工具同步为每个叶子的**本地副本** `references/03-common-contract.md`:
|
|
28
28
|
|
|
29
|
-
```
|
|
29
|
+
```text
|
|
30
30
|
# 生成/修复所有叶子副本(只为缺失或漂移的叶子写入;重复执行无 diff)
|
|
31
31
|
python3 scripts/kb_tool.py sync-leaf-common-contract --skill-root <本技能层> --write
|
|
32
32
|
# 只报告 missing / drifted / unexpected(validate 已自动执行同等检查)
|
package/skills/crwu/crwu-dev-audit-skill-maintainer/references/04-registry-and-mapping-update.md
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
- **定位**:知识库 ↔ Skill 映射的**只读派生视图**,给人一眼看现状用;事实源仍是知识库最新目录 + `07-skill-registry.md` + 源仓技能层里的真实目录。它不参与运行时路由,不替代 registry。
|
|
39
39
|
- **生成**:只由检查器 `--emit-map` 生成,禁止手工编辑状态列:
|
|
40
40
|
|
|
41
|
-
```
|
|
41
|
+
```text
|
|
42
42
|
python3 scripts/check_audit_skill_mappings.py \
|
|
43
43
|
--repo-root . --catalog <本次 crwu-dws 快照> --max-age-hours <H> \
|
|
44
44
|
--emit-map <本技能目录>/references/07-kb-skill-map.md
|
package/skills/crwu/crwu-dev-audit-skill-maintainer/references/05-validation-and-delivery.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## 检查器
|
|
11
11
|
|
|
12
|
-
```
|
|
12
|
+
```text
|
|
13
13
|
python3 scripts/check_audit_skill_mappings.py \
|
|
14
14
|
--repo-root <source-repo> \
|
|
15
15
|
--catalog <目录树、snapshot 或 node-index> \
|
|
@@ -71,7 +71,7 @@ python3 scripts/check_audit_skill_mappings.py \
|
|
|
71
71
|
|
|
72
72
|
## 新 Skill 验证
|
|
73
73
|
|
|
74
|
-
```
|
|
74
|
+
```text
|
|
75
75
|
# 以下命令在技能目录内执行(`scripts/` = 本技能自带脚本);跨技能脚本按**技能层**寻址 ——
|
|
76
76
|
# DSH 一个层就是一个技能根:本技能与 crwu-audit 在自研层,crwu-dws 在公共层(不是同一个根)。
|
|
77
77
|
CRWU_SKILLS_ROOT=<本技能所安装到的自研层>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
## 运行
|
|
21
21
|
|
|
22
|
-
```
|
|
22
|
+
```text
|
|
23
23
|
# 源仓技能:引用卫生 + 实时协议 lint(禁止本地知识库根常量与根路径字面、禁止硬编码 nodeId,crwu-audit* 目录从严)
|
|
24
24
|
python3 scripts/kb_tool.py validate --skill-root <skills 安装根>
|
|
25
25
|
|
|
@@ -58,7 +58,7 @@ python3 scripts/kb_tool.py validate --skill-root <skills 安装根> --forbid-lit
|
|
|
58
58
|
映射一致性(registry ↔ classification ↔ 真实技能目录 ↔ 最新知识库目录)
|
|
59
59
|
由本技能 `scripts/check_audit_skill_mappings.py` 校验:
|
|
60
60
|
|
|
61
|
-
```
|
|
61
|
+
```text
|
|
62
62
|
# 只读盘点(json 供机器消费;--strict 有 error 时退出 1)
|
|
63
63
|
python3 scripts/check_audit_skill_mappings.py --repo-root <源仓> --catalog <本次目录> --format json --strict
|
|
64
64
|
|