helloloop 0.1.0 → 0.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.
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "helloloop",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Backlog-driven continuous repository execution for Codex with verification loops and explicit skill and CLI entrypoints.",
5
5
  "author": {
6
- "name": "HelloWind",
7
- "url": "https://github.com/hellowind777"
6
+ "name": "HelloLoop"
8
7
  },
9
8
  "license": "MIT",
10
9
  "keywords": [
@@ -18,8 +17,8 @@
18
17
  "interface": {
19
18
  "displayName": "HelloLoop",
20
19
  "shortDescription": "Continuous repo execution with backlog and Ralph Loop guards",
21
- "longDescription": "HelloLoop packages backlog-driven continuous development for Codex as a pure official plugin bundle. Because current Codex runtime does not load Hook manifests from plugins, this plugin intentionally drops `~helloloop` Hook mode and uses explicit skill and CLI entrypoints instead.",
22
- "developerName": "HelloWind",
20
+ "longDescription": "HelloLoop packages backlog-driven continuous development for Codex as an official plugin bundle with explicit skill and CLI entrypoints.",
21
+ "developerName": "HelloLoop",
23
22
  "category": "Coding",
24
23
  "capabilities": [
25
24
  "Interactive",
package/README.md CHANGED
@@ -1,100 +1,91 @@
1
1
  # HelloLoop
2
2
 
3
- `HelloLoop` 是一个面向 Codex backlog 驱动开发插件。
3
+ `HelloLoop` 是一个面向 Codex 的独立插件,用来把“按 backlog 持续推进仓库开发”这件事标准化、可追踪、可验证地跑起来。
4
4
 
5
- 它把持续开发所需的任务队列、执行策略、验证命令和运行记录集中到目标仓库的 `.helloloop/` 目录里,并通过显式 CLI / skill 入口推动任务逐步落地。
5
+ 它不只是在单轮对话里改一段代码,而是把任务队列、必读文档、执行约束、验证命令和运行记录统一放进目标仓库的 `.helloloop/` 目录,让 Codex 可以按明确流程持续接续开发。
6
+
7
+ 命令入口按 `Node.js 20+` 设计,支持 Windows、macOS 和 Linux。
6
8
 
7
9
  ## 目录
8
10
 
9
11
  - [HelloLoop 是什么](#helloloop-是什么)
10
12
  - [核心能力](#核心能力)
11
13
  - [适用场景](#适用场景)
12
- - [项目结构](#项目结构)
13
14
  - [安装](#安装)
14
15
  - [快速开始](#快速开始)
15
- - [命令说明](#命令说明)
16
+ - [命令速查](#命令速查)
16
17
  - [状态目录](#状态目录)
17
- - [任务与执行模型](#任务与执行模型)
18
- - [发布到 npm](#发布到-npm)
19
- - [验证](#验证)
18
+ - [工作机制](#工作机制)
19
+ - [仓库结构](#仓库结构)
20
20
  - [相关文档](#相关文档)
21
21
 
22
22
  ## HelloLoop 是什么
23
23
 
24
- `HelloLoop` 解决的是“让 Codex 在同一个仓库里持续推进任务”这个问题。
24
+ `HelloLoop` 解决的是以下问题:
25
25
 
26
- 与一次性执行单个改动不同,它围绕一份 backlog 运行:
26
+ - 你的仓库里已经有开发文档、任务拆解或 backlog
27
+ - 你希望 Codex 能按顺序接着做,而不是每次都从头解释背景
28
+ - 你希望每一轮执行前都自动带上项目状态、必读文档和实现约束
29
+ - 你希望每次运行后都留下状态记录、验证结果和运行痕迹
27
30
 
28
- - 先从 backlog 里选择当前最合适的任务
29
- - 根据项目状态、必读文档和约束生成执行提示
30
- - 调用 Codex 完成实现
31
- - 运行验证命令确认结果
32
- - 失败时按 Ralph Loop 思路重试或换路
33
- - 把状态、结果和运行产物写回目标仓库
31
+ 围绕这个目标,`HelloLoop` 提供了一套明确的仓库内执行模型:
34
32
 
35
- 这意味着你可以把 `HelloLoop` 当成一个“面向仓库持续推进”的执行层,而不是单次脚本集合。
33
+ 1. backlog 中选择当前可执行任务
34
+ 2. 汇总项目上下文、任务目标和约束
35
+ 3. 生成面向 Codex 的执行提示
36
+ 4. 调用 Codex 完成实现
37
+ 5. 执行验证命令
38
+ 6. 回写状态、日志和运行记录
36
39
 
37
40
  ## 核心能力
38
41
 
39
- - **插件安装**:把运行时 bundle 安装到 `~/.codex/plugins/helloloop`
40
- - **仓库初始化**:为目标仓库生成 `.helloloop/` 初始状态文件
41
- - **任务选择**:基于优先级、依赖和风险等级选择下一任务
42
- - **干跑预览**:先生成下一任务提示词和验证列表,再决定是否执行
43
- - **单轮执行**:执行一个任务并回写状态
44
- - **循环执行**:连续执行多个任务,直到达到上限或遇到阻塞
45
- - **验证联动**:优先读取任务自身验证命令,否则回退到仓库 `.helloagents/verify.yaml`
46
- - **运行留痕**:把每次执行的提示词、日志、验证输出保存到 `runs/`
42
+ - **插件安装**:安装到 Codex Home,作为独立插件使用
43
+ - **仓库初始化**:在目标仓库生成 `.helloloop/` 状态目录
44
+ - **任务调度**:基于优先级、依赖、风险等级挑选下一任务
45
+ - **干跑预览**:先看下一任务、提示词和验证命令,再决定是否执行
46
+ - **单轮执行**:执行一个任务并回写结果
47
+ - **循环执行**:连续执行多个任务,直到完成、阻塞或达到上限
48
+ - **验证联动**:优先使用任务级验证命令,缺省时读取仓库验证配置
49
+ - **运行留痕**:把提示词、stdout、stderr、验证输出沉淀到 `runs/`
47
50
 
48
51
  ## 适用场景
49
52
 
50
- - 你已经有 backlog,希望 Codex 按队列持续推进
51
- - 你希望每个任务执行前都自动带上项目状态和文档约束
52
- - 你希望执行失败后自动进入重试或换路,而不是停在一次失败
53
- - 你希望把任务状态、验证结果和运行痕迹沉淀在仓库内
54
- - 你希望通过 npm 分发这个插件,并在 GitHub Tag 发布时自动同步到 npm
55
-
56
- ## 项目结构
57
-
58
- ```text
59
- helloloop/
60
- ├── .codex-plugin/ # Codex 插件 manifest
61
- ├── bin/ # npm bin 入口
62
- ├── docs/ # 说明文档
63
- ├── scripts/ # CLI 安装脚本与入口
64
- ├── skills/ # 插件技能
65
- ├── src/ # 核心实现
66
- ├── templates/ # 初始化模板
67
- └── tests/ # 回归测试
68
- ```
69
-
70
- 源码仓库包含 `docs/` 和 `tests/`,但安装到 Codex Home 时只会复制运行时必需文件。
53
+ - 你有一套开发文档,希望 Codex 接续完成后续开发
54
+ - 你有清晰 backlog,希望 AI 按队列逐项推进
55
+ - 你希望把“任务、约束、验证、结果”都放在仓库里长期维护
56
+ - 你希望执行失败后不是停住,而是能按既定策略继续推进
57
+ - 你希望多人协作时,每个人都能快速看懂当前任务状态
71
58
 
72
59
  ## 安装
73
60
 
74
- ### 方式一:通过 npm / npx 安装
61
+ ### 通过 npm / npx 安装
75
62
 
76
63
  ```powershell
77
- npx helloloop install --codex-home C:\Users\hellowind\.codex
64
+ npx helloloop install --codex-home <CODEX_HOME>
78
65
  ```
79
66
 
80
- ### 方式二:从源码仓库安装
67
+ ### 从源码仓库安装
81
68
 
82
69
  ```powershell
83
- pwsh -NoLogo -NoProfile -File .\scripts\install-home-plugin.ps1 -CodexHome C:\Users\hellowind\.codex
70
+ node ./scripts/helloloop.mjs install --codex-home <CODEX_HOME>
84
71
  ```
85
72
 
86
- 如果已存在同名安装目录,追加 `-Force` `--force` 覆盖即可。
73
+ 如果你在 Windows 上更习惯 PowerShell,也可以使用:
74
+
75
+ ```powershell
76
+ pwsh -NoLogo -NoProfile -File .\scripts\install-home-plugin.ps1 -CodexHome <CODEX_HOME>
77
+ ```
87
78
 
88
- 安装完成后,运行时文件会位于:
79
+ 安装完成后,插件会被放到:
89
80
 
90
81
  ```text
91
- C:\Users\hellowind\.codex\plugins\helloloop
82
+ <CODEX_HOME>\plugins\helloloop
92
83
  ```
93
84
 
94
- 同时会自动更新:
85
+ 同时会更新:
95
86
 
96
87
  ```text
97
- C:\Users\hellowind\.codex\.agents\plugins\marketplace.json
88
+ <CODEX_HOME>\.agents\plugins\marketplace.json
98
89
  ```
99
90
 
100
91
  ## 快速开始
@@ -102,44 +93,60 @@ C:\Users\hellowind\.codex\.agents\plugins\marketplace.json
102
93
  ### 1. 安装插件
103
94
 
104
95
  ```powershell
105
- npx helloloop install --codex-home C:\Users\hellowind\.codex
96
+ npx helloloop install --codex-home <CODEX_HOME>
97
+ ```
98
+
99
+ 之后的日常命令推荐直接使用:
100
+
101
+ ```powershell
102
+ npx helloloop <command> [options]
106
103
  ```
107
104
 
108
- ### 2. 在目标仓库初始化状态目录
105
+ 如果你已经全局安装过:
109
106
 
110
107
  ```powershell
111
- node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs init --repo D:\GitHub\dev\your-repo
108
+ helloloop <command> [options]
112
109
  ```
113
110
 
111
+ 在 Codex 当前会话里,也可以直接运行同样的 `npx helloloop ...` 命令,不需要重开终端。
112
+
113
+ ### 2. 在目标仓库初始化 `.helloloop/`
114
+
115
+ ```powershell
116
+ npx helloloop init --repo <REPO_ROOT>
117
+ ```
118
+
119
+ 初始化完成后,模板会落在目标仓库根目录下的 `.helloloop/`,而不是插件目录本身。
120
+
114
121
  ### 3. 检查运行条件
115
122
 
116
123
  ```powershell
117
- node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs doctor --repo D:\GitHub\dev\your-repo
124
+ npx helloloop doctor --repo <REPO_ROOT>
118
125
  ```
119
126
 
120
- ### 4. 查看当前状态或下一任务
127
+ ### 4. 查看状态与下一任务
121
128
 
122
129
  ```powershell
123
- node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs status --repo D:\GitHub\dev\your-repo
124
- node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs next --repo D:\GitHub\dev\your-repo
130
+ npx helloloop status --repo <REPO_ROOT>
131
+ npx helloloop next --repo <REPO_ROOT>
125
132
  ```
126
133
 
127
134
  ### 5. 执行一个任务或连续执行
128
135
 
129
136
  ```powershell
130
- node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs run-once --repo D:\GitHub\dev\your-repo
131
- node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs run-loop --repo D:\GitHub\dev\your-repo --max-tasks 2
137
+ npx helloloop run-once --repo <REPO_ROOT>
138
+ npx helloloop run-loop --repo <REPO_ROOT> --max-tasks 2
132
139
  ```
133
140
 
134
- ## 命令说明
141
+ ## 命令速查
135
142
 
136
143
  | 命令 | 作用 |
137
144
  | --- | --- |
138
- | `install` | 安装插件到 Codex Home,并更新 marketplace |
139
- | `init` | 初始化目标仓库 `.helloloop/` |
140
- | `doctor` | 检查 Codex CLI、模板、配置文件和插件文件是否齐备 |
141
- | `status` | 查看 backlog 汇总与下一任务 |
142
- | `next` | 干跑生成下一任务预览,不真正调用 Codex |
145
+ | `install` | 安装插件到 Codex Home,并更新插件 marketplace |
146
+ | `init` | 初始化目标仓库的 `.helloloop/` |
147
+ | `doctor` | 检查 Codex、插件文件和目标仓库配置是否齐备 |
148
+ | `status` | 查看 backlog 汇总、当前状态和下一任务 |
149
+ | `next` | 生成下一任务预览,不真正调用 Codex |
143
150
  | `run-once` | 执行一个任务 |
144
151
  | `run-loop` | 连续执行多个任务 |
145
152
 
@@ -147,22 +154,22 @@ node C:\Users\hellowind\.codex\plugins\helloloop\scripts\helloloop.mjs run-loop
147
154
 
148
155
  | 选项 | 说明 |
149
156
  | --- | --- |
150
- | `--repo <dir>` | 目标仓库根目录 |
157
+ | `--repo <dir>` | 目标仓库根目录,默认当前目录 |
151
158
  | `--codex-home <dir>` | 指定 Codex Home |
152
- | `--config-dir <dir>` | 自定义状态目录,默认 `.helloloop` |
159
+ | `--config-dir <dir>` | 指定状态目录名,默认 `.helloloop` |
153
160
  | `--dry-run` | 只生成提示词和预览,不真正调用 Codex |
154
161
  | `--task-id <id>` | 指定执行某个任务 |
155
- | `--max-tasks <n>` | `run-loop` 最多执行多少个任务 |
156
- | `--max-attempts <n>` | 每种策略内最大重试次数 |
162
+ | `--max-tasks <n>` | `run-loop` 最多执行的任务数 |
163
+ | `--max-attempts <n>` | 每种策略的最大重试次数 |
157
164
  | `--max-strategies <n>` | 单任务最大换路次数 |
158
- | `--allow-high-risk` | 允许执行 `medium` / `high` / `critical` 风险任务 |
165
+ | `--allow-high-risk` | 允许执行 `medium` 及以上风险任务 |
159
166
  | `--required-doc <path>` | 追加全局必读文档 |
160
167
  | `--constraint <text>` | 追加全局实现约束 |
161
- | `--force` | 覆盖安装目录 |
168
+ | `--force` | 覆盖已有安装目录 |
162
169
 
163
170
  ### Skill 名称
164
171
 
165
- 安装为 Codex 插件后,可通过插件命名空间使用:
172
+ 安装为 Codex 插件后,推荐显式使用:
166
173
 
167
174
  ```text
168
175
  helloloop:helloloop
@@ -170,7 +177,7 @@ helloloop:helloloop
170
177
 
171
178
  ## 状态目录
172
179
 
173
- `HelloLoop` 在目标仓库内默认使用 `.helloloop/` 保存执行状态。
180
+ `HelloLoop` 默认在目标仓库根目录创建 `.helloloop/`,用来保存 backlog、策略配置、运行状态和执行留痕。
174
181
 
175
182
  典型结构如下:
176
183
 
@@ -184,151 +191,73 @@ helloloop:helloloop
184
191
  └── runs/
185
192
  ```
186
193
 
187
- ### 各文件作用
194
+ 各文件作用如下:
188
195
 
189
- - `backlog.json`:任务列表、优先级、风险、验收条件、依赖关系
190
- - `policy.json`:循环上限、重试次数、Codex 执行参数
191
- - `project.json`:全局必读文档、实现约束和 planner 配置
192
- - `status.json`:机器可读的最近运行状态
193
- - `STATE.md`:给人看的当前状态摘要
194
- - `runs/`:每次任务执行的提示词、stdout、stderr 和验证记录
196
+ - `backlog.json`:任务列表、优先级、风险、依赖、验收条件
197
+ - `policy.json`:循环上限、重试策略、Codex 执行参数
198
+ - `project.json`:全局必读文档、实现约束、任务规划提示
199
+ - `status.json`:最近一次运行的机器可读状态
200
+ - `STATE.md`:面向人的当前进展摘要
201
+ - `runs/`:每次执行的提示词、日志和验证输出
195
202
 
196
- 如果旧仓库仍保留 `.helloagents/helloloop/`,当前版本也会自动识别;你也可以显式传 `--config-dir .helloagents/helloloop`。
203
+ ## 工作机制
197
204
 
198
- ## 任务与执行模型
205
+ ### 任务模型
199
206
 
200
- ### backlog 任务字段
201
-
202
- `backlog.json` 中的任务通常包含这些字段:
207
+ `backlog.json` 中的任务通常包含以下字段:
203
208
 
204
209
  - `id`:任务唯一标识
205
210
  - `title`:任务标题
206
- - `status`:`pending` / `in_progress` / `done` / `failed` / `blocked`
211
+ - `status`:`pending`、`in_progress`、`done`、`failed`、`blocked`
207
212
  - `priority`:`P0` 到 `P3`
208
- - `risk`:`low` / `medium` / `high` / `critical`
209
- - `goal`:任务目标
210
- - `docs`:执行前必读文档
211
- - `paths`:主要涉及目录
213
+ - `risk`:`low`、`medium`、`high`、`critical`
214
+ - `goal`:本任务要达成的目标
215
+ - `docs`:执行前必须阅读的文档
216
+ - `paths`:本任务主要涉及的目录
212
217
  - `acceptance`:验收条件
213
218
  - `dependsOn`:依赖的上游任务
214
- - `verify`:任务专属验证命令(可选)
219
+ - `verify`:任务专属验证命令
215
220
 
216
221
  ### 执行流程
217
222
 
218
- `HelloLoop` 的核心执行逻辑如下:
219
-
220
- 1. 从 backlog 中筛出可执行任务
221
- 2. 按优先级和依赖关系选择下一任务
222
- 3. 读取仓库状态、必读文档和实现约束
223
- 4. 生成 Codex 执行提示词
224
- 5. 调用 `codex exec`
225
- 6. 运行验证命令
226
- 7. 成功则把任务标记为完成
227
- 8. 失败则按 Ralph Loop 记录失败历史并继续重试或换路
223
+ `HelloLoop` 在每一轮执行中会完成这些事情:
228
224
 
229
- ### 风险与阻塞规则
225
+ 1. 找出当前可执行任务
226
+ 2. 读取仓库状态、任务描述和必读文档
227
+ 3. 生成清晰的 Codex 执行提示
228
+ 4. 运行 Codex 完成开发
229
+ 5. 执行验证命令
230
+ 6. 更新任务状态和运行记录
230
231
 
231
- - 默认只自动执行 `low` 风险任务
232
- - `medium` 及以上风险任务需要显式传入 `--allow-high-risk`
233
- - 如果存在未收束的 `in_progress` 任务,新的自动执行会被阻塞
234
- - 如果存在 `failed` 或 `blocked` 任务,执行会停下来等待处理
235
- - 如果依赖任务未完成,相关任务不会被挑选执行
232
+ ### 风险控制
236
233
 
237
- ## 发布到 npm
234
+ - 默认优先自动执行 `low` 风险任务
235
+ - 较高风险任务需要显式允许
236
+ - 存在未完成依赖时,任务不会被挑选执行
237
+ - 存在未收束的执行状态时,循环会停止并等待处理
238
238
 
239
- 仓库已加入自动发布工作流:
239
+ ## 仓库结构
240
240
 
241
241
  ```text
242
- .github/workflows/publish.yml
243
- ```
244
-
245
- 这个工作流借鉴了 `helloagents` 的发布结构,并做了适合 `HelloLoop` 的简化与对齐:
246
-
247
- - Git Tag 作为发布触发器
248
- - 发布前校验 `package.json` 版本与 Tag 是否一致
249
- - 自动运行 `npm test`
250
- - 自动运行 `npm pack --dry-run`
251
- - 自动发布到 npm
252
- - 自动创建 GitHub Release
253
-
254
- ### 推荐发布方式
255
-
256
- #### 正式版
257
-
258
- 1. 修改 `package.json` 中的 `version`
259
- 2. 提交并推送代码
260
- 3. 创建同版本 Tag
261
-
262
- 示例:
263
-
264
- ```powershell
265
- npm version patch --no-git-tag-version
266
- git add package.json
267
- git commit -m "chore: release v0.1.1"
268
- git push origin main
269
- git tag v0.1.1
270
- git push origin v0.1.1
271
- ```
272
-
273
- 推送 `v0.1.1` 后,Action 会把 `0.1.1` 发布到 npm 的 `latest` 通道。
274
-
275
- #### Beta 版
276
-
277
- Beta Tag 采用:
278
-
279
- ```text
280
- v0.2.0-beta.1
281
- ```
282
-
283
- 这类 Tag 会发布到 npm 的 `beta` 通道。工作流会要求:
284
-
285
- - `package.json` 中的基础版本为 `0.2.0`
286
- - 实际发布版本为 `0.2.0-beta.1`
287
-
288
- ### npm Trusted Publishing 配置
289
-
290
- 为了让 GitHub Actions 无需 `NPM_TOKEN` 直接发布到 npm,建议使用 npm Trusted Publishing。
291
-
292
- 在 npm 包设置中把以下信息绑定为 Trusted Publisher:
293
-
294
- - GitHub 仓库:`hellowind777/helloloop`
295
- - Workflow 文件:`publish.yml`
296
- - 触发来源:GitHub-hosted runner
297
-
298
- 发布工作流已经按 Trusted Publishing 方式准备好:
299
-
300
- - `id-token: write`
301
- - Node 24
302
- - 升级到最新 npm CLI
303
- - 直接执行 `npm publish`
304
-
305
- ### 工作流触发规则
306
-
307
- - `push tags: v*`:标准自动发布入口
308
- - `workflow_dispatch`:手动输入 Tag 重新发布某个版本
309
-
310
- ## 验证
311
-
312
- ### 本地回归
313
-
314
- ```powershell
315
- npm test
316
- ```
317
-
318
- ### 打包预检
319
-
320
- ```powershell
321
- npm pack --dry-run
242
+ helloloop/
243
+ ├── .codex-plugin/ # Codex 插件 manifest 与展示元数据
244
+ ├── bin/ # npm 命令入口
245
+ ├── docs/ # 补充说明文档
246
+ ├── scripts/ # 安装脚本与 CLI 入口
247
+ ├── skills/ # 插件技能
248
+ ├── src/ # 核心实现
249
+ ├── templates/ # 初始化时写入 .helloloop/ 的模板
250
+ └── tests/ # 回归测试
322
251
  ```
323
252
 
324
- ### 安装烟测
253
+ 其中:
325
254
 
326
- ```powershell
327
- node .\bin\helloloop.mjs install --codex-home C:\Users\hellowind\AppData\Local\Temp\helloloop-smoke --force
328
- ```
255
+ - `src/` 用来放 `HelloLoop` 的实际实现逻辑,例如任务选择、状态加载、执行流程、提示词生成和安装流程
256
+ - `tests/` 用来做回归验证,确保 CLI、模板、插件 bundle 和执行流程没有被改坏
257
+ - `templates/` 是初始化目标仓库时写入 `.helloloop/` 的模板来源
329
258
 
330
259
  ## 相关文档
331
260
 
332
- - 安装说明:`docs/install.md`
333
- - 插件主说明:`docs/README.md`
334
- - 官方标准映射:`docs/plugin-standard.md`
261
+ - `docs/README.md`:插件 bundle 结构补充说明
262
+ - `docs/install.md`:安装说明
263
+ - `docs/plugin-standard.md`:官方插件结构与标准对照
package/package.json CHANGED
@@ -1,21 +1,17 @@
1
1
  {
2
2
  "name": "helloloop",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Standalone Codex plugin bundle for backlog-driven repository execution with Ralph Loop guards",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/hellowind777/helloloop.git"
9
- },
10
- "homepage": "https://github.com/hellowind777/helloloop#readme",
11
- "bugs": {
12
- "url": "https://github.com/hellowind777/helloloop/issues"
8
+ "url": "git+https://github.com/hellowind777/helloloop.git"
13
9
  },
14
10
  "publishConfig": {
15
11
  "access": "public"
16
12
  },
17
13
  "bin": {
18
- "helloloop": "./bin/helloloop.mjs"
14
+ "helloloop": "bin/helloloop.js"
19
15
  },
20
16
  "files": [
21
17
  ".codex-plugin",
@@ -28,10 +24,9 @@
28
24
  "templates"
29
25
  ],
30
26
  "scripts": {
31
- "test": "node --test tests/cli_surface.test.mjs tests/install_script.test.mjs tests/ralph_loop.test.mjs tests/plugin_bundle.test.mjs"
27
+ "test": "node --test tests/cli_surface.test.mjs tests/install_script.test.mjs tests/process_shell.test.mjs tests/ralph_loop.test.mjs tests/plugin_bundle.test.mjs"
32
28
  },
33
29
  "engines": {
34
30
  "node": ">=20"
35
31
  }
36
32
  }
37
-
@@ -11,18 +11,17 @@ Use this plugin when the task is continuous repository execution rather than a s
11
11
 
12
12
  - This bundle root is the official plugin surface for HelloLoop.
13
13
  - It ships standard Codex plugin metadata through `.codex-plugin/plugin.json` and a plugin skill through `skills/`.
14
- - Current Codex runtime does not auto-load Hook handlers from plugins.
15
- - This plugin therefore does not support `~helloloop` or automatic Stop-hook continuation.
14
+ - This plugin is designed around explicit skill and CLI entrypoints.
16
15
 
17
16
  ## Setup
18
17
 
19
18
  1. Install with `npx helloloop install --codex-home <CODEX_HOME>` or use `scripts/install-home-plugin.ps1`.
20
- 2. From the target repository, run `node <helloloop-plugin-root>/scripts/helloloop.mjs doctor --repo <repo-root>`.
21
- 3. From the target repository, run `node <helloloop-plugin-root>/scripts/helloloop.mjs init --repo <repo-root>`.
19
+ 2. From the target repository, run `npx helloloop doctor --repo <repo-root>`.
20
+ 3. From the target repository, run `npx helloloop init --repo <repo-root>`.
22
21
 
23
22
  ## Operating Model
24
23
 
25
- - `.helloloop/` is the CLI and backlog state directory.
24
+ - `.helloloop/` is the default CLI and backlog state directory.
26
25
  - The installed plugin bundle keeps runtime files such as `src/`, `templates/`, `bin/`, `scripts/`, and `skills/`.
27
26
  - Source-only materials such as `docs/` and `tests/` stay in the development repository.
28
27
 
@@ -35,15 +34,14 @@ Use this plugin when the task is continuous repository execution rather than a s
35
34
 
36
35
  ## Primary Commands
37
36
 
38
- - `node <helloloop-plugin-root>/scripts/helloloop.mjs status --repo <repo-root>`
39
- - `node <helloloop-plugin-root>/scripts/helloloop.mjs next --repo <repo-root>`
40
- - `node <helloloop-plugin-root>/scripts/helloloop.mjs run-once --repo <repo-root>`
41
- - `node <helloloop-plugin-root>/scripts/helloloop.mjs run-loop --repo <repo-root>`
37
+ - `npx helloloop status --repo <repo-root>`
38
+ - `npx helloloop next --repo <repo-root>`
39
+ - `npx helloloop run-once --repo <repo-root>`
40
+ - `npx helloloop run-loop --repo <repo-root>`
42
41
 
43
42
  ## Reporting Rules
44
43
 
45
44
  - State explicitly that the plugin runs in pure official plugin mode.
46
- - Call out any request that depends on Hook-only behavior such as `UserPromptSubmit` or `Stop`, because those are intentionally unsupported here.
47
45
  - Keep Ralph Loop guardrails and repo verification intact.
48
46
 
49
47
  ## Docs
package/src/cli.mjs CHANGED
@@ -7,6 +7,8 @@ import { scaffoldIfMissing } from "./config.mjs";
7
7
  import { installPluginBundle } from "./install.mjs";
8
8
  import { runLoop, runOnce, renderStatusText } from "./runner.mjs";
9
9
 
10
+ const REPO_ROOT_PLACEHOLDER = "<REPO_ROOT>";
11
+
10
12
  function parseArgs(argv) {
11
13
  const [command = "status", ...rest] = argv;
12
14
  const options = {
@@ -68,6 +70,14 @@ function printHelp() {
68
70
  console.log(helpText());
69
71
  }
70
72
 
73
+ function renderFollowupExamples() {
74
+ return [
75
+ "下一步示例:",
76
+ `npx helloloop doctor --repo ${REPO_ROOT_PLACEHOLDER}`,
77
+ `如已全局安装,也可直接运行:helloloop doctor --repo ${REPO_ROOT_PLACEHOLDER}`,
78
+ ].join("\n");
79
+ }
80
+
71
81
  function probeCodexVersion() {
72
82
  const codexVersion = process.platform === "win32"
73
83
  ? spawnSync("codex --version", {
@@ -171,8 +181,7 @@ export async function runCli(argv) {
171
181
  console.log(`HelloLoop 已安装到:${result.targetPluginRoot}`);
172
182
  console.log(`Marketplace 已更新:${result.marketplaceFile}`);
173
183
  console.log("");
174
- console.log("下一步示例:");
175
- console.log(`node ${path.join(result.targetPluginRoot, "scripts", "helloloop.mjs")} doctor --repo D:\\GitHub\\dev\\your-repo`);
184
+ console.log(renderFollowupExamples());
176
185
  return;
177
186
  }
178
187
 
@@ -259,4 +268,4 @@ export async function runCli(argv) {
259
268
 
260
269
  throw new Error(`未知命令:${command}`);
261
270
  }
262
-
271
+
package/src/config.mjs CHANGED
@@ -98,7 +98,7 @@ export function loadVerifyCommands(context) {
98
98
  }
99
99
 
100
100
  export function loadRepoStateText(context) {
101
- return readTextIfExists(context.repoStateFile, "").trim();
101
+ return readTextIfExists(context.stateFile, "").trim();
102
102
  }
103
103
 
104
104
  export function writeStatus(context, status) {
@@ -138,4 +138,4 @@ export function scaffoldIfMissing(context) {
138
138
 
139
139
  return created;
140
140
  }
141
-
141
+
package/src/context.mjs CHANGED
@@ -1,35 +1,16 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
 
4
- import { fileExists, resolveFrom } from "./common.mjs";
4
+ import { resolveFrom } from "./common.mjs";
5
5
 
6
6
  const __filename = fileURLToPath(import.meta.url);
7
7
  const __dirname = path.dirname(__filename);
8
8
  const toolRoot = path.resolve(__dirname, "..");
9
9
  const defaultConfigDirName = ".helloloop";
10
- const legacyConfigDirName = ".helloagents/helloloop";
11
-
12
- function resolveConfigDirName(repoRoot, explicitConfigDirName) {
13
- if (explicitConfigDirName) {
14
- return explicitConfigDirName;
15
- }
16
-
17
- const defaultConfigRoot = resolveFrom(repoRoot, ...defaultConfigDirName.split("/"));
18
- if (fileExists(defaultConfigRoot)) {
19
- return defaultConfigDirName;
20
- }
21
-
22
- const legacyConfigRoot = resolveFrom(repoRoot, ...legacyConfigDirName.split("/"));
23
- if (fileExists(legacyConfigRoot)) {
24
- return legacyConfigDirName;
25
- }
26
-
27
- return defaultConfigDirName;
28
- }
29
10
 
30
11
  export function createContext(options = {}) {
31
12
  const repoRoot = path.resolve(options.repoRoot || process.cwd());
32
- const configDirName = resolveConfigDirName(repoRoot, options.configDirName);
13
+ const configDirName = options.configDirName || defaultConfigDirName;
33
14
  const configRoot = resolveFrom(repoRoot, ...configDirName.split("/"));
34
15
 
35
16
  return {
@@ -49,8 +30,7 @@ export function createContext(options = {}) {
49
30
  statusFile: resolveFrom(configRoot, "status.json"),
50
31
  stateFile: resolveFrom(configRoot, "STATE.md"),
51
32
  runsDir: resolveFrom(configRoot, "runs"),
52
- repoStateFile: resolveFrom(repoRoot, ".helloagents", "STATE.md"),
53
33
  repoVerifyFile: resolveFrom(repoRoot, ".helloagents", "verify.yaml"),
54
34
  };
55
35
  }
56
-
36
+
package/src/process.mjs CHANGED
@@ -66,6 +66,57 @@ function buildCmdCommandLine(executable, args) {
66
66
  return [quoteForCmd(executable), ...args.map((item) => quoteForCmd(item))].join(" ");
67
67
  }
68
68
 
69
+ function hasCommand(command, platform = process.platform) {
70
+ if (platform === "win32") {
71
+ const result = spawnSync("where.exe", [command], {
72
+ encoding: "utf8",
73
+ shell: false,
74
+ });
75
+ return result.status === 0;
76
+ }
77
+
78
+ const result = spawnSync("sh", ["-lc", `command -v ${command}`], {
79
+ encoding: "utf8",
80
+ shell: false,
81
+ });
82
+ return result.status === 0;
83
+ }
84
+
85
+ export function resolveVerifyShellInvocation(options = {}) {
86
+ const platform = options.platform || process.platform;
87
+ const commandExists = options.commandExists || ((command) => hasCommand(command, platform));
88
+
89
+ if (platform === "win32") {
90
+ if (commandExists("pwsh")) {
91
+ return {
92
+ command: "pwsh",
93
+ argsPrefix: ["-NoLogo", "-NoProfile", "-Command"],
94
+ shell: false,
95
+ };
96
+ }
97
+
98
+ if (commandExists("powershell")) {
99
+ return {
100
+ command: "powershell",
101
+ argsPrefix: ["-NoLogo", "-NoProfile", "-Command"],
102
+ shell: false,
103
+ };
104
+ }
105
+
106
+ return {
107
+ command: "cmd.exe",
108
+ argsPrefix: ["/d", "/s", "/c"],
109
+ shell: false,
110
+ };
111
+ }
112
+
113
+ return {
114
+ command: "sh",
115
+ argsPrefix: ["-lc"],
116
+ shell: false,
117
+ };
118
+ }
119
+
69
120
  function resolveCodexExecutable(explicitExecutable = "") {
70
121
  if (explicitExecutable) {
71
122
  return explicitExecutable;
@@ -214,13 +265,13 @@ export async function runCodexExec({ context, prompt, runDir, policy }) {
214
265
  }
215
266
 
216
267
  export async function runShellCommand(context, commandLine, runDir, index) {
217
- const result = await runChild("pwsh", [
218
- "-NoLogo",
219
- "-NoProfile",
220
- "-Command",
268
+ const shellInvocation = resolveVerifyShellInvocation();
269
+ const result = await runChild(shellInvocation.command, [
270
+ ...shellInvocation.argsPrefix,
221
271
  commandLine,
222
272
  ], {
223
273
  cwd: context.repoRoot,
274
+ shell: shellInvocation.shell,
224
275
  });
225
276
 
226
277
  const prefix = String(index + 1).padStart(2, "0");
package/src/runner.mjs CHANGED
@@ -338,4 +338,4 @@ export function renderStatusText(context, options = {}) {
338
338
  nextTask ? renderTaskSummary(nextTask) : "",
339
339
  ].filter(Boolean).join("\n");
340
340
  }
341
-
341
+
@@ -9,4 +9,4 @@
9
9
  - 当前任务:无
10
10
  - 最近结果:HelloLoop 已初始化
11
11
  - 下一建议:先完善 backlog.json
12
-
12
+
@@ -15,4 +15,4 @@
15
15
  "message": "HelloLoop 已初始化。",
16
16
  "updatedAt": "2026-03-27T00:00:00.000Z"
17
17
  }
18
-
18
+
File without changes