helloloop 0.2.0 → 0.3.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 +228 -279
- package/hosts/claude/marketplace/.claude-plugin/marketplace.json +3 -1
- package/hosts/claude/marketplace/plugins/helloloop/.claude-plugin/plugin.json +1 -1
- package/hosts/claude/marketplace/plugins/helloloop/commands/helloloop.md +16 -9
- package/hosts/claude/marketplace/plugins/helloloop/skills/helloloop/SKILL.md +4 -1
- package/hosts/gemini/extension/GEMINI.md +8 -4
- package/hosts/gemini/extension/commands/helloloop.toml +15 -8
- package/hosts/gemini/extension/gemini-extension.json +1 -1
- package/package.json +2 -2
- package/scripts/uninstall-home-plugin.ps1 +25 -0
- package/skills/helloloop/SKILL.md +28 -3
- package/src/analyze_confirmation.mjs +79 -3
- package/src/analyze_prompt.mjs +12 -0
- package/src/analyze_user_input.mjs +303 -0
- package/src/analyzer.mjs +38 -0
- package/src/cli.mjs +211 -25
- package/src/cli_support.mjs +114 -27
- package/src/discovery.mjs +243 -9
- package/src/discovery_inference.mjs +62 -18
- package/src/discovery_paths.mjs +143 -8
- package/src/discovery_prompt.mjs +298 -0
- package/src/install.mjs +218 -7
- package/src/rebuild.mjs +116 -0
- package/templates/analysis-output.schema.json +58 -0
|
@@ -8,11 +8,18 @@ argument-hint: [PATH]
|
|
|
8
8
|
规则如下:
|
|
9
9
|
|
|
10
10
|
1. 将当前代码视为事实源,将开发文档视为目标源。
|
|
11
|
-
2. 如果用户在命令后提供了 `$ARGUMENTS
|
|
12
|
-
3.
|
|
13
|
-
4.
|
|
14
|
-
5.
|
|
15
|
-
6.
|
|
11
|
+
2. 如果用户在命令后提供了 `$ARGUMENTS`,必须同时保留其中的显式路径和自然语言补充要求,不要依赖固定关键词硬编码决策。
|
|
12
|
+
3. 自动识别目标仓库与开发文档,并先分析“当前代码做到哪里了”“与文档目标是否存在偏差”“当前项目与文档目标是否匹配”。
|
|
13
|
+
4. 如果当前目录没有明确开发文档,先展示顶层文档文件、顶层目录和疑似项目目录,再询问用户开发文档路径。
|
|
14
|
+
5. 项目路径对外只有一个概念;如果用户输入的项目路径不存在,就把它视为准备创建的新项目目录,不要再单独追问“新项目路径”。
|
|
15
|
+
6. 在目标仓库根目录创建或刷新 `.helloloop/`,至少维护 `backlog.json`、`project.json`、`status.json`、`STATE.md` 与 `runs/`。
|
|
16
|
+
7. 如果用户给了开发文档但无法定位项目仓库,或者给了项目路径但无法定位开发文档,必须停下来询问用户,而不是猜测。
|
|
17
|
+
8. 如果当前项目目录已存在,但分析认为它与开发文档目标明显冲突,必须先明确提示用户,并确认是继续现有项目、还是清理后按文档重建。
|
|
18
|
+
9. 在真正执行开发前,必须输出一份中文执行确认单,至少包含:
|
|
19
|
+
- 路径判断与判断依据
|
|
20
|
+
- 本次命令补充输入
|
|
21
|
+
- 需求语义理解
|
|
22
|
+
- 项目匹配判断
|
|
16
23
|
- 目标仓库
|
|
17
24
|
- 开发文档
|
|
18
25
|
- 当前进度
|
|
@@ -22,7 +29,7 @@ argument-hint: [PATH]
|
|
|
22
29
|
- 首个待执行任务
|
|
23
30
|
- 验证命令预览
|
|
24
31
|
- 自动执行停止条件
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
10. 未经用户确认,不要开始正式修改代码。
|
|
33
|
+
11. 用户确认后,使用 Claude Code 的原生工具持续推进 backlog,直到开发文档的最终目标完成,且相关测试、验证、验收都已通过;遇到硬阻塞或需要用户补充关键信息时再停下。
|
|
34
|
+
12. 始终优先使用安全 shell 与原生文件工具;在 Windows 上避免危险的嵌套命令、路径拼接删除和 `cmd` 风格破坏性命令。
|
|
35
|
+
13. 不要调用外部 `npx helloloop` 来替代这个原生工作流;你现在就在 HelloLoop 的 Claude Code 原生模式中。
|
|
@@ -13,11 +13,14 @@ description: 当用户希望 Claude Code 按开发文档先分析当前进度,
|
|
|
13
13
|
2. 分析当前代码与文档目标之间的真实进度和偏差
|
|
14
14
|
3. 在目标仓库根目录创建或刷新 `.helloloop/`
|
|
15
15
|
4. 输出中文执行确认单
|
|
16
|
-
5. 用户确认后,继续用 Claude Code
|
|
16
|
+
5. 用户确认后,继续用 Claude Code 原生工具接续开发、测试和验收,直到最终目标完成
|
|
17
17
|
|
|
18
18
|
## 关键规则
|
|
19
19
|
|
|
20
20
|
- 如果缺少目标仓库或开发文档,必须停下来询问用户。
|
|
21
|
+
- 如果当前目录没有明确开发文档,应先展示顶层文档文件、顶层目录和疑似项目目录,再询问文档路径。
|
|
22
|
+
- 项目路径对外只有一个概念;如果用户提供的项目路径不存在,直接按新项目路径处理,不要再追问“新项目路径”。
|
|
23
|
+
- 如果当前项目与开发文档目标明显冲突,必须先确认是继续现有项目、清理后重建,还是取消。
|
|
21
24
|
- 不允许跳过执行确认单直接开始正式开发。
|
|
22
25
|
- 不允许把开发文档整体压成一个大任务;需要输出足够细的 backlog。
|
|
23
26
|
- 代码是事实源,开发文档是目标源。
|
|
@@ -9,16 +9,20 @@
|
|
|
9
9
|
## 默认流程
|
|
10
10
|
|
|
11
11
|
1. 自动识别项目仓库与开发文档
|
|
12
|
-
2.
|
|
13
|
-
3.
|
|
14
|
-
4.
|
|
15
|
-
5.
|
|
12
|
+
2. 如果当前目录没有明确开发文档,先展示顶层文档文件、顶层目录和疑似项目目录,再询问文档路径
|
|
13
|
+
3. 项目路径对外只有一个概念;若用户输入的路径不存在,直接按新项目路径处理
|
|
14
|
+
4. 分析当前代码与开发文档的差距,并判断当前项目与文档目标是否匹配
|
|
15
|
+
5. 在目标仓库根目录创建或刷新 `.helloloop/`
|
|
16
|
+
6. 输出中文执行确认单(含路径判断、语义理解、项目匹配判断)
|
|
17
|
+
7. 若当前项目与开发文档目标明显冲突,先确认是继续现有项目还是清理后重建
|
|
18
|
+
8. 用户确认后,再继续执行后续开发任务,直到最终目标完成且测试、验收全部通过
|
|
16
19
|
|
|
17
20
|
## 强制规则
|
|
18
21
|
|
|
19
22
|
- 代码是事实源,开发文档是目标源。
|
|
20
23
|
- 开发前必须先输出执行确认单。
|
|
21
24
|
- 如果无法识别目标仓库或开发文档,必须停下来询问用户。
|
|
25
|
+
- 不要单独追问“新项目路径”;项目路径只需要用户给一次。
|
|
22
26
|
- 如果识别到偏差修正任务,优先收口偏差,再推进后续 backlog。
|
|
23
27
|
- 真正执行前确认,真正结束前验证。
|
|
24
28
|
|
|
@@ -4,10 +4,16 @@ prompt = """
|
|
|
4
4
|
|
|
5
5
|
执行要求:
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
7
|
+
1. 自动识别目标仓库与开发文档;如果用户在命令后提供了参数,必须同时保留其中的显式路径和自然语言补充要求,不要靠固定关键词硬编码判断。
|
|
8
|
+
2. 如果当前目录没有明确开发文档,应先展示顶层文档文件、顶层目录和疑似项目目录,再询问用户开发文档路径。
|
|
9
|
+
3. 项目路径对外只有一个概念;如果用户给出的项目路径不存在,直接按新项目路径处理,不要再单独追问“新项目路径”。
|
|
10
|
+
4. 分析当前代码与开发文档之间的真实进度和偏差,并判断当前项目目录与开发文档目标是否匹配。
|
|
11
|
+
5. 在目标仓库根目录创建或刷新 `.helloloop/`,至少维护 `backlog.json`、`project.json`、`status.json`、`STATE.md` 与 `runs/`。
|
|
12
|
+
6. 在真正开发前,必须输出中文执行确认单,至少包含:
|
|
13
|
+
- 路径判断与判断依据
|
|
14
|
+
- 本次命令补充输入
|
|
15
|
+
- 需求语义理解
|
|
16
|
+
- 项目匹配判断
|
|
11
17
|
- 目标仓库
|
|
12
18
|
- 开发文档
|
|
13
19
|
- 当前进度
|
|
@@ -17,8 +23,9 @@ prompt = """
|
|
|
17
23
|
- 首个待执行任务
|
|
18
24
|
- 验证命令预览
|
|
19
25
|
- 自动执行停止条件
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
7. 如果当前项目目录已存在,但分析认为它与开发文档目标明显冲突,必须先明确提示用户,并确认是继续现有项目、还是清理后按文档重建。
|
|
27
|
+
8. 用户未确认前,不要开始正式修改代码。
|
|
28
|
+
9. 用户确认后,继续用 Gemini CLI 原生工具推进 backlog,直到开发文档的最终目标完成,且相关测试、验证、验收都已通过;遇到硬阻塞或需要用户补充关键信息时再停下。
|
|
29
|
+
10. 如果用户给了开发文档但找不到项目仓库,或给了项目路径但找不到开发文档,必须停下来询问。
|
|
30
|
+
11. Windows 上优先用安全的文件与 shell 操作;禁止危险删除、硬重置、强推和其他破坏性命令。
|
|
24
31
|
"""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloloop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "面向 Codex CLI、Claude Code、Gemini CLI 的多宿主开发工作流插件",
|
|
5
5
|
"author": "HelloLoop",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"templates"
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
|
-
"test": "node --test tests/analyze_cli.test.mjs tests/cli_surface.test.mjs tests/install_script.test.mjs tests/process_shell.test.mjs tests/prompt_guardrails.test.mjs tests/ralph_loop.test.mjs tests/plugin_bundle.test.mjs"
|
|
33
|
+
"test": "node --test tests/analyze_cli.test.mjs tests/analyze_intent_cli.test.mjs tests/cli_surface.test.mjs tests/install_script.test.mjs tests/process_shell.test.mjs tests/prompt_guardrails.test.mjs tests/ralph_loop.test.mjs tests/plugin_bundle.test.mjs"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
|
36
36
|
"node": ">=20"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[CmdletBinding()]
|
|
2
|
+
param(
|
|
3
|
+
[string]$CodexHome = (Join-Path $HOME ".codex")
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
$sourceRoot = Split-Path -Parent $PSScriptRoot
|
|
7
|
+
$cliEntry = Join-Path $sourceRoot "scripts\helloloop.mjs"
|
|
8
|
+
|
|
9
|
+
if (-not (Test-Path $cliEntry)) {
|
|
10
|
+
throw "未找到 CLI 入口:$cliEntry"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
|
|
14
|
+
throw "未找到 node,可先安装 Node.js 20+ 后再运行。"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
$arguments = @(
|
|
18
|
+
$cliEntry,
|
|
19
|
+
"uninstall",
|
|
20
|
+
"--codex-home",
|
|
21
|
+
$CodexHome
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
& node @arguments
|
|
25
|
+
exit $LASTEXITCODE
|
|
@@ -9,7 +9,7 @@ description: 当用户希望 Codex 先分析仓库当前进度、生成确认单
|
|
|
9
9
|
|
|
10
10
|
## 强制入口规则
|
|
11
11
|
|
|
12
|
-
- 用户显式调用 `$helloloop` / `helloloop:helloloop` 时,默认必须优先执行 `npx helloloop` 或 `npx helloloop <PATH>`。
|
|
12
|
+
- 用户显式调用 `$helloloop` / `#helloloop` / `helloloop:helloloop` 时,默认必须优先执行 `npx helloloop` 或 `npx helloloop <PATH>`。
|
|
13
13
|
- 不允许在对话里手工模拟 `HelloLoop` 的分析、确认单、backlog 编排和自动续跑流程来代替 CLI。
|
|
14
14
|
- 只有在以下情况,才允许先停下来问用户而不是直接执行 CLI:
|
|
15
15
|
1. 用户既没有给路径,当前目录也无法判断项目仓库或开发文档
|
|
@@ -23,6 +23,27 @@ description: 当用户希望 Codex 先分析仓库当前进度、生成确认单
|
|
|
23
23
|
- 用户给了单一路径 → 先执行 `npx helloloop <PATH>`
|
|
24
24
|
- 用户明确只想先看分析和确认单 → 执行 `npx helloloop --dry-run`
|
|
25
25
|
- 用户明确要求跳过确认直接开始 → 执行 `npx helloloop -y`
|
|
26
|
+
- 用户在命令后附带了额外路径或自然语言要求 → 必须把这些附加内容一并传给主 CLI,不允许丢弃或手工改写
|
|
27
|
+
|
|
28
|
+
## 附加输入处理规则
|
|
29
|
+
|
|
30
|
+
- 命令后的显式路径优先于自动发现结果。
|
|
31
|
+
- 命令后的非路径文本不靠关键词硬编码分流,而是作为“本次用户意图”原样传给 `HelloLoop` 的确认单与分析 prompt。
|
|
32
|
+
- 如果附加输入里同时包含文档路径、项目路径和额外要求,优先保留全部信息,再由 CLI 输出确认单统一确认。
|
|
33
|
+
- 不允许因为语言不同(中文 / 英文 / 其他语言)就忽略附加要求。
|
|
34
|
+
|
|
35
|
+
## 路径发现与提问规则
|
|
36
|
+
|
|
37
|
+
- 如果当前目录没有自动识别到明确开发文档,应先展示顶层文档文件、顶层目录和疑似项目目录,再要求用户补充文档路径。
|
|
38
|
+
- 项目路径对外只有一个概念,不要单独追问“新项目路径”。
|
|
39
|
+
- 如果用户输入的项目路径不存在,应直接把它视为准备创建的新项目目录。
|
|
40
|
+
- 如果自动发现同时出现多个冲突的文档路径或项目路径,不允许替用户猜测,必须停下来确认。
|
|
41
|
+
|
|
42
|
+
## 项目冲突规则
|
|
43
|
+
|
|
44
|
+
- 如果分析认为“当前项目目录已存在,但与开发文档目标明显冲突”,必须先提示用户选择继续、重建还是取消。
|
|
45
|
+
- 非交互模式下,只有显式追加 `--rebuild-existing`,才允许直接清理当前项目后重建。
|
|
46
|
+
- 未经确认,不允许默认清空现有项目目录。
|
|
26
47
|
|
|
27
48
|
## 插件边界
|
|
28
49
|
|
|
@@ -45,8 +66,8 @@ description: 当用户希望 Codex 先分析仓库当前进度、生成确认单
|
|
|
45
66
|
|
|
46
67
|
- 代码是事实源,开发文档是目标源。
|
|
47
68
|
- `HelloLoop` 会先分析当前真实进度,再生成或刷新 `.helloloop/backlog.json`。
|
|
48
|
-
-
|
|
49
|
-
- 用户确认后,默认会持续执行到 backlog
|
|
69
|
+
- 分析后会展示中文执行确认单,明确告知路径判断、语义理解、项目匹配、当前进度、待办任务、验证命令和执行边界。
|
|
70
|
+
- 用户确认后,默认会持续执行到 backlog 清空,或开发文档的最终目标完成且测试、验收通过,或遇到硬阻塞。
|
|
50
71
|
- 真正的代码分析与实现仍由本机 `codex` CLI 完成。
|
|
51
72
|
- `$helloloop` 的职责是把用户请求路由到主 CLI 流程,而不是在对话里手工复刻一套平行流程。
|
|
52
73
|
|
|
@@ -54,8 +75,10 @@ description: 当用户希望 Codex 先分析仓库当前进度、生成确认单
|
|
|
54
75
|
|
|
55
76
|
- `npx helloloop`
|
|
56
77
|
- `npx helloloop <PATH>`
|
|
78
|
+
- `npx helloloop <PATH> <补充说明>`
|
|
57
79
|
- `npx helloloop --dry-run`
|
|
58
80
|
- `npx helloloop -y`
|
|
81
|
+
- `npx helloloop --rebuild-existing`
|
|
59
82
|
|
|
60
83
|
## 手动控制命令
|
|
61
84
|
|
|
@@ -65,6 +88,8 @@ description: 当用户希望 Codex 先分析仓库当前进度、生成确认单
|
|
|
65
88
|
- `npx helloloop run-loop --max-tasks <n>`
|
|
66
89
|
- `npx helloloop doctor`
|
|
67
90
|
- `npx helloloop init`
|
|
91
|
+
- `npx helloloop install --host all`
|
|
92
|
+
- `npx helloloop uninstall --host all`
|
|
68
93
|
|
|
69
94
|
## 调用方式
|
|
70
95
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
|
+
import { renderInputIssueLines, renderUserIntentLines } from "./analyze_user_input.mjs";
|
|
3
4
|
import { analyzeExecution, summarizeBacklog } from "./backlog.mjs";
|
|
4
5
|
import { loadPolicy, loadVerifyCommands } from "./config.mjs";
|
|
5
6
|
|
|
@@ -62,6 +63,76 @@ function resolvePreviewVerifyCommands(context, execution) {
|
|
|
62
63
|
return loadVerifyCommands(context);
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
function renderResolutionLines(discovery, context, docsDisplay) {
|
|
67
|
+
const repoResolution = discovery?.resolution?.repo;
|
|
68
|
+
const docsResolution = discovery?.resolution?.docs;
|
|
69
|
+
const repoBasis = Array.isArray(repoResolution?.basis) && repoResolution.basis.length
|
|
70
|
+
? repoResolution.basis.join(";")
|
|
71
|
+
: "无";
|
|
72
|
+
const docsBasis = Array.isArray(docsResolution?.basis) && docsResolution.basis.length
|
|
73
|
+
? docsResolution.basis.join(";")
|
|
74
|
+
: "无";
|
|
75
|
+
const repoState = repoResolution?.exists === false
|
|
76
|
+
? "当前目录不存在,将按新项目创建"
|
|
77
|
+
: "已存在项目目录";
|
|
78
|
+
|
|
79
|
+
return [
|
|
80
|
+
"路径判断:",
|
|
81
|
+
`- 开发文档:${docsDisplay.length ? docsDisplay.join(",") : "未识别"}`,
|
|
82
|
+
`- 文档来源:${docsResolution?.sourceLabel || "自动判断"}`,
|
|
83
|
+
`- 文档把握:${docsResolution?.confidenceLabel || "中"}`,
|
|
84
|
+
`- 文档依据:${docsBasis}`,
|
|
85
|
+
`- 目标仓库:${context.repoRoot.replaceAll("\\", "/")}`,
|
|
86
|
+
`- 项目状态:${repoState}`,
|
|
87
|
+
`- 仓库来源:${repoResolution?.sourceLabel || "自动判断"}`,
|
|
88
|
+
`- 仓库把握:${repoResolution?.confidenceLabel || "中"}`,
|
|
89
|
+
`- 仓库依据:${repoBasis}`,
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function renderRequestInterpretationLines(analysis) {
|
|
94
|
+
const interpretation = analysis?.requestInterpretation;
|
|
95
|
+
if (!interpretation) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [
|
|
100
|
+
"需求语义理解:",
|
|
101
|
+
`- 总结:${interpretation.summary || "无"}`,
|
|
102
|
+
...(interpretation.priorities.length
|
|
103
|
+
? interpretation.priorities.map((item) => `- 优先关注:${item}`)
|
|
104
|
+
: ["- 优先关注:无"]),
|
|
105
|
+
...(interpretation.cautions.length
|
|
106
|
+
? interpretation.cautions.map((item) => `- 特别注意:${item}`)
|
|
107
|
+
: ["- 特别注意:无"]),
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function renderRepoDecisionLines(analysis) {
|
|
112
|
+
const decision = analysis?.repoDecision;
|
|
113
|
+
if (!decision) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const compatibilityMap = {
|
|
118
|
+
compatible: "兼容,可直接接续",
|
|
119
|
+
conflict: "明显冲突",
|
|
120
|
+
uncertain: "存在不确定性",
|
|
121
|
+
};
|
|
122
|
+
const actionMap = {
|
|
123
|
+
continue_existing: "继续在当前项目上接续",
|
|
124
|
+
confirm_rebuild: "先确认是否清理当前项目后重建",
|
|
125
|
+
start_new: "按新项目路径继续推进",
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return [
|
|
129
|
+
"项目匹配判断:",
|
|
130
|
+
`- 匹配结论:${compatibilityMap[decision.compatibility] || decision.compatibility}`,
|
|
131
|
+
`- 建议动作:${actionMap[decision.action] || decision.action}`,
|
|
132
|
+
`- 判断依据:${decision.reason}`,
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
|
|
65
136
|
export function resolveAutoRunMaxTasks(backlog, options = {}) {
|
|
66
137
|
const explicitMaxTasks = Number(options.maxTasks);
|
|
67
138
|
if (Number.isFinite(explicitMaxTasks) && explicitMaxTasks > 0) {
|
|
@@ -73,7 +144,7 @@ export function resolveAutoRunMaxTasks(backlog, options = {}) {
|
|
|
73
144
|
return Math.max(1, pendingTotal);
|
|
74
145
|
}
|
|
75
146
|
|
|
76
|
-
export function renderAnalyzeConfirmation(context, analysis, backlog, options = {}) {
|
|
147
|
+
export function renderAnalyzeConfirmation(context, analysis, backlog, options = {}, discovery = {}) {
|
|
77
148
|
const summary = summarizeBacklog(backlog);
|
|
78
149
|
const execution = analyzeExecution(backlog, options);
|
|
79
150
|
const policy = loadPolicy(context);
|
|
@@ -82,12 +153,17 @@ export function renderAnalyzeConfirmation(context, analysis, backlog, options =
|
|
|
82
153
|
const docsDisplay = analysis.requiredDocs.map((entry) => (
|
|
83
154
|
toDisplayPath(context.repoRoot, path.resolve(context.repoRoot, entry))
|
|
84
155
|
));
|
|
156
|
+
const userIntentLines = renderUserIntentLines(options.userIntent);
|
|
157
|
+
const inputIssueLines = renderInputIssueLines(options.inputIssues);
|
|
85
158
|
|
|
86
159
|
return [
|
|
87
160
|
"执行确认单",
|
|
88
161
|
"============",
|
|
89
|
-
|
|
90
|
-
|
|
162
|
+
...renderResolutionLines(discovery, context, docsDisplay),
|
|
163
|
+
...(userIntentLines.length ? ["", "本次命令补充输入:", ...formatList(userIntentLines)] : []),
|
|
164
|
+
...(inputIssueLines.length ? ["", "输入提示:", ...inputIssueLines] : []),
|
|
165
|
+
...(renderRequestInterpretationLines(analysis).length ? ["", ...renderRequestInterpretationLines(analysis)] : []),
|
|
166
|
+
...(renderRepoDecisionLines(analysis).length ? ["", ...renderRepoDecisionLines(analysis)] : []),
|
|
91
167
|
"",
|
|
92
168
|
"当前进度:",
|
|
93
169
|
`- ${analysis.summary.currentState}`,
|
package/src/analyze_prompt.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatList } from "./common.mjs";
|
|
2
|
+
import { renderUserIntentLines } from "./analyze_user_input.mjs";
|
|
2
3
|
import {
|
|
3
4
|
hasCustomProjectConstraints,
|
|
4
5
|
listMandatoryGuardrails,
|
|
@@ -30,15 +31,18 @@ function renderDocPackets(docPackets) {
|
|
|
30
31
|
|
|
31
32
|
export function buildAnalysisPrompt({
|
|
32
33
|
repoRoot,
|
|
34
|
+
repoOriginallyExisted = true,
|
|
33
35
|
docsEntries,
|
|
34
36
|
docPackets,
|
|
35
37
|
existingStateText = "",
|
|
36
38
|
existingBacklogText = "",
|
|
37
39
|
existingProjectConstraints = [],
|
|
40
|
+
userIntent = {},
|
|
38
41
|
}) {
|
|
39
42
|
const mandatoryGuardrails = listMandatoryGuardrails();
|
|
40
43
|
const effectiveConstraints = resolveProjectConstraints(existingProjectConstraints);
|
|
41
44
|
const usingFallbackConstraints = !hasCustomProjectConstraints(existingProjectConstraints);
|
|
45
|
+
const userIntentLines = renderUserIntentLines(userIntent);
|
|
42
46
|
|
|
43
47
|
return [
|
|
44
48
|
"你要为一个本地代码仓库做“接续开发分析”。",
|
|
@@ -50,9 +54,12 @@ export function buildAnalysisPrompt({
|
|
|
50
54
|
"3. 生成的任务必须颗粒度足够,能直接进入开发,不允许输出“继续开发”这类空泛任务。",
|
|
51
55
|
"4. 只关注当前目标仓库,不要把其他仓库的任务混进来;如果文档覆盖多仓库,只提取当前仓库相关任务。",
|
|
52
56
|
"5. 如果某项工作依赖其他仓库或外部输入,允许输出 `blocked` 任务,但必须明确阻塞原因。",
|
|
57
|
+
"6. 如果“本次命令补充输入”中包含自然语言要求,无论中文、英文还是混合输入,都必须按语义理解并体现在后续任务中,不要依赖固定关键词。",
|
|
53
58
|
"",
|
|
54
59
|
section("目标仓库", `- 路径:${repoRoot.replaceAll("\\", "/")}`),
|
|
60
|
+
section("仓库初始状态", `- 该项目目录在本次分析前${repoOriginallyExisted ? "已经存在" : "尚不存在,将按新项目处理"}`),
|
|
55
61
|
section("开发文档入口", docsEntries.map((item) => `- ${item}`).join("\n")),
|
|
62
|
+
listSection("本次命令补充输入", userIntentLines),
|
|
56
63
|
existingStateText ? section("已有状态摘要", existingStateText) : "",
|
|
57
64
|
listSection("内建安全底线", mandatoryGuardrails),
|
|
58
65
|
listSection(usingFallbackConstraints ? "默认工程约束(文档未明确时也必须遵守)" : "已有项目约束", effectiveConstraints),
|
|
@@ -70,6 +77,11 @@ export function buildAnalysisPrompt({
|
|
|
70
77
|
"9. `docs` 必须引用本次文档入口中的相关路径;`paths` 必须写当前仓库内的实际目录或文件模式。",
|
|
71
78
|
"10. `acceptance` 必须可验证,不要写空话。",
|
|
72
79
|
"11. `constraints` 只写从项目文档或现有项目配置中提炼出的项目特有约束;不要重复内建安全底线。",
|
|
80
|
+
"12. 如果存在命令补充输入,请额外输出 `requestInterpretation`:包含 `summary`、`priorities`、`cautions`,用于总结你对用户补充要求的语义理解。",
|
|
81
|
+
"13. 额外输出 `repoDecision`:包含 `compatibility`、`action`、`reason`,用于判断当前项目目录与开发文档目标是否匹配。",
|
|
82
|
+
"14. 当当前项目目录已存在,但代码结构/产品方向与开发文档目标明显冲突,且更合理的路径是清理后重建时,`repoDecision.compatibility` 设为 `conflict`,`repoDecision.action` 设为 `confirm_rebuild`。",
|
|
83
|
+
"15. 当当前项目目录与开发文档目标一致或可以直接接续时,`repoDecision.compatibility` 设为 `compatible`,`repoDecision.action` 设为 `continue_existing`。",
|
|
84
|
+
"16. 当本次项目目录原本不存在,或文档目标明显是从零开始新建项目时,`repoDecision.action` 可设为 `start_new`。",
|
|
73
85
|
].join("\n")),
|
|
74
86
|
].filter(Boolean).join("\n");
|
|
75
87
|
}
|