helloagents 3.0.22 → 3.0.23

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helloagents",
3
- "version": "3.0.22",
3
+ "version": "3.0.23",
4
4
  "description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing, quality verification (Ralph Loop), safety guards, and notifications.",
5
5
  "author": {
6
6
  "name": "HelloWind",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helloagents",
3
- "version": "3.0.22",
3
+ "version": "3.0.23",
4
4
  "description": "HelloAGENTS — Quality-driven orchestration kernel for AI CLIs with intelligent routing, quality verification (Ralph Loop), safety guards, and notifications.",
5
5
  "author": {
6
6
  "name": "HelloWind",
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  **A workflow layer for AI coding CLIs: skills, project knowledge, delivery checks, safer config writes, and resumable execution.**
10
10
 
11
- [![Version](https://img.shields.io/badge/version-3.0.22-orange.svg)](./package.json)
11
+ [![Version](https://img.shields.io/badge/version-3.0.23-orange.svg)](./package.json)
12
12
  [![npm](https://img.shields.io/npm/v/helloagents.svg)](https://www.npmjs.com/package/helloagents)
13
13
  [![Node](https://img.shields.io/badge/node-%3E%3D18-339933.svg)](./package.json)
14
14
  [![Skills](https://img.shields.io/badge/skills-14-6366f1.svg)](./skills)
@@ -209,7 +209,7 @@ Runtime evidence files include:
209
209
  - `.helloagents/sessions/<workspace>/<session>/artifacts/closeout.json`
210
210
  - `.helloagents/sessions/<workspace>/<session>/artifacts/loop-results.tsv`
211
211
 
212
- Delivery gate, guard, and loop messages use action-oriented wording such as processing path, closeout action, and visual validation action, so blocked flows show what to do next without turning executable steps into optional suggestions.
212
+ Delivery gate, guard, and loop messages use action-oriented wording such as processing path, closeout action, and visual validation action, so blocked flows show what to do next without turning executable steps into optional suggestions. Final closeout also enforces a single HelloAGENTS wrapper, so one reply does not emit duplicate closeout headers.
213
213
 
214
214
  ### 7) Safer install, update, cleanup, and diagnostics
215
215
 
@@ -220,6 +220,7 @@ The CLI manages host files explicitly:
220
220
  - `cleanup` removes managed injections and links
221
221
  - `uninstall` performs scoped cleanup before package removal
222
222
  - `doctor` reports drift in carriers, links, hooks, config entries, plugin roots, cache copies, and versions
223
+ - per-host mode tracking is written only after a host setup succeeds, so failed native global installs do not leave stale mode records
223
224
 
224
225
  ## Quick Start
225
226
 
@@ -616,7 +617,7 @@ Default shape:
616
617
  | `project_store_mode` | `"local"` | `local` or `repo-shared` |
617
618
  | `commit_attribution` | `""` | optional text appended to commit messages |
618
619
  | `install_mode` | `"standby"` | current default install mode |
619
- | `host_install_modes` | `{}` | managed per-CLI mode map, such as `{ "codex": "standby" }`; used before falling back to `install_mode` |
620
+ | `host_install_modes` | `{}` | managed per-CLI mode map, such as `{ "codex": "standby" }`; recorded only after successful host setup and used before falling back to `install_mode` |
620
621
 
621
622
  ## How Each CLI Is Integrated
622
623
 
@@ -657,7 +658,7 @@ Run all tests:
657
658
  npm test
658
659
  ```
659
660
 
660
- The current suite includes 103 tests and covers:
661
+ The current suite includes 107 tests and covers:
661
662
 
662
663
  - install, update, uninstall, cleanup, and mode switching
663
664
  - Claude, Gemini, and Codex config merge and restore behavior
@@ -666,7 +667,7 @@ The current suite includes 103 tests and covers:
666
667
  - `helloagents doctor`
667
668
  - project storage and `repo-shared` behavior
668
669
  - session-scoped `state_path`, runtime signals, and evidence
669
- - runtime routing, guard, verification, visual evidence, and delivery gates
670
+ - runtime routing, guard, verification, visual evidence, delivery gates, single-wrapper closeout validation, and successful-mode tracking after native install failures
670
671
  - README and skill contract alignment
671
672
 
672
673
  ## FAQ
package/README_CN.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  **面向 AI 编码 CLI 的工作流层:技能、知识库、交付检查、更安全的配置写入,以及可恢复的执行流程。**
10
10
 
11
- [![Version](https://img.shields.io/badge/version-3.0.22-orange.svg)](./package.json)
11
+ [![Version](https://img.shields.io/badge/version-3.0.23-orange.svg)](./package.json)
12
12
  [![npm](https://img.shields.io/npm/v/helloagents.svg)](https://www.npmjs.com/package/helloagents)
13
13
  [![Node](https://img.shields.io/badge/node-%3E%3D18-339933.svg)](./package.json)
14
14
  [![Skills](https://img.shields.io/badge/skills-14-6366f1.svg)](./skills)
@@ -209,7 +209,7 @@ HelloAGENTS 不把“命令通过”和“任务完成”简单画等号。交
209
209
  - `.helloagents/sessions/<workspace>/<session>/artifacts/closeout.json`
210
210
  - `.helloagents/sessions/<workspace>/<session>/artifacts/loop-results.tsv`
211
211
 
212
- 交付门控、守卫和循环提示使用执行性表述,例如处理路径、收尾动作和视觉验收动作。阻塞流程会说明下一步要做什么,而不是把可执行步骤写成泛化建议。
212
+ 交付门控、守卫和循环提示使用执行性表述,例如处理路径、收尾动作和视觉验收动作。阻塞流程会说明下一步要做什么,而不是把可执行步骤写成泛化建议。最终收尾还会强制只保留一个 HelloAGENTS 外层块,避免同一条回复重复输出完成标题。
213
213
 
214
214
  ### 7)更安全的安装、更新、清理和诊断
215
215
 
@@ -220,6 +220,7 @@ CLI 显式管理宿主文件:
220
220
  - `cleanup` 删除受管注入和链接
221
221
  - `uninstall` 在移除包前执行对应清理
222
222
  - `doctor` 检查规则文件、链接、hooks、配置项、插件根目录、缓存副本和版本漂移
223
+ - 单 CLI 模式记录只会在宿主安装成功后写入,避免原生全局安装失败后留下错误模式记录
223
224
 
224
225
  ## 快速开始
225
226
 
@@ -618,7 +619,7 @@ UI 任务遵循以下优先级:
618
619
  | `project_store_mode` | `"local"` | `local` 或 `repo-shared` |
619
620
  | `commit_attribution` | `""` | 提交信息附加署名 |
620
621
  | `install_mode` | `"standby"` | 当前默认安装模式 |
621
- | `host_install_modes` | `{}` | 受管的单 CLI 模式记录,如 `{ "codex": "standby" }`;优先于 `install_mode` |
622
+ | `host_install_modes` | `{}` | 受管的单 CLI 模式记录,如 `{ "codex": "standby" }`;仅在宿主安装成功后写入,并优先于 `install_mode` |
622
623
 
623
624
  ## 各 CLI 集成方式
624
625
 
@@ -659,7 +660,7 @@ Codex 默认走规则文件驱动。
659
660
  npm test
660
661
  ```
661
662
 
662
- 当前测试共 103 项,覆盖:
663
+ 当前测试共 107 项,覆盖:
663
664
 
664
665
  - 安装、更新、卸载、清理和模式切换
665
666
  - Claude、Gemini、Codex 的配置合并与恢复
@@ -668,7 +669,7 @@ npm test
668
669
  - `helloagents doctor`
669
670
  - 项目存储和 `repo-shared`
670
671
  - 会话级 `state_path`、运行态信号和证据
671
- - 运行时选路、Guard、验证、视觉证据和交付门控
672
+ - 运行时选路、Guard、验证、视觉证据、交付门控、单次收尾包装校验,以及原生安装失败后的模式记录
672
673
  - README 与 skill 契约一致性
673
674
 
674
675
  ## FAQ
package/bootstrap-lite.md CHANGED
@@ -116,7 +116,7 @@
116
116
  图标:💡直接响应 | ⚡快速执行 | 🔵规划流程 | ✅完成 | ❓等待输入 | ⚠️警告 | ❌错误
117
117
 
118
118
  使用约束:
119
- - 首行必须保留 `【HelloAGENTS】` 和连字符 `-`,不得省略;状态图标与收尾内容必须一致。正文仍在等待用户输入、确认、授权或补充信息(含确认是否执行已给出的方案或修改)时,只能使用 `❓等待输入`;仅在本轮执行已完成且不存在待确认动作时,才能使用 `✅完成`。
119
+ - 首行必须保留 `【HelloAGENTS】` 和连字符 `-`,不得省略;状态图标与收尾内容必须一致。正文仍在等待用户输入、确认、授权或补充信息(含确认是否执行已给出的方案或修改)时,只能使用 `❓等待输入`;仅在本轮执行已完成且不存在待确认动作时,才能使用 `✅完成`。同一条最终收尾消息只使用一次该格式;若主体需要分段,在同一个外层块内分节,不得在正文中再次输出 `【HelloAGENTS】` 或第二个 `🔄 下一步`。
120
120
  - `🔄 下一步` 必须写真正的下一步动作,不写单纯当前状态或条件式能力表述。若正在等待确认,写清待确认动作;若仍有已授权且可继续执行的动作,不得收尾,必须继续执行;若当前任务已完整结束且确无合理后续,可填写“当前任务已完成;无后续动作。”
121
121
 
122
122
  ### 收尾状态信号
package/bootstrap.md CHANGED
@@ -116,7 +116,7 @@
116
116
  图标:💡直接响应 | ⚡快速执行 | 🔵规划流程 | ✅完成 | ❓等待输入 | ⚠️警告 | ❌错误
117
117
 
118
118
  使用约束:
119
- - 首行必须保留 `【HelloAGENTS】` 和连字符 `-`,不得省略;状态图标与收尾内容必须一致。正文仍在等待用户输入、确认、授权或补充信息(含确认是否执行已给出的方案或修改)时,只能使用 `❓等待输入`;仅在本轮执行已完成且不存在待确认动作时,才能使用 `✅完成`。
119
+ - 首行必须保留 `【HelloAGENTS】` 和连字符 `-`,不得省略;状态图标与收尾内容必须一致。正文仍在等待用户输入、确认、授权或补充信息(含确认是否执行已给出的方案或修改)时,只能使用 `❓等待输入`;仅在本轮执行已完成且不存在待确认动作时,才能使用 `✅完成`。同一条最终收尾消息只使用一次该格式;若主体需要分段,在同一个外层块内分节,不得在正文中再次输出 `【HelloAGENTS】` 或第二个 `🔄 下一步`。
120
120
  - `🔄 下一步` 必须写真正的下一步动作,不写单纯当前状态或条件式能力表述。若正在等待确认,写清待确认动作;若仍有已授权且可继续执行的动作,不得收尾,必须继续执行;若当前任务已完整结束且确无合理后续,可填写“当前任务已完成;无后续动作。”
121
121
 
122
122
  ### 收尾状态信号
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helloagents",
3
- "version": "3.0.22",
3
+ "version": "3.0.23",
4
4
  "description": "Quality-driven orchestration kernel for AI CLIs",
5
5
  "contextFileName": "bootstrap.md",
6
6
  "author": "HelloWind",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helloagents",
3
- "version": "3.0.22",
3
+ "version": "3.0.23",
4
4
  "type": "module",
5
5
  "description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing, quality verification (Ralph Loop), safety guards, and notifications.",
6
6
  "author": "HelloWind",
@@ -59,14 +59,18 @@ function clearTrackedHostMode(settings, host) {
59
59
  delete settings.host_install_modes[host]
60
60
  }
61
61
 
62
- function setAllTrackedHostModes(settings, mode) {
63
- settings.host_install_modes = Object.fromEntries(HOSTS.map((host) => [host, mode]))
64
- }
65
-
66
62
  function clearAllTrackedHostModes(settings) {
67
63
  settings.host_install_modes = {}
68
64
  }
69
65
 
66
+ function syncTrackedHostMode(settings, host, result, mode) {
67
+ if (!result?.skipped && result?.ok !== false) {
68
+ setTrackedHostMode(settings, host, mode)
69
+ return
70
+ }
71
+ clearTrackedHostMode(settings, host)
72
+ }
73
+
70
74
  export function normalizeHost(value = '') {
71
75
  return normalizeLifecycleHost(value)
72
76
  }
@@ -157,8 +161,11 @@ export function switchMode(newMode) {
157
161
  runtime.ok(runtime.msg(`当前已是 ${newMode} 模式,正在刷新安装`, `Already in ${newMode} mode, refreshing installation`))
158
162
  }
159
163
 
160
- installAllHosts(runtime, newMode)
161
- setAllTrackedHostModes(config, newMode)
164
+ const results = installAllHosts(runtime, newMode)
165
+ clearAllTrackedHostModes(config)
166
+ for (const host of HOSTS) {
167
+ syncTrackedHostMode(config, host, results?.[host], newMode)
168
+ }
162
169
  writeSettings(config)
163
170
  runtime.printInstallMsg(newMode, isRefresh ? 'refresh' : 'switch')
164
171
  }
@@ -229,7 +236,7 @@ export function runScopedLifecycle(action, rawArgs) {
229
236
  writeSettings(settings)
230
237
  }
231
238
  } else if (!result.skipped) {
232
- setTrackedHostMode(settings, host, mode)
239
+ syncTrackedHostMode(settings, host, result, mode)
233
240
  writeSettings(settings)
234
241
  }
235
242
  }
@@ -48,6 +48,56 @@ function buildBlockReason(routeContext, detail, cwd) {
48
48
  ].filter(Boolean).join('\n')
49
49
  }
50
50
 
51
+ function getLastAssistantMessage(payload = {}) {
52
+ return String(
53
+ payload.lastAssistantMessage
54
+ || payload.last_assistant_message
55
+ || payload['last-assistant-message']
56
+ || '',
57
+ ).trim()
58
+ }
59
+
60
+ function countMatches(text, pattern) {
61
+ const matches = text.match(pattern)
62
+ return matches ? matches.length : 0
63
+ }
64
+
65
+ function validateFormattedCloseoutMessage(routeContext, payload, cwd) {
66
+ const message = getLastAssistantMessage(payload)
67
+ if (!message || !message.includes('【HelloAGENTS】')) return ''
68
+
69
+ const firstNonEmptyLine = message
70
+ .split(/\r?\n/)
71
+ .map((line) => line.trim())
72
+ .find(Boolean)
73
+
74
+ if (!firstNonEmptyLine || !/^[💡⚡🔵✅❓⚠️❌]【HelloAGENTS】- /.test(firstNonEmptyLine)) {
75
+ return buildBlockReason(
76
+ routeContext,
77
+ '最终收尾消息使用了 HelloAGENTS 外层格式,但首个非空行不是规范标题行。',
78
+ cwd,
79
+ )
80
+ }
81
+
82
+ if (countMatches(message, /[💡⚡🔵✅❓⚠️❌]【HelloAGENTS】-/g) > 1) {
83
+ return buildBlockReason(
84
+ routeContext,
85
+ '最终收尾消息重复输出了 HelloAGENTS 标题;请把所有内容合并到同一个外层块内。',
86
+ cwd,
87
+ )
88
+ }
89
+
90
+ if (countMatches(message, /^🔄 下一步:/gm) > 1) {
91
+ return buildBlockReason(
92
+ routeContext,
93
+ '最终收尾消息重复输出了 `🔄 下一步`;请只保留一个真实下一步。',
94
+ cwd,
95
+ )
96
+ }
97
+
98
+ return ''
99
+ }
100
+
51
101
  function getMainTurnState(cwd, payload = {}) {
52
102
  const turnState = readTurnState(cwd, { payload })
53
103
  return turnState?.role === 'main' ? turnState : null
@@ -64,11 +114,13 @@ function hasStructuredBlocker(turnState) {
64
114
  )
65
115
  }
66
116
 
67
- function validateTurnState(routeContext, turnState, cwd) {
117
+ function validateTurnState(routeContext, turnState, cwd, payload = {}) {
68
118
  if (!turnState) {
69
119
  return buildBlockReason(routeContext, '缺少主代理 turn-state。', cwd)
70
120
  }
71
121
  if (turnState.kind === 'complete') {
122
+ const formatReason = validateFormattedCloseoutMessage(routeContext, payload, cwd)
123
+ if (formatReason) return formatReason
72
124
  return ''
73
125
  }
74
126
  if (turnState.kind === 'waiting' || turnState.kind === 'blocked') {
@@ -101,7 +153,7 @@ function main() {
101
153
  return
102
154
  }
103
155
 
104
- const reason = validateTurnState(routeContext, getMainTurnState(cwd, payload), cwd)
156
+ const reason = validateTurnState(routeContext, getMainTurnState(cwd, payload), cwd, payload)
105
157
  process.stdout.write(JSON.stringify(reason ? { decision: 'block', reason } : { decision: 'continue' }))
106
158
  }
107
159
 
@@ -5,7 +5,7 @@ description: 按任务类型适用 — 建立质量驱动工作流,通过技
5
5
 
6
6
  # HelloAGENTS
7
7
 
8
- 主代理触发或读取任意 skill 时,只有本轮最终收尾消息才按通用输出格式包装;流式内容、进度或状态汇报、中间文本,以及任何仍将继续执行的文本,都保持自然输出。最终收尾中的 `🔄 下一步` 写真实动作,不写当前状态;等待用户授权时使用等待输入态收尾,已获授权且可继续执行时不得收尾。
8
+ 主代理触发或读取任意 skill 时,只有本轮最终收尾消息才按通用输出格式包装;流式内容、进度或状态汇报、中间文本,以及任何仍将继续执行的文本,都保持自然输出。最终收尾中的 `🔄 下一步` 写真实动作,不写当前状态;等待用户授权时使用等待输入态收尾,已获授权且可继续执行时不得收尾。同一条最终收尾消息只包装一次;若需要分段,在同一个外层块内展开,不在正文里再次输出 `【HelloAGENTS】` 或第二个 `🔄 下一步`。
9
9
  子代理只豁免路由与收尾要求,直接执行任务;安全、质量、验证和失败处理规则仍持续生效,且不得包装 HelloAGENTS 外层输出格式。
10
10
  只有运行时必须识别本轮“完成 / 等待输入 / 阻塞”时,主代理才写 turn-state;普通问候、普通问答、T0 只读分析和一次性解释不调用。必须调用场景:显式 `~auto` / `~loop`、非只读任务完成验证并进入收尾、需要 delivery gate / Ralph Loop / closeout evidence、需要等待或阻塞且运行时必须识别状态、已进入项目连续流程或方案包闭环。首选 `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