helloagents 3.0.30 → 3.0.32

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 (42) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +7 -19
  4. package/README_CN.md +8 -20
  5. package/bootstrap-lite.md +18 -18
  6. package/bootstrap.md +18 -18
  7. package/gemini-extension.json +1 -1
  8. package/install.ps1 +3 -3
  9. package/install.sh +3 -3
  10. package/package.json +1 -1
  11. package/scripts/advisor-state.mjs +1 -1
  12. package/scripts/cli-config.mjs +8 -0
  13. package/scripts/cli-doctor.mjs +2 -76
  14. package/scripts/cli-host-detect.mjs +0 -29
  15. package/scripts/cli-hosts.mjs +0 -8
  16. package/scripts/cli-lifecycle-hosts.mjs +1 -22
  17. package/scripts/cli-lifecycle.mjs +17 -3
  18. package/scripts/cli-messages.mjs +12 -24
  19. package/scripts/guard.mjs +1 -1
  20. package/scripts/notify-context.mjs +7 -2
  21. package/scripts/notify-events.mjs +0 -5
  22. package/scripts/notify-route.mjs +1 -1
  23. package/scripts/notify-source.mjs +0 -1
  24. package/scripts/plan-contract.mjs +1 -1
  25. package/scripts/ralph-loop.mjs +35 -0
  26. package/scripts/runtime-scope.mjs +1 -1
  27. package/scripts/turn-stop-gate.mjs +5 -5
  28. package/skills/commands/auto/SKILL.md +2 -2
  29. package/skills/commands/build/SKILL.md +3 -3
  30. package/skills/commands/global/SKILL.md +1 -1
  31. package/skills/commands/help/SKILL.md +11 -11
  32. package/skills/commands/loop/SKILL.md +1 -1
  33. package/skills/commands/plan/SKILL.md +1 -1
  34. package/skills/commands/prd/SKILL.md +1 -1
  35. package/skills/commands/test/SKILL.md +1 -1
  36. package/skills/commands/verify/SKILL.md +5 -5
  37. package/skills/hello-review/SKILL.md +1 -1
  38. package/skills/hello-subagent/SKILL.md +2 -2
  39. package/skills/hello-ui/SKILL.md +1 -1
  40. package/skills/hello-verify/SKILL.md +7 -7
  41. package/skills/helloagents/SKILL.md +7 -7
  42. package/scripts/cli-deepseek.mjs +0 -131
@@ -3,10 +3,9 @@ import { join } from 'node:path'
3
3
 
4
4
  import { DEFAULTS } from './cli-config.mjs'
5
5
  import { inspectCodexDoctor as inspectCodexDoctorImpl } from './cli-doctor-codex.mjs'
6
- import { inspectNativeDeepseekDoctor } from './cli-deepseek.mjs'
7
6
  import { printDoctorText } from './cli-doctor-render.mjs'
8
7
  import { buildRuntimeCarrier } from './cli-runtime-carrier.mjs'
9
- import { FULL_CARRIER_PROFILE_MARKER, loadHooksWithCliEntry, safeJson, safeRead } from './cli-utils.mjs'
8
+ import { loadHooksWithCliEntry, safeJson, safeRead } from './cli-utils.mjs'
10
9
 
