helloagents 3.0.33 → 3.0.35

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.
Files changed (57) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.codex-plugin/plugin.json +3 -4
  3. package/README.md +70 -71
  4. package/README_CN.md +70 -71
  5. package/bootstrap-lite.md +9 -11
  6. package/bootstrap.md +21 -23
  7. package/gemini-extension.json +1 -1
  8. package/install.ps1 +21 -3
  9. package/install.sh +19 -2
  10. package/package.json +2 -2
  11. package/scripts/capability-registry.mjs +5 -3
  12. package/scripts/cli-doctor-codex.mjs +150 -1
  13. package/scripts/cli-doctor-render.mjs +2 -1
  14. package/scripts/cli-lifecycle-hosts.mjs +76 -34
  15. package/scripts/cli-lifecycle.mjs +50 -15
  16. package/scripts/cli-messages.mjs +5 -5
  17. package/scripts/delivery-gate-messages.mjs +5 -4
  18. package/scripts/delivery-gate.mjs +11 -22
  19. package/scripts/guard.mjs +1 -1
  20. package/scripts/notify-closeout.mjs +61 -22
  21. package/scripts/notify-context.mjs +5 -5
  22. package/scripts/notify-route.mjs +1 -1
  23. package/scripts/notify.mjs +2 -2
  24. package/scripts/plan-contract.mjs +10 -14
  25. package/scripts/project-session-cleanup.mjs +45 -31
  26. package/scripts/qa-review-state.mjs +313 -0
  27. package/scripts/ralph-loop.mjs +32 -13
  28. package/scripts/runtime-scope.mjs +1 -3
  29. package/scripts/session-capsule.mjs +51 -13
  30. package/scripts/state-document.mjs +77 -0
  31. package/scripts/workflow-core.mjs +13 -19
  32. package/scripts/workflow-plan-files.mjs +1 -1
  33. package/scripts/workflow-recommendation.mjs +55 -67
  34. package/scripts/workflow-state.mjs +8 -8
  35. package/skills/commands/auto/SKILL.md +12 -12
  36. package/skills/commands/build/SKILL.md +9 -10
  37. package/skills/commands/commit/SKILL.md +1 -1
  38. package/skills/commands/help/SKILL.md +11 -13
  39. package/skills/commands/init/SKILL.md +18 -9
  40. package/skills/commands/loop/SKILL.md +70 -96
  41. package/skills/commands/plan/SKILL.md +7 -8
  42. package/skills/commands/prd/SKILL.md +3 -3
  43. package/skills/commands/qa/SKILL.md +49 -0
  44. package/skills/hello-ui/SKILL.md +3 -3
  45. package/skills/helloagents/SKILL.md +11 -14
  46. package/skills/qa-review/SKILL.md +92 -0
  47. package/templates/plans/contract.json +4 -7
  48. package/templates/plans/plan.md +1 -1
  49. package/templates/plans/tasks.md +1 -1
  50. package/templates/verify.yaml +1 -1
  51. package/scripts/review-state.mjs +0 -193
  52. package/scripts/verify-state.mjs +0 -175
  53. package/skills/commands/global/SKILL.md +0 -71
  54. package/skills/commands/verify/SKILL.md +0 -46
  55. package/skills/commands/wiki/SKILL.md +0 -57
  56. package/skills/hello-review/SKILL.md +0 -42
  57. package/skills/hello-verify/SKILL.md +0 -144
