helloagents 3.0.33 → 3.0.37
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/.claude-plugin/marketplace.json +1 -4
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -4
- package/README.md +78 -74
- package/README_CN.md +78 -74
- package/bootstrap-lite.md +9 -11
- package/bootstrap.md +21 -23
- package/gemini-extension.json +1 -1
- package/install.ps1 +27 -4
- package/install.sh +27 -3
- package/package.json +2 -2
- package/scripts/capability-registry.mjs +5 -3
- package/scripts/cli-doctor-codex.mjs +153 -1
- package/scripts/cli-doctor-render.mjs +2 -1
- package/scripts/cli-doctor.mjs +3 -3
- package/scripts/cli-hosts.mjs +1 -1
- package/scripts/cli-lifecycle-hosts.mjs +124 -54
- package/scripts/cli-lifecycle.mjs +50 -15
- package/scripts/cli-messages.mjs +7 -7
- package/scripts/cli-runtime-root.mjs +9 -1
- package/scripts/delivery-gate-messages.mjs +5 -4
- package/scripts/delivery-gate.mjs +11 -22
- package/scripts/guard.mjs +1 -1
- package/scripts/notify-closeout.mjs +61 -22
- package/scripts/notify-context.mjs +5 -5
- package/scripts/notify-route.mjs +1 -1
- package/scripts/notify-sound.mjs +2 -1
- package/scripts/notify.mjs +2 -2
- package/scripts/plan-contract.mjs +10 -14
- package/scripts/project-session-cleanup.mjs +91 -31
- package/scripts/qa-review-state.mjs +313 -0
- package/scripts/ralph-loop.mjs +32 -13
- package/scripts/runtime-artifacts.mjs +2 -2
- package/scripts/runtime-scope.mjs +14 -13
- package/scripts/runtime-ttl.mjs +7 -4
- package/scripts/session-capsule.mjs +75 -13
- package/scripts/session-token.mjs +44 -9
- package/scripts/state-document.mjs +77 -0
- package/scripts/workflow-core.mjs +13 -19
- package/scripts/workflow-plan-files.mjs +1 -1
- package/scripts/workflow-recommendation.mjs +55 -67
- package/scripts/workflow-state.mjs +8 -8
- package/skills/commands/auto/SKILL.md +12 -12
- package/skills/commands/build/SKILL.md +9 -10
- package/skills/commands/commit/SKILL.md +1 -1
- package/skills/commands/help/SKILL.md +11 -13
- package/skills/commands/init/SKILL.md +18 -9
- package/skills/commands/loop/SKILL.md +70 -96
- package/skills/commands/plan/SKILL.md +7 -8
- package/skills/commands/prd/SKILL.md +3 -3
- package/skills/commands/qa/SKILL.md +49 -0
- package/skills/hello-ui/SKILL.md +3 -3
- package/skills/helloagents/SKILL.md +11 -14
- package/skills/qa-review/SKILL.md +92 -0
- package/templates/plans/contract.json +4 -7
- package/templates/plans/plan.md +1 -1
- package/templates/plans/tasks.md +1 -1
- package/templates/verify.yaml +1 -1
- package/scripts/review-state.mjs +0 -193
- package/scripts/verify-state.mjs +0 -175
- package/skills/commands/global/SKILL.md +0 -71
- package/skills/commands/verify/SKILL.md +0 -46
- package/skills/commands/wiki/SKILL.md +0 -57
- package/skills/hello-review/SKILL.md +0 -42
- package/skills/hello-verify/SKILL.md +0 -144
- /package/hooks/{hooks.json → hooks-gemini.json} +0 -0
package/gemini-extension.json
CHANGED
package/install.ps1
CHANGED
|
@@ -15,6 +15,8 @@ $Target = if ($env:HELLOAGENTS_TARGET) { $env:HELLOAGENTS_TARGET } else { "" }
|
|
|
15
15
|
$Mode = if ($env:HELLOAGENTS_MODE) { $env:HELLOAGENTS_MODE } else { "" }
|
|
16
16
|
$Branch = if ($env:HELLOAGENTS_BRANCH) { $env:HELLOAGENTS_BRANCH } else { "" }
|
|
17
17
|
$Package = if ($env:HELLOAGENTS_PACKAGE) { $env:HELLOAGENTS_PACKAGE } else { "" }
|
|
18
|
+
$HasExplicitPackage = [bool]$Package
|
|
19
|
+
$HasExplicitTarget = $false
|
|
18
20
|
|
|
19
21
|
if ($env:HELLOAGENTS) {
|
|
20
22
|
$Parts = $env:HELLOAGENTS.Split(":", 2)
|
|
@@ -25,6 +27,8 @@ if ($env:HELLOAGENTS) {
|
|
|
25
27
|
if (-not $Mode -and $Parts.Count -gt 1) { $Mode = $Parts[1] }
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
$HasExplicitTarget = [bool]$Target
|
|
31
|
+
|
|
28
32
|
if (-not $Target) { $Target = "all" }
|
|
29
33
|
$Target = $Target.ToLowerInvariant()
|
|
30
34
|
if ($Mode) { $Mode = $Mode.ToLowerInvariant() }
|
|
@@ -53,6 +57,23 @@ function Invoke-Npm {
|
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
function Clear-HelloagentsEnv {
|
|
61
|
+
foreach ($name in @(
|
|
62
|
+
"HELLOAGENTS",
|
|
63
|
+
"HELLOAGENTS_ACTION",
|
|
64
|
+
"HELLOAGENTS_TARGET",
|
|
65
|
+
"HELLOAGENTS_HOST",
|
|
66
|
+
"HELLOAGENTS_MODE",
|
|
67
|
+
"HELLOAGENTS_BRANCH",
|
|
68
|
+
"HELLOAGENTS_PACKAGE",
|
|
69
|
+
"HELLOAGENTS_DEPLOY"
|
|
70
|
+
)) {
|
|
71
|
+
Remove-Item "Env:$name" -ErrorAction SilentlyContinue
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Clear-HelloagentsEnv
|
|
76
|
+
|
|
56
77
|
function Enable-PostinstallDeploy {
|
|
57
78
|
$env:HELLOAGENTS_DEPLOY = "1"
|
|
58
79
|
$env:HELLOAGENTS_TARGET = $Target
|
|
@@ -89,11 +110,13 @@ function Uninstall-Hosts {
|
|
|
89
110
|
|
|
90
111
|
switch ($Action) {
|
|
91
112
|
"install" {
|
|
92
|
-
|
|
113
|
+
if ($HasExplicitTarget) {
|
|
114
|
+
Enable-PostinstallDeploy
|
|
115
|
+
}
|
|
93
116
|
Invoke-Npm -NpmArgs @("install", "-g", $Package)
|
|
94
117
|
}
|
|
95
118
|
"update" {
|
|
96
|
-
if ($Branch -or $
|
|
119
|
+
if ($Branch -or $HasExplicitPackage) {
|
|
97
120
|
Invoke-Npm -NpmArgs @("install", "-g", $Package)
|
|
98
121
|
} else {
|
|
99
122
|
& npm update -g helloagents
|
|
@@ -107,14 +130,14 @@ switch ($Action) {
|
|
|
107
130
|
Cleanup-Hosts
|
|
108
131
|
}
|
|
109
132
|
"switch-branch" {
|
|
110
|
-
if (-not $Branch -and -not $
|
|
133
|
+
if (-not $Branch -and -not $HasExplicitPackage) {
|
|
111
134
|
throw "HELLOAGENTS_BRANCH or HELLOAGENTS_PACKAGE is required for switch-branch"
|
|
112
135
|
}
|
|
113
136
|
Invoke-Npm -NpmArgs @("install", "-g", $Package)
|
|
114
137
|
Sync-Hosts
|
|
115
138
|
}
|
|
116
139
|
"branch" {
|
|
117
|
-
if (-not $Branch -and -not $
|
|
140
|
+
if (-not $Branch -and -not $HasExplicitPackage) {
|
|
118
141
|
throw "HELLOAGENTS_BRANCH or HELLOAGENTS_PACKAGE is required for branch"
|
|
119
142
|
}
|
|
120
143
|
Invoke-Npm -NpmArgs @("install", "-g", $Package)
|
package/install.sh
CHANGED
|
@@ -16,6 +16,11 @@ TARGET="${HELLOAGENTS_TARGET:-}"
|
|
|
16
16
|
MODE="${HELLOAGENTS_MODE:-}"
|
|
17
17
|
BRANCH="${HELLOAGENTS_BRANCH:-}"
|
|
18
18
|
PACKAGE="${HELLOAGENTS_PACKAGE:-}"
|
|
19
|
+
HAS_EXPLICIT_PACKAGE=0
|
|
20
|
+
HAS_EXPLICIT_TARGET=0
|
|
21
|
+
if [ -n "$PACKAGE" ]; then
|
|
22
|
+
HAS_EXPLICIT_PACKAGE=1
|
|
23
|
+
fi
|
|
19
24
|
|
|
20
25
|
if [ -n "${HELLOAGENTS:-}" ]; then
|
|
21
26
|
SPEC_TARGET="${HELLOAGENTS%%:*}"
|
|
@@ -31,6 +36,10 @@ if [ -n "${HELLOAGENTS:-}" ]; then
|
|
|
31
36
|
MODE="${MODE:-$SPEC_MODE}"
|
|
32
37
|
fi
|
|
33
38
|
|
|
39
|
+
if [ -n "$TARGET" ]; then
|
|
40
|
+
HAS_EXPLICIT_TARGET=1
|
|
41
|
+
fi
|
|
42
|
+
|
|
34
43
|
TARGET="${TARGET:-all}"
|
|
35
44
|
TARGET="$(printf '%s' "$TARGET" | tr '[:upper:]' '[:lower:]')"
|
|
36
45
|
MODE="$(printf '%s' "$MODE" | tr '[:upper:]' '[:lower:]')"
|
|
@@ -55,6 +64,19 @@ if [ -z "$PACKAGE" ]; then
|
|
|
55
64
|
fi
|
|
56
65
|
fi
|
|
57
66
|
|
|
67
|
+
clear_lifecycle_env() {
|
|
68
|
+
unset HELLOAGENTS
|
|
69
|
+
unset HELLOAGENTS_ACTION
|
|
70
|
+
unset HELLOAGENTS_TARGET
|
|
71
|
+
unset HELLOAGENTS_HOST
|
|
72
|
+
unset HELLOAGENTS_MODE
|
|
73
|
+
unset HELLOAGENTS_BRANCH
|
|
74
|
+
unset HELLOAGENTS_PACKAGE
|
|
75
|
+
unset HELLOAGENTS_DEPLOY
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
clear_lifecycle_env
|
|
79
|
+
|
|
58
80
|
sync_hosts() {
|
|
59
81
|
if [ "$TARGET" = "all" ]; then
|
|
60
82
|
if [ -n "$MODE" ]; then
|
|
@@ -111,11 +133,13 @@ enable_postinstall_deploy() {
|
|
|
111
133
|
|
|
112
134
|
case "$ACTION" in
|
|
113
135
|
install)
|
|
114
|
-
|
|
136
|
+
if [ "$HAS_EXPLICIT_TARGET" -eq 1 ]; then
|
|
137
|
+
enable_postinstall_deploy
|
|
138
|
+
fi
|
|
115
139
|
npm install -g "$PACKAGE"
|
|
116
140
|
;;
|
|
117
141
|
update)
|
|
118
|
-
if [ -n "$BRANCH" ] || [
|
|
142
|
+
if [ -n "$BRANCH" ] || [ "$HAS_EXPLICIT_PACKAGE" -eq 1 ]; then
|
|
119
143
|
npm install -g "$PACKAGE"
|
|
120
144
|
else
|
|
121
145
|
npm update -g helloagents || npm install -g helloagents
|
|
@@ -126,7 +150,7 @@ case "$ACTION" in
|
|
|
126
150
|
cleanup_hosts
|
|
127
151
|
;;
|
|
128
152
|
switch-branch|branch)
|
|
129
|
-
if [ -z "$BRANCH" ] && [
|
|
153
|
+
if [ -z "$BRANCH" ] && [ "$HAS_EXPLICIT_PACKAGE" -ne 1 ]; then
|
|
130
154
|
echo "HELLOAGENTS_BRANCH or HELLOAGENTS_PACKAGE is required for switch-branch" >&2
|
|
131
155
|
exit 1
|
|
132
156
|
fi
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.37",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing,
|
|
5
|
+
"description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing, unified QA gates, safety guards, and notifications.",
|
|
6
6
|
"author": "HelloWind",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"homepage": "https://github.com/hellowind777/helloagents",
|
|
@@ -30,10 +30,12 @@ export function selectCapabilities({ cwd, skillName = '', options = {} }) {
|
|
|
30
30
|
: '独立 advisor:当前契约要求进入收尾前写当前会话 `artifacts/advisor.json`,记录 advisor reason、focus、consultedSources 与结论。',
|
|
31
31
|
})
|
|
32
32
|
}
|
|
33
|
-
if (plan?.contract?.
|
|
33
|
+
if ((plan?.contract?.qaFocus || []).length > 0) {
|
|
34
34
|
capabilities.push({
|
|
35
|
-
id: '
|
|
36
|
-
description:
|
|
35
|
+
id: 'qa-evaluator',
|
|
36
|
+
description: plan?.contract?.qaMode === 'deep'
|
|
37
|
+
? `深度 qa-review:当前收尾主路径是 ~qa,按阻断性质量闭环执行;重点:${plan.contract.qaFocus.join(';')}。`
|
|
38
|
+
: `统一 qa-review:当前收尾主路径是 ~qa,重点:${plan.contract.qaFocus.join(';')}。`,
|
|
37
39
|
})
|
|
38
40
|
}
|
|
39
41
|
if (plan?.contract?.ui?.required || existsSync(getProjectDesignContractPath(cwd))) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process'
|
|
1
2
|
import { existsSync, realpathSync } from 'node:fs'
|
|
3
|
+
import { platform } from 'node:os'
|
|
2
4
|
import { join } from 'node:path'
|
|
3
5
|
|
|
4
6
|
import { CODEX_MARKETPLACE_NAME, CODEX_PLUGIN_CONFIG_HEADER, CODEX_PLUGIN_NAME } from './cli-codex.mjs'
|
|
@@ -76,6 +78,143 @@ function buildDoctorIssue(runtime, code, cn, en) {
|
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
function normalizeDoctorText(value = '') {
|
|
82
|
+
return String(value || '').replace(/\s+/g, ' ').trim()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function readFirstInteger(value = '') {
|
|
86
|
+
const match = String(value || '').match(/-?\d+/)
|
|
87
|
+
return match ? Number.parseInt(match[0], 10) : null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function readNativeDoctorDetail(checks, checkId, detailKey) {
|
|
91
|
+
return String(checks?.[checkId]?.details?.[detailKey] || '').trim()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function readNativeDoctorList(value = '') {
|
|
95
|
+
const normalized = normalizeDoctorText(value)
|
|
96
|
+
if (!normalized || normalized === '(none)') return []
|
|
97
|
+
return normalized.split(/\s*,\s*/).map((entry) => entry.trim()).filter(Boolean)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function summarizeNativeCodexDoctor(payload = {}) {
|
|
101
|
+
const checks = payload?.checks || {}
|
|
102
|
+
const configCheck = checks['config.load'] || {}
|
|
103
|
+
const sandboxCheck = checks['sandbox.helpers'] || {}
|
|
104
|
+
const mcpCount = readFirstInteger(readNativeDoctorDetail(checks, 'config.load', 'mcp servers'))
|
|
105
|
+
const fsSandbox = readNativeDoctorDetail(checks, 'sandbox.helpers', 'filesystem sandbox').toLowerCase()
|
|
106
|
+
const linuxHelper = readNativeDoctorDetail(checks, 'sandbox.helpers', 'codex-linux-sandbox helper').toLowerCase()
|
|
107
|
+
|| readNativeDoctorDetail(checks, 'sandbox.helpers', 'linux helper').toLowerCase()
|
|
108
|
+
const execveHelper = readNativeDoctorDetail(checks, 'sandbox.helpers', 'execve wrapper helper').toLowerCase()
|
|
109
|
+
|
|
110
|
+
let sandboxAvailable = null
|
|
111
|
+
if (sandboxCheck && Object.keys(sandboxCheck).length > 0) {
|
|
112
|
+
sandboxAvailable = Boolean(
|
|
113
|
+
(fsSandbox && !fsSandbox.includes('unrestricted'))
|
|
114
|
+
|| (linuxHelper && linuxHelper !== 'none')
|
|
115
|
+
|| (execveHelper && execveHelper !== 'none')
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
version: String(payload?.codexVersion || '').trim(),
|
|
121
|
+
configPath: readNativeDoctorDetail(checks, 'config.load', 'config.toml'),
|
|
122
|
+
resolvedProvider: readNativeDoctorDetail(checks, 'config.load', 'model provider'),
|
|
123
|
+
resolvedModel: readNativeDoctorDetail(checks, 'config.load', 'model'),
|
|
124
|
+
sandboxAvailable,
|
|
125
|
+
mcpPresent: typeof mcpCount === 'number' ? mcpCount > 0 : false,
|
|
126
|
+
skillsSelected: readNativeDoctorList(
|
|
127
|
+
readNativeDoctorDetail(checks, 'config.load', 'selected skills')
|
|
128
|
+
|| readNativeDoctorDetail(checks, 'config.load', 'skills selected')
|
|
129
|
+
),
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function summarizeNativeCodexDoctorOutput(payload = {}) {
|
|
134
|
+
const checks = Object.values(payload?.checks || {})
|
|
135
|
+
const failedCheck = checks.find((check) => check?.status === 'fail')
|
|
136
|
+
if (failedCheck?.issues?.length) {
|
|
137
|
+
return normalizeDoctorText(failedCheck.issues.map((issue) => issue?.cause || issue?.measured || '').filter(Boolean).join(' | '))
|
|
138
|
+
}
|
|
139
|
+
if (failedCheck?.summary) return normalizeDoctorText(failedCheck.summary)
|
|
140
|
+
|
|
141
|
+
const warningCheck = checks.find((check) => check?.status === 'warn')
|
|
142
|
+
if (warningCheck?.issues?.length) {
|
|
143
|
+
return normalizeDoctorText(warningCheck.issues.map((issue) => issue?.cause || issue?.measured || '').filter(Boolean).join(' | '))
|
|
144
|
+
}
|
|
145
|
+
if (warningCheck?.summary) return normalizeDoctorText(warningCheck.summary)
|
|
146
|
+
|
|
147
|
+
return ''
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function inspectNativeCodexDoctor(runtime) {
|
|
151
|
+
const command = platform() === 'win32' ? 'codex.cmd' : 'codex'
|
|
152
|
+
try {
|
|
153
|
+
const result = spawnSync(command, ['doctor', '--json'], {
|
|
154
|
+
cwd: process.cwd(),
|
|
155
|
+
env: {
|
|
156
|
+
...process.env,
|
|
157
|
+
HOME: runtime.home || process.env.HOME,
|
|
158
|
+
USERPROFILE: runtime.home || process.env.USERPROFILE,
|
|
159
|
+
NO_COLOR: process.env.NO_COLOR || '1',
|
|
160
|
+
},
|
|
161
|
+
encoding: 'utf-8',
|
|
162
|
+
timeout: 20_000,
|
|
163
|
+
shell: platform() === 'win32',
|
|
164
|
+
windowsHide: true,
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
if (result.error) {
|
|
168
|
+
return {
|
|
169
|
+
available: false,
|
|
170
|
+
ok: false,
|
|
171
|
+
status: '',
|
|
172
|
+
summary: null,
|
|
173
|
+
output: normalizeDoctorText(result.error.message || ''),
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const stdout = String(result.stdout || '').trim()
|
|
178
|
+
if (!stdout) {
|
|
179
|
+
return {
|
|
180
|
+
available: true,
|
|
181
|
+
ok: result.status === 0,
|
|
182
|
+
status: '',
|
|
183
|
+
summary: null,
|
|
184
|
+
output: normalizeDoctorText(result.stderr || ''),
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
const payload = JSON.parse(stdout)
|
|
190
|
+
const status = String(payload?.overallStatus || '').trim().toLowerCase()
|
|
191
|
+
return {
|
|
192
|
+
available: true,
|
|
193
|
+
ok: status ? status !== 'fail' : result.status === 0,
|
|
194
|
+
status,
|
|
195
|
+
summary: summarizeNativeCodexDoctor(payload),
|
|
196
|
+
output: summarizeNativeCodexDoctorOutput(payload),
|
|
197
|
+
}
|
|
198
|
+
} catch {
|
|
199
|
+
return {
|
|
200
|
+
available: true,
|
|
201
|
+
ok: result.status === 0,
|
|
202
|
+
status: '',
|
|
203
|
+
summary: null,
|
|
204
|
+
output: normalizeDoctorText(stdout || result.stderr || ''),
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
return {
|
|
209
|
+
available: false,
|
|
210
|
+
ok: false,
|
|
211
|
+
status: '',
|
|
212
|
+
summary: null,
|
|
213
|
+
output: normalizeDoctorText(error?.message || ''),
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
79
218
|
function normalizeDoctorMode(mode = '') {
|
|
80
219
|
return mode || 'none'
|
|
81
220
|
}
|
|
@@ -209,6 +348,7 @@ export function inspectCodexDoctor(runtime, settings) {
|
|
|
209
348
|
const host = 'codex'
|
|
210
349
|
const trackedMode = normalizeDoctorMode(runtime.getTrackedHostMode(settings, host))
|
|
211
350
|
const detectedMode = normalizeDoctorMode(runtime.detectHostMode(host))
|
|
351
|
+
const nativeDoctor = inspectNativeCodexDoctor(runtime)
|
|
212
352
|
const { checks, pluginVersion, cacheVersion } = buildCodexChecks(runtime, settings, trackedMode, detectedMode)
|
|
213
353
|
checks.pluginVersionMatch = pluginVersion ? pluginVersion === runtime.pkgVersion : false
|
|
214
354
|
checks.pluginCacheVersionMatch = cacheVersion ? cacheVersion === runtime.pkgVersion : false
|
|
@@ -230,7 +370,19 @@ export function inspectCodexDoctor(runtime, settings) {
|
|
|
230
370
|
if (!checks.pluginCacheVersionMatch && !cacheVersion && detectedMode === 'global') notes.push(runtime.msg('未读到 global 插件缓存版本信息', 'Global plugin cache version was not readable'))
|
|
231
371
|
if (detectedMode !== 'none' && !checks.codexGoalsFeature) notes.push(runtime.msg('Codex /goal 未启用;如需长程执行,可运行 `helloagents codex goals enable`。', 'Codex /goal is not enabled; run `helloagents codex goals enable` if you need long-running goals.'))
|
|
232
372
|
if (detectedMode !== 'none' && checks.legacyCodexHooksFeature) notes.push(runtime.msg('检测到旧版 `codex_hooks`;HelloAGENTS 只兼容 Codex 最新版,请移除旧 key。', 'Legacy `codex_hooks` was detected; HelloAGENTS targets latest Codex only, so remove the old key.'))
|
|
373
|
+
if (!nativeDoctor.available) notes.push(runtime.msg('未检测到原生 `codex doctor`;当前仅检查 HelloAGENTS 受管覆盖层。', 'Native `codex doctor` was not available; only the HelloAGENTS managed overlay was checked.'))
|
|
233
374
|
|
|
234
375
|
const status = summarizeDoctorStatus(issues, { trackedMode, detectedMode })
|
|
235
|
-
return {
|
|
376
|
+
return {
|
|
377
|
+
host,
|
|
378
|
+
label: runtime.getHostLabel(host),
|
|
379
|
+
trackedMode,
|
|
380
|
+
detectedMode,
|
|
381
|
+
status,
|
|
382
|
+
checks,
|
|
383
|
+
nativeDoctor,
|
|
384
|
+
issues,
|
|
385
|
+
notes,
|
|
386
|
+
suggestedFix: suggestCodexDoctorFix(status, trackedMode),
|
|
387
|
+
}
|
|
236
388
|
}
|
|
@@ -20,7 +20,8 @@ export function printDoctorText(runtime, report) {
|
|
|
20
20
|
if (entry.nativeDoctor) {
|
|
21
21
|
console.log(` native_doctor.available: ${entry.nativeDoctor.available ? 'ok' : 'missing'}`)
|
|
22
22
|
if (entry.nativeDoctor.available) {
|
|
23
|
-
console.log(` native_doctor.ok: ${entry.nativeDoctor.ok ? 'ok' : '
|
|
23
|
+
console.log(` native_doctor.ok: ${entry.nativeDoctor.ok ? 'ok' : 'fail'}`)
|
|
24
|
+
if (entry.nativeDoctor.status) console.log(` native_doctor.status: ${entry.nativeDoctor.status}`)
|
|
24
25
|
}
|
|
25
26
|
if (entry.nativeDoctor.summary) {
|
|
26
27
|
if (entry.nativeDoctor.summary.version) console.log(` native_doctor.version: ${entry.nativeDoctor.summary.version}`)
|
package/scripts/cli-doctor.mjs
CHANGED
|
@@ -106,8 +106,8 @@ function suggestDoctorFix(host, status, trackedMode) {
|
|
|
106
106
|
return `helloagents update ${host}${trackedMode && trackedMode !== 'none' ? ` --${trackedMode}` : ''}`
|
|
107
107
|
}
|
|
108
108
|
if (status === 'manual-plugin') {
|
|
109
|
-
if (host === 'claude') return '/plugin marketplace add hellowind777/helloagents; /plugin install helloagents@helloagents'
|
|
110
|
-
if (host === 'gemini') return '
|
|
109
|
+
if (host === 'claude') return '/plugin marketplace add https://github.com/hellowind777/helloagents.git; /plugin install helloagents@helloagents'
|
|
110
|
+
if (host === 'gemini') return 'helloagents install gemini --global'
|
|
111
111
|
}
|
|
112
112
|
if (status === 'not-installed') {
|
|
113
113
|
return `helloagents install ${host} --standby`
|
|
@@ -176,7 +176,7 @@ function inspectGeminiDoctor(settings) {
|
|
|
176
176
|
const detectedMode = normalizeDoctorMode(runtime.detectHostMode(host))
|
|
177
177
|
const geminiDir = join(runtime.home, '.gemini')
|
|
178
178
|
const geminiSettings = safeJson(join(geminiDir, 'settings.json')) || {}
|
|
179
|
-
const expectedHooks = readExpectedHooks('hooks.json', '${extensionPath}')
|
|
179
|
+
const expectedHooks = readExpectedHooks('hooks-gemini.json', '${extensionPath}')
|
|
180
180
|
const checks = {
|
|
181
181
|
carrierMarker: (safeRead(join(geminiDir, 'GEMINI.md')) || '').includes('HELLOAGENTS_START'),
|
|
182
182
|
carrierContentMatch: extractManagedCarrierContent(join(geminiDir, 'GEMINI.md'))
|
package/scripts/cli-hosts.mjs
CHANGED
|
@@ -65,7 +65,7 @@ export function installGeminiStandby(home, pkgRoot) {
|
|
|
65
65
|
createLink(pkgRoot, join(geminiDir, 'helloagents'));
|
|
66
66
|
|
|
67
67
|
const settingsPath = join(geminiDir, 'settings.json');
|
|
68
|
-
const hooksData = loadHooksWithCliEntry(pkgRoot, 'hooks.json', '${extensionPath}');
|
|
68
|
+
const hooksData = loadHooksWithCliEntry(pkgRoot, 'hooks-gemini.json', '${extensionPath}');
|
|
69
69
|
if (hooksData) mergeSettingsHooks(settingsPath, hooksData);
|
|
70
70
|
|
|
71
71
|
return true;
|