helloagents 3.0.38 → 3.1.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/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +17 -13
- package/README_CN.md +17 -13
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/scripts/cli-branch.mjs +2 -5
- package/scripts/cli-codex-config.mjs +187 -26
- package/scripts/cli-codex.mjs +10 -14
- package/scripts/cli-doctor-codex.mjs +18 -15
- package/scripts/cli-doctor.mjs +48 -15
- package/scripts/cli-host-detect.mjs +38 -5
- package/scripts/cli-lifecycle-hosts.mjs +48 -20
- package/scripts/cli-messages.mjs +9 -8
- package/scripts/cli-process.mjs +16 -0
- package/scripts/cli-runtime-root.mjs +55 -12
- package/scripts/cli-toml.mjs +4 -0
- package/scripts/project-session-cleanup.mjs +0 -32
- package/scripts/runtime-scope.mjs +185 -100
- package/scripts/session-capsule.mjs +6 -65
- package/scripts/session-token.mjs +16 -2
- package/scripts/state-document.mjs +7 -51
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing, unified QA gates, safety guards, and notifications.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "HelloWind",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "HelloAGENTS — Quality-driven orchestration kernel for AI CLIs with intelligent routing, unified QA gates, 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
|
-
[](./package.json)
|
|
12
12
|
[](https://www.npmjs.com/package/helloagents)
|
|
13
13
|
[](./package.json)
|
|
14
14
|
[](./skills)
|
|
@@ -189,7 +189,7 @@ HelloAGENTS now resolves the current state file from `state_path`:
|
|
|
189
189
|
|
|
190
190
|
`<workspace>` is the current Git branch, `detached-<sha>` for a detached HEAD, or `workspace` for non-Git projects. `<session>` is the current project-local session token. `.helloagents/sessions/active.json` only keeps the latest active workspace/session mapping plus alias bridges, so the same CLI session stays in one directory and `/resume` can reuse it.
|
|
191
191
|
|
|
192
|
-
For project-local sessions, HelloAGENTS first uses stable host identifiers such as `sessionId`, `conversationId`, `threadId`, or `HELLOAGENTS_NOTIFY_SESSION_ID`. If the host only exposes a window or terminal id such as `WT_SESSION`, `TERM_SESSION_ID`, or `WINDOWID`, HelloAGENTS uses it only as a lightweight alias bridge and reuses the mapped session first instead of fanning out duplicate directories.
|
|
192
|
+
For project-local sessions, HelloAGENTS first uses stable host identifiers such as `sessionId`, `conversationId`, `threadId`, or `HELLOAGENTS_NOTIFY_SESSION_ID`. If the host only exposes a window or terminal id such as `WT_SESSION`, `TERM_SESSION_ID`, or `WINDOWID`, HelloAGENTS uses it only as a lightweight alias bridge and reuses the mapped session first instead of fanning out duplicate directories. If a session starts before a stable host identifier is available, HelloAGENTS can begin in `default` and keep reusing that same active directory after the same CLI session later exposes a stable identifier, instead of splitting into a second session directory.
|
|
193
193
|
|
|
194
194
|
`STATE.md` records where the current workflow stopped. It is not a universal memory file for every conversation. Codex `/goal` does not replace `state_path`, `turn-state`, or local evidence files; it only handles long-running continuation on the Codex side.
|
|
195
195
|
|
|
@@ -210,7 +210,7 @@ Runtime state now stays intentionally small:
|
|
|
210
210
|
- `~/.codex/.helloagents/notify-state.json` for Codex-native closeout de-duplication only
|
|
211
211
|
|
|
212
212
|
`STATE.md` only keeps the human-readable recovery snapshot. `runtime.json` is machine-only and keeps the minimal runtime state. `artifacts/*.json` stays limited to structured receipts. `events.jsonl` remains opt-in trace output and stays off by default.
|
|
213
|
-
Project-local `STATE.md` is now materialized more lazily
|
|
213
|
+
Project-local `STATE.md` is now materialized more lazily.
|
|
214
214
|
|
|
215
215
|
Standard runtime evidence and transient runtime state now expire after 72 hours. Long-running Codex goal flows still keep their 720-hour upper bound where the workflow explicitly needs it.
|
|
216
216
|
|
|
@@ -225,8 +225,10 @@ The CLI manages host files explicitly:
|
|
|
225
225
|
- `update` refreshes the selected target or all targets
|
|
226
226
|
- `cleanup` removes managed injections and links
|
|
227
227
|
- `uninstall` performs scoped cleanup before package removal
|
|
228
|
-
- `doctor` reports drift in carriers, links, hooks, config entries, plugin roots, cache copies, and
|
|
228
|
+
- `doctor` reports drift in carriers, links, hooks, config entries, plugin roots, cache copies, versions, and real Claude/Gemini global install artifacts; for Codex, it also surfaces native `codex doctor` output when available
|
|
229
|
+
- Codex managed `notify = ["helloagents-js", "codex-notify"]` stays portable, and `doctor`, `cleanup`, and `uninstall` also recognize wrapped `--previous-notify` chains used by Codex App / Computer Use
|
|
229
230
|
- per-host mode tracking is written only after host setup succeeds, and failed native global cleanup keeps the host tracked as `global` instead of silently layering standby on top
|
|
231
|
+
- Windows `.cmd` / `.bat` lifecycle calls now run through an explicit command wrapper, so host installs, branch switching, and doctor flows do not emit Node `DEP0190` shell deprecation warnings
|
|
230
232
|
|
|
231
233
|
## Quick Start
|
|
232
234
|
|
|
@@ -313,7 +315,7 @@ If you omit `--standby` or `--global`, HelloAGENTS first reuses the tracked/dete
|
|
|
313
315
|
|
|
314
316
|
Use these when you do not want to depend on the `helloagents` binary being available during package updates. In `HELLOAGENTS=target[:mode]`, target can be `all`, `claude`, `gemini`, or `codex`; mode can be `standby` or `global`. For install, an omitted mode is treated as `standby`. For update, cleanup, uninstall, and branch switching, an omitted mode is forwarded unchanged so HelloAGENTS can reuse the tracked or detected mode for that CLI first. If you do not provide `HELLOAGENTS`, the one-shot install scripts now behave like plain package install: they install or update the package only and do not auto-deploy any host CLI. For a custom tarball or package spec, set `HELLOAGENTS_PACKAGE` instead of `HELLOAGENTS_BRANCH`. For a guaranteed refresh of an already installed package, prefer `npm explore -g helloagents -- npm run sync-hosts -- ...` after the package command.
|
|
315
317
|
|
|
316
|
-
Host configs use the stable `helloagents-js` entrypoint and runtime root `~/.helloagents/helloagents`, so Node global package paths can change without breaking managed hooks or Codex `notify`. Codex hooks use standalone `~/.codex/hooks.json` instead of adding large hook blocks to `config.toml`, and Codex global plugin roots plus plugin cache now link back to that same stable runtime root.
|
|
318
|
+
Host configs use the stable `helloagents-js` entrypoint and runtime root `~/.helloagents/helloagents`, so Node global package paths can change without breaking managed hooks or Codex `notify`. Codex hooks use standalone `~/.codex/hooks.json` instead of adding large hook blocks to `config.toml`, and Codex global plugin roots plus plugin cache now link back to that same stable runtime root. Claude Code global installs now use a dedicated local marketplace projection under `~/.helloagents/host-projections/claude-marketplace`, and Gemini global extension packaging uses `~/.helloagents/host-projections/gemini`, so host-specific packaging stays isolated from the shared runtime root.
|
|
317
319
|
|
|
318
320
|
#### npm commands
|
|
319
321
|
|
|
@@ -445,16 +447,16 @@ npm uninstall -g helloagents
|
|
|
445
447
|
|
|
446
448
|
| CLI | Install method | Files involved |
|
|
447
449
|
|-----|----------------|----------------|
|
|
448
|
-
| Claude Code | native plugin install |
|
|
449
|
-
| Gemini CLI | native extension install |
|
|
450
|
+
| Claude Code | native plugin install | `~/.helloagents/host-projections/claude-marketplace`, Claude Code plugin metadata/cache managed by the host |
|
|
451
|
+
| Gemini CLI | native extension install | `~/.helloagents/host-projections/gemini`, `~/.gemini/extensions/helloagents` |
|
|
450
452
|
| Codex CLI | native local-plugin chain | `~/.agents/plugins/marketplace.json`, `~/plugins/helloagents/ -> ~/.helloagents/helloagents`, `~/.codex/plugins/cache/local-plugins/helloagents/local/ -> ~/.helloagents/helloagents`, `~/.codex/config.toml`, `~/.codex/hooks.json`, `~/.codex/helloagents -> ~/.helloagents/helloagents` |
|
|
451
453
|
|
|
452
|
-
In global mode, HelloAGENTS now attempts the host-native install commands automatically.
|
|
454
|
+
In global mode, HelloAGENTS now attempts the host-native install commands automatically. Claude Code uses the local marketplace projection, Gemini uses the local extension projection, and Codex keeps linking back to the same stable runtime root, so install, update, branch switching, mode switching, cleanup, and uninstall all refresh against one consistent runtime copy. If a host command is unavailable, run the same commands manually:
|
|
453
455
|
|
|
454
456
|
```text
|
|
455
|
-
/plugin marketplace add
|
|
457
|
+
/plugin marketplace add "~/.helloagents/host-projections/claude-marketplace"
|
|
456
458
|
/plugin install helloagents@helloagents
|
|
457
|
-
|
|
459
|
+
gemini extensions link "~/.helloagents/host-projections/gemini"
|
|
458
460
|
```
|
|
459
461
|
|
|
460
462
|
For Claude Code, the CLI also tries the equivalent `claude plugin marketplace add ...` and `claude plugin install ...` commands. The marketplace is named `helloagents`, and the plugin is also named `helloagents`, so the install target is `helloagents@helloagents`. Restart the host CLI after a global install.
|
|
@@ -652,15 +654,16 @@ Codex is rules-file driven by default.
|
|
|
652
654
|
|
|
653
655
|
- standby writes `~/.codex/AGENTS.md`
|
|
654
656
|
- standby writes a portable managed `model_instructions_file = "~/.codex/AGENTS.md"`
|
|
655
|
-
- standby writes a managed `notify = ["helloagents-js", "codex-notify"]` command for closeout notification
|
|
657
|
+
- standby writes a managed and portable `notify = ["helloagents-js", "codex-notify"]` command for closeout notification, so reinstalling, updating, or moving to another machine does not require rewriting an absolute path
|
|
656
658
|
- standby writes silent Codex hooks to `~/.codex/hooks.json`
|
|
657
659
|
- Codex `SessionStart` stays silent and reads the current `~/.helloagents/helloagents.json` at runtime instead of baking a config snapshot into `config.toml`, so first-turn and post-compaction settings stay current
|
|
658
660
|
- install and update also sync HelloAGENTS-managed Codex hook trust state in `~/.codex/config.toml`, so Codex 0.129.0+ does not re-prompt for the managed hooks
|
|
659
661
|
- that hook trust state is machine-local generated metadata derived from the current absolute `~/.codex/hooks.json` path; unlike `model_instructions_file = "~/.codex/AGENTS.md"`, it is not portable config and should be regenerated on each machine
|
|
660
662
|
- standby creates `~/.codex/helloagents -> ~/.helloagents/helloagents`
|
|
661
663
|
- global mode installs the native local-plugin chain, but keeps `~/.helloagents/helloagents` as the single managed runtime source by linking plugin roots, plugin cache, and `~/.codex/helloagents` back to it
|
|
664
|
+
- `doctor`, `cleanup`, and `uninstall` also recognize wrapped notify chains such as `--previous-notify ["helloagents-js", "codex-notify"]`, so Codex App / Computer Use wrappers do not cause false drift reports or break notify restoration
|
|
662
665
|
- for Codex app/plugin discovery, `global` is the native path; `standby` remains the lighter default for explicit project work
|
|
663
|
-
- cleanup removes only the HelloAGENTS-managed hook trust entries
|
|
666
|
+
- cleanup removes only the HelloAGENTS-managed hook trust entries, while keeping user-owned hook state untouched
|
|
664
667
|
- Codex hooks only synchronize runtime state and enforce Stop gates; they do not inject HelloAGENTS rules or route text through hook output
|
|
665
668
|
- Codex closeout de-duplicates Stop hooks and native `codex-notify`, so one turn does not notify twice, and clientless delegated child-completion events stay silent when the managed Stop hook is active
|
|
666
669
|
- `/goal` remains Codex-native. Enable it explicitly with `helloagents codex goals enable` when long-running plan execution is needed
|
|
@@ -678,10 +681,11 @@ npm test
|
|
|
678
681
|
The current suite covers:
|
|
679
682
|
|
|
680
683
|
- install, update, cleanup, uninstall, branch switching, and mode switching
|
|
684
|
+
- Windows `.cmd` / `.bat` lifecycle dispatch without Node `DEP0190` warnings
|
|
681
685
|
- one-shot shell and PowerShell lifecycle dispatch, plus wrapper env cleanup and mode-routing rules for install, update, cleanup, uninstall, and branch switching
|
|
682
686
|
- Claude, Gemini, and Codex host integration behavior, including global-to-standby cleanup and failed native cleanup tracking
|
|
683
687
|
- Codex managed `model_instructions_file`, `notify`, `hooks.json`, hook trust state, local plugin, marketplace, and cache behavior
|
|
684
|
-
- Codex cleanup
|
|
688
|
+
- Codex cleanup and canonical managed notify restoration rules, including wrapped `--previous-notify` chains
|
|
685
689
|
- Codex `/goal` feature toggles, long-running route context, and goal-aware command contracts
|
|
686
690
|
- `helloagents doctor`
|
|
687
691
|
- project storage and `repo-shared` behavior
|
package/README_CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**面向 AI 编码 CLI 的工作流层:技能、知识库、交付检查、更安全的配置写入,以及可恢复的执行流程。**
|
|
10
10
|
|
|
11
|
-
[](./package.json)
|
|
12
12
|
[](https://www.npmjs.com/package/helloagents)
|
|
13
13
|
[](./package.json)
|
|
14
14
|
[](./skills)
|
|
@@ -189,7 +189,7 @@ HelloAGENTS 现在只从 `state_path` 解析当前状态文件:
|
|
|
189
189
|
|
|
190
190
|
`<workspace>` 是当前 Git 分支、detached HEAD 的 `detached-<sha>`,或非 Git 项目的 `workspace`。`<session>` 是当前项目本地会话标识。`.helloagents/sessions/active.json` 只保留最近一次活跃的工作区/会话映射和 alias 桥接,这样同一个 CLI 会话会稳定落在同一个目录里,`/resume` 也能复用它。
|
|
191
191
|
|
|
192
|
-
对于项目本地会话目录,HelloAGENTS 会优先使用稳定宿主标识,如 `sessionId`、`conversationId`、`threadId` 或 `HELLOAGENTS_NOTIFY_SESSION_ID`。如果宿主只能提供 `WT_SESSION`、`TERM_SESSION_ID`、`WINDOWID` 这类窗口或终端标识,HelloAGENTS 只把它们当作轻量 alias
|
|
192
|
+
对于项目本地会话目录,HelloAGENTS 会优先使用稳定宿主标识,如 `sessionId`、`conversationId`、`threadId` 或 `HELLOAGENTS_NOTIFY_SESSION_ID`。如果宿主只能提供 `WT_SESSION`、`TERM_SESSION_ID`、`WINDOWID` 这类窗口或终端标识,HelloAGENTS 只把它们当作轻量 alias 桥接,并优先复用已映射的会话目录,而不是继续分裂出重复目录。如果一个会话启动时还拿不到稳定宿主标识,HelloAGENTS 可以先落到 `default`,等同一个 CLI 会话后续拿到稳定标识时,仍继续复用这个活动目录,而不是再拆出第二个会话目录。
|
|
193
193
|
|
|
194
194
|
`STATE.md` 只记录当前工作流做到哪里,不承担所有对话的统一记忆。Codex `/goal` 也不替代 `state_path`、`turn-state` 或本地证据文件;它只负责 Codex 侧的长程续跑。
|
|
195
195
|
|
|
@@ -210,7 +210,7 @@ HelloAGENTS 不把“命令通过”和“任务完成”简单画等号。交
|
|
|
210
210
|
- 仅用于 Codex 原生收尾去重的 `~/.codex/.helloagents/notify-state.json`
|
|
211
211
|
|
|
212
212
|
`STATE.md` 只保留给人看的恢复快照。`runtime.json` 只给机器用,只保存极少量运行态。`artifacts/*.json` 只保留结构化收据。`events.jsonl` 仍是可选 trace 输出,默认不写。
|
|
213
|
-
项目本地 `STATE.md`
|
|
213
|
+
项目本地 `STATE.md` 现在会更晚创建。
|
|
214
214
|
|
|
215
215
|
标准运行态证据和临时运行态现在默认 72 小时过期。只有工作流明确需要的长程 Codex goal 链路,才继续保留 720 小时上限。
|
|
216
216
|
|
|
@@ -225,8 +225,10 @@ CLI 显式管理宿主文件:
|
|
|
225
225
|
- `update` 刷新指定目标或全部目标
|
|
226
226
|
- `cleanup` 删除受管注入和链接
|
|
227
227
|
- `uninstall` 在移除包前执行对应清理
|
|
228
|
-
- `doctor` 检查规则文件、链接、hooks
|
|
228
|
+
- `doctor` 检查规则文件、链接、hooks、配置项、插件根目录、缓存副本、版本漂移,以及 Claude / Gemini 是否真的装上了全局插件或扩展;对 Codex 还会在可用时附带原生 `codex doctor` 结果
|
|
229
|
+
- Codex 受管 `notify = ["helloagents-js", "codex-notify"]` 会继续保持可移植;`doctor`、`cleanup` 和 `uninstall` 也能识别 Codex App / Computer Use 使用的 `--previous-notify` 包装链
|
|
229
230
|
- 单 CLI 模式记录只会在宿主安装成功后写入;如果原生全局清理失败,也会继续保留 `global` 记录,而不是悄悄叠加 standby
|
|
231
|
+
- Windows 下的 `.cmd` / `.bat` 生命周期调用现在统一走显式命令包装,不再出现 Node `DEP0190` shell 弃用警告
|
|
230
232
|
|
|
231
233
|
## 快速开始
|
|
232
234
|
|
|
@@ -313,7 +315,7 @@ helloagents codex goals enable
|
|
|
313
315
|
|
|
314
316
|
当你不想依赖更新过程中的 `helloagents` 可执行文件时,用 npm 或一键脚本。`HELLOAGENTS=目标[:模式]` 中,目标支持 `all`、`claude`、`gemini`、`codex`;模式支持 `standby`、`global`。用于安装时,省略模式按 `standby` 处理;用于更新、清理、卸载和切换分支时,省略模式会原样下传,让 HelloAGENTS 先复用该 CLI 已记录或检测到的模式。如果未提供 `HELLOAGENTS`,一键安装脚本现在会保持“只装包/只升级包”的默认语义,不会自动部署任何宿主 CLI。若要安装自定义 tarball 或包规格,用 `HELLOAGENTS_PACKAGE`,不要写 `HELLOAGENTS_BRANCH`。对于已经装好的包,如需确保宿主一定刷新,优先在包命令后显式执行一次 `npm explore -g helloagents -- npm run sync-hosts -- ...`。
|
|
315
317
|
|
|
316
|
-
宿主配置使用稳定的 `helloagents-js` 入口和运行根目录 `~/.helloagents/helloagents`,Node 全局包路径变化不会破坏受管 hooks 或 Codex `notify`。Codex hooks 使用独立 `~/.codex/hooks.json`,不把大段配置写入 `config.toml`;Codex 全局插件根目录和插件缓存也会回链到这个稳定运行根目录。
|
|
318
|
+
宿主配置使用稳定的 `helloagents-js` 入口和运行根目录 `~/.helloagents/helloagents`,Node 全局包路径变化不会破坏受管 hooks 或 Codex `notify`。Codex hooks 使用独立 `~/.codex/hooks.json`,不把大段配置写入 `config.toml`;Codex 全局插件根目录和插件缓存也会回链到这个稳定运行根目录。Claude Code 的 global 安装现在使用独立本地 marketplace 投影 `~/.helloagents/host-projections/claude-marketplace`,Gemini 的 global 扩展使用 `~/.helloagents/host-projections/gemini`,宿主专用打包链路不再污染共享运行根。
|
|
317
319
|
|
|
318
320
|
#### npm 命令
|
|
319
321
|
|
|
@@ -445,16 +447,16 @@ npm uninstall -g helloagents
|
|
|
445
447
|
|
|
446
448
|
| CLI | 安装方式 | 涉及文件 |
|
|
447
449
|
|-----|----------|----------|
|
|
448
|
-
| Claude Code | 原生插件安装 |
|
|
449
|
-
| Gemini CLI | 原生扩展安装 |
|
|
450
|
+
| Claude Code | 原生插件安装 | `~/.helloagents/host-projections/claude-marketplace`,以及由 Claude Code 宿主管理的插件元数据 / 缓存 |
|
|
451
|
+
| Gemini CLI | 原生扩展安装 | `~/.helloagents/host-projections/gemini`、`~/.gemini/extensions/helloagents` |
|
|
450
452
|
| Codex CLI | 原生本地插件流程 | `~/.agents/plugins/marketplace.json`、`~/plugins/helloagents/ -> ~/.helloagents/helloagents`、`~/.codex/plugins/cache/local-plugins/helloagents/local/ -> ~/.helloagents/helloagents`、`~/.codex/config.toml`、`~/.codex/hooks.json`、`~/.codex/helloagents -> ~/.helloagents/helloagents` |
|
|
451
453
|
|
|
452
|
-
全局模式下,HelloAGENTS
|
|
454
|
+
全局模式下,HelloAGENTS 会自动尝试宿主原生命令。Claude Code 走本地 marketplace 投影,Gemini 走本地 extension 投影,Codex 继续回链同一个稳定运行根,因此安装、更新、切分支、切模式、清理和卸载都会围绕同一份运行时副本刷新。若宿主命令不可用,再手动执行:
|
|
453
455
|
|
|
454
456
|
```text
|
|
455
|
-
/plugin marketplace add
|
|
457
|
+
/plugin marketplace add "~/.helloagents/host-projections/claude-marketplace"
|
|
456
458
|
/plugin install helloagents@helloagents
|
|
457
|
-
|
|
459
|
+
gemini extensions link "~/.helloagents/host-projections/gemini"
|
|
458
460
|
```
|
|
459
461
|
|
|
460
462
|
Claude Code 会自动尝试等价的 `claude plugin marketplace add ...` 和 `claude plugin install ...` 命令。marketplace 名称和插件名称都是 `helloagents`,所以安装目标是 `helloagents@helloagents`。全局安装后需要重启宿主 CLI。
|
|
@@ -656,15 +658,16 @@ Codex 默认走规则文件驱动。
|
|
|
656
658
|
|
|
657
659
|
- 标准模式写入 `~/.codex/AGENTS.md`
|
|
658
660
|
- 标准模式写入可移植的受管 `model_instructions_file = "~/.codex/AGENTS.md"`
|
|
659
|
-
-
|
|
661
|
+
- 标准模式写入受管且可移植的 `notify = ["helloagents-js", "codex-notify"]` 命令用于收尾通知,因此重装、更新或换电脑时都不需要改写绝对路径
|
|
660
662
|
- 标准模式把静默 Codex hooks 写入 `~/.codex/hooks.json`
|
|
661
663
|
- Codex 的 `SessionStart` 保持静默,并在运行时读取当前 `~/.helloagents/helloagents.json`,不会把配置快照固化进 `config.toml`,因此首次对话和上下文压缩后的设置都能保持最新
|
|
662
664
|
- 安装和更新还会把 HelloAGENTS 受管的 Codex hook trust 状态同步到 `~/.codex/config.toml`,因此 Codex 0.129.0+ 不会再对这些受管 hooks 反复提示确认
|
|
663
665
|
- 这些 hook trust 状态是基于当前机器 `~/.codex/hooks.json` 真实绝对路径生成的本机状态;它不同于 `model_instructions_file = "~/.codex/AGENTS.md"` 这类可移植配置,应在每台机器上重新生成
|
|
664
666
|
- 标准模式创建 `~/.codex/helloagents -> ~/.helloagents/helloagents`
|
|
665
667
|
- 全局模式安装原生本地插件流程,但仍把 `~/.helloagents/helloagents` 作为唯一受管运行时源;插件根目录、插件缓存和 `~/.codex/helloagents` 都会回链到它
|
|
668
|
+
- `doctor`、`cleanup` 和 `uninstall` 也能识别 `--previous-notify ["helloagents-js", "codex-notify"]` 这类包装后的 notify 链,因此 Codex App / Computer Use 不会再触发误报或破坏 notify 恢复
|
|
666
669
|
- 如果你主要看重 Codex app / 插件发现链路,优先使用 `global`;如果你主要看重更轻量、更显式的项目工作流,保留 `standby`
|
|
667
|
-
- 清理时只删除 HelloAGENTS 自己写入的 hook trust
|
|
670
|
+
- 清理时只删除 HelloAGENTS 自己写入的 hook trust 条目,不影响用户已有的 hook 状态
|
|
668
671
|
- Codex hooks 只做静默运行态同步和 Stop 门禁,不通过 hook 注入 HelloAGENTS 规则或路由说明
|
|
669
672
|
- Codex 收尾会对 Stop hook 和原生 `codex-notify` 去重,避免同一轮重复通知;受管 Stop hook 生效时,client 为空的委派子任务完成事件也会保持静默
|
|
670
673
|
- `/goal` 保持 Codex 原生能力;需要长程执行时,用 `helloagents codex goals enable` 显式启用
|
|
@@ -682,10 +685,11 @@ npm test
|
|
|
682
685
|
当前测试覆盖:
|
|
683
686
|
|
|
684
687
|
- 安装、更新、清理、卸载、分支切换和模式切换
|
|
688
|
+
- Windows `.cmd` / `.bat` 生命周期分发链路,且不再出现 Node `DEP0190` 警告
|
|
685
689
|
- shell 与 PowerShell 一键脚本分发链路,以及包装脚本在安装、更新、清理、卸载和分支切换中的环境清理与模式传递规则
|
|
686
690
|
- Claude、Gemini、Codex 的宿主集成行为,包括全局切回标准模式的清理和原生清理失败时的模式保留
|
|
687
691
|
- Codex 受管 `model_instructions_file`、`notify`、`hooks.json`、hook trust 状态、本地插件、marketplace 和缓存行为
|
|
688
|
-
-
|
|
692
|
+
- Codex 清理链路,以及包括 wrapped `--previous-notify` 在内的受管 notify 恢复规则
|
|
689
693
|
- Codex `/goal` 功能开关、长程路由上下文和 goal 感知命令契约
|
|
690
694
|
- `helloagents doctor`
|
|
691
695
|
- 项目存储和 `repo-shared`
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"type": "module",
|
|
5
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",
|
package/scripts/cli-branch.mjs
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { spawnSync } from 'node:child_process'
|
|
2
|
-
|
|
3
1
|
import { normalizeHost } from './cli-lifecycle.mjs'
|
|
2
|
+
import { spawnCommandSync } from './cli-process.mjs'
|
|
4
3
|
|
|
5
4
|
const DEFAULT_REPO_ARCHIVE_BASE = 'https://github.com/hellowind777/helloagents/archive/refs/heads'
|
|
6
5
|
|
|
7
6
|
function runCommand(command, args) {
|
|
8
|
-
const
|
|
9
|
-
const result = spawnSync(command, args, {
|
|
7
|
+
const result = spawnCommandSync(command, args, {
|
|
10
8
|
encoding: 'utf-8',
|
|
11
9
|
errors: 'replace',
|
|
12
|
-
shell: needsShell,
|
|
13
10
|
stdio: 'inherit',
|
|
14
11
|
windowsHide: true,
|
|
15
12
|
})
|
|
@@ -13,13 +13,8 @@ export const CODEX_MANAGED_TOML_COMMENT = '# helloagents-managed'
|
|
|
13
13
|
export const CODEX_MANAGED_MODEL_INSTRUCTIONS_PATH = '~/.codex/AGENTS.md'
|
|
14
14
|
export const CODEX_MANAGED_NOTIFY_COMMAND = 'helloagents-js'
|
|
15
15
|
export const CODEX_MANAGED_NOTIFY_VALUE = `["${CODEX_MANAGED_NOTIFY_COMMAND}", "codex-notify"]`
|
|
16
|
-
const CODEX_MANAGED_NOTIFY_LEGACY_VALUES = [
|
|
17
|
-
`["${CODEX_MANAGED_NOTIFY_COMMAND}.cmd", "codex-notify"]`,
|
|
18
|
-
`["${CODEX_MANAGED_NOTIFY_COMMAND}.exe", "codex-notify"]`,
|
|
19
|
-
]
|
|
20
16
|
export const CODEX_MANAGED_TUI_NOTIFICATIONS_VALUE = '["plan-mode-prompt"]'
|
|
21
17
|
export const CODEX_HOOKS_FEATURE_KEY = 'hooks'
|
|
22
|
-
export const CODEX_LEGACY_HOOKS_FEATURE_KEY = 'codex_hooks'
|
|
23
18
|
export const CODEX_GOALS_FEATURE_KEY = 'goals'
|
|
24
19
|
export const CODEX_MANAGED_GOALS_FEATURE_LINE = `${CODEX_GOALS_FEATURE_KEY} = true ${CODEX_MANAGED_TOML_COMMENT}`
|
|
25
20
|
export const CODEX_MANAGED_GOALS_DISABLED_LINE = `${CODEX_GOALS_FEATURE_KEY} = false ${CODEX_MANAGED_TOML_COMMENT}`
|
|
@@ -29,6 +24,155 @@ function normalizePath(value = '') {
|
|
|
29
24
|
return String(value || '').replace(/\\/g, '/')
|
|
30
25
|
}
|
|
31
26
|
|
|
27
|
+
function isManagedCodexNotifyParts(parts) {
|
|
28
|
+
return Array.isArray(parts)
|
|
29
|
+
&& parts.length === 2
|
|
30
|
+
&& parts[0] === CODEX_MANAGED_NOTIFY_COMMAND
|
|
31
|
+
&& parts[1] === 'codex-notify'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function extractTomlArrayLiteral(text = '') {
|
|
35
|
+
const source = String(text || '')
|
|
36
|
+
const equalsIndex = source.indexOf('=')
|
|
37
|
+
let quoted = false
|
|
38
|
+
let escaped = false
|
|
39
|
+
let commented = false
|
|
40
|
+
let depth = 0
|
|
41
|
+
let start = -1
|
|
42
|
+
|
|
43
|
+
for (let index = equalsIndex >= 0 ? equalsIndex + 1 : 0; index < source.length; index += 1) {
|
|
44
|
+
const char = source[index]
|
|
45
|
+
|
|
46
|
+
if (commented) {
|
|
47
|
+
if (char === '\n') commented = false
|
|
48
|
+
continue
|
|
49
|
+
}
|
|
50
|
+
if (escaped) {
|
|
51
|
+
escaped = false
|
|
52
|
+
continue
|
|
53
|
+
}
|
|
54
|
+
if (char === '\\' && quoted) {
|
|
55
|
+
escaped = true
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
if (char === '"') {
|
|
59
|
+
quoted = !quoted
|
|
60
|
+
continue
|
|
61
|
+
}
|
|
62
|
+
if (quoted) continue
|
|
63
|
+
if (char === '#') {
|
|
64
|
+
commented = true
|
|
65
|
+
continue
|
|
66
|
+
}
|
|
67
|
+
if (char === '[') {
|
|
68
|
+
if (depth === 0) start = index
|
|
69
|
+
depth += 1
|
|
70
|
+
continue
|
|
71
|
+
}
|
|
72
|
+
if (char === ']' && depth > 0) {
|
|
73
|
+
depth -= 1
|
|
74
|
+
if (depth === 0 && start >= 0) return source.slice(start, index + 1)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return ''
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function parseTomlStringArrayLiteral(literal = '') {
|
|
82
|
+
const source = String(literal || '').trim()
|
|
83
|
+
if (!source.startsWith('[') || !source.endsWith(']')) return null
|
|
84
|
+
|
|
85
|
+
const items = []
|
|
86
|
+
let quoted = false
|
|
87
|
+
let escaped = false
|
|
88
|
+
let tokenStart = -1
|
|
89
|
+
|
|
90
|
+
for (let index = 1; index < source.length; index += 1) {
|
|
91
|
+
const char = source[index]
|
|
92
|
+
|
|
93
|
+
if (quoted) {
|
|
94
|
+
if (escaped) {
|
|
95
|
+
escaped = false
|
|
96
|
+
continue
|
|
97
|
+
}
|
|
98
|
+
if (char === '\\') {
|
|
99
|
+
escaped = true
|
|
100
|
+
continue
|
|
101
|
+
}
|
|
102
|
+
if (char === '"') {
|
|
103
|
+
try {
|
|
104
|
+
items.push(JSON.parse(source.slice(tokenStart, index + 1)))
|
|
105
|
+
} catch {
|
|
106
|
+
return null
|
|
107
|
+
}
|
|
108
|
+
quoted = false
|
|
109
|
+
tokenStart = -1
|
|
110
|
+
}
|
|
111
|
+
continue
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (char === '#') {
|
|
115
|
+
while (index < source.length && source[index] !== '\n') index += 1
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
if (/\s|,/.test(char)) continue
|
|
119
|
+
if (char === ']') return items
|
|
120
|
+
if (char !== '"') return null
|
|
121
|
+
|
|
122
|
+
quoted = true
|
|
123
|
+
tokenStart = index
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function analyzeNotifyCommandParts(parts = []) {
|
|
130
|
+
if (isManagedCodexNotifyParts(parts)) {
|
|
131
|
+
return {
|
|
132
|
+
managed: true,
|
|
133
|
+
shape: 'direct',
|
|
134
|
+
containsCodexNotify: true,
|
|
135
|
+
entrypoint: [...parts],
|
|
136
|
+
wrapper: '',
|
|
137
|
+
rawCommand: [...parts],
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let containsCodexNotify = parts.includes('codex-notify')
|
|
142
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
143
|
+
if (parts[index] !== '--previous-notify') continue
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const nested = JSON.parse(parts[index + 1])
|
|
147
|
+
if (!Array.isArray(nested) || !nested.every((entry) => typeof entry === 'string')) continue
|
|
148
|
+
|
|
149
|
+
const nestedAnalysis = analyzeNotifyCommandParts(nested)
|
|
150
|
+
containsCodexNotify = containsCodexNotify || nestedAnalysis.containsCodexNotify
|
|
151
|
+
if (!nestedAnalysis.managed) continue
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
managed: true,
|
|
155
|
+
shape: 'chained',
|
|
156
|
+
containsCodexNotify: true,
|
|
157
|
+
entrypoint: [...nestedAnalysis.entrypoint],
|
|
158
|
+
wrapper: parts[0] || '',
|
|
159
|
+
rawCommand: [...parts],
|
|
160
|
+
}
|
|
161
|
+
} catch {
|
|
162
|
+
continue
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
managed: false,
|
|
168
|
+
shape: parts.length ? 'external' : 'invalid',
|
|
169
|
+
containsCodexNotify,
|
|
170
|
+
entrypoint: [],
|
|
171
|
+
wrapper: '',
|
|
172
|
+
rawCommand: [...parts],
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
32
176
|
function splitTomlLines(text = '') {
|
|
33
177
|
return String(text || '').replace(/\r\n/g, '\n').split('\n')
|
|
34
178
|
}
|
|
@@ -105,10 +249,6 @@ export function readCodexHooksFeatureLine(text) {
|
|
|
105
249
|
return readCodexFeatureLine(text, CODEX_HOOKS_FEATURE_KEY)
|
|
106
250
|
}
|
|
107
251
|
|
|
108
|
-
export function readLegacyCodexHooksFeatureLine(text) {
|
|
109
|
-
return readCodexFeatureLine(text, CODEX_LEGACY_HOOKS_FEATURE_KEY)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
252
|
export function readCodexGoalsFeatureLine(text) {
|
|
113
253
|
return readCodexFeatureLine(text, CODEX_GOALS_FEATURE_KEY)
|
|
114
254
|
}
|
|
@@ -146,15 +286,6 @@ export function removeCodexGoalsFeatureConfig(text) {
|
|
|
146
286
|
)
|
|
147
287
|
}
|
|
148
288
|
|
|
149
|
-
export function removeLegacyManagedCodexHooksFeatureConfig(text) {
|
|
150
|
-
return removeTomlSectionLine(
|
|
151
|
-
text,
|
|
152
|
-
CODEX_FEATURES_HEADER,
|
|
153
|
-
CODEX_LEGACY_HOOKS_FEATURE_KEY,
|
|
154
|
-
isManagedLegacyCodexHooksFeature,
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
289
|
export function restoreCodexGoalsFeatureConfig(text, { codexGoalsLine = '' } = {}) {
|
|
159
290
|
if (!codexGoalsLine) return normalizeToml(text)
|
|
160
291
|
return upsertTomlSectionLine(
|
|
@@ -173,10 +304,44 @@ export function isManagedCodexModelInstruction(line = '') {
|
|
|
173
304
|
export function isManagedCodexNotify(line = '') {
|
|
174
305
|
const value = String(line || '').replace(/\\/g, '/')
|
|
175
306
|
return value.includes(CODEX_MANAGED_TOML_COMMENT)
|
|
176
|
-
&& (
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
307
|
+
&& value.includes(CODEX_MANAGED_NOTIFY_VALUE)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export function analyzeCodexNotifyBlock(block = '') {
|
|
311
|
+
const source = String(block || '').trim()
|
|
312
|
+
if (!source) {
|
|
313
|
+
return {
|
|
314
|
+
exists: false,
|
|
315
|
+
managed: false,
|
|
316
|
+
containsCodexNotify: false,
|
|
317
|
+
shape: 'missing',
|
|
318
|
+
entrypoint: [],
|
|
319
|
+
wrapper: '',
|
|
320
|
+
rawCommand: [],
|
|
321
|
+
rawBlock: '',
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const literal = extractTomlArrayLiteral(source)
|
|
326
|
+
const parts = literal ? parseTomlStringArrayLiteral(literal) : null
|
|
327
|
+
if (!parts) {
|
|
328
|
+
return {
|
|
329
|
+
exists: true,
|
|
330
|
+
managed: false,
|
|
331
|
+
containsCodexNotify: source.includes('codex-notify'),
|
|
332
|
+
shape: 'invalid',
|
|
333
|
+
entrypoint: [],
|
|
334
|
+
wrapper: '',
|
|
335
|
+
rawCommand: [],
|
|
336
|
+
rawBlock: source,
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
exists: true,
|
|
342
|
+
...analyzeNotifyCommandParts(parts),
|
|
343
|
+
rawBlock: source,
|
|
344
|
+
}
|
|
180
345
|
}
|
|
181
346
|
|
|
182
347
|
export function isManagedCodexTuiNotifications(line = '') {
|
|
@@ -193,10 +358,6 @@ export function isManagedCodexHooksFeature(line = '') {
|
|
|
193
358
|
return isManagedFeatureLine(line, CODEX_HOOKS_FEATURE_KEY)
|
|
194
359
|
}
|
|
195
360
|
|
|
196
|
-
export function isManagedLegacyCodexHooksFeature(line = '') {
|
|
197
|
-
return isManagedFeatureLine(line, CODEX_LEGACY_HOOKS_FEATURE_KEY)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
361
|
export function isManagedCodexGoalsFeature(line = '') {
|
|
201
362
|
return isManagedFeatureLine(line, CODEX_GOALS_FEATURE_KEY)
|
|
202
363
|
}
|
package/scripts/cli-codex.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from './cli-utils.mjs';
|
|
9
9
|
import { ensureTimestampedBackup, readCodexBackup, removeCodexBackup } from './cli-codex-backup.mjs';
|
|
10
10
|
import {
|
|
11
|
+
analyzeCodexNotifyBlock,
|
|
11
12
|
CODEX_MANAGED_TOML_COMMENT,
|
|
12
13
|
CODEX_MANAGED_MODEL_INSTRUCTIONS_PATH,
|
|
13
14
|
CODEX_PLUGIN_CONFIG_HEADER,
|
|
@@ -17,12 +18,9 @@ import {
|
|
|
17
18
|
isManagedCodexGoalsFeature,
|
|
18
19
|
isManagedCodexModelInstruction,
|
|
19
20
|
isManagedCodexNotify,
|
|
20
|
-
isManagedLegacyCodexHooksFeature,
|
|
21
21
|
readCodexGoalsFeatureLine,
|
|
22
|
-
readLegacyCodexHooksFeatureLine,
|
|
23
22
|
removeCodexGoalsFeatureConfig,
|
|
24
23
|
removeCodexManagedTuiConfig,
|
|
25
|
-
removeLegacyManagedCodexHooksFeatureConfig,
|
|
26
24
|
removeCodexPluginConfig,
|
|
27
25
|
restoreCodexGoalsFeatureConfig,
|
|
28
26
|
restoreCodexTopLevelConfig,
|
|
@@ -33,8 +31,10 @@ import {
|
|
|
33
31
|
syncManagedCodexHookTrust,
|
|
34
32
|
} from './cli-codex-hooks-state.mjs';
|
|
35
33
|
import {
|
|
34
|
+
hasTopLevelTomlBlock,
|
|
36
35
|
readTopLevelTomlLine,
|
|
37
36
|
readTopLevelTomlBlock,
|
|
37
|
+
removeTopLevelTomlBlock,
|
|
38
38
|
removeTopLevelTomlLines,
|
|
39
39
|
} from './cli-toml.mjs';
|
|
40
40
|
import { buildRuntimeCarrier, readCarrierSettings } from './cli-runtime-carrier.mjs';
|
|
@@ -156,12 +156,11 @@ function cleanupCodexManagedConfig(configPath, { removePluginConfig = false } =
|
|
|
156
156
|
const currentModelInstructions = readTopLevelTomlLine(toml, 'model_instructions_file');
|
|
157
157
|
const currentNotify = readTopLevelTomlBlock(toml, 'notify');
|
|
158
158
|
const currentCodexGoalsFeature = readCodexGoalsFeatureLine(toml);
|
|
159
|
-
const
|
|
159
|
+
const currentNotifyAnalysis = analyzeCodexNotifyBlock(currentNotify);
|
|
160
160
|
|
|
161
161
|
const shouldRestoreModelInstructions = isManagedCodexModelInstruction(currentModelInstructions);
|
|
162
|
-
const shouldRestoreNotify = isManagedCodexNotify(currentNotify);
|
|
162
|
+
const shouldRestoreNotify = currentNotifyAnalysis.managed || isManagedCodexNotify(currentNotify);
|
|
163
163
|
const shouldRestoreCodexGoalsFeature = isManagedCodexGoalsFeature(currentCodexGoalsFeature);
|
|
164
|
-
const shouldRemoveLegacyCodexHooksFeature = isManagedLegacyCodexHooksFeature(currentLegacyCodexHooksFeature);
|
|
165
164
|
|
|
166
165
|
if (removePluginConfig) {
|
|
167
166
|
toml = removeCodexPluginConfig(toml);
|
|
@@ -170,16 +169,15 @@ function cleanupCodexManagedConfig(configPath, { removePluginConfig = false } =
|
|
|
170
169
|
toml = removeCodexGoalsFeatureConfig(toml);
|
|
171
170
|
}
|
|
172
171
|
toml = removeCodexManagedTuiConfig(toml);
|
|
173
|
-
if (shouldRemoveLegacyCodexHooksFeature) {
|
|
174
|
-
toml = removeLegacyManagedCodexHooksFeatureConfig(toml);
|
|
175
|
-
}
|
|
176
172
|
if (shouldRestoreModelInstructions) {
|
|
177
173
|
toml = removeTopLevelTomlLines(toml, (line) =>
|
|
178
174
|
line.startsWith('model_instructions_file =') && isManagedCodexModelInstruction(line)).text;
|
|
179
175
|
}
|
|
180
176
|
if (shouldRestoreNotify) {
|
|
181
|
-
toml =
|
|
182
|
-
|
|
177
|
+
toml = hasTopLevelTomlBlock(toml, 'notify')
|
|
178
|
+
? removeTopLevelTomlBlock(toml, 'notify')
|
|
179
|
+
: removeTopLevelTomlLines(toml, (line) =>
|
|
180
|
+
line.startsWith('notify =')).text;
|
|
183
181
|
}
|
|
184
182
|
|
|
185
183
|
const backupModelInstructions = readTopLevelTomlLine(backupToml, 'model_instructions_file');
|
|
@@ -190,7 +188,7 @@ function cleanupCodexManagedConfig(configPath, { removePluginConfig = false } =
|
|
|
190
188
|
modelInstructionsLine: shouldRestoreModelInstructions && !isManagedCodexBackupInstruction(backupModelInstructions)
|
|
191
189
|
? backupModelInstructions
|
|
192
190
|
: '',
|
|
193
|
-
notifyLine: shouldRestoreNotify && !
|
|
191
|
+
notifyLine: shouldRestoreNotify && !analyzeCodexNotifyBlock(backupNotify).managed
|
|
194
192
|
? backupNotify
|
|
195
193
|
: '',
|
|
196
194
|
});
|
|
@@ -220,7 +218,6 @@ export function installCodexStandby(home, pkgRoot) {
|
|
|
220
218
|
modelInstructionsPath: CODEX_MANAGED_MODEL_INSTRUCTIONS_PATH,
|
|
221
219
|
});
|
|
222
220
|
toml = installCodexManagedTuiConfig(toml);
|
|
223
|
-
toml = removeLegacyManagedCodexHooksFeatureConfig(toml);
|
|
224
221
|
safeWrite(configPath, toml);
|
|
225
222
|
installCodexStandaloneHooks(home, pkgRoot);
|
|
226
223
|
|
|
@@ -312,7 +309,6 @@ export function installCodexGlobal(home, pkgRoot) {
|
|
|
312
309
|
modelInstructionsPath: CODEX_MANAGED_MODEL_INSTRUCTIONS_PATH,
|
|
313
310
|
});
|
|
314
311
|
toml = installCodexManagedTuiConfig(toml);
|
|
315
|
-
toml = removeLegacyManagedCodexHooksFeatureConfig(toml);
|
|
316
312
|
toml = upsertCodexPluginConfig(toml);
|
|
317
313
|
safeWrite(configPath, toml);
|
|
318
314
|
installCodexStandaloneHooks(home, pkgRoot);
|