helloagents 3.0.30 → 3.0.31

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 (40) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +5 -18
  4. package/README_CN.md +7 -20
  5. package/bootstrap-lite.md +15 -15
  6. package/bootstrap.md +15 -15
  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 +1 -1
  21. package/scripts/notify-events.mjs +0 -1
  22. package/scripts/notify-source.mjs +0 -1
  23. package/scripts/plan-contract.mjs +1 -1
  24. package/scripts/runtime-scope.mjs +1 -1
  25. package/scripts/turn-stop-gate.mjs +5 -5
  26. package/skills/commands/auto/SKILL.md +2 -2
  27. package/skills/commands/build/SKILL.md +3 -3
  28. package/skills/commands/global/SKILL.md +1 -1
  29. package/skills/commands/help/SKILL.md +11 -11
  30. package/skills/commands/loop/SKILL.md +1 -1
  31. package/skills/commands/plan/SKILL.md +1 -1
  32. package/skills/commands/prd/SKILL.md +1 -1
  33. package/skills/commands/test/SKILL.md +1 -1
  34. package/skills/commands/verify/SKILL.md +5 -5
  35. package/skills/hello-review/SKILL.md +1 -1
  36. package/skills/hello-subagent/SKILL.md +1 -1
  37. package/skills/hello-ui/SKILL.md +1 -1
  38. package/skills/hello-verify/SKILL.md +7 -7
  39. package/skills/helloagents/SKILL.md +6 -6
  40. package/scripts/cli-deepseek.mjs +0 -131
@@ -5,9 +5,9 @@ description: 按任务类型适用 — 建立质量驱动工作流,通过技
5
5
 
6
6
  # HelloAGENTS
7
7
 
8
- 主代理触发或读取任意 skill 时,只有本轮最终收尾消息才按通用输出格式包装;流式内容、进度或状态汇报、中间文本,以及任何仍将继续执行的文本,都保持自然输出。最终收尾中的 `🔄 下一步` 写真实动作,不写当前状态;等待用户授权时使用等待输入态收尾,已获授权且可继续执行时不得收尾。同一条最终收尾消息只包装一次;若需要分段,在同一个外层块内展开,不在正文里再次输出 `【HelloAGENTS】` 或第二个 `🔄 下一步`。
8
+ 主代理触发或读取任意 skill 时,只有当前对话的最终回复才按通用输出格式包装;流式内容、进度或状态汇报、中间文本,以及任何仍将继续执行的文本,都保持自然输出。最终回复中的 `🔄 下一步` 写真实动作,不写当前状态;等待用户授权时使用等待输入态收尾,已获授权且可继续执行时不得收尾。同一条最终回复只包装一次;若需要分段,在同一个外层块内展开,不在正文里再次输出 `【HelloAGENTS】` 或第二个 `🔄 下一步`。
9
9
  子代理只豁免输出格式、交互确认与停顿、统一执行流程、任务分层、完成判定、命令路由和流程状态,直接执行任务;安全、质量、验证和失败处理规则仍持续生效,且不得包装 HelloAGENTS 外层输出格式。
10
- 只有运行时必须识别本轮“完成 / 等待输入 / 阻塞”时,主代理才写 turn-state;普通问候、普通问答、T0 只读分析和一次性解释不调用。必须调用场景:显式 `~auto` / `~loop`、非只读任务完成验证并进入收尾、需要让运行时识别本轮已完成、等待输入或已阻塞时、已进入项目连续流程或方案包闭环。首选 `helloagents-turn-state write --kind complete --role main`;等待或阻塞时写 `kind=waiting` / `kind=blocked`,并同时写 `reasonCategory` 与 `reason`。显式 `~auto` / `~loop` 下,还必须写入 `blocker.target`、`blocker.evidence`、`blocker.requiredAction`。不要查找、读取或拼接 `turn-state.mjs` 源码路径。子代理不得写 turn-state。
10
+ 只有运行时必须识别当前对话“完成 / 等待输入 / 阻塞”时,主代理才写 turn-state;普通问候、普通问答、T0 只读分析和一次性解释不调用。必须调用场景:显式 `~auto` / `~loop`、非只读任务完成验证并进入收尾、需要让运行时识别当前对话已完成、等待输入或已阻塞时、已进入项目连续流程或方案包闭环。首选 `helloagents-turn-state write --kind complete --role main`;等待或阻塞时写 `kind=waiting` / `kind=blocked`,并同时写 `reasonCategory` 与 `reason`。显式 `~auto` / `~loop` 下,还必须写入 `blocker.target`、`blocker.evidence`、`blocker.requiredAction`。不要查找、读取或拼接 `turn-state.mjs` 源码路径。子代理不得写 turn-state。
11
11
  普通问答、解释、分析、改写、邮件回复和其他一次性交付虽然不进入完整实现、验证或收尾流程,但仍属于交付:默认只交付与当前请求直接对应的一版最终结果;请求已满足时直接结束,不主动追加无执行价值的延伸、派生版本、不同写法、第二版或邀约式收尾,除非用户明确要求。
