helloagents 3.0.12 → 3.0.15-beta.1
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 +6 -4
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +169 -30
- package/README_CN.md +169 -30
- package/bootstrap-lite.md +27 -20
- package/bootstrap.md +30 -23
- package/cli.mjs +119 -11
- package/gemini-extension.json +1 -1
- package/install.ps1 +125 -0
- package/install.sh +118 -0
- package/package.json +23 -4
- package/scripts/advisor-state.mjs +36 -63
- package/scripts/capability-registry.mjs +3 -3
- package/scripts/cli-branch.mjs +84 -0
- package/scripts/cli-codex-config.mjs +11 -20
- package/scripts/cli-codex.mjs +32 -38
- package/scripts/cli-doctor-render.mjs +4 -0
- package/scripts/cli-doctor.mjs +40 -30
- package/scripts/cli-host-detect.mjs +0 -1
- package/scripts/cli-hosts.mjs +16 -8
- package/scripts/cli-lifecycle-hosts.mjs +92 -27
- package/scripts/cli-lifecycle.mjs +9 -7
- package/scripts/cli-messages.mjs +34 -16
- package/scripts/cli-runtime-carrier.mjs +36 -0
- package/scripts/cli-runtime-root.mjs +72 -0
- package/scripts/cli-toml.mjs +0 -79
- package/scripts/cli-utils.mjs +30 -4
- package/scripts/closeout-state.mjs +35 -62
- package/scripts/delivery-gate-messages.mjs +70 -0
- package/scripts/delivery-gate.mjs +9 -75
- package/scripts/guard-rules.mjs +42 -42
- package/scripts/guard.mjs +44 -24
- package/scripts/notify-context.mjs +19 -28
- package/scripts/notify-gates.mjs +2 -0
- package/scripts/notify-route.mjs +9 -7
- package/scripts/notify-ui.mjs +46 -33
- package/scripts/notify.mjs +60 -32
- package/scripts/project-storage.mjs +35 -66
- package/scripts/ralph-loop.mjs +36 -31
- package/scripts/replay-state.mjs +31 -128
- package/scripts/review-state.mjs +34 -61
- package/scripts/runtime-artifacts.mjs +95 -0
- package/scripts/runtime-context.mjs +35 -29
- package/scripts/runtime-scope.mjs +313 -0
- package/scripts/session-capsule.mjs +202 -0
- package/scripts/turn-state-cli.mjs +17 -0
- package/scripts/turn-state.mjs +185 -66
- package/scripts/turn-stop-gate.mjs +24 -6
- package/scripts/verify-state.mjs +34 -85
- package/scripts/visual-state.mjs +38 -65
- package/scripts/workflow-core.mjs +2 -2
- package/scripts/workflow-plan-files.mjs +1 -1
- package/scripts/workflow-recommendation.mjs +17 -13
- package/scripts/workflow-state.mjs +5 -5
- package/skills/commands/build/SKILL.md +1 -1
- package/skills/commands/commit/SKILL.md +1 -1
- package/skills/commands/help/SKILL.md +3 -3
- package/skills/commands/loop/SKILL.md +1 -1
- package/skills/commands/plan/SKILL.md +8 -6
- package/skills/commands/prd/SKILL.md +5 -3
- package/skills/commands/verify/SKILL.md +5 -5
- package/skills/hello-debug/SKILL.md +20 -3
- package/skills/hello-review/SKILL.md +2 -2
- package/skills/hello-subagent/SKILL.md +2 -2
- package/skills/hello-test/SKILL.md +6 -2
- package/skills/hello-ui/SKILL.md +4 -4
- package/skills/hello-verify/SKILL.md +10 -7
- package/skills/helloagents/SKILL.md +12 -7
- package/templates/context.md +6 -0
- package/templates/plans/plan.md +3 -0
- package/templates/plans/tasks.md +8 -3
package/scripts/cli-doctor.mjs
CHANGED
|
@@ -2,14 +2,20 @@ import { existsSync, realpathSync } from 'node:fs'
|
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
|
|
4
4
|
import { CODEX_MARKETPLACE_NAME, CODEX_PLUGIN_CONFIG_HEADER, CODEX_PLUGIN_NAME } from './cli-codex.mjs'
|
|
5
|
+
import {
|
|
6
|
+
CODEX_MANAGED_MODEL_INSTRUCTIONS_PATH,
|
|
7
|
+
CODEX_MANAGED_NOTIFY_VALUE,
|
|
8
|
+
} from './cli-codex-config.mjs'
|
|
5
9
|
import { DEFAULTS } from './cli-config.mjs'
|
|
6
10
|
import { printDoctorText } from './cli-doctor-render.mjs'
|
|
11
|
+
import { buildRuntimeCarrier } from './cli-runtime-carrier.mjs'
|
|
7
12
|
import { readTopLevelTomlLine } from './cli-toml.mjs'
|
|
8
|
-
import {
|
|
13
|
+
import { loadHooksWithCliEntry, safeJson, safeRead } from './cli-utils.mjs'
|
|
9
14
|
|
|
10
15
|
const runtime = {
|
|
11
16
|
home: '',
|
|
12
17
|
pkgRoot: '',
|
|
18
|
+
sourceRoot: '',
|
|
13
19
|
pkgVersion: '',
|
|
14
20
|
msg: (cn, en) => en || cn,
|
|
15
21
|
readSettings: () => ({}),
|
|
@@ -69,15 +75,16 @@ function pickManagedHooks(hooks) {
|
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
function readExpectedHooks(hooksFile, pathVar) {
|
|
72
|
-
return pickManagedHooks(
|
|
78
|
+
return pickManagedHooks(loadHooksWithCliEntry(runtime.pkgRoot, hooksFile, pathVar)?.hooks || {})
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
function managedHooksMatch(actualHooks, expectedHooks) {
|
|
76
82
|
return stringifySorted(pickManagedHooks(actualHooks || {})) === stringifySorted(expectedHooks || {})
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
function
|
|
80
|
-
|
|
85
|
+
function readExpectedCarrierContent(fileName, settings) {
|
|
86
|
+
const bootstrap = safeRead(join(runtime.pkgRoot, fileName)) || ''
|
|
87
|
+
return normalizeText(buildRuntimeCarrier(bootstrap, settings))
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
function buildDoctorIssue(code, cn, en) {
|
|
@@ -104,7 +111,7 @@ function suggestDoctorFix(host, status, trackedMode) {
|
|
|
104
111
|
return `helloagents update ${host}${trackedMode && trackedMode !== 'none' ? ` --${trackedMode}` : ''}`
|
|
105
112
|
}
|
|
106
113
|
if (status === 'manual-plugin') {
|
|
107
|
-
if (host === 'claude') return '/plugin marketplace add hellowind777/helloagents'
|
|
114
|
+
if (host === 'claude') return '/plugin marketplace add hellowind777/helloagents; /plugin install helloagents@helloagents'
|
|
108
115
|
if (host === 'gemini') return 'gemini extensions install https://github.com/hellowind777/helloagents'
|
|
109
116
|
}
|
|
110
117
|
if (status === 'not-installed') {
|
|
@@ -126,12 +133,13 @@ function inspectClaudeDoctor(settings) {
|
|
|
126
133
|
const expectedHooks = readExpectedHooks('hooks-claude.json', '${CLAUDE_PLUGIN_ROOT}')
|
|
127
134
|
const checks = {
|
|
128
135
|
carrierMarker: (safeRead(join(claudeDir, 'CLAUDE.md')) || '').includes('HELLOAGENTS_START'),
|
|
129
|
-
carrierContentMatch: extractManagedCarrierContent(join(claudeDir, 'CLAUDE.md'))
|
|
136
|
+
carrierContentMatch: extractManagedCarrierContent(join(claudeDir, 'CLAUDE.md'))
|
|
137
|
+
=== readExpectedCarrierContent('bootstrap-lite.md', settings),
|
|
130
138
|
homeLink: safeRealTarget(join(claudeDir, 'helloagents')) === runtime.pkgRoot,
|
|
131
139
|
settingsHooks: JSON.stringify(claudeSettings.hooks || {}).includes('helloagents'),
|
|
132
140
|
settingsHooksMatch: managedHooksMatch(claudeSettings.hooks || {}, expectedHooks),
|
|
133
141
|
settingsPermission: Array.isArray(claudeSettings.permissions?.allow)
|
|
134
|
-
&& claudeSettings.permissions.allow.includes('Read(~/.
|
|
142
|
+
&& claudeSettings.permissions.allow.includes('Read(~/.helloagents/helloagents/**)'),
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
const issues = []
|
|
@@ -142,15 +150,15 @@ function inspectClaudeDoctor(settings) {
|
|
|
142
150
|
if (detectedMode === 'standby') {
|
|
143
151
|
if (!checks.carrierMarker) issues.push(buildDoctorIssue('standby-carrier-missing', 'standby 规则文件缺少 HELLOAGENTS 标记', 'Standby carrier is missing the HELLOAGENTS marker'))
|
|
144
152
|
if (checks.carrierMarker && !checks.carrierContentMatch) issues.push(buildDoctorIssue('standby-carrier-drift', 'standby 规则文件内容与当前 bootstrap-lite.md 不一致', 'Standby carrier content differs from the current bootstrap-lite.md'))
|
|
145
|
-
if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby home
|
|
153
|
+
if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby home 链接缺失或未指向稳定运行根目录', 'Standby home link is missing or points to a different runtime root'))
|
|
146
154
|
if (!checks.settingsHooks) issues.push(buildDoctorIssue('standby-hooks-missing', 'standby settings hooks 缺失', 'Standby settings hooks are missing'))
|
|
147
155
|
if (checks.settingsHooks && !checks.settingsHooksMatch) issues.push(buildDoctorIssue('standby-hooks-drift', 'standby settings hooks 与当前 hooks 配置不一致', 'Standby settings hooks differ from the current hook configuration'))
|
|
148
156
|
if (!checks.settingsPermission) issues.push(buildDoctorIssue('standby-permission-missing', 'standby Claude 权限注入缺失', 'Standby Claude permission injection is missing'))
|
|
149
157
|
}
|
|
150
158
|
if (trackedMode === 'global') {
|
|
151
159
|
notes.push(runtime.msg(
|
|
152
|
-
'Claude Code 的 global
|
|
153
|
-
'Claude Code global
|
|
160
|
+
'Claude Code 的 global 模式由宿主插件系统管理;doctor 只检查 standby 残留,不直接探测插件状态。',
|
|
161
|
+
'Claude Code global mode is managed by the host plugin system; doctor only checks for standby residue and does not inspect plugin state directly.',
|
|
154
162
|
))
|
|
155
163
|
if (checks.carrierMarker || checks.homeLink || checks.settingsHooks || checks.settingsPermission) {
|
|
156
164
|
issues.push(buildDoctorIssue('global-standby-residue', 'global 模式下仍残留 standby 注入/链接', 'Standby injections or links still remain while the host is tracked as global'))
|
|
@@ -176,7 +184,8 @@ function inspectGeminiDoctor(settings) {
|
|
|
176
184
|
const expectedHooks = readExpectedHooks('hooks.json', '${extensionPath}')
|
|
177
185
|
const checks = {
|
|
178
186
|
carrierMarker: (safeRead(join(geminiDir, 'GEMINI.md')) || '').includes('HELLOAGENTS_START'),
|
|
179
|
-
carrierContentMatch: extractManagedCarrierContent(join(geminiDir, 'GEMINI.md'))
|
|
187
|
+
carrierContentMatch: extractManagedCarrierContent(join(geminiDir, 'GEMINI.md'))
|
|
188
|
+
=== readExpectedCarrierContent('bootstrap-lite.md', settings),
|
|
180
189
|
homeLink: safeRealTarget(join(geminiDir, 'helloagents')) === runtime.pkgRoot,
|
|
181
190
|
settingsHooks: JSON.stringify(geminiSettings.hooks || {}).includes('helloagents'),
|
|
182
191
|
settingsHooksMatch: managedHooksMatch(geminiSettings.hooks || {}, expectedHooks),
|
|
@@ -190,14 +199,14 @@ function inspectGeminiDoctor(settings) {
|
|
|
190
199
|
if (detectedMode === 'standby') {
|
|
191
200
|
if (!checks.carrierMarker) issues.push(buildDoctorIssue('standby-carrier-missing', 'standby 规则文件缺少 HELLOAGENTS 标记', 'Standby carrier is missing the HELLOAGENTS marker'))
|
|
192
201
|
if (checks.carrierMarker && !checks.carrierContentMatch) issues.push(buildDoctorIssue('standby-carrier-drift', 'standby 规则文件内容与当前 bootstrap-lite.md 不一致', 'Standby carrier content differs from the current bootstrap-lite.md'))
|
|
193
|
-
if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby home
|
|
202
|
+
if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby home 链接缺失或未指向稳定运行根目录', 'Standby home link is missing or points to a different runtime root'))
|
|
194
203
|
if (!checks.settingsHooks) issues.push(buildDoctorIssue('standby-hooks-missing', 'standby settings hooks 缺失', 'Standby settings hooks are missing'))
|
|
195
204
|
if (checks.settingsHooks && !checks.settingsHooksMatch) issues.push(buildDoctorIssue('standby-hooks-drift', 'standby settings hooks 与当前 hooks 配置不一致', 'Standby settings hooks differ from the current hook configuration'))
|
|
196
205
|
}
|
|
197
206
|
if (trackedMode === 'global') {
|
|
198
207
|
notes.push(runtime.msg(
|
|
199
|
-
'Gemini CLI 的 global
|
|
200
|
-
'Gemini CLI global
|
|
208
|
+
'Gemini CLI 的 global 模式由宿主扩展系统管理;doctor 只检查 standby 残留,不直接探测扩展状态。',
|
|
209
|
+
'Gemini CLI global mode is managed by the host extension system; doctor only checks for standby residue and does not inspect extension state directly.',
|
|
201
210
|
))
|
|
202
211
|
if (checks.carrierMarker || checks.homeLink || checks.settingsHooks) {
|
|
203
212
|
issues.push(buildDoctorIssue('global-standby-residue', 'global 模式下仍残留 standby 注入/链接', 'Standby injections or links still remain while the host is tracked as global'))
|
|
@@ -217,12 +226,12 @@ function inspectGeminiDoctor(settings) {
|
|
|
217
226
|
function appendCodexStandbyIssues(issues, checks) {
|
|
218
227
|
if (!checks.carrierMarker) issues.push(buildDoctorIssue('standby-carrier-missing', 'standby 规则文件缺少 HELLOAGENTS 标记', 'Standby carrier is missing the HELLOAGENTS marker'))
|
|
219
228
|
if (checks.carrierMarker && !checks.carrierContentMatch) issues.push(buildDoctorIssue('standby-carrier-drift', 'standby 规则文件内容与当前 bootstrap-lite.md 不一致', 'Standby carrier content differs from the current bootstrap-lite.md'))
|
|
220
|
-
if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby home
|
|
229
|
+
if (!checks.homeLink) issues.push(buildDoctorIssue('standby-link-missing', 'standby home 链接缺失或未指向稳定运行根目录', 'Standby home link is missing or points to a different runtime root'))
|
|
221
230
|
if (!checks.modelInstructionsFile) issues.push(buildDoctorIssue('standby-model-instructions-missing', 'standby config 缺少受管 model_instructions_file', 'Standby config is missing the managed model_instructions_file'))
|
|
222
231
|
if (checks.modelInstructionsFile && !checks.modelInstructionsPathMatch) issues.push(buildDoctorIssue('standby-model-instructions-drift', 'standby model_instructions_file 未指向受管 `~/.codex/AGENTS.md`', 'Standby model_instructions_file does not point to the managed `~/.codex/AGENTS.md`'))
|
|
223
232
|
if (!checks.codexNotify) issues.push(buildDoctorIssue('standby-notify-missing', 'standby notify 配置缺失', 'Standby notify configuration is missing'))
|
|
224
|
-
if (checks.codexNotify && !checks.notifyPathMatch) issues.push(buildDoctorIssue('standby-notify-drift', 'standby notify
|
|
225
|
-
if (checks.pluginRoot || checks.pluginCache || checks.marketplaceEntry || checks.pluginEnabled
|
|
233
|
+
if (checks.codexNotify && !checks.notifyPathMatch) issues.push(buildDoctorIssue('standby-notify-drift', 'standby notify 未使用受管命令入口', 'Standby notify does not use the managed command entrypoint'))
|
|
234
|
+
if (checks.pluginRoot || checks.pluginCache || checks.marketplaceEntry || checks.pluginEnabled) {
|
|
226
235
|
issues.push(buildDoctorIssue('standby-global-residue', 'standby 模式下仍残留 global 插件文件或配置', 'Global plugin artifacts still remain while Codex is in standby mode'))
|
|
227
236
|
}
|
|
228
237
|
}
|
|
@@ -239,8 +248,8 @@ function appendCodexGlobalIssues(issues, checks, pluginVersion, cacheVersion) {
|
|
|
239
248
|
if (!checks.pluginEnabled) issues.push(buildDoctorIssue('global-plugin-disabled', 'global config 中缺少插件启用段', 'Global plugin enablement block is missing from config'))
|
|
240
249
|
if (!checks.modelInstructionsFile) issues.push(buildDoctorIssue('global-model-instructions-missing', 'global config 缺少受管 model_instructions_file', 'Global config is missing the managed model_instructions_file'))
|
|
241
250
|
if (checks.modelInstructionsFile && !checks.modelInstructionsPathMatch) issues.push(buildDoctorIssue('global-model-instructions-drift', 'global model_instructions_file 未指向受管 `~/.codex/AGENTS.md`', 'Global model_instructions_file does not point to the managed `~/.codex/AGENTS.md`'))
|
|
242
|
-
if (!checks.
|
|
243
|
-
if (checks.
|
|
251
|
+
if (!checks.codexNotify) issues.push(buildDoctorIssue('global-notify-missing', 'global notify 配置缺失', 'Global notify configuration is missing'))
|
|
252
|
+
if (checks.codexNotify && !checks.globalNotifyPathMatch) issues.push(buildDoctorIssue('global-notify-drift', 'global notify 未使用受管命令入口', 'Global notify does not use the managed command entrypoint'))
|
|
244
253
|
if (pluginVersion && !checks.pluginVersionMatch) issues.push(buildDoctorIssue('global-plugin-version-drift', 'global 插件根目录版本与当前包版本不一致', 'Global plugin root version does not match the current package version'))
|
|
245
254
|
if (cacheVersion && !checks.pluginCacheVersionMatch) issues.push(buildDoctorIssue('global-plugin-cache-version-drift', 'global 插件缓存版本与当前包版本不一致', 'Global plugin cache version does not match the current package version'))
|
|
246
255
|
if (checks.homeLink) {
|
|
@@ -262,31 +271,31 @@ function inspectCodexDoctor(settings) {
|
|
|
262
271
|
const homeLinkTarget = safeRealTarget(join(codexDir, 'helloagents'))
|
|
263
272
|
const pkgRootTarget = safeRealTarget(runtime.pkgRoot) || normalizePath(runtime.pkgRoot)
|
|
264
273
|
const pluginRootTarget = safeRealTarget(pluginRoot) || normalizePath(pluginRoot)
|
|
265
|
-
const standbyNotifyPath = normalizePath(join(runtime.pkgRoot, 'scripts', 'notify.mjs'))
|
|
266
|
-
const globalNotifyPath = normalizePath(join(pluginRoot, 'scripts', 'notify.mjs'))
|
|
267
|
-
const managedHomeCarrierPath = normalizePath(join(codexDir, 'AGENTS.md'))
|
|
268
274
|
const modelInstructionsLine = readTopLevelTomlLine(codexConfig, 'model_instructions_file')
|
|
269
275
|
const expectedHomeCarrier = (detectedMode === 'global' || (detectedMode === 'none' && trackedMode === 'global'))
|
|
270
276
|
? 'bootstrap.md'
|
|
271
277
|
: 'bootstrap-lite.md'
|
|
272
278
|
const checks = {
|
|
273
279
|
carrierMarker: (safeRead(join(codexDir, 'AGENTS.md')) || '').includes('HELLOAGENTS_START'),
|
|
274
|
-
carrierContentMatch: extractManagedCarrierContent(join(codexDir, 'AGENTS.md'))
|
|
280
|
+
carrierContentMatch: extractManagedCarrierContent(join(codexDir, 'AGENTS.md'))
|
|
281
|
+
=== readExpectedCarrierContent(expectedHomeCarrier, settings),
|
|
275
282
|
homeLink: homeLinkTarget === pkgRootTarget,
|
|
276
283
|
globalHomeLink: homeLinkTarget === pluginRootTarget,
|
|
277
284
|
modelInstructionsFile: !!modelInstructionsLine,
|
|
278
285
|
modelInstructionsPathMatch: !!modelInstructionsLine
|
|
279
|
-
&& normalizePath(modelInstructionsLine).includes(`"${
|
|
286
|
+
&& normalizePath(modelInstructionsLine).includes(`"${CODEX_MANAGED_MODEL_INSTRUCTIONS_PATH}"`),
|
|
280
287
|
codexNotify: codexConfig.includes('codex-notify'),
|
|
281
|
-
notifyPathMatch: codexConfig.includes(
|
|
288
|
+
notifyPathMatch: codexConfig.includes(CODEX_MANAGED_NOTIFY_VALUE),
|
|
282
289
|
pluginRoot: existsSync(pluginRoot),
|
|
283
290
|
pluginCache: existsSync(pluginCacheRoot),
|
|
284
|
-
pluginCarrierMatch: normalizeText(safeRead(join(pluginRoot, 'AGENTS.md')) || '')
|
|
285
|
-
|
|
291
|
+
pluginCarrierMatch: normalizeText(safeRead(join(pluginRoot, 'AGENTS.md')) || '')
|
|
292
|
+
=== readExpectedCarrierContent('bootstrap.md', settings),
|
|
293
|
+
pluginCacheCarrierMatch: normalizeText(safeRead(join(pluginCacheRoot, 'AGENTS.md')) || '')
|
|
294
|
+
=== readExpectedCarrierContent('bootstrap.md', settings),
|
|
286
295
|
marketplaceEntry: Array.isArray(marketplace.plugins) && marketplace.plugins.some((plugin) => plugin?.name === CODEX_PLUGIN_NAME),
|
|
287
296
|
pluginEnabled: codexConfig.includes(CODEX_PLUGIN_CONFIG_HEADER) && codexConfig.includes('enabled = true'),
|
|
288
|
-
globalNotifyPath: codexConfig.includes('
|
|
289
|
-
globalNotifyPathMatch: codexConfig.includes(
|
|
297
|
+
globalNotifyPath: codexConfig.includes('codex-notify'),
|
|
298
|
+
globalNotifyPathMatch: codexConfig.includes(CODEX_MANAGED_NOTIFY_VALUE),
|
|
290
299
|
pluginVersionMatch: pluginVersion ? pluginVersion === runtime.pkgVersion : false,
|
|
291
300
|
pluginCacheVersionMatch: cacheVersion ? cacheVersion === runtime.pkgVersion : false,
|
|
292
301
|
}
|
|
@@ -355,7 +364,8 @@ function buildDoctorReport(host) {
|
|
|
355
364
|
return {
|
|
356
365
|
config: {
|
|
357
366
|
packageVersion: runtime.pkgVersion,
|
|
358
|
-
|
|
367
|
+
runtimeRoot: runtime.pkgRoot,
|
|
368
|
+
packageRoot: runtime.sourceRoot || runtime.pkgRoot,
|
|
359
369
|
installMode: settings.install_mode || DEFAULTS.install_mode,
|
|
360
370
|
trackedHostModes: settings.host_install_modes || {},
|
|
361
371
|
},
|
|
@@ -75,7 +75,6 @@ function detectCodexMode(home) {
|
|
|
75
75
|
|| existsSync(join(codexDir, 'plugins', 'cache', CODEX_MARKETPLACE_NAME, CODEX_PLUGIN_NAME))
|
|
76
76
|
|| marketplace.includes(`"name": "${CODEX_PLUGIN_NAME}"`)
|
|
77
77
|
|| codexConfig.includes(CODEX_PLUGIN_KEY)
|
|
78
|
-
|| codexConfig.includes(`/plugins/${CODEX_PLUGIN_NAME}/scripts/notify.mjs`)
|
|
79
78
|
|| codexHomeLinkTarget === globalPluginRoot
|
|
80
79
|
) {
|
|
81
80
|
return 'global'
|
package/scripts/cli-hosts.mjs
CHANGED
|
@@ -3,15 +3,15 @@ import { existsSync } from 'node:fs';
|
|
|
3
3
|
import {
|
|
4
4
|
ensureDir,
|
|
5
5
|
safeRead,
|
|
6
|
-
removeIfExists,
|
|
7
6
|
createLink,
|
|
8
7
|
removeLink,
|
|
9
8
|
injectMarkedContent,
|
|
10
9
|
removeMarkedContent,
|
|
11
10
|
mergeSettingsHooks,
|
|
12
11
|
cleanSettingsHooks,
|
|
13
|
-
|
|
12
|
+
loadHooksWithCliEntry,
|
|
14
13
|
} from './cli-utils.mjs';
|
|
14
|
+
import { buildRuntimeCarrier, readCarrierSettings } from './cli-runtime-carrier.mjs';
|
|
15
15
|
|
|
16
16
|
export function installClaudeStandby(home, pkgRoot) {
|
|
17
17
|
const claudeDir = join(home, '.claude');
|
|
@@ -19,15 +19,21 @@ export function installClaudeStandby(home, pkgRoot) {
|
|
|
19
19
|
|
|
20
20
|
const bootstrapContent = safeRead(join(pkgRoot, 'bootstrap-lite.md'));
|
|
21
21
|
if (bootstrapContent) {
|
|
22
|
-
injectMarkedContent(
|
|
22
|
+
injectMarkedContent(
|
|
23
|
+
join(claudeDir, 'CLAUDE.md'),
|
|
24
|
+
buildRuntimeCarrier(bootstrapContent, readCarrierSettings(home)).trimEnd(),
|
|
25
|
+
);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
createLink(pkgRoot, join(claudeDir, 'helloagents'));
|
|
26
29
|
|
|
27
30
|
const settingsPath = join(claudeDir, 'settings.json');
|
|
28
|
-
const hooksData =
|
|
31
|
+
const hooksData = loadHooksWithCliEntry(pkgRoot, 'hooks-claude.json', '${CLAUDE_PLUGIN_ROOT}');
|
|
29
32
|
if (hooksData) {
|
|
30
|
-
mergeSettingsHooks(settingsPath, hooksData, [
|
|
33
|
+
mergeSettingsHooks(settingsPath, hooksData, [
|
|
34
|
+
'Read(~/.helloagents/helloagents/**)',
|
|
35
|
+
'Read(~/.claude/helloagents/**)',
|
|
36
|
+
]);
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
return true;
|
|
@@ -50,13 +56,16 @@ export function installGeminiStandby(home, pkgRoot) {
|
|
|
50
56
|
|
|
51
57
|
const bootstrapContent = safeRead(join(pkgRoot, 'bootstrap-lite.md'));
|
|
52
58
|
if (bootstrapContent) {
|
|
53
|
-
injectMarkedContent(
|
|
59
|
+
injectMarkedContent(
|
|
60
|
+
join(geminiDir, 'GEMINI.md'),
|
|
61
|
+
buildRuntimeCarrier(bootstrapContent, readCarrierSettings(home)).trimEnd(),
|
|
62
|
+
);
|
|
54
63
|
}
|
|
55
64
|
|
|
56
65
|
createLink(pkgRoot, join(geminiDir, 'helloagents'));
|
|
57
66
|
|
|
58
67
|
const settingsPath = join(geminiDir, 'settings.json');
|
|
59
|
-
const hooksData =
|
|
68
|
+
const hooksData = loadHooksWithCliEntry(pkgRoot, 'hooks.json', '${extensionPath}');
|
|
60
69
|
if (hooksData) mergeSettingsHooks(settingsPath, hooksData);
|
|
61
70
|
|
|
62
71
|
return true;
|
|
@@ -69,7 +78,6 @@ export function uninstallGeminiStandby(home) {
|
|
|
69
78
|
removeMarkedContent(join(geminiDir, 'GEMINI.md'));
|
|
70
79
|
removeLink(join(geminiDir, 'helloagents'));
|
|
71
80
|
cleanSettingsHooks(join(geminiDir, 'settings.json'));
|
|
72
|
-
removeIfExists(join(geminiDir, 'helloagents-hooks.json'));
|
|
73
81
|
|
|
74
82
|
return true;
|
|
75
83
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process'
|
|
2
|
+
|
|
1
3
|
import { installClaudeStandby, installGeminiStandby, uninstallClaudeStandby, uninstallGeminiStandby } from './cli-hosts.mjs'
|
|
2
4
|
import {
|
|
5
|
+
cleanupCodexGlobalResidueForStandby,
|
|
3
6
|
installCodexGlobal,
|
|
4
7
|
installCodexStandby,
|
|
5
8
|
uninstallCodexGlobal,
|
|
@@ -7,6 +10,55 @@ import {
|
|
|
7
10
|
} from './cli-codex.mjs'
|
|
8
11
|
import { getHostLabel } from './cli-host-detect.mjs'
|
|
9
12
|
|
|
13
|
+
const CLAUDE_COMMAND = process.env.HELLOAGENTS_CLAUDE_CMD || 'claude'
|
|
14
|
+
const GEMINI_COMMAND = process.env.HELLOAGENTS_GEMINI_CMD || 'gemini'
|
|
15
|
+
const CLAUDE_MARKETPLACE = 'hellowind777/helloagents'
|
|
16
|
+
const CLAUDE_PLUGIN = 'helloagents@helloagents'
|
|
17
|
+
const GEMINI_EXTENSION = 'https://github.com/hellowind777/helloagents'
|
|
18
|
+
|
|
19
|
+
function runHostCommand(command, args) {
|
|
20
|
+
const needsShell = process.platform === 'win32' && /\.cmd$/i.test(command)
|
|
21
|
+
const result = spawnSync(command, args, {
|
|
22
|
+
encoding: 'utf-8',
|
|
23
|
+
errors: 'replace',
|
|
24
|
+
shell: needsShell,
|
|
25
|
+
windowsHide: true,
|
|
26
|
+
})
|
|
27
|
+
const errorMessage = result.error?.message || ''
|
|
28
|
+
return {
|
|
29
|
+
ok: result.status === 0,
|
|
30
|
+
missing: result.error?.code === 'ENOENT',
|
|
31
|
+
output: `${result.stdout || ''}${result.stderr || ''}${errorMessage}`.trim(),
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function buildNativeResult(result, successCN, successEN, manualCN, manualEN) {
|
|
36
|
+
if (result.ok) return { noteCN: successCN, noteEN: successEN }
|
|
37
|
+
return {
|
|
38
|
+
noteCN: `${manualCN}${result.output ? `;原因:${result.output}` : ''}`,
|
|
39
|
+
noteEN: `${manualEN}${result.output ? `; reason: ${result.output}` : ''}`,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function installClaudeGlobalPlugin() {
|
|
44
|
+
const add = runHostCommand(CLAUDE_COMMAND, ['plugin', 'marketplace', 'add', CLAUDE_MARKETPLACE])
|
|
45
|
+
if (!add.ok && add.missing) return { ok: false, output: '未找到 claude 命令' }
|
|
46
|
+
const install = runHostCommand(CLAUDE_COMMAND, ['plugin', 'install', CLAUDE_PLUGIN, '--scope', 'user'])
|
|
47
|
+
return { ok: install.ok, output: install.output || add.output }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function installGeminiGlobalExtension() {
|
|
51
|
+
return runHostCommand(GEMINI_COMMAND, ['extensions', 'install', GEMINI_EXTENSION])
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function removeClaudeGlobalPlugin() {
|
|
55
|
+
return runHostCommand(CLAUDE_COMMAND, ['plugin', 'remove', 'helloagents'])
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function removeGeminiGlobalExtension() {
|
|
59
|
+
return runHostCommand(GEMINI_COMMAND, ['extensions', 'uninstall', 'helloagents'])
|
|
60
|
+
}
|
|
61
|
+
|
|
10
62
|
function reportHostAction(runtime, action, host, mode, result = {}) {
|
|
11
63
|
const label = getHostLabel(host)
|
|
12
64
|
const isCleanup = action === 'cleanup' || action === 'uninstall'
|
|
@@ -36,24 +88,31 @@ function installHostStandby(runtime, host) {
|
|
|
36
88
|
installGeminiStandby(runtime.home, runtime.pkgRoot)
|
|
37
89
|
return {}
|
|
38
90
|
}
|
|
39
|
-
|
|
40
|
-
|
|
91
|
+
if (!installCodexStandby(runtime.home, runtime.pkgRoot)) return { skipped: true }
|
|
92
|
+
cleanupCodexGlobalResidueForStandby(runtime.home)
|
|
93
|
+
return {}
|
|
41
94
|
}
|
|
42
95
|
|
|
43
96
|
function installHostGlobal(runtime, host) {
|
|
44
97
|
if (host === 'claude') {
|
|
45
98
|
uninstallClaudeStandby(runtime.home)
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
99
|
+
return buildNativeResult(
|
|
100
|
+
installClaudeGlobalPlugin(),
|
|
101
|
+
'已自动安装 Claude Code 插件;重启 Claude Code 后生效',
|
|
102
|
+
'Claude Code plugin installed automatically; restart Claude Code to apply',
|
|
103
|
+
'Claude Code 插件自动安装失败,请在 Claude Code 中执行: /plugin marketplace add hellowind777/helloagents;/plugin install helloagents@helloagents',
|
|
104
|
+
'Claude Code plugin auto-install failed. Run inside Claude Code: /plugin marketplace add hellowind777/helloagents; /plugin install helloagents@helloagents',
|
|
105
|
+
)
|
|
50
106
|
}
|
|
51
107
|
if (host === 'gemini') {
|
|
52
108
|
uninstallGeminiStandby(runtime.home)
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
109
|
+
return buildNativeResult(
|
|
110
|
+
installGeminiGlobalExtension(),
|
|
111
|
+
'已自动安装 Gemini CLI 扩展;重启 Gemini CLI 后生效',
|
|
112
|
+
'Gemini CLI extension installed automatically; restart Gemini CLI to apply',
|
|
113
|
+
'Gemini CLI 扩展自动安装失败,请手动执行: gemini extensions install https://github.com/hellowind777/helloagents',
|
|
114
|
+
'Gemini CLI extension auto-install failed. Run manually: gemini extensions install https://github.com/hellowind777/helloagents',
|
|
115
|
+
)
|
|
57
116
|
}
|
|
58
117
|
uninstallCodexStandby(runtime.home)
|
|
59
118
|
return installCodexGlobal(runtime.home, runtime.pkgRoot) ? {} : { skipped: true }
|
|
@@ -70,35 +129,41 @@ function cleanupHostStandby(runtime, host) {
|
|
|
70
129
|
function cleanupHostGlobal(runtime, host) {
|
|
71
130
|
if (host === 'claude') {
|
|
72
131
|
uninstallClaudeStandby(runtime.home)
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
132
|
+
return buildNativeResult(
|
|
133
|
+
removeClaudeGlobalPlugin(),
|
|
134
|
+
'已自动移除 Claude Code 插件',
|
|
135
|
+
'Claude Code plugin removed automatically',
|
|
136
|
+
'Claude Code 插件自动移除失败,请手动执行: /plugin remove helloagents',
|
|
137
|
+
'Claude Code plugin auto-remove failed. Run manually: /plugin remove helloagents',
|
|
138
|
+
)
|
|
77
139
|
}
|
|
78
140
|
if (host === 'gemini') {
|
|
79
141
|
uninstallGeminiStandby(runtime.home)
|
|
80
|
-
return
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
142
|
+
return buildNativeResult(
|
|
143
|
+
removeGeminiGlobalExtension(),
|
|
144
|
+
'已自动移除 Gemini CLI 扩展',
|
|
145
|
+
'Gemini CLI extension removed automatically',
|
|
146
|
+
'Gemini CLI 扩展自动移除失败,请手动执行: gemini extensions uninstall helloagents',
|
|
147
|
+
'Gemini CLI extension auto-remove failed. Run manually: gemini extensions uninstall helloagents',
|
|
148
|
+
)
|
|
84
149
|
}
|
|
85
150
|
return { skipped: !uninstallCodexGlobal(runtime.home) }
|
|
86
151
|
}
|
|
87
152
|
|
|
88
153
|
function installStandby(runtime) {
|
|
89
|
-
uninstallCodexGlobal(runtime.home)
|
|
90
154
|
if (installClaudeStandby(runtime.home, runtime.pkgRoot)) runtime.ok(runtime.msg('Claude Code 已配置(standby 模式)', 'Claude Code configured (standby mode)'))
|
|
91
155
|
if (installGeminiStandby(runtime.home, runtime.pkgRoot)) runtime.ok(runtime.msg('Gemini CLI 已配置(standby 模式)', 'Gemini CLI configured (standby mode)'))
|
|
92
|
-
if (installCodexStandby(runtime.home, runtime.pkgRoot))
|
|
156
|
+
if (installCodexStandby(runtime.home, runtime.pkgRoot)) {
|
|
157
|
+
cleanupCodexGlobalResidueForStandby(runtime.home)
|
|
158
|
+
runtime.ok(runtime.msg('Codex CLI 已配置(standby 模式)', 'Codex CLI configured (standby mode)'))
|
|
159
|
+
}
|
|
93
160
|
else console.log(runtime.msg(' - Codex CLI 未检测到,跳过', ' - Codex CLI not detected, skipped'))
|
|
94
161
|
}
|
|
95
162
|
|
|
96
163
|
function installGlobal(runtime) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (installCodexGlobal(runtime.home, runtime.pkgRoot)) runtime.ok(runtime.msg('Codex CLI 已安装原生本地插件(global 模式)', 'Codex CLI native local plugin installed (global mode)'))
|
|
101
|
-
else console.log(runtime.msg(' - Codex CLI 未检测到,跳过', ' - Codex CLI not detected, skipped'))
|
|
164
|
+
for (const host of ['claude', 'gemini', 'codex']) {
|
|
165
|
+
reportHostAction(runtime, 'install', host, 'global', installHostGlobal(runtime, host))
|
|
166
|
+
}
|
|
102
167
|
}
|
|
103
168
|
|
|
104
169
|
export function installAllHosts(runtime, mode) {
|
|
@@ -107,8 +172,8 @@ export function installAllHosts(runtime, mode) {
|
|
|
107
172
|
}
|
|
108
173
|
|
|
109
174
|
export function uninstallAllHosts(runtime) {
|
|
110
|
-
|
|
111
|
-
|
|
175
|
+
cleanupHostGlobal(runtime, 'claude')
|
|
176
|
+
cleanupHostGlobal(runtime, 'gemini')
|
|
112
177
|
uninstallCodexStandby(runtime.home)
|
|
113
178
|
uninstallCodexGlobal(runtime.home)
|
|
114
179
|
}
|
|
@@ -15,6 +15,7 @@ export const HOSTS = ['claude', 'gemini', 'codex']
|
|
|
15
15
|
const runtime = {
|
|
16
16
|
home: '',
|
|
17
17
|
pkgRoot: '',
|
|
18
|
+
sourceRoot: '',
|
|
18
19
|
helloagentsHome: '',
|
|
19
20
|
configFile: '',
|
|
20
21
|
pkgVersion: '',
|
|
@@ -124,10 +125,11 @@ function resolveInstallMode(explicitMode, settings) {
|
|
|
124
125
|
|
|
125
126
|
|
|
126
127
|
export function syncVersion() {
|
|
128
|
+
const packageRoot = runtime.sourceRoot || runtime.pkgRoot
|
|
127
129
|
const targets = [
|
|
128
|
-
join(
|
|
129
|
-
join(
|
|
130
|
-
join(
|
|
130
|
+
join(packageRoot, '.claude-plugin', 'plugin.json'),
|
|
131
|
+
join(packageRoot, '.codex-plugin', 'plugin.json'),
|
|
132
|
+
join(packageRoot, 'gemini-extension.json'),
|
|
131
133
|
]
|
|
132
134
|
for (const path of targets) {
|
|
133
135
|
const obj = safeJson(path)
|
|
@@ -135,9 +137,9 @@ export function syncVersion() {
|
|
|
135
137
|
obj.version = runtime.pkgVersion
|
|
136
138
|
safeWrite(path, JSON.stringify(obj, null, 2) + '\n')
|
|
137
139
|
}
|
|
138
|
-
const marketPath = join(
|
|
140
|
+
const marketPath = join(packageRoot, '.claude-plugin', 'marketplace.json')
|
|
139
141
|
const market = safeJson(marketPath)
|
|
140
|
-
if (market?.plugins?.[0]) {
|
|
142
|
+
if (market?.plugins?.[0]?.version) {
|
|
141
143
|
market.plugins[0].version = runtime.pkgVersion
|
|
142
144
|
safeWrite(marketPath, JSON.stringify(market, null, 2) + '\n')
|
|
143
145
|
}
|
|
@@ -173,8 +175,8 @@ function runAllHostsLifecycle(action, explicitMode) {
|
|
|
173
175
|
}
|
|
174
176
|
runtime.ok(runtime.msg('所有 CLI 配置已清理', 'All CLI configurations cleaned'))
|
|
175
177
|
console.log(runtime.msg(
|
|
176
|
-
' ℹ ~/.helloagents/ 已保留(如需彻底清理请手动删除)\n ℹ
|
|
177
|
-
' ℹ ~/.helloagents/ preserved (delete manually if desired)\n ℹ
|
|
178
|
+
' ℹ ~/.helloagents/ 已保留(如需彻底清理请手动删除)\n ℹ 已自动尝试移除 Claude/Gemini 插件或扩展;如宿主命令不可用,请手动执行对应移除命令',
|
|
179
|
+
' ℹ ~/.helloagents/ preserved (delete manually if desired)\n ℹ Claude/Gemini plugin or extension removal was attempted automatically; if host commands are unavailable, remove them manually',
|
|
178
180
|
))
|
|
179
181
|
console.log()
|
|
180
182
|
return
|
package/scripts/cli-messages.mjs
CHANGED
|
@@ -20,7 +20,11 @@ function codexGlobalStatus({ home, msg }) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function pluginCommands() {
|
|
23
|
-
return
|
|
23
|
+
return [
|
|
24
|
+
' Claude Code: /plugin marketplace add hellowind777/helloagents',
|
|
25
|
+
' /plugin install helloagents@helloagents',
|
|
26
|
+
' Gemini CLI: gemini extensions install https://github.com/hellowind777/helloagents',
|
|
27
|
+
].join('\n')
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
function removeHint(msg) {
|
|
@@ -30,6 +34,13 @@ function removeHint(msg) {
|
|
|
30
34
|
)
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
function restartHint(msg) {
|
|
38
|
+
return msg(
|
|
39
|
+
'重装、刷新或切换模式后,请重启对应 AI CLI 或新开会话;已运行会话不会自动重载注入规则。',
|
|
40
|
+
'After reinstalling, refreshing, or switching modes, restart the target AI CLI or open a new session; already running sessions do not reload injected rules automatically.',
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
function renderInstallMessage(context, mode, state) {
|
|
34
45
|
const { msg } = context
|
|
35
46
|
const install = state === 'install'
|
|
@@ -38,34 +49,34 @@ function renderInstallMessage(context, mode, state) {
|
|
|
38
49
|
if (mode === 'global') {
|
|
39
50
|
if (install) {
|
|
40
51
|
return msg(
|
|
41
|
-
`\n ✅ HelloAGENTS 已安装(global 模式)!\n\n
|
|
42
|
-
`\n ✅ HelloAGENTS installed (global mode)!\n\n
|
|
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)`,
|
|
43
54
|
)
|
|
44
55
|
}
|
|
45
56
|
return msg(
|
|
46
57
|
refresh
|
|
47
|
-
?
|
|
48
|
-
:
|
|
58
|
+
? ` global 模式已刷新。\n Claude Code / Gemini 已自动尝试刷新宿主插件/扩展;Codex 原生本地插件已重装并同步最新文件。\n ${restartHint(msg)}`
|
|
59
|
+
: ` 所有项目将自动启用完整 HelloAGENTS 规则。\n Claude Code / Gemini 已自动尝试安装宿主插件/扩展;Codex 已自动安装原生本地插件。\n ${restartHint(msg)}\n\n若宿主命令不可用,请手动执行:\n${pluginCommands()}`,
|
|
49
60
|
refresh
|
|
50
|
-
?
|
|
51
|
-
:
|
|
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()}`,
|
|
52
63
|
)
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
if (install) {
|
|
56
67
|
return msg(
|
|
57
|
-
`\n ✅ HelloAGENTS 已安装(standby 模式)!\n\n Claude Code: 已自动配置(~/.claude/CLAUDE.md + hooks)\n Gemini CLI: 已自动配置(~/.gemini/GEMINI.md)\n Codex: ${codexStandbyStatus(context)}\n\n standby 模式下,hello-* 技能不会自动触发。\n 在项目中使用 ~wiki 仅创建/同步知识库,或用 ~init 完整初始化项目;也可用 ~command 按需调用。\n\n 切换模式:\n helloagents --global
|
|
58
|
-
`\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 In standby mode, hello-* skills won't auto-trigger.\n Use ~wiki to create or sync the KB only, or ~init for the full project bootstrap; ~command stays available on demand.\n\n Switch modes:\n helloagents --global Global mode (
|
|
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 完整初始化项目;也可用 ~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 to create or sync the KB only, or ~init for the full project bootstrap; ~command stays available on demand.\n\n Switch modes:\n helloagents --global Global mode (auto-attempts Claude/Gemini plugins or extensions; native local plugin auto-install for Codex)`,
|
|
59
70
|
)
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
return msg(
|
|
63
74
|
refresh
|
|
64
|
-
? ` standby 模式已刷新,CLI 注入与链接已同步最新文件。\n ${removeHint(msg)}`
|
|
65
|
-
: ` 项目可通过 ~wiki 创建/同步知识库,或通过 ~init 完整初始化;未激活项目仅注入通用规则。\n ${removeHint(msg)}`,
|
|
75
|
+
? ` standby 模式已刷新,CLI 注入与链接已同步最新文件。\n ${restartHint(msg)}\n ${removeHint(msg)}`
|
|
76
|
+
: ` 项目可通过 ~wiki 创建/同步知识库,或通过 ~init 完整初始化;未激活项目仅注入通用规则。\n ${restartHint(msg)}\n ${removeHint(msg)}`,
|
|
66
77
|
refresh
|
|
67
|
-
? ` Standby mode refreshed; injected files and links were synchronized.\n ${removeHint(msg)}`
|
|
68
|
-
: ` Projects can use ~wiki for KB-only activation or ~init for the full bootstrap. Unactivated projects get lite rules only.\n ${removeHint(msg)}`,
|
|
78
|
+
? ` Standby mode refreshed; injected files and links were synchronized.\n ${restartHint(msg)}\n ${removeHint(msg)}`
|
|
79
|
+
: ` Projects can use ~wiki for KB-only activation or ~init for the full bootstrap. Unactivated projects get lite rules only.\n ${restartHint(msg)}\n ${removeHint(msg)}`,
|
|
69
80
|
)
|
|
70
81
|
}
|
|
71
82
|
|
|
@@ -74,11 +85,12 @@ function renderHelp({ pkgVersion, msg }) {
|
|
|
74
85
|
HelloAGENTS v${pkgVersion} — The orchestration kernel for AI CLIs
|
|
75
86
|
|
|
76
87
|
${msg('安装', 'Install')}:
|
|
77
|
-
npm install -g helloagents ${msg('
|
|
88
|
+
npm install -g helloagents ${msg('(安装命令并同步稳定运行根目录;CLI 部署需显式执行 helloagents install ...)', '(installs the command and syncs the stable runtime root; deploy to CLIs explicitly with helloagents install ...)')}
|
|
89
|
+
HELLOAGENTS=codex:global npm install -g helloagents
|
|
78
90
|
helloagents-js ${msg('(稳定别名,避免与系统中同名可执行文件冲突)', '(stable alias to avoid conflicts with system executables of the same name)')}
|
|
79
91
|
|
|
80
92
|
${msg('模式切换', 'Mode switching')}:
|
|
81
|
-
helloagents --global ${msg('
|
|
93
|
+
helloagents --global ${msg('全局模式(自动尝试 Claude/Gemini 插件或扩展;Codex 自动装原生本地插件)', 'Global mode (auto-attempts Claude/Gemini plugins or extensions; native local plugin auto-install for Codex)')}
|
|
82
94
|
helloagents --standby ${msg('标准模式(非插件安装,hello-* 不自动触发,默认)', "Standby mode (non-plugin install, hello-* won't auto-trigger, default)")}
|
|
83
95
|
|
|
84
96
|
${msg('单 CLI 管理', 'Scoped CLI management')}:
|
|
@@ -89,6 +101,12 @@ ${msg('单 CLI 管理', 'Scoped CLI management')}:
|
|
|
89
101
|
helloagents uninstall gemini
|
|
90
102
|
${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')}
|
|
91
103
|
|
|
104
|
+
${msg('分支切换', 'Branch switching')}:
|
|
105
|
+
helloagents switch-branch beta
|
|
106
|
+
helloagents switch-branch beta claude --global
|
|
107
|
+
helloagents branch github:hellowind777/helloagents#beta --all --standby
|
|
108
|
+
${msg('先通过 npm 安装指定 ref,再通过 npm 脚本同步宿主 CLI', 'Installs the requested ref with npm first, then syncs host CLIs through npm scripts')}
|
|
109
|
+
|
|
92
110
|
${msg('诊断', 'Diagnostics')}:
|
|
93
111
|
helloagents doctor
|
|
94
112
|
helloagents doctor codex --json
|
|
@@ -97,7 +115,7 @@ ${msg('诊断', 'Diagnostics')}:
|
|
|
97
115
|
${msg('卸载', 'Uninstall')}:
|
|
98
116
|
helloagents cleanup ${msg('(推荐先执行,显式清理所有 CLI 注入/链接)', '(recommended first, explicitly cleans CLI injections/links)')}
|
|
99
117
|
npm uninstall -g helloagents
|
|
100
|
-
${msg('
|
|
118
|
+
${msg('如宿主命令不可用,另需手动移除:', 'If host commands are unavailable, also remove manually:')}
|
|
101
119
|
Claude Code: /plugin remove helloagents
|
|
102
120
|
Gemini CLI: gemini extensions uninstall helloagents
|
|
103
121
|
`.trim()
|