@@ -1,193 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import { fileURLToPath } from 'node:url'
3
- import { appendReplayEvent } from './replay-state.mjs'
4
- import {
5
- captureWorkspaceFingerprint,
6
- clearRuntimeEvidence,
7
- getRuntimeEvidencePath,
8
- getRuntimeEvidenceRelativePath,
9
- readRuntimeEvidence,
10
- validateEvidenceFingerprint,
11
- validateEvidenceTimestamp,
12
- writeRuntimeEvidence,
13
- } from './runtime-artifacts.mjs'
14
-
15
- export const REVIEW_EVIDENCE_FILE_NAME = 'review.json'
16
- const VALID_REVIEW_OUTCOMES = new Set(['clean', 'findings'])
17
-
18
- function normalizeStringArray(values) {
19
- if (!Array.isArray(values)) return []
20
- return [...new Set(values
21
- .map((value) => (typeof value === 'string' ? value.trim() : ''))
22
- .filter(Boolean))]
23
- }
24
-
25
- function normalizeReviewOutcome(value) {
26
- const normalized = typeof value === 'string' ? value.trim().toLowerCase() : ''
27
- return VALID_REVIEW_OUTCOMES.has(normalized) ? normalized : ''
28
- }
29
-
30
- export function getReviewEvidencePath(cwd, options = {}) {
31
- return getRuntimeEvidencePath(cwd, REVIEW_EVIDENCE_FILE_NAME, options)
32
- }
33
-
34
- export function readReviewEvidence(cwd, options = {}) {
35
- return readRuntimeEvidence(cwd, REVIEW_EVIDENCE_FILE_NAME, options)
36
- }
37
-
38
- export function clearReviewEvidence(cwd, options = {}) {
39
- clearRuntimeEvidence(cwd, REVIEW_EVIDENCE_FILE_NAME, options)
40
- }
41
-
42
- export function normalizeReviewEvidence(input = {}) {
43
- return {
44
- source: typeof input.source === 'string' && input.source.trim() ? input.source.trim() : 'manual',
45
- originCommand: typeof input.originCommand === 'string' ? input.originCommand.trim() : '',
46
- reviewMode: typeof input.reviewMode === 'string' ? input.reviewMode.trim() : '',
47
- outcome: normalizeReviewOutcome(input.outcome),
48
- conclusion: typeof input.conclusion === 'string' ? input.conclusion.trim() : '',
49
- findings: normalizeStringArray(input.findings),
50
- fileReferences: normalizeStringArray(input.fileReferences),
51
- }
52
- }
53
-
54
- export function writeReviewEvidence(cwd, {
55
- source = 'stop',
56
- originCommand = '',
57
- reviewMode = '',
58
- outcome = '',
59
- conclusion = '',
60
- findings = [],
61
- fileReferences = [],
62
- } = {}, options = {}) {
63
- const normalized = normalizeReviewEvidence({
64
- source,
65
- originCommand,
66
- reviewMode,
67
- outcome,
68
- conclusion,
69
- findings,
70
- fileReferences,
71
- })
72
- const payload = {
73
- updatedAt: new Date().toISOString(),
74
- source: normalized.source,
75
- originCommand: normalized.originCommand,
76
- reviewMode: normalized.reviewMode,
77
- conclusion: normalized.conclusion,
78
- outcome: normalized.outcome,
79
- findings: normalized.findings,
80
- fileReferences: normalized.fileReferences,
81
- fingerprint: captureWorkspaceFingerprint(cwd),
82
- }
83
- writeRuntimeEvidence(cwd, REVIEW_EVIDENCE_FILE_NAME, payload, options)
84
- appendReplayEvent(cwd, {
85
- event: 'review_evidence_written',
86
- source: normalized.source,
87
- skillName: normalized.originCommand,
88
- payload: options.payload || {},
89
- details: {
90
- reviewMode: normalized.reviewMode,
91
- outcome: normalized.outcome,
92
- conclusion: normalized.conclusion,
93
- findings: normalized.findings,
94
- fileReferences: normalized.fileReferences,
95
- },
96
- artifacts: [getRuntimeEvidenceRelativePath(cwd, REVIEW_EVIDENCE_FILE_NAME, options)],
97
- })
98
- return payload
99
- }
100
-
101
- function readRequiredReviewEvidence(cwd, options = {}) {
102
- const evidence = readReviewEvidence(cwd, options)
103
- if (evidence) return { evidence }
104
- return {
105
- error: {
106
- required: true,
107
- status: 'missing',
108
- details: ['缺少 review-first 收尾所需的成功审查证据'],
109
- },
110
- }
111
- }
112
-
113
- function validateReviewTimestamp(evidence, now) {
114
- return validateEvidenceTimestamp(evidence, now, '审查证据')
115
- }
116
-
117
- function validateReviewFingerprint(cwd, evidence) {
118
- return validateEvidenceFingerprint(cwd, evidence, '成功审查证据')
119
- }
120
-
121
- function validateReviewOutcome(evidence) {
122
- if (!normalizeReviewOutcome(evidence.outcome) || !String(evidence.conclusion || '').trim()) {
123
- return {
124
- required: true,
125
- status: 'invalid',
126
- evidence,
127
- details: ['审查证据必须记录明确的 outcome 和 conclusion'],
128
- }
129
- }
130
- if (normalizeReviewOutcome(evidence.outcome) !== 'clean') {
131
- return {
132
- required: true,
133
- status: 'blocked',
134
- evidence,
135
- details: ['最新审查证据仍记录阻塞问题'],
136
- }
137
- }
138
- return null
139
- }
140
-
141
- export function getReviewEvidenceStatus(cwd, { required = false, now = Date.now(), ...options } = {}) {
142
- if (!required) {
143
- return {
144
- required: false,
145
- status: 'not-applicable',
146
- }
147
- }
148
-
149
- const requiredEvidence = readRequiredReviewEvidence(cwd, options)
150
- if (requiredEvidence.error) return requiredEvidence.error
151
-
152
- const { evidence } = requiredEvidence
153
- const timestampError = validateReviewTimestamp(evidence, now)
154
- if (timestampError) return timestampError
155
-
156
- const fingerprintError = validateReviewFingerprint(cwd, evidence)
157
- if (fingerprintError) return fingerprintError
158
-
159
- const outcomeError = validateReviewOutcome(evidence)
160
- if (outcomeError) return outcomeError
161
-
162
- return {
163
- required: true,
164
- status: 'valid',
165
- evidence,
166
- }
167
- }
168
-
169
- function readStdinJson() {
170
- try {
171
- return JSON.parse(readFileSync(0, 'utf-8'))
172
- } catch {
173
- return {}
174
- }
175
- }
176
-
177
- function main() {
178
- const command = process.argv[2] || ''
179
- if (command !== 'write') return
180
-
181
- const input = readStdinJson()
182
- const cwd = input.cwd || process.cwd()
183
- const payload = writeReviewEvidence(cwd, input, { payload: input })
184
- process.stdout.write(JSON.stringify({
185
- suppressOutput: true,
186
- path: getReviewEvidencePath(cwd, { payload: input }),
187
- payload,
188
- }))
189
- }
190
-
191
- if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
192
- main()
193
- }
@@ -1,175 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import { appendReplayEvent } from './replay-state.mjs'
4
- import {
5
- getProjectVerifyYamlPath,
6
- } from './project-storage.mjs'
7
- import {
8
- captureWorkspaceFingerprint,
9
- clearRuntimeEvidence,
10
- getRuntimeEvidencePath,
11
- getRuntimeEvidenceRelativePath,
12
- readRuntimeEvidence,
13
- validateEvidenceFingerprint,
14
- validateEvidenceTimestamp,
15
- writeRuntimeEvidence,
16
- } from './runtime-artifacts.mjs'
17
-
18
- export const VERIFY_EVIDENCE_FILE_NAME = 'verify.json'
19
- const SHELL_OPERATORS = /[;&|`$(){}\n\r]/
20
-
21
- export function getVerifyEvidencePath(cwd, options = {}) {
22
- return getRuntimeEvidencePath(cwd, VERIFY_EVIDENCE_FILE_NAME, options)
23
- }
24
-
25
- export function readVerifyEvidence(cwd, options = {}) {
26
- return readRuntimeEvidence(cwd, VERIFY_EVIDENCE_FILE_NAME, options)
27
- }
28
-
29
- export function clearVerifyEvidence(cwd, options = {}) {
30
- clearRuntimeEvidence(cwd, VERIFY_EVIDENCE_FILE_NAME, options)
31
- }
32
-
33
- function loadVerifyYaml(cwd) {
34
- const f = getProjectVerifyYamlPath(cwd)
35
- if (!existsSync(f)) return null
36
- try {
37
- const content = readFileSync(f, 'utf-8')
38
- const cmds = []
39
- let inCmds = false
40
- for (const line of content.split('\n')) {
41
- const s = line.trim()
42
- if (s.startsWith('commands:')) { inCmds = true; continue }
43
- if (inCmds) {
44
- if (s.startsWith('- ') && !s.startsWith('# ')) {
45
- const cmd = s.slice(2).trim().replace(/^["']|["']$/g, '')
46
- if (cmd && !cmd.startsWith('#')) cmds.push(cmd)
47
- } else if (s && !s.startsWith('#')) {
48
- break
49
- }
50
- }
51
- }
52
- return cmds.length ? cmds : null
53
- } catch {
54
- return null
55
- }
56
- }
57
-
58
- function detectFromPackageJson(cwd) {
59
- const f = join(cwd, 'package.json')
60
- if (!existsSync(f)) return []
61
- try {
62
- const scripts = JSON.parse(readFileSync(f, 'utf-8')).scripts || {}
63
- return ['lint', 'typecheck', 'type-check', 'test', 'build']
64
- .filter((k) => k in scripts)
65
- .map((k) => `npm run ${k}`)
66
- } catch {
67
- return []
68
- }
69
- }
70
-
71
- function detectFromPyproject(cwd) {
72
- const f = join(cwd, 'pyproject.toml')
73
- if (!existsSync(f)) return []
74
- try {
75
- const content = readFileSync(f, 'utf-8')
76
- const cmds = []
77
- if (content.includes('[tool.ruff')) cmds.push('ruff check .')
78
- if (content.includes('[tool.mypy')) cmds.push('mypy .')
79
- if (content.includes('[tool.pytest')) cmds.push('pytest --tb=short -q')
80
- return cmds
81
- } catch {
82
- return []
83
- }
84
- }
85
-
86
- export function detectCommands(cwd) {
87
- const yaml = loadVerifyYaml(cwd)
88
- if (yaml?.length) return yaml
89
- const pkg = detectFromPackageJson(cwd)
90
- if (pkg.length) return pkg
91
- return detectFromPyproject(cwd)
92
- }
93
-
94
- export function hasUnsafeVerifyCommand(commands = []) {
95
- return commands.some((cmd) => SHELL_OPERATORS.test(cmd))
96
- }
97
-
98
- export function writeVerifyEvidence(cwd, { commands = [], fastOnly = false, source = 'ralph-loop' } = {}, options = {}) {
99
- const payload = {
100
- updatedAt: new Date().toISOString(),
101
- commands,
102
- fastOnly,
103
- source,
104
- fingerprint: captureWorkspaceFingerprint(cwd),
105
- }
106
- writeRuntimeEvidence(cwd, VERIFY_EVIDENCE_FILE_NAME, payload, options)
107
- appendReplayEvent(cwd, {
108
- event: 'verify_evidence_written',
109
- source,
110
- payload: options.payload || {},
111
- details: {
112
- commands,
113
- fastOnly,
114
- },
115
- artifacts: [getRuntimeEvidenceRelativePath(cwd, VERIFY_EVIDENCE_FILE_NAME, options)],
116
- })
117
- }
118
-
119
- function validateVerifyEvidencePresence(commands, evidence) {
120
- if (evidence) return null
121
- return {
122
- required: true,
123
- status: 'missing',
124
- commands,
125
- details: ['缺少当前工作流的成功验证证据'],
126
- }
127
- }
128
-
129
- function validateVerifyEvidenceFreshness(cwd, commands, evidence, now) {
130
- if (evidence.fastOnly) {
131
- return {
132
- required: true,
133
- status: 'fast-only',
134
- commands,
135
- evidence,
136
- details: ['最新验证证据只覆盖子代理快速检查'],
137
- }
138
- }
139
-
140
- const timestampError = validateEvidenceTimestamp(evidence, now, '验证证据')
141
- return timestampError ? { ...timestampError, commands } : null
142
- }
143
-
144
- function validateVerifyFingerprint(cwd, commands, evidence) {
145
- const fingerprintError = validateEvidenceFingerprint(cwd, evidence, '成功验证证据')
146
- return fingerprintError ? { ...fingerprintError, commands } : null
147
- }
148
-
149
- export function getVerifyEvidenceStatus(cwd, { now = Date.now(), ...options } = {}) {
150
- const commands = detectCommands(cwd)
151
- if (!commands.length) {
152
- return {
153
- required: false,
154
- status: 'not-applicable',
155
- commands,
156
- }
157
- }
158
-
159
- const evidence = readVerifyEvidence(cwd, options)
160
- const missingError = validateVerifyEvidencePresence(commands, evidence)
161
- if (missingError) return missingError
162
-
163
- const freshnessError = validateVerifyEvidenceFreshness(cwd, commands, evidence, now)
164
- if (freshnessError) return freshnessError
165
-
166
- const fingerprintError = validateVerifyFingerprint(cwd, commands, evidence)
167
- if (fingerprintError) return fingerprintError
168
-
169
- return {
170
- required: true,
171
- status: 'valid',
172
- commands,
173
- evidence,
174
- }
175
- }
@@ -1,71 +0,0 @@
1
- ---
2
- name: ~global
3
- description: 初始化项目级全局模式(~global 命令)
4
- policy:
5
- allow_implicit_invocation: false
6
- ---
7
- Trigger: ~global
8
-
9
- `~global` 是用户显式命令,用来初始化项目级全局模式。
10
-
11
- `~global` 不受 `kb_create_mode` 限制。
12
- 执行 `~global` 时,`.helloagents/` 目录结构、模板格式和状态文件规则按当前已加载的 HelloAGENTS 规则执行;本命令额外负责项目级规则文件和各宿主项目级 HelloAGENTS 包根链接。
13
- `.helloagents/` 在本 skill 中统一按项目级存储路径理解:项目本地 `.helloagents/` 继续承担项目本地存储目录;状态文件只使用 `state_path`;若 `project_store_mode=repo-shared`,知识库、`DESIGN.md` 与方案包按当前上下文中已注入的项目知识/方案目录写入。
14
-
15
- ## 流程
16
-
17
- ### 阶段 1:环境搭建(必做)
18
-
19
- 1. 创建 `.helloagents/` 目录 + `state_path`(按 templates/STATE.md 格式,初始“主线目标”写当前初始化任务,初始状态为空闲)
20
- 2. 定位插件根目录:优先读取当前上下文中已注入的“当前 HelloAGENTS 包根目录”;若上下文未提供,再根据当前已加载的 HelloAGENTS 规则来源反推,禁止猜测其他目录
21
- 3. 刷新各宿主项目级 HelloAGENTS 包根链接(删除旧的重建):
22
- - `.claude/skills/helloagents` symlink → `{插件根目录}/`
23
- - `.gemini/skills/helloagents` symlink → `{插件根目录}/`
24
- - `.codex/skills/helloagents` symlink → `{插件根目录}/`
25
- 这些链接用于项目级规则定位 HelloAGENTS 的 `skills/`、`templates/` 和 `scripts/`;宿主若支持递归发现 `SKILL.md`,也可直接识别包内 skills。
26
- 4. 读取 `{插件根目录}` 中的全量规则模板,在受管内容第一行写入 `<!-- HELLOAGENTS_PROFILE: full -->`,再用 `<!-- HELLOAGENTS_START -->` / `<!-- HELLOAGENTS_END -->` 标记包裹后写入:
27
- - `AGENTS.md`(项目根目录,Codex 读取)
28
- - `CLAUDE.md`(项目根目录,Claude Code 读取)
29
- - `.gemini/GEMINI.md`(Gemini CLI 读取,需先创建 .gemini/ 目录)
30
- 注意:如果文件已存在且包含标记,替换标记内的内容;如果文件已存在但无标记,追加到末尾;如果文件不存在,创建新文件
31
- 5. 追加 `.gitignore`(如果对应行不存在):
32
- ```
33
- .helloagents/
34
- .claude/skills/helloagents
35
- .gemini/skills/helloagents
36
- .codex/skills/helloagents
37
- AGENTS.md
38
- CLAUDE.md
39
- .gemini/GEMINI.md
40
- ```
41
-
42
- ### 阶段 2:知识库创建(条件性)
43
-
44
- 检查项目是否有实际代码文件(非空项目):
45
- - 有代码文件 → 执行完整知识库创建(下方流程)
46
- - 空项目 → 跳过,告知用户"项目为空,知识库将在后续开发中创建"
47
-
48
- 知识库创建流程(与原 ~global 一致;逻辑写入 `.helloagents/`,`project_store_mode=repo-shared` 时实际落在共享知识目录):
49
- 1. 按 templates/ 目录的模板格式,分析项目代码库后生成:
50
- - context.md — 按 templates/context.md 格式,填入项目概述、技术栈、架构、目录结构、模块链接
51
- - guidelines.md — 按 templates/guidelines.md 格式,从现有代码推断编码约定
52
- - verify.yaml — 验证命令(从 package.json/pyproject.toml 检测)
53
- - CHANGELOG.md — 按 templates/CHANGELOG.md 格式,初始版本
54
- - DESIGN.md — 如果项目包含 UI 代码,按 templates/DESIGN.md 格式提取项目级设计契约(产品表面、设计 token、组件与模式、状态覆盖、无障碍要求、禁止事项等)
55
- 2. 创建 modules/ 目录,按 templates/modules/module.md 格式为主要模块生成文档
56
- 3. 不覆盖已存在的文件
57
-
58
- ## verify.yaml 格式
59
- ```yaml
60
- commands:
61
- - npm run lint
62
- - npm run test
63
- ```
64
-
65
- ## 幂等性
66
- 重复执行 ~global 是安全的:
67
- - 已存在的 .helloagents/ 文件不覆盖
68
- - `state_path` 只记录当前初始化任务;后续进入其他任务时必须按新任务重写
69
- - 各宿主项目级 HelloAGENTS 包根链接会刷新(删除旧的重建)
70
- - AGENTS.md/CLAUDE.md/GEMINI.md 中标记内容替换更新
71
- - .gitignore 只追加缺失行
@@ -1,46 +0,0 @@
1
- ---
2
- name: ~verify
3
- description: 验证总入口 — 审查、lint、typecheck、test、build 与修复循环(~verify 命令)
4
- policy:
5
- allow_implicit_invocation: false
6
- ---
7
- Trigger: ~verify [scope]
8
-
9
- ## 流程
10
-
11
- 0. 先对齐当前工作流状态:
12
- - 若当前上下文中已注入“当前工作流约束”或“当前推荐下一命令”,先服从它
13
- - 即使命令通过,也不能越过当前方案包边界:不完整方案包不能视为可信交付记录,未闭合方案包不能被整体报告为已完成
14
- - 当推荐路径已进入 `~verify` / 收尾时,优先把本命令用于审查、验真和交付收尾
15
- - 若当前存在活跃方案包,先读取 `requirements.md`、`plan.md`、`tasks.md`、`contract.json`,把它们当作当前验证契约;不要只看命令结果
16
- - 若当前运行在 Codex active goal 下,按 active goal 关联方案包和 `state_path` 复核范围;`/goal` 只负责续跑,不改变验证契约
17
- - 若 `contract.json` 声明 `advisor.required=true` 或 `ui.styleAdvisor.required=true`,则本次验证还必须补齐当前会话 `artifacts/advisor.json`;advisor / style advisor 都是可选能力,不是默认常驻步骤
18
- - 若 `contract.json` 声明 `ui.visualValidation.required=true`,则本次验证还必须补齐当前会话 `artifacts/visual.json`;视觉验收优先用截图/浏览器工具,没有工具时才降级为结构化代码级自检
19
- 1. 先决定验证分流:
20
- - 若当前上下文中已注入“验证分流”,先按该分流执行
21
- - 用户显式使用 `~review` 时,即使当前没有注入分流,也按审查优先起步
22
- - 若没有注入分流、也不是 `~review`,默认先做全量验证;执行中一旦发现高风险流程、关键权限/配置/迁移/发布边界或明显未覆盖的风险点,立即补做 `hello-review`
23
- 2. 审查优先模式:
24
- - 获取变更范围:无参数默认未提交变更;`staged` 代表暂存区;指定文件/目录则只审查对应范围
25
- - 按 hello-* 技能查找路径读取 `hello-review` SKILL.md,执行逐文件审查
26
- - 高风险流程除显式范围外,还要主动补查相关配置、迁移、权限、部署或安全边界文件,不能只盯住单个功能文件
27
- - 审查结论确定后,立即调用 `scripts/review-state.mjs write` 写当前会话 `artifacts/review.json`;用结构化字段记录 `outcome`、`conclusion`、`findings`、`fileReferences`,不要让后续检查脚本再从自然语言消息里猜结论
28
- 3. 全量验证模式或审查后继续验证:
29
- - 读取 `hello-verify` SKILL.md
30
- - 按其“验证命令来源”优先级检测命令
31
- - 逐个运行所有检测到的命令
32
- - 收集每个命令的输出和退出码
33
- - 对照当前契约逐项核对:requirements 是否覆盖、tasks 中每项“完成标准”是否满足、`plan.md` 中风险与设计约束是否被验证、`contract.json` 中声明的 `verifyMode` / reviewer / tester 关注边界是否已被覆盖
34
- - 若 Codex active goal 存在,还要确认 `tasks.md` 的 AFK/HITL 边界:仍有可执行 AFK 项时,不进入 complete;只在目标、任务、验证和收尾都闭合后标记 goal complete
35
- - 若 `advisor.required=true` 或 `ui.styleAdvisor.required=true`,在进入收尾前调用 `scripts/advisor-state.mjs write` 写当前会话 `artifacts/advisor.json`;记录触发原因、focus、consultedSources、结论与建议,禁止只在自然语言里留一段 advisor 意见
36
- - 若 `ui.visualValidation.required=true`,在进入收尾前调用 `scripts/visual-state.mjs write` 写当前会话 `artifacts/visual.json`;记录 `reason`、`tooling`、`screensChecked`、`statesChecked`、`status`、`summary`、`findings` 与 `recommendations`
37
- 4. 汇总报告:
38
- - ✅ 通过的审查项 / 命令
39
- - ❌ 失败的审查项 / 命令 + 错误详情
40
- - 合同核对结论:哪些需求 / 任务完成标准已满足,哪些仍未满足
41
- - 修复建议
42
- - 高风险流程额外说明:不能把“命令通过”直接等同于“风险已解除”;若仍存在未验证的风险边界、待授权操作或不可逆步骤,必须明确列出并停下
43
-
44
- ## 失败处理
45
- - 有失败 → 逐个修复,修复后重新运行对应审查或验证
46
- - 全部通过 → 按当前已加载的 HelloAGENTS 规则进入 CONSOLIDATE 收尾;若 Codex active goal 的目标也已满足,再标记 goal complete,并按交付边界报告完成
@@ -1,57 +0,0 @@
1
- ---
2
- name: ~wiki
3
- description: 初始化或同步项目知识库(与 ~init 同义)
4
- policy:
5
- allow_implicit_invocation: false
6
- ---
7
- Trigger: ~wiki
8
-
9
- `~wiki` 是用户显式命令,仅创建、补全或同步项目知识库。
10
-
11
- `~wiki` 是显式知识库命令,不受 `kb_create_mode` 限制。
12
- 执行 `~wiki` 时,`.helloagents/` 目录结构、模板格式和状态文件重写规则按当前已加载的 HelloAGENTS 规则执行;不写入项目级规则文件,也不创建项目级 HelloAGENTS 包根链接。
13
- `.helloagents/` 在本 skill 中统一按项目级存储路径理解:状态文件只使用 `state_path`;若 `project_store_mode=repo-shared`,`context.md`、`guidelines.md`、`verify.yaml`、`CHANGELOG.md`、`DESIGN.md`、`modules/` 改按当前上下文中已注入的项目知识目录写入。
14
-
15
- ## 流程
16
-
17
- ### 阶段 1:基础准备(必做)
18
-
19
- 1. 创建 `.helloagents/` 目录 + `state_path`(按 templates/STATE.md 格式);初始“主线目标”只写当前知识库初始化 / 同步目标,不把它写成长期项目总目标
20
- 2. 追加 `.gitignore`(如果对应行不存在):
21
- ```
22
- .helloagents/
23
- ```
24
- 3. 明确不执行以下操作:
25
- - 不创建或更新项目级规则文件(`AGENTS.md`、`CLAUDE.md`、`.gemini/GEMINI.md`)
26
- - 不创建项目级 HelloAGENTS 包根链接
27
-
28
- ### 阶段 2:知识库创建或补全(条件性)
29
-
30
- 检查项目是否有实际代码文件(非空项目):
31
- - 有代码文件 → 执行完整知识库创建/补全(下方流程)
32
- - 空项目 → 保留 `.helloagents/` 和 `state_path`,告知用户“项目为空,其余知识文件将在后续开发或首次编码任务中补全”
33
-
34
- 知识库创建/补全流程(统一写入 `.helloagents/` 对应的项目级存储路径;`project_store_mode=repo-shared` 时实际落在共享知识目录):
35
- 1. 按 templates/ 目录的模板格式,分析项目代码库后创建或补全:
36
- - context.md — 按 templates/context.md 格式,填入项目概述、技术栈、架构、目录结构、模块链接
37
- - guidelines.md — 按 templates/guidelines.md 格式,从现有代码推断编码约定
38
- - verify.yaml — 验证命令(从 package.json/pyproject.toml 检测)
39
- - CHANGELOG.md — 按 templates/CHANGELOG.md 格式创建或更新
40
- - DESIGN.md — 如果项目包含 UI 代码,按 templates/DESIGN.md 格式提取或补全项目级设计契约(产品表面、设计 token、组件与模式、状态覆盖、无障碍要求、禁止事项等)
41
- 2. 创建或补全 modules/ 目录,按 templates/modules/module.md 格式为主要模块生成文档
42
- 3. 已存在的文件按模板格式增量更新,不自由改写结构;无新增信息时保持原样
43
-
44
- ## verify.yaml 格式
45
- ```yaml
46
- commands:
47
- - npm run lint
48
- - npm run test
49
- ```
50
-
51
- ## 幂等性
52
- 重复执行 `~wiki` 是安全的:
53
- - `.helloagents/` 缺失时创建,已存在时复用
54
- - `state_path` 按当前任务状态重写,不追加历史;它只记录当前知识库任务,不承担项目的长期记忆
55
- - 知识库文件缺失时补全,已存在时按模板增量更新
56
- - `.gitignore` 只追加缺失行
57
- - 永不写入项目级规则文件,也不创建任何项目级 HelloAGENTS 包根链接
@@ -1,42 +0,0 @@
1
- ---
2
- name: hello-review
3
- description: 审查代码变更、检查 PR、review 代码质量,或用户要求看看代码、检查代码时使用。
4
- ---
5
-
6
- 代码审查必须遵循以下规范。
7
-
8
- ## 审查维度
9
-
10
- 逐文件检查以下维度:
11
- - 逻辑正确性:Bug、边界条件、空值处理、竞态条件
12
- - 安全漏洞:注入、XSS、硬编码密钥、权限绕过
13
- - 性能问题:N+1 查询、内存泄漏、不必要的重渲染、大循环
14
- - 可维护性:命名清晰、职责单一、重复代码、过度抽象
15
- - 错误处理:异常是否被正确捕获和处理
16
-
17
- ## 严重度分类
18
-
19
- - 🔴 严重:必须修复(Bug、安全漏洞、数据丢失风险)
20
- - 🟡 建议:应该修复(性能问题、可维护性、代码风格)
21
- - 🟢 良好:值得肯定的好实践
22
-
23
- ## 审查原则
24
-
25
- - 指出问题时给出具体修复建议和代码示例
26
- - 不只挑毛病,也肯定好的实践
27
- - 关注变更本身,不扩大审查范围到未修改的代码
28
- - 严重问题优先,建议性问题其次
29
-
30
- ## 输出要求
31
-
32
- - 审查结束时必须单独给出一行“审查结论:...”
33
- - 若发现阻塞问题,结论中明确写出存在问题,并在正文中为每个问题附文件定位
34
- - 若未发现阻塞问题,明确写“审查结论:未发现阻塞问题。”
35
- - 若当前项目已初始化,或当前审查结果需要进入后续交付检查或收尾,审查结论确定后立即调用 `scripts/review-state.mjs write` 写当前会话 `artifacts/review.json`
36
- - `artifacts/review.json` 必须使用结构化字段记录:`outcome`(`clean` / `findings`)、`conclusion`、`findings`、`fileReferences`
37
- - 不要依赖“审查结论:...”这行让运行时再从自然语言里猜机器结论;这行只服务于人类阅读
38
-
39
- ## 交付检查
40
- - [ ] 每个文件都已审查
41
- - [ ] 严重问题都有修复建议
42
- - [ ] 按严重度分类输出