12
12
 
13
13
  `.helloagents/` 在所有 skill 中都统一按项目级存储路径理解:项目本地 `.helloagents/` 负责知识、方案和会话运行态,不作为项目是否已初始化的判定信号;状态文件只使用 `state_path`(实际位于 `sessions/{workspace}/{session}/STATE.md`);会话证据使用当前 `state_path` 所在目录下的 `artifacts/*.json`;`sessions/active.json` 只作为当前活跃会话索引;若 `project_store_mode=repo-shared`,`context.md`、`guidelines.md`、`DESIGN.md`、`verify.yaml`、`modules/`、`plans/`、`archive/` 按当前上下文中已注入的“当前项目存储”/“项目知识/方案目录”解析,不要假定这些文件一定实际位于当前工作树中。
@@ -50,18 +50,18 @@ description: 按任务类型适用 — 建立质量驱动工作流,通过技
50
50
  禁止行为:
51
51
  - 禁止在 ROUTE / TIER / SPEC 阶段读取实现类技能(hello-ui/hello-test/hello-verify 等)
52
52
  - 禁止因为"可能用到"就提前读取技能文件——等到真正需要时再读
53
- - 同一会话内,同一路径的配置文件、模块、SKILL、模板只读一次并跨轮复用;缺少所需内容、读取失败、用户要求刷新或本轮修改后才重新读取
53
+ - 同一会话内,同一路径的配置文件、模块、SKILL、模板只读一次并跨轮复用;缺少所需内容、读取失败、用户要求刷新或本次修改后才重新读取
54
54
  - ~command 命令只读取对应的 command SKILL.md,不连带读取其他技能
55
55
 
56
56
  ## 技能查找路径
57
57
 
58
58
  按以下路径查找,找到即停,不自行猜测或遍历其他路径。
59
59
 
60
- 路径定义:`{HELLOAGENTS_READ_ROOT}` = 本轮已确定的 HelloAGENTS 读取根目录,统一用于读取 `skills/` 与 `templates/`
60
+ 路径定义:`{HELLOAGENTS_READ_ROOT}` = 当前对话已确定的 HelloAGENTS 读取根目录,统一用于读取 `skills/` 与 `templates/`
61
61
  先确定当前技能根目录:
62
- - 优先使用当前上下文中已注入的“本轮 HelloAGENTS 读取根目录”
62
+ - 优先使用当前上下文中已注入的“当前对话 HelloAGENTS 读取根目录”
63
63
  - 若当前上下文未注入,则使用稳定运行根目录 `~/.helloagents/helloagents`
64
- - 宿主固定链接(Codex `~/.codex/helloagents`、Claude `~/.claude/helloagents`、Gemini `~/.gemini/helloagents`、DeepSeek `~/.deepseek/helloagents`)只作为兼容别名,不作为优先探测路径
64
+ - 宿主固定链接(Codex `~/.codex/helloagents`、Claude `~/.claude/helloagents`、Gemini `~/.gemini/helloagents`)只作为兼容别名,不作为优先探测路径
65
65
  - 仍无法确定时,明确说明缺少 HelloAGENTS 读取根目录;不要递归扫描 `$HOME`、`Downloads`、项目目录或旧版本目录
66
66
  - 全局模式或已初始化项目时,技能是否需要使用由当前已加载 AGENTS 规则决定;不要因此额外探测项目目录里的 HelloAGENTS skills 路径
67
67
 