11
10
  const runtime = {
12
11
  home: '',
@@ -219,78 +218,6 @@ function inspectGeminiDoctor(settings) {
219
218
  return { host, label: runtime.getHostLabel(host), trackedMode, detectedMode, status, checks, issues, notes, suggestedFix: suggestDoctorFix(host, status, trackedMode) }
220
219
  }
221
220
 
222
- function inspectDeepseekDoctor(settings) {
223
- const host = 'deepseek'
224
- const trackedMode = normalizeDoctorMode(runtime.getTrackedHostMode(settings, host))
225
- const detectedMode = normalizeDoctorMode(runtime.detectHostMode(host))
226
- const deepseekDir = join(runtime.home, '.deepseek')
227
- const carrierPath = join(deepseekDir, 'AGENTS.md')
228
- const expectedCarrierFile = (detectedMode === 'global' || (detectedMode === 'none' && trackedMode === 'global'))
229
- ? 'bootstrap.md'
230
- : 'bootstrap-lite.md'
231
- const checks = {
232
- carrierMarker: (safeRead(carrierPath) || '').includes('HELLOAGENTS_START'),
233
- carrierContentMatch: extractManagedCarrierContent(carrierPath)
234
- === readExpectedCarrierContent(
235
- expectedCarrierFile,
236
- settings,
237
- expectedCarrierFile === 'bootstrap.md' ? { profile: 'full' } : {},
238
- ),
239
- homeLink: safeRealTarget(join(deepseekDir, 'helloagents')) === runtime.pkgRoot,
240
- fullProfile: (safeRead(carrierPath) || '').includes(FULL_CARRIER_PROFILE_MARKER),
241
- }
242
- const nativeDoctor = inspectNativeDeepseekDoctor()
243
- const issues = []
244
- const notes = []
245
-
246
- if (trackedMode !== 'none' && detectedMode !== 'none' && trackedMode !== detectedMode) {
247
- issues.push(buildDoctorIssue('tracked-mode-mismatch', '记录模式与检测模式不一致', 'Tracked mode does not match detected mode'))
248
- }
249
- if (detectedMode === 'standby') {
250
- if (!checks.carrierMarker) issues.push(buildDoctorIssue('standby-carrier-missing', 'standby `~/.deepseek/AGENTS.md` 缺少 HelloAGENTS 标记', 'Standby `~/.deepseek/AGENTS.md` is missing the HELLOAGENTS marker'))
251
- if (checks.carrierMarker && !checks.carrierContentMatch) issues.push(buildDoctorIssue('standby-carrier-drift', 'standby `~/.deepseek/AGENTS.md` 与当前标准模式规则不一致', 'Standby `~/.deepseek/AGENTS.md` differs from the current standby rules'))
252
- if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby `~/.deepseek/helloagents` 链接缺失或未指向稳定运行根目录', 'Standby `~/.deepseek/helloagents` link is missing or points to a different runtime root'))
253
- if (checks.fullProfile) issues.push(buildDoctorIssue('standby-full-profile-residue', 'standby 模式下不应保留 full 标记', 'Standby mode should not keep the full profile marker'))
254
- }
255
- if (detectedMode === 'global') {
256
- if (!checks.carrierMarker) issues.push(buildDoctorIssue('global-carrier-missing', 'global `~/.deepseek/AGENTS.md` 缺少 HelloAGENTS 标记', 'Global `~/.deepseek/AGENTS.md` is missing the HELLOAGENTS marker'))
257
- if (checks.carrierMarker && !checks.carrierContentMatch) issues.push(buildDoctorIssue('global-carrier-drift', 'global `~/.deepseek/AGENTS.md` 与当前全局模式规则不一致', 'Global `~/.deepseek/AGENTS.md` differs from the current global rules'))
258
- if (!checks.homeLink) issues.push(buildDoctorIssue('global-link-missing', 'global `~/.deepseek/helloagents` 链接缺失或未指向稳定运行根目录', 'Global `~/.deepseek/helloagents` link is missing or points to a different runtime root'))
259
- if (!checks.fullProfile) issues.push(buildDoctorIssue('global-full-profile-missing', 'global 模式缺少 full 标记', 'Global mode is missing the full profile marker'))
260
- }
261
- if (trackedMode === 'none' && detectedMode !== 'none') {
262
- issues.push(buildDoctorIssue('untracked-managed-state', '检测到受管状态,但配置中未记录该 CLI 模式', 'Managed state detected but this CLI mode is not tracked in config'))
263
- }
264
- if (trackedMode !== 'none' && detectedMode === 'none') {
265
- issues.push(buildDoctorIssue('tracked-state-missing', '配置记录该 CLI 已安装,但未检测到对应的受管文件或配置', 'Config says this CLI is installed, but no managed artifacts were detected'))
266
- }
267
- if (!nativeDoctor.available) {
268
- notes.push(runtime.msg(
269
- '未找到 deepseek 命令;已跳过 DeepSeek 原生 doctor。',
270
- 'The deepseek command was not found; DeepSeek native doctor was skipped.',
271
- ))
272
- } else if (!nativeDoctor.ok) {
273
- issues.push(buildDoctorIssue('native-doctor-failed', 'DeepSeek 原生 doctor 返回非零状态', 'DeepSeek native doctor returned a non-zero status'))
274
- }
275
- if (nativeDoctor.available && nativeDoctor.parseError) {
276
- issues.push(buildDoctorIssue('native-doctor-invalid-json', 'DeepSeek 原生 doctor 输出不是可解析的 JSON', 'DeepSeek native doctor output was not valid JSON'))
277
- }
278
-
279
- const status = summarizeDoctorStatus(issues, { host, trackedMode, detectedMode })
280
- return {
281
- host,
282
- label: runtime.getHostLabel(host),
283
- trackedMode,
284
- detectedMode,
285
- status,
286
- checks,
287
- issues,
288
- notes,
289
- nativeDoctor,
290
- suggestedFix: suggestDoctorFix(host, status, trackedMode),
291
- }
292
- }
293
-
294
221
  function parseDoctorArgs(args) {
295
222
  const wantsJson = args.includes('--json')
296
223
  const unknownFlags = args.filter((arg) => arg.startsWith('--') && arg !== '--json' && arg !== '--all')
@@ -311,13 +238,12 @@ function parseDoctorArgs(args) {
311
238
  function inspectDoctorHost(host, settings) {
312
239
  if (host === 'claude') return inspectClaudeDoctor(settings)
313
240
  if (host === 'gemini') return inspectGeminiDoctor(settings)
314
- if (host === 'deepseek') return inspectDeepseekDoctor(settings)
315
241
  return inspectCodexDoctorImpl(runtime, settings)
316
242
  }
317
243
 
318
244
  function buildDoctorReport(host) {
319
245
  const settings = runtime.readSettings(true)
320
- const hosts = host === 'all' ? ['claude', 'gemini', 'codex', 'deepseek'] : [host]
246
+ const hosts = host === 'all' ? ['claude', 'gemini', 'codex'] : [host]
321
247
  const reports = hosts.map((target) => inspectDoctorHost(target, settings))
322
248
  const summary = reports.reduce((acc, report) => {
323
249
  acc[report.status] = (acc[report.status] || 0) + 1
@@ -7,7 +7,6 @@ import {
7
7
  CODEX_PLUGIN_NAME,
8
8
  } from './cli-codex.mjs'
9
9
  import { getStableRuntimeRoot } from './cli-runtime-root.mjs'
10
- import { FULL_CARRIER_PROFILE_MARKER } from './cli-utils.mjs'
11
10
  import { safeJson, safeRead } from './cli-utils.mjs'
12
11
 
13
12
  const HOST_ALIASES = new Map([
@@ -19,8 +18,6 @@ const HOST_ALIASES = new Map([
19
18
  ['gemini-cli', 'gemini'],
20
19
  ['codex', 'codex'],
21
20
  ['codex-cli', 'codex'],
22
- ['deepseek', 'deepseek'],
23
- ['deepseek-tui', 'deepseek'],
24
21
  ])
25
22
 
26
23
  function hasHelloagentsMarker(filePath) {
@@ -31,10 +28,6 @@ function hasHelloagentsSettings(filePath) {
31
28
  return JSON.stringify(safeJson(filePath) || {}).includes('helloagents')
32
29
  }
33
30
 
34
- function hasFullCarrierProfile(filePath) {
35
- return (safeRead(filePath) || '').includes(FULL_CARRIER_PROFILE_MARKER)
36
- }
37
-
38
31
  function normalizePath(value = '') {
39
32
  return String(value || '').replace(/\\/g, '/').toLowerCase()
40
33
  }
@@ -97,26 +90,6 @@ function detectCodexMode(home) {
97
90
  return ''
98
91
  }
99
92
 
100
- function detectDeepseekMode(home) {
101
- const deepseekDir = join(home, '.deepseek')
102
- const carrierPath = join(deepseekDir, 'AGENTS.md')
103
- const runtimeRoot = normalizePath(getStableRuntimeRoot(home))
104
- const homeLinkTarget = safeRealTarget(join(deepseekDir, 'helloagents'))
105
- if (
106
- (hasHelloagentsMarker(carrierPath) || (existsSync(join(deepseekDir, 'helloagents')) && homeLinkTarget === runtimeRoot))
107
- && hasFullCarrierProfile(carrierPath)
108
- ) {
109
- return 'global'
110
- }
111
- if (
112
- (existsSync(join(deepseekDir, 'helloagents')) && homeLinkTarget === runtimeRoot)
113
- || hasHelloagentsMarker(carrierPath)
114
- ) {
115
- return 'standby'
116
- }
117
- return ''
118
- }
119
-
120
93
  export function normalizeHost(value = '') {
121
94
  return HOST_ALIASES.get(String(value || '').toLowerCase()) || ''
122
95
  }
@@ -125,7 +98,6 @@ export function getHostLabel(host) {
125
98
  if (host === 'claude') return 'Claude Code'
126
99
  if (host === 'gemini') return 'Gemini CLI'
127
100
  if (host === 'codex') return 'Codex CLI'
128
- if (host === 'deepseek') return 'DeepSeek TUI'
129
101
  return 'All CLIs'
130
102
  }
131
103
 
@@ -133,6 +105,5 @@ export function detectHostMode(host, runtime) {
133
105
  if (host === 'claude') return detectClaudeMode(runtime.home)
134
106
  if (host === 'gemini') return detectGeminiMode(runtime.home)
135
107
  if (host === 'codex') return detectCodexMode(runtime.home)
136
- if (host === 'deepseek') return detectDeepseekMode(runtime.home)
137
108
  return ''
138
109
  }
@@ -12,7 +12,6 @@ import {
12
12
  loadHooksWithCliEntry,
13
13
  } from './cli-utils.mjs';
14
14
  import { buildRuntimeCarrier, readCarrierSettings } from './cli-runtime-carrier.mjs';
15
- import { installDeepseekGlobal, installDeepseekStandby, uninstallDeepseekGlobal, uninstallDeepseekStandby } from './cli-deepseek.mjs'
16
15
 
17
16
  export function installClaudeStandby(home, pkgRoot) {
18
17
  const claudeDir = join(home, '.claude');
@@ -82,10 +81,3 @@ export function uninstallGeminiStandby(home) {
82
81
 
83
82
  return true;
84
83
  }
85
-
86
- export {
87
- installDeepseekGlobal,
88
- installDeepseekStandby,
89
- uninstallDeepseekGlobal,
90
- uninstallDeepseekStandby,
91
- }
@@ -2,12 +2,8 @@ import { spawnSync } from 'node:child_process'
2
2
 
3
3
  import {
4
4
  installClaudeStandby,
5
- installDeepseekGlobal,
6
- installDeepseekStandby,
7
5
  installGeminiStandby,
8
6
  uninstallClaudeStandby,
9
- uninstallDeepseekGlobal,
10
- uninstallDeepseekStandby,
11
7
  uninstallGeminiStandby,
12
8
  } from './cli-hosts.mjs'
13
9
  import {
@@ -100,10 +96,6 @@ function installHostStandby(runtime, host) {
100
96
  installGeminiStandby(runtime.home, runtime.pkgRoot)
101
97
  return {}
102
98
  }
103
- if (host === 'deepseek') {
104
- installDeepseekStandby(runtime.home, runtime.pkgRoot)
105
- return {}
106
- }
107
99
  if (!installCodexStandby(runtime.home, runtime.pkgRoot)) return { skipped: true }
108
100
  cleanupCodexGlobalResidueForStandby(runtime.home)
109
101
  return {}
@@ -130,10 +122,6 @@ function installHostGlobal(runtime, host) {
130
122
  'Gemini CLI extension auto-install failed. Run manually: gemini extensions install https://github.com/hellowind777/helloagents',
131
123
  )
132
124
  }
133
- if (host === 'deepseek') {
134
- installDeepseekGlobal(runtime.home, runtime.pkgRoot)
135
- return {}
136
- }
137
125
  uninstallCodexStandby(runtime.home)
138
126
  return installCodexGlobal(runtime.home, runtime.pkgRoot) ? {} : { skipped: true }
139
127
  }
@@ -141,7 +129,6 @@ function installHostGlobal(runtime, host) {
141
129
  function cleanupHostStandby(runtime, host) {
142
130
  if (host === 'claude') return { skipped: !uninstallClaudeStandby(runtime.home) }
143
131
  if (host === 'gemini') return { skipped: !uninstallGeminiStandby(runtime.home) }
144
- if (host === 'deepseek') return { skipped: !uninstallDeepseekStandby(runtime.home) }
145
132
  const standbyCleaned = uninstallCodexStandby(runtime.home)
146
133
  const globalResidueCleaned = uninstallCodexGlobal(runtime.home)
147
134
  return { skipped: !(standbyCleaned || globalResidueCleaned) }
@@ -168,7 +155,6 @@ function cleanupHostGlobal(runtime, host) {
168
155
  'Gemini CLI extension auto-remove failed. Run manually: gemini extensions uninstall helloagents',
169
156
  )
170
157
  }
171
- if (host === 'deepseek') return { skipped: !uninstallDeepseekGlobal(runtime.home) }
172
158
  return { skipped: !uninstallCodexGlobal(runtime.home) }
173
159
  }
174
160
 
@@ -194,18 +180,12 @@ function installStandby(runtime) {
194
180
  console.log(runtime.msg(' - Codex CLI 未检测到,跳过', ' - Codex CLI not detected, skipped'))
195
181
  results.codex = { skipped: true }
196
182
  }
197
- if (installDeepseekStandby(runtime.home, runtime.pkgRoot)) {
198
- runtime.ok(runtime.msg('DeepSeek TUI 已配置(standby 模式)', 'DeepSeek TUI configured (standby mode)'))
199
- results.deepseek = {}
200
- } else {
201
- results.deepseek = { skipped: true }
202
- }
203
183
  return results
204
184
  }
205
185
 
206
186
  function installGlobal(runtime) {
207
187
  const results = {}
208
- for (const host of ['claude', 'gemini', 'codex', 'deepseek']) {
188
+ for (const host of ['claude', 'gemini', 'codex']) {
209
189
  const result = installHostGlobal(runtime, host)
210
190
  reportHostAction(runtime, 'install', host, 'global', result)
211
191
  results[host] = result
@@ -223,7 +203,6 @@ export function uninstallAllHosts(runtime) {
223
203
  cleanupHostGlobal(runtime, 'gemini')
224
204
  uninstallCodexStandby(runtime.home)
225
205
  uninstallCodexGlobal(runtime.home)
226
- uninstallDeepseekStandby(runtime.home)
227
206
  }
228
207
 
229
208
  export function runHostLifecycle(runtime, action, host, mode) {
@@ -10,7 +10,7 @@ import {
10
10
  import { installAllHosts, runHostLifecycle, uninstallAllHosts } from './cli-lifecycle-hosts.mjs'
11
11
  import { ensureDir, safeJson, safeWrite } from './cli-utils.mjs'
12
12
 
13
- export const HOSTS = ['claude', 'gemini', 'codex', 'deepseek']
13
+ export const HOSTS = ['claude', 'gemini', 'codex']
14
14
 
15
15
  const runtime = {
16
16
  home: '',
@@ -28,14 +28,28 @@ export function initCliLifecycle(options) {
28
28
  Object.assign(runtime, options)
29
29
  }
30
30
 
31
+ function sanitizeSettings(settings = {}) {
32
+ const next = settings && typeof settings === 'object' ? { ...settings } : {}
33
+ const tracked = next.host_install_modes
34
+ if (!tracked || typeof tracked !== 'object' || Array.isArray(tracked)) {
35
+ next.host_install_modes = {}
36
+ return next
37
+ }
38
+ next.host_install_modes = Object.fromEntries(
39
+ Object.entries(tracked).filter(([host, mode]) => HOSTS.includes(host) && typeof mode === 'string' && mode),
40
+ )
41
+ return next
42
+ }
43
+
31
44
  export function readSettings(shouldEnsure = false) {
32
45
  if (shouldEnsure) ensureConfig(runtime.helloagentsHome, runtime.configFile, safeJson, ensureDir)
33
- return safeJson(runtime.configFile) || {}
46
+ return sanitizeSettings(safeJson(runtime.configFile) || {})
34
47
  }
35
48
 
36
49
  function writeSettings(settings) {
50
+ const sanitized = sanitizeSettings(settings)
37
51
  ensureDir(runtime.helloagentsHome)
38
- writeFileSync(runtime.configFile, JSON.stringify(settings, null, 2), 'utf-8')
52
+ writeFileSync(runtime.configFile, JSON.stringify(sanitized, null, 2), 'utf-8')
39
53
  }
40
54
 
41
55
  function hasTrackedHostModes(settings) {
@@ -19,18 +19,6 @@ function codexGlobalStatus({ home, msg }) {
19
19
  : msg('安装 Codex CLI 后重新运行 npm install -g helloagents', 'Install Codex CLI then re-run npm install -g helloagents')
20
20
  }
21
21
 
22
- function deepseekStandbyStatus({ home, msg }) {
23
- return existsSync(join(home, '.deepseek'))
24
- ? msg('已自动配置(~/.deepseek/AGENTS.md)', 'Auto-configured (~/.deepseek/AGENTS.md)')
25
- : msg('安装 DeepSeek TUI 后重新运行 npm install -g helloagents', 'Install DeepSeek TUI then re-run npm install -g helloagents')
26
- }
27
-
28
- function deepseekGlobalStatus({ home, msg }) {
29
- return existsSync(join(home, '.deepseek'))
30
- ? msg('已自动切到受管全局载体(~/.deepseek/AGENTS.md)', 'Managed global carrier applied (~/.deepseek/AGENTS.md)')
31
- : msg('安装 DeepSeek TUI 后重新运行 npm install -g helloagents', 'Install DeepSeek TUI then re-run npm install -g helloagents')
32
- }
33
-
34
22
  function pluginCommands() {
35
23
  return [
36
24
  ' Claude Code: /plugin marketplace add hellowind777/helloagents',
@@ -61,24 +49,24 @@ function renderInstallMessage(context, mode, state) {
61
49
  if (mode === 'global') {
62
50
  if (install) {
63
51
  return msg(
64
- `\n ✅ HelloAGENTS 已安装(global 模式)!\n\n Claude Code / Gemini CLI: 已自动尝试宿主原生插件/扩展安装\n Codex: ${codexGlobalStatus(context)}(~/.agents/plugins/marketplace.json + ~/plugins/helloagents)\n DeepSeek TUI: ${deepseekGlobalStatus(context)}\n\n ${restartHint(msg)}\n\n 若宿主命令不可用,请手动执行:\n${pluginCommands()}\n\n 切换模式:\n helloagents --standby 标准模式(默认,非插件安装)`,
65
- `\n ✅ HelloAGENTS installed (global mode)!\n\n Claude Code / Gemini CLI: native plugin/extension install attempted automatically\n Codex: ${codexGlobalStatus(context)} (~/.agents/plugins/marketplace.json + ~/plugins/helloagents)\n DeepSeek TUI: ${deepseekGlobalStatus(context)}\n\n ${restartHint(msg)}\n\n If a host command is unavailable, run manually:\n${pluginCommands()}\n\n Switch modes:\n helloagents --standby Standby mode (default, non-plugin install)`,
52
+ `\n ✅ HelloAGENTS 已安装(global 模式)!\n\n Claude Code / Gemini CLI: 已自动尝试宿主原生插件/扩展安装\n Codex: ${codexGlobalStatus(context)}(~/.agents/plugins/marketplace.json + ~/plugins/helloagents)\n\n ${restartHint(msg)}\n\n 若宿主命令不可用,请手动执行:\n${pluginCommands()}\n\n 切换模式:\n helloagents --standby 标准模式(默认,非插件安装)`,
53
+ `\n ✅ HelloAGENTS installed (global mode)!\n\n Claude Code / Gemini CLI: native plugin/extension install attempted automatically\n Codex: ${codexGlobalStatus(context)} (~/.agents/plugins/marketplace.json + ~/plugins/helloagents)\n\n ${restartHint(msg)}\n\n If a host command is unavailable, run manually:\n${pluginCommands()}\n\n Switch modes:\n helloagents --standby Standby mode (default, non-plugin install)`,
66
54
  )
67
55
  }
68
56
  return msg(
69
57
  refresh
70
- ? ` global 模式已刷新。\n Claude Code / Gemini 已自动尝试刷新宿主插件/扩展;Codex 原生本地插件已重装并同步最新文件;DeepSeek TUI 受管全局载体已同步。\n ${restartHint(msg)}`
71
- : ` 所有项目将自动启用完整 HelloAGENTS 规则。\n Claude Code / Gemini 已自动尝试安装宿主插件/扩展;Codex 已自动安装原生本地插件;DeepSeek TUI 已切到受管全局载体。\n ${restartHint(msg)}\n\n若宿主命令不可用,请手动执行:\n${pluginCommands()}`,
58
+ ? ` global 模式已刷新。\n Claude Code / Gemini 已自动尝试刷新宿主插件/扩展;Codex 原生本地插件已重装并同步最新文件。\n ${restartHint(msg)}`
59
+ : ` 所有项目将自动启用完整 HelloAGENTS 规则。\n Claude Code / Gemini 已自动尝试安装宿主插件/扩展;Codex 已自动安装原生本地插件。\n ${restartHint(msg)}\n\n若宿主命令不可用,请手动执行:\n${pluginCommands()}`,
72
60
  refresh
73
- ? ` Global mode refreshed.\n Claude Code / Gemini native plugin/extension refresh was attempted automatically; Codex native local-plugin files were reinstalled and synced; the managed DeepSeek TUI global carrier was refreshed.\n ${restartHint(msg)}`
74
- : ` All projects will use full HelloAGENTS rules.\n Claude Code / Gemini native plugin/extension install was attempted automatically; Codex now uses the native local-plugin path automatically; DeepSeek TUI now uses the managed global carrier.\n ${restartHint(msg)}\n\nIf a host command is unavailable, run manually:\n${pluginCommands()}`,
61
+ ? ` Global mode refreshed.\n Claude Code / Gemini native plugin/extension refresh was attempted automatically; Codex native local-plugin files were reinstalled and synced.\n ${restartHint(msg)}`
62
+ : ` All projects will use full HelloAGENTS rules.\n Claude Code / Gemini native plugin/extension install was attempted automatically; Codex now uses the native local-plugin path automatically.\n ${restartHint(msg)}\n\nIf a host command is unavailable, run manually:\n${pluginCommands()}`,
75
63
  )
76
64
  }
77
65
 
78
66
  if (install) {
79
67
  return msg(
80
- `\n ✅ HelloAGENTS 已安装(standby 模式)!\n\n Claude Code: 已自动配置(~/.claude/CLAUDE.md + hooks)\n Gemini CLI: 已自动配置(~/.gemini/GEMINI.md)\n Codex: ${codexStandbyStatus(context)}\n DeepSeek TUI: ${deepseekStandbyStatus(context)}\n\n ${restartHint(msg)}\n\n standby 模式下,hello-* 技能不会自动触发。\n 在项目中使用 ~wiki 或 ~init 仅创建/同步知识库;用 ~global 初始化项目级全局模式;也可用 ~command 按需调用。\n\n 切换模式:\n helloagents --global 项目级全局模式(自动尝试 Claude/Gemini 插件或扩展;Codex 自动装原生本地插件;DeepSeek 使用受管 AGENTS 载体)`,
81
- `\n ✅ HelloAGENTS installed (standby mode)!\n\n Claude Code: Auto-configured (~/.claude/CLAUDE.md + hooks)\n Gemini CLI: Auto-configured (~/.gemini/GEMINI.md)\n Codex: ${codexStandbyStatus(context)}\n DeepSeek TUI: ${deepseekStandbyStatus(context)}\n\n ${restartHint(msg)}\n\n In standby mode, hello-* skills won't auto-trigger.\n Use ~wiki or ~init to create or sync the KB only; use ~global to initialize project-level global mode; ~command stays available on demand.\n\n Switch modes:\n helloagents --global Project-level global mode (auto-attempts Claude/Gemini plugins or extensions; native local plugin auto-install for Codex; DeepSeek uses a managed AGENTS carrier)`,
68
+ `\n ✅ HelloAGENTS 已安装(standby 模式)!\n\n Claude Code: 已自动配置(~/.claude/CLAUDE.md + hooks)\n Gemini CLI: 已自动配置(~/.gemini/GEMINI.md)\n Codex: ${codexStandbyStatus(context)}\n\n ${restartHint(msg)}\n\n standby 模式下,hello-* 技能不会自动触发。\n 在项目中使用 ~wiki 或 ~init 仅创建/同步知识库;用 ~global 初始化项目级全局模式;也可用 ~command 按需调用。\n\n 切换模式:\n helloagents --global 项目级全局模式(自动尝试 Claude/Gemini 插件或扩展;Codex 自动装原生本地插件)`,
69
+ `\n ✅ HelloAGENTS installed (standby mode)!\n\n Claude Code: Auto-configured (~/.claude/CLAUDE.md + hooks)\n Gemini CLI: Auto-configured (~/.gemini/GEMINI.md)\n Codex: ${codexStandbyStatus(context)}\n\n ${restartHint(msg)}\n\n In standby mode, hello-* skills won't auto-trigger.\n Use ~wiki or ~init to create or sync the KB only; use ~global to initialize project-level global mode; ~command stays available on demand.\n\n Switch modes:\n helloagents --global Project-level global mode (auto-attempts Claude/Gemini plugins or extensions; native local plugin auto-install for Codex)`,
82
70
  )
83
71
  }
84
72
 
@@ -102,17 +90,17 @@ HelloAGENTS v${pkgVersion} — The orchestration kernel for AI CLIs
102
90
  helloagents-js ${msg('(受管宿主配置的跨平台稳定入口)', '(cross-platform stable entrypoint for managed host configs)')}
103
91
 
104
92
  ${msg('模式切换', 'Mode switching')}:
105
- helloagents --global ${msg('项目级全局模式(自动尝试 Claude/Gemini 插件或扩展;Codex 自动装原生本地插件;DeepSeek 使用受管 AGENTS 载体)', 'Project-level global mode (auto-attempts Claude/Gemini plugins or extensions; native local plugin auto-install for Codex; DeepSeek uses a managed AGENTS carrier)')}
93
+ helloagents --global ${msg('项目级全局模式(自动尝试 Claude/Gemini 插件或扩展;Codex 自动装原生本地插件)', 'Project-level global mode (auto-attempts Claude/Gemini plugins or extensions; native local plugin auto-install for Codex)')}
106
94
  helloagents --standby ${msg('标准模式(非插件安装,hello-* 不自动触发,默认)', "Standby mode (non-plugin install, hello-* won't auto-trigger, default)")}
107
95
 
108
96
  ${msg('单 CLI 管理', 'Scoped CLI management')}:
109
97
  helloagents install codex --standby
110
- helloagents install deepseek --standby
98
+ helloagents install gemini --standby
111
99
  helloagents install --all --global
112
100
  helloagents update codex
113
101
  helloagents cleanup claude --global
114
102
  helloagents uninstall gemini
115
- ${msg('支持: claude | gemini | codex | deepseek | --all;省略模式时优先沿用该 CLI 已记录/已检测的模式,否则回退 standby', 'Hosts: claude | gemini | codex | deepseek | --all; omit mode to reuse the tracked/detected mode for that CLI, then fall back to standby')}
103
+ ${msg('支持: claude | gemini | codex | --all;省略模式时优先沿用该 CLI 已记录/已检测的模式,否则回退 standby', 'Hosts: claude | gemini | codex | --all; omit mode to reuse the tracked/detected mode for that CLI, then fall back to standby')}
116
104
 
117
105
  ${msg('分支切换', 'Branch switching')}:
118
106
  helloagents switch-branch beta
@@ -123,7 +111,7 @@ ${msg('分支切换', 'Branch switching')}:
123
111
  ${msg('诊断', 'Diagnostics')}:
124
112
  helloagents doctor
125
113
  helloagents doctor codex --json
126
- ${msg('检查 carrier、链接、hooks、配置注入、Codex 插件安装、DeepSeek 原生 doctor 摘要、受管 model_instructions_file 指向、Codex hook trust 本机状态与版本漂移', 'Checks carriers, links, hooks, config injections, Codex plugin installation, DeepSeek native doctor summaries, managed model_instructions_file targeting, machine-local Codex hook trust state, and version drift')}
114
+ ${msg('检查 carrier、链接、hooks、配置注入、Codex 插件安装、受管 model_instructions_file 指向、Codex hook trust 本机状态与版本漂移', 'Checks carriers, links, hooks, config injections, Codex plugin installation, managed model_instructions_file targeting, machine-local Codex hook trust state, and version drift')}
127
115
 
128
116
  ${msg('Codex /goal', 'Codex /goal')}:
129
117
  helloagents codex goals status
package/scripts/guard.mjs CHANGED
@@ -133,7 +133,7 @@ function buildPostWriteWarnings(data) {
133
133
  const filePath = data.tool_input?.file_path || ''
134
134
  return [
135
135
  ...(detectIdeaBoundaryContext(data)?.zeroSideEffect
136
- ? ['~idea 本轮要求只读探索;检测到写入文件的工具调用,请回到探索输出,或升级到 ~plan / ~build / ~prd / ~auto 后再修改文件']
136
+ ? ['~idea 当前任务要求只读探索;检测到写入文件的工具调用,请回到探索输出,或升级到 ~plan / ~build / ~prd / ~auto 后再修改文件']
137
137
  : []),
138
138
  ...scanUnrequestedFiles(filePath, data.tool_name),
139
139
  ...(content ? [...scanForSecrets(content), ...scanDangerousPackages(content, filePath)] : []),
@@ -34,7 +34,7 @@ function buildReadRootBlock(readRoot) {
34
34
  turnStateCommand: 'helloagents-turn-state write --kind complete --role main',
35
35
  turnStateUsage: '仅在运行时需要识别完成、等待或阻塞时调用;普通问答不调用',
36
36
  };
37
- return `## 本轮 HelloAGENTS 读取根目录\n\`\`\`json\n${JSON.stringify(block, null, 2)}\n\`\`\``;
37
+ return `## 当前对话 HelloAGENTS 读取根目录\n\`\`\`json\n${JSON.stringify(block, null, 2)}\n\`\`\``;
38
38
  }
39
39
 
40
40
  export function resolveCanonicalCommandSkill(skillName) {
@@ -54,6 +54,10 @@ function buildAliasRouteNote(skillName) {
54
54
  return '';
55
55
  }
56
56
 
57
+ function buildDelegatedTaskHint() {
58
+ return '若当前输入明显来自上级代理、控制器或多代理协作上下文,且本次输出会交回上级代理继续汇总、决策或复述,而不是直接交付给最终用户,则按子代理处理:直接完成局部任务并返回结果、证据或阻塞项,不使用 HelloAGENTS 外层输出格式,不写 turn-state,不做面向最终用户的收尾。'
59
+ }
60
+
57
61
  export function buildCompactionContext({ payload, pkgRoot, settings, bootstrapFile, host }) {
58
62
  const summaryParts = [];
59
63
  summaryParts.push('## HelloAGENTS 压缩摘要');
@@ -148,7 +152,7 @@ export function buildRouteInstruction({ skillName, extraRules = '', cwd, pkgRoot
148
152
  const commandHint = buildCommandRouteHint(canonicalSkillName, cwd, workflowOptions);
149
153
  const capabilityHint = buildCapabilityHint({ cwd, skillName: canonicalSkillName, options: workflowOptions });
150
154
  const projectStorageHint = buildProjectStorageHint(cwd, workflowOptions);
151
- return `用户使用了 ~${skillName} 命令。当前命令技能文件已解析为:${skillPath}。请直接读取这个 SKILL.md;不要再探测其他 helloagents 路径。${aliasNote ? ` ${aliasNote}` : ''}${projectStorageHint ? ` ${projectStorageHint}` : ''}${commandHint ? ` ${commandHint}` : ''}${capabilityHint ? ` ${capabilityHint}` : ''}${extraRules}`;
155
+ return `用户使用了 ~${skillName} 命令。当前命令技能文件已解析为:${skillPath}。请直接读取这个 SKILL.md;不要再探测其他 helloagents 路径。 ${buildDelegatedTaskHint()}${aliasNote ? ` ${aliasNote}` : ''}${projectStorageHint ? ` ${projectStorageHint}` : ''}${commandHint ? ` ${commandHint}` : ''}${capabilityHint ? ` ${capabilityHint}` : ''}${extraRules}`;
152
156
  }
153
157
 
154
158
  export function buildSemanticRouteInstruction(cwd, payload = {}) {
@@ -159,6 +163,7 @@ export function buildSemanticRouteInstruction(cwd, payload = {}) {
159
163
  return [
160
164
  '当前消息未使用 ~command。',
161
165
  '请根据用户请求的真实意图选路,不依赖关键词表。',
166
+ buildDelegatedTaskHint(),
162
167
  'Delivery Tier: T0=探索/比较;T1=低风险小改动或显式验证;T2=多文件功能/新项目/需要结构化产物;T3=高风险或不可逆操作。',
163
168
  '路由映射:~idea=只读探索,不创建文件;~build=明确实现;~verify=审查/验证;~plan=结构化规划;~prd=重型规格;~auto=自动选择并继续执行后续阶段。',
164
169
  '若判定为 T3,默认先走 ~plan / ~prd;纯审查/验证请求才优先 ~verify。',
@@ -4,14 +4,9 @@ export function shouldIgnoreCodexNotifyClient(client) {
4
4
  return normalized !== 'codex' && !normalized.startsWith('codex-');
5
5
  }
6
6
 
7
- export function shouldIgnoreFormattedSubagent(lastMsg, outputFormatEnabled) {
8
- return outputFormatEnabled && !lastMsg.includes('【HelloAGENTS】');
9
- }
10
-
11
7
  export function resolveNotifyHost(argv = []) {
12
8
  const args = Array.from(argv, (value) => String(value || ''));
13
9
  const command = args[2] || args[0] || '';
14
- if (args.includes('--deepseek')) return 'deepseek';
15
10
  if (args.includes('--gemini')) return 'gemini';
16
11
  if (args.includes('--codex') || command === 'codex-notify') return 'codex';
17
12
  return 'claude';
@@ -17,7 +17,7 @@ export function resolveBootstrapFile(cwd, settings = {}, host = '') {
17
17
  }
18
18
 
19
19
  function shouldBypassRoute(prompt) {
20
- return !prompt || /^\[子代理任务\]/.test(prompt)
20
+ return !prompt
21
21
  }
22
22
 
23
23
  function buildHelpExtraRules(skillName) {
@@ -6,7 +6,6 @@ const HOST_LABELS = {
6
6
  codex: 'Codex',
7
7
  claude: 'Claude Code',
8
8
  gemini: 'Gemini',
9
- deepseek: 'DeepSeek TUI',
10
9
  }
11
10
 
12
11
  function normalizePath(filePath = '') {
@@ -5,7 +5,7 @@ import { resolveProjectPlanDir } from './project-storage.mjs'
5
5
 
6
6
  export const PLAN_CONTRACT_FILE_NAME = 'contract.json'
7
7
  const VALID_VERIFY_MODES = new Set(['test-first', 'review-first'])
8
- const VALID_ADVISOR_SOURCES = new Set(['claude', 'codex', 'gemini', 'deepseek'])
8
+ const VALID_ADVISOR_SOURCES = new Set(['claude', 'codex', 'gemini'])
9
9
 
10
10
  function normalizeStringArray(values) {
11
11
  if (!Array.isArray(values)) return []
@@ -89,6 +89,30 @@ function runVerify(commands, cwd) {
89
89
  return failures;
90
90
  }
91
91
 
92
+ function getLastAssistantMessage(data = {}) {
93
+ return String(
94
+ data.lastAssistantMessage
95
+ || data.last_assistant_message
96
+ || data['last-assistant-message']
97
+ || '',
98
+ ).trim();
99
+ }
100
+
101
+ function hasHelloagentsWrapper(message = '') {
102
+ if (!message.includes('【HelloAGENTS】')) return false;
103
+ const firstNonEmptyLine = message
104
+ .split(/\r?\n/)
105
+ .map((line) => line.trim())
106
+ .find(Boolean);
107
+ return /^[💡⚡🔵✅❓⚠️❌]【HelloAGENTS】- /.test(firstNonEmptyLine || '') || message.includes('【HelloAGENTS】');
108
+ }
109
+
110
+ function validateSubagentOutput(data = {}) {
111
+ const message = getLastAssistantMessage(data);
112
+ if (!message || !hasHelloagentsWrapper(message)) return '';
113
+ return '[HelloAGENTS Runtime] 子代理输出不应使用 HelloAGENTS 外层格式。当前回复不是直接面向最终用户的终局交付,请改为自然输出,只返回结果、证据或阻塞项。';
114
+ }
115
+
92
116
  /** Filter commands to fast checks only for subagent mode. Returns null if no fast commands found. */
93
117
  function filterSubagentCommands(commands) {
94
118
  const fast = commands.filter(cmd =>
@@ -117,6 +141,17 @@ export function evaluateRalphLoop(data = {}, runtime = {}) {
117
141
  const isSubagent = runtime.isSubagent ?? IS_SUBAGENT;
118
142
  const hookEventName = runtime.hookEventName || HOOK_EVENT;
119
143
 
144
+ if (isSubagent) {
145
+ const formatReason = validateSubagentOutput(data);
146
+ if (formatReason) {
147
+ return {
148
+ decision: 'block',
149
+ reason: formatReason,
150
+ suppressOutput: true,
151
+ };
152
+ }
153
+ }
154
+
120
155
  let commands = detectCommands(cwd);
121
156
  if (!commands?.length) {
122
157
  return { suppressOutput: true };
@@ -146,7 +146,7 @@ export function getProjectRoot(cwd) {
146
146
 
147
147
  function getCarrierPathForRoot(root, host = '') {
148
148
  if (!root) return ''
149
- if (host === 'codex' || host === 'deepseek') return join(root, 'AGENTS.md')
149
+ if (host === 'codex') return join(root, 'AGENTS.md')
150
150
  if (host === 'gemini') return join(root, '.gemini', 'GEMINI.md')
151
151
  return join(root, 'CLAUDE.md')
152
152
  }
@@ -39,7 +39,7 @@ function buildBlockReason(routeContext, detail, cwd) {
39
39
  const commandLabel = `~${routeContext.skillName}`
40
40
  const workflowHint = buildWorkflowHint(cwd)
41
41
  return [
42
- `[HelloAGENTS Runtime] 显式 ${commandLabel} 本轮不应直接停下。`,
42
+ `[HelloAGENTS Runtime] 显式 ${commandLabel} 当前对话不应直接停下。`,
43
43
  detail,
44
44
  workflowHint,
45
45
  '若无真实阻塞,请继续沿当前路径执行。',
@@ -74,7 +74,7 @@ function validateFormattedCloseoutMessage(routeContext, payload, cwd) {
74
74
  if (!firstNonEmptyLine || !/^[💡⚡🔵✅❓⚠️❌]【HelloAGENTS】- /.test(firstNonEmptyLine)) {
75
75
  return buildBlockReason(
76
76
  routeContext,
77
- '最终收尾消息使用了 HelloAGENTS 外层格式,但首个非空行不是规范标题行。',
77
+ '最终回复使用了 HelloAGENTS 外层格式,但首个非空行不是规范标题行。',
78
78
  cwd,
79
79
  )
80
80
  }
@@ -82,7 +82,7 @@ function validateFormattedCloseoutMessage(routeContext, payload, cwd) {
82
82
  if (countMatches(message, /[💡⚡🔵✅❓⚠️❌]【HelloAGENTS】-/g) > 1) {
83
83
  return buildBlockReason(
84
84
  routeContext,
85
- '最终收尾消息重复输出了 HelloAGENTS 标题;请把所有内容合并到同一个外层块内。',
85
+ '最终回复重复输出了 HelloAGENTS 标题;请把所有内容合并到同一个外层块内。',
86
86
  cwd,
87
87
  )
88
88
  }
@@ -90,7 +90,7 @@ function validateFormattedCloseoutMessage(routeContext, payload, cwd) {
90
90
  if (countMatches(message, /^🔄 下一步:/gm) > 1) {
91
91
  return buildBlockReason(
92
92
  routeContext,
93
- '最终收尾消息重复输出了 `🔄 下一步`;请只保留一个真实下一步。',
93
+ '最终回复重复输出了 `🔄 下一步`;请只保留一个真实下一步。',
94
94
  cwd,
95
95
  )
96
96
  }
@@ -140,7 +140,7 @@ function validateTurnState(routeContext, turnState, cwd, payload = {}) {
140
140
  cwd,
141
141
  )
142
142
  }
143
- return buildBlockReason(routeContext, `当前 turn-state 为 \`${turnState.kind}\`,不能作为本轮结束状态。`, cwd)
143
+ return buildBlockReason(routeContext, `当前 turn-state 为 \`${turnState.kind}\`,不能作为当前对话结束状态。`, cwd)
144
144
  }
145
145
 
146
146
  export function evaluateTurnStopGate(payload = {}) {
@@ -15,7 +15,7 @@ Trigger: ~auto <任务描述>
15
15
  - `T3` 高风险或不可逆操作默认不直接进入 `~build`;优先先走 `~plan` 或 `~prd`,纯审查/纯验证请求才可先进入 `~verify`
16
16
  - 主路径一旦确定,立即读取对应 command skill,并在阶段完成后继续执行后续阶段,避免同一任务重复探索或重复等待
17
17
  - 选路不替代授权;涉及外部副作用或高风险不可逆操作时,仍遵守 HelloAGENTS 阻塞判定与确认规则
18
- - 用户显式使用 `~auto`,表示已授权在当前任务边界内沿选定主路径持续执行;若本轮运行在 Codex `/goal` 下,`/goal` 只提供长程续跑与预算,`~auto` 仍按方案包、`state_path` 与验证契约推进;`~plan` / `~prd` 作为中间阶段时,不再额外询问“是否开始执行”,除非仍有真实阻塞;不得把 `🔄 下一步` 当作阶段交接或继续执行占位
18
+ - 用户显式使用 `~auto`,表示已授权在当前任务边界内沿选定主路径持续执行;若当前运行在 Codex `/goal` 下,`/goal` 只提供长程续跑与预算,`~auto` 仍按方案包、`state_path` 与验证契约推进;`~plan` / `~prd` 作为中间阶段时,不再额外询问“是否开始执行”,除非仍有真实阻塞;不得把 `🔄 下一步` 当作阶段交接或继续执行占位
19
19
  - 优先消费当前上下文中已注入的 ROUTE / TIER、当前工作流约束与项目状态;不要在 `~auto` 内另建一套关键词路由表
20
20
 
21
21
  ## 流程
@@ -33,7 +33,7 @@ Trigger: ~auto <任务描述>
33
33
  ### 1. 选路
34
34
 
35
35
  - 先按当前上下文里已注入的 ROUTE / TIER 语义约束判断,不依赖关键词命中做机械分流
36
- - 若本轮没有足够的注入约束,再结合以下信号补足判断:影响范围、风险等级、是否需要结构化产物、是否已有活跃方案包、用户是否只想先比较方向
36
+ - 若当前上下文没有足够的注入约束,再结合以下信号补足判断:影响范围、风险等级、是否需要结构化产物、是否已有活跃方案包、用户是否只想先比较方向
37
37
  - 选路优先级:
38
38
  - 纯探索 / 点子 / 方向比较 → `~idea`
39
39
  - 明确要求验证 / 审查 / 跑检查 → `~verify`
@@ -20,15 +20,15 @@ Trigger: ~build [description]
20
20
 
21
21
  ### 1. 恢复与定位
22
22
 
23
- - 优先按当前已加载的 HelloAGENTS 规则恢复当前任务,并遵循“.helloagents/ 文件读取优先级”;若当前消息明确要继续上次任务、会话刚经历恢复 / 压缩,或本轮运行在 Codex active goal 下,先读取 `state_path`,再用当前用户消息、活跃方案包 / PRD 与代码事实确认当前任务
23
+ - 优先按当前已加载的 HelloAGENTS 规则恢复当前任务,并遵循“.helloagents/ 文件读取优先级”;若当前消息明确要继续上次任务、会话刚经历恢复 / 压缩,或当前运行在 Codex active goal 下,先读取 `state_path`,再用当前用户消息、活跃方案包 / PRD 与代码事实确认当前任务
24
24
  - 若存在最近的活跃方案包,读取对应的:
25
25
  - `requirements.md`
26
26
  - `plan.md`
27
27
  - `tasks.md`
28
28
  - `contract.json`
29
- - 实现时优先把 `tasks.md` 中每个任务的“完成标准”当作本轮实现约束,不要只按任务标题猜测范围
29
+ - 实现时优先把 `tasks.md` 中每个任务的“完成标准”当作本次实现约束,不要只按任务标题猜测范围
30
30
  - `contract.json` 存在时,优先按其中的 `verifyMode`、`reviewerFocus`、`testerFocus` 理解后续验证边界
31
- - 若本轮运行在 Codex active goal 下,按 `tasks.md` 未完成项、`contract.json` 与 `state_path` 恢复实现位置;不要自动创建新 goal,也不要把 goal 目标原文替代方案包
31
+ - 若当前运行在 Codex active goal 下,按 `tasks.md` 未完成项、`contract.json` 与 `state_path` 恢复实现位置;不要自动创建新 goal,也不要把 goal 目标原文替代方案包
32
32
  - 若当前上下文中已注入“当前工作流约束”或“当前推荐下一命令”,先服从它;只有推荐仍为 `~build`,或用户明确提出新增实现范围时,才继续 `~build`
33
33
  - 其余项目知识库与相关代码文件,按 HelloAGENTS 项目上下文要求读取
34
34
  - 若任务涉及 UI,按以下优先级读取并遵循:当前活跃 `plan.md` / PRD 中的 UI 决策 > 逻辑 `.helloagents/DESIGN.md`(实际路径按当前项目存储模式解析) > 已读取的 `hello-ui` 规则;同时所有 UI 任务都必须满足 UI 质量基线