@@ -1,131 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import { existsSync } from 'node:fs'
3
- import { join } from 'node:path'
4
-
5
- import { buildRuntimeCarrier, readCarrierSettings } from './cli-runtime-carrier.mjs'
6
- import { createLink, ensureDir, injectMarkedContent, removeLink, removeMarkedContent, safeRead } from './cli-utils.mjs'
7
-
8
- export const DEEPSEEK_COMMAND = process.env.HELLOAGENTS_DEEPSEEK_CMD || 'deepseek'
9
-
10
- function looksLikeCommandPath(command = '') {
11
- return /[\\/]/.test(command) || /^[A-Za-z]:/.test(command)
12
- }
13
-
14
- function injectDeepseekCarrier(home, pkgRoot, bootstrapFile, options = {}) {
15
- const deepseekDir = join(home, '.deepseek')
16
- ensureDir(deepseekDir)
17
-
18
- const bootstrapContent = safeRead(join(pkgRoot, bootstrapFile))
19
- if (!bootstrapContent) return false
20
-
21
- injectMarkedContent(
22
- join(deepseekDir, 'AGENTS.md'),
23
- buildRuntimeCarrier(bootstrapContent, readCarrierSettings(home), options).trimEnd(),
24
- )
25
- createLink(pkgRoot, join(deepseekDir, 'helloagents'))
26
- return true
27
- }
28
-
29
- export function installDeepseekStandby(home, pkgRoot) {
30
- return injectDeepseekCarrier(home, pkgRoot, 'bootstrap-lite.md')
31
- }
32
-
33
- export function installDeepseekGlobal(home, pkgRoot) {
34
- return injectDeepseekCarrier(home, pkgRoot, 'bootstrap.md', { profile: 'full' })
35
- }
36
-
37
- export function uninstallDeepseekStandby(home) {
38
- const deepseekDir = join(home, '.deepseek')
39
- if (!existsSync(deepseekDir)) return false
40
-
41
- removeMarkedContent(join(deepseekDir, 'AGENTS.md'))
42
- removeLink(join(deepseekDir, 'helloagents'))
43
- return true
44
- }
45
-
46
- export function uninstallDeepseekGlobal(home) {
47
- return uninstallDeepseekStandby(home)
48
- }
49
-
50
- function runDeepseekCommand(command, args = []) {
51
- if (looksLikeCommandPath(command) && !existsSync(command)) {
52
- return {
53
- ok: false,
54
- missing: true,
55
- exitCode: null,
56
- stdout: '',
57
- stderr: '',
58
- errorMessage: '',
59
- combinedOutput: '',
60
- }
61
- }
62
- const needsShell = process.platform === 'win32' && /\.cmd$/i.test(command)
63
- const result = spawnSync(command, args, {
64
- encoding: 'utf-8',
65
- errors: 'replace',
66
- shell: needsShell,
67
- windowsHide: true,
68
- })
69
- const stdout = String(result.stdout || '').trim()
70
- const stderr = String(result.stderr || '').trim()
71
- const errorMessage = result.error?.message || ''
72
- return {
73
- ok: result.status === 0,
74
- missing: result.error?.code === 'ENOENT',
75
- exitCode: typeof result.status === 'number' ? result.status : null,
76
- stdout,
77
- stderr,
78
- errorMessage,
79
- combinedOutput: [stdout, stderr, errorMessage].filter(Boolean).join('\n').trim(),
80
- }
81
- }
82
-
83
- function tryParseJson(text = '') {
84
- if (!text) return null
85
- try {
86
- return JSON.parse(text)
87
- } catch {
88
- return null
89
- }
90
- }
91
-
92
- function buildDoctorSummary(report = {}) {
93
- const skills = report.skills || {}
94
- const capability = report.capability || {}
95
- const sandbox = report.sandbox || {}
96
- const mcp = report.mcp || {}
97
- return {
98
- version: typeof report.version === 'string' ? report.version : '',
99
- configPath: typeof report.config_path === 'string' ? report.config_path : '',
100
- skillsSelected: Array.isArray(skills.selected) ? skills.selected : [],
101
- mcpPresent: Boolean(mcp.present),
102
- sandboxAvailable: typeof sandbox.available === 'boolean' ? sandbox.available : null,
103
- resolvedProvider: typeof capability.resolved_provider === 'string' ? capability.resolved_provider : '',
104
- resolvedModel: typeof capability.resolved_model === 'string' ? capability.resolved_model : '',
105
- }
106
- }
107
-
108
- export function inspectNativeDeepseekDoctor() {
109
- const result = runDeepseekCommand(DEEPSEEK_COMMAND, ['doctor', '--json'])
110
- if (result.missing) {
111
- return {
112
- available: false,
113
- command: DEEPSEEK_COMMAND,
114
- exitCode: null,
115
- ok: false,
116
- summary: null,
117
- note: 'command-not-found',
118
- }
119
- }
120
-
121
- const parsed = tryParseJson(result.stdout) || tryParseJson(result.combinedOutput)
122
- return {
123
- available: true,
124
- command: DEEPSEEK_COMMAND,
125
- exitCode: result.exitCode,
126
- ok: result.ok,
127
- summary: parsed ? buildDoctorSummary(parsed) : null,
128
- parseError: parsed ? '' : (result.combinedOutput ? 'invalid-json' : ''),
129
- output: parsed ? '' : result.combinedOutput,
130
- }
131
- }