abelworkflow 0.6.5 → 0.8.0

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/.gitignore CHANGED
@@ -7,10 +7,12 @@
7
7
  */tmp/
8
8
  skills/dev-browser/profiles/
9
9
  skills/dev-browser/tmp/
10
+ skills/dev-browser/.cache/
11
+ *cache*/
10
12
  */dist/
11
13
  */build/
12
14
  .claude/
13
15
  .codex/
14
16
  *pycache*/
15
- .codex
16
17
  openspec/
18
+ package-lock.json
package/AGENTS.md CHANGED
@@ -13,15 +13,15 @@
13
13
 
14
14
  ## Context Rules
15
15
 
16
- - Use `mcp__augment-context-engine__codebase-retrieval` as the primary codebase search tool
16
+ - {{CODEBASE_RETRIEVAL_POLICY}}
17
17
  - Rely only on project code plus `grok/context7` results
18
18
  - If information is insufficient or uncertain, state it explicitly
19
19
 
20
20
  ## Workflow
21
21
 
22
22
  ```
23
- /oc:init → /oc:research → /oc:plan → /oc:implementation(TDD)
24
- ↘ /oc:diagnose (bug fix)
23
+ /abel-init → /abel-research → /abel-plan → /abel-implement(TDD)
24
+ ↘ /abel-diagnose (bug fix)
25
25
  ```
26
26
 
27
27
  ## Universal Constraints
package/README.md CHANGED
@@ -112,7 +112,7 @@ npx abelworkflow --help
112
112
  |---|---|---|
113
113
  | `grok-search` | `~/.agents/skills/grok-search/.env` | `GROK_API_URL` `GROK_API_KEY` `GROK_MODEL` |
114
114
  | `context7-auto-research` | `~/.agents/skills/context7-auto-research/.env` | `CONTEXT7_API_KEY` |
115
- | `prompt-enhancer` | `~/.agents/skills/prompt-enhancer/.env` | `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` `PE_MODEL` |
115
+ | `prompt-enhancer` | `~/.agents/skills/prompt-enhancer/.env` | `PE_API_URL` `PE_API_KEY` `PE_MODEL` |
116
116
 
117
117
  ### 方法二:源码克隆安装
118
118
 
@@ -178,15 +178,15 @@ node .\bin\abelworkflow.mjs install
178
178
  |---|---|---|---|
179
179
  | `AGENTS.md` | `~/.claude/CLAUDE.md` | `~/.codex/AGENTS.md` | 全局系统提示词/规则 |
180
180
  | `skills/<skill>/` | `~/.claude/skills/<skill>/` | `~/.codex/skills/<skill>/` | Skills(每个目录一个技能) |
181
- | `commands/oc/` | `~/.claude/commands/oc/` | `~/.codex/prompts/*.md` | Claude 读 `commands/`;Codex 读 `prompts/` |
181
+ | `commands/abel-*.md` | `~/.claude/commands/abel-*.md` | `~/.codex/prompts/abel-*.md` | 扁平化部署,避免命名冲突 |
182
182
 
183
183
  ### 验证(可选)
184
184
 
185
185
  **Linux/macOS(bash/zsh)**
186
186
 
187
187
  ```bash
188
- ls -la "$HOME/.claude/CLAUDE.md" "$HOME/.claude/commands/oc"
189
- ls -la "$HOME/.codex/AGENTS.md" "$HOME/.codex/prompts/"{init,research,plan,implementation,diagnose}.md
188
+ ls -la "$HOME/.claude/CLAUDE.md" "$HOME/.claude/commands/"abel-*.md
189
+ ls -la "$HOME/.codex/AGENTS.md" "$HOME/.codex/prompts/"abel-*.md
190
190
  cat "$HOME/.claude/settings.json" | head
191
191
  cat "$HOME/.codex/config.toml" | head
192
192
  ```
@@ -194,9 +194,9 @@ cat "$HOME/.codex/config.toml" | head
194
194
  **Windows(PowerShell)**
195
195
 
196
196
  ```powershell
197
- Get-Item "$HOME\.claude\CLAUDE.md", "$HOME\.claude\commands\oc"
197
+ Get-Item "$HOME\.claude\CLAUDE.md"; Get-ChildItem "$HOME\.claude\commands\abel-*.md"
198
198
  Get-Item "$HOME\.codex\AGENTS.md"
199
- Get-ChildItem "$HOME\.codex\prompts" | Where-Object { $_.Name -in @("init.md", "research.md", "plan.md", "implementation.md", "diagnose.md") }
199
+ Get-ChildItem "$HOME\.codex\prompts\abel-*.md"
200
200
  Get-Content "$HOME\.claude\settings.json" -TotalCount 10
201
201
  Get-Content "$HOME\.codex\config.toml" -TotalCount 10
202
202
  ```
@@ -1,11 +1,11 @@
1
1
  ---
2
- name: OC:Diagnose
2
+ name: abel-diagnose
3
3
  description: Parallel diagnosis with batch fix reporting via systematic root cause analysis.
4
- category: OC
5
- tags: [diagnosis, bugfix]
4
+ category: abel
5
+ tags: [abel, diagnosis, bugfix]
6
6
  argument-hint: <problem-description>
7
7
  ---
8
- <!-- OC:START -->
8
+ <!-- ABEL:START -->
9
9
  **Arguments**
10
10
  - Required: `<problem-description>` (one or more bug descriptions; comma-separated supported)
11
11
 
@@ -31,7 +31,7 @@ argument-hint: <problem-description>
31
31
 
32
32
  **Steps**
33
33
  1. Parse input, infer scope, and split into issue list (single or multiple).
34
- 2. For each issue in parallel: collect logs/traces and locate code via `mcp__augment-context-engine__codebase-retrieval`.
34
+ 2. For each issue in parallel: collect logs/traces and locate code via the configured codebase retrieval policy.
35
35
  3. For each issue in parallel: perform root cause analysis; use `/sequential-think` for multi-component chains.
36
36
  4. Build dependency/conflict graph across issues and compute safe fix order.
37
37
  5. Run `/confidence-check` per issue; only issues with score ≥90% can move to fix generation.
@@ -60,4 +60,4 @@ Total: {n} | ReadyToFix: {n_ready} | Blocked: {n_blocked}
60
60
  ### Final Status
61
61
  {FIXED|PARTIAL|NEEDS_REVIEW|BLOCKED}
62
62
  ```
63
- <!-- OC:END -->
63
+ <!-- ABEL:END -->
@@ -1,12 +1,12 @@
1
1
  ---
2
- name: OC:Implementation
2
+ name: abel-implement
3
3
  description: Implement approved changes with mandatory TDD.
4
- category: OC
5
- tags: [openspec, implementation, TDD]
4
+ category: abel
5
+ tags: [abel, implementation, TDD]
6
6
  argument-hint: [change_name]
7
7
  ---
8
8
 
9
- <!-- OC:START -->
9
+ <!-- ABEL:START -->
10
10
  **Arguments**
11
11
  - Requested: `<change_name>`
12
12
 
@@ -154,4 +154,4 @@ Frontend Review
154
154
 
155
155
  ✓ Implementation complete
156
156
  ```
157
- <!-- OC:END -->
157
+ <!-- ABEL:END -->
@@ -1,11 +1,11 @@
1
1
  ---
2
- name: OC:Init
2
+ name: abel-init
3
3
  description: Initialize OpenSpec environment and validate required tooling.
4
- category: OC
4
+ category: abel
5
5
  tags: [openspec, init, setup]
6
6
  ---
7
7
 
8
- <!-- OC:START -->
8
+ <!-- ABEL:START -->
9
9
  **Guardrails**
10
10
  - Complete steps in order; stop on failure
11
11
  - Preserve existing config; do not overwrite without confirmation
@@ -16,12 +16,12 @@ tags: [openspec, init, setup]
16
16
  2. Verify `openspec` availability via `openspec --version`.
17
17
  3. If missing, `npm install -g @fission-ai/openspec@latest`, then re-check version.
18
18
  4. Run `openspec init` (or `openspec update` for existing projects).
19
- 5. Verify required capability:
20
- - MCP: `mcp__augment-context-engine__codebase-retrieval`
19
+ 5. {{AUGMENT_CONTEXT_ENGINE_VALIDATION}}
20
+ 6. Verify required skills:
21
21
  - Skills: `/dev-browser` `/sequential-think` `/context7-auto-research` `/grok-search` `/confidence-check`
22
- 6. Output summary with ✓/✗:
22
+ 7. Output summary with ✓/✗:
23
23
  - OpenSpec installation
24
24
  - Project initialization
25
- - MCP availability
25
+ - MCP availability if enabled
26
26
  - Required skills availability
27
- <!-- OC:END -->
27
+ <!-- ABEL:END -->
@@ -1,11 +1,11 @@
1
1
  ---
2
- name: OC:Plan
2
+ name: abel-plan
3
3
  description: Refine approved change into a zero-decision executable plan.
4
- category: OC
5
- tags: [OC, plan, PBT]
4
+ category: abel
5
+ tags: [abel, plan, PBT]
6
6
  argument-hint: [change_name]
7
7
  ---
8
- <!-- OC:START -->
8
+ <!-- ABEL:START -->
9
9
  **Guardrails**
10
10
  - Strictly adhere to **OpenSpec** rules when writing **standardized spec-structured projects**.
11
11
  - The goal of this phase is to eliminate ALL decision points from the task flow—implementation should be pure mechanical execution.
@@ -39,8 +39,8 @@ argument-hint: [change_name]
39
39
 
40
40
  4. **Uncertainty Elimination Audit**: Invoke skills to detect and eliminate remaining ambiguities:
41
41
  ```
42
- # First, use augment-context-engine to validate against existing codebase patterns
43
- mcp__augment-context-engine__codebase-retrieval: "Search for existing implementations similar to change <change_name>. Keywords: [key concepts from proposal]"
42
+ # First, validate against existing codebase patterns
43
+ {{CODEBASE_RETRIEVAL_PATTERN_AUDIT}}
44
44
  # Then audit for ambiguities directly and list them explicitly
45
45
  Review change <change_name> for decision points that remain unspecified. For each: [AMBIGUITY] <description> → [REQUIRED CONSTRAINT] <what must be specified>.
46
46
  Identify implicit assumptions in change <change_name>. For each: [ASSUMPTION] <description> → [EXPLICIT CONSTRAINT NEEDED] <concrete specification>.
@@ -85,4 +85,4 @@ A proposal is ready to exit the Plan phase only when:
85
85
  - [ ] All PBT properties documented with falsification strategies
86
86
  - [ ] `openspec validate <change_name> --strict` returns zero issues
87
87
  - [ ] User has explicitly approved all constraint decisions
88
- <!-- OC:END -->
88
+ <!-- ABEL:END -->
@@ -1,13 +1,13 @@
1
1
  ---
2
- name: OC:Research
2
+ name: abel-research
3
3
  description: Transform user requirements into constraint sets via structured exploration (NO implementation)
4
- category: OC
5
- tags: [OC, research, constraints, exploration, subagents]
4
+ category: abel
5
+ tags: [abel, research, constraints, exploration, subagents]
6
6
  ---
7
7
 
8
- <!-- OC:RESEARCH:START -->
8
+ <!-- ABEL:RESEARCH:START -->
9
9
 
10
- # OC:Research — Operating Mode (Constraints & Specs Only)
10
+ # abel-research — Operating Mode (Constraints & Specs Only)
11
11
 
12
12
  ## Non‑Negotiable Rules (Highest Priority)
13
13
  1. RESEARCH MODE ONLY.
@@ -38,7 +38,7 @@ Produce constraint sets that narrow the solution space, plus measurable success
38
38
  ---
39
39
 
40
40
  ## Phase 2 — Initial Codebase Assessment (Read‑Only)
41
- - Use `mcp__augment-context-engine__codebase-retrieval` as the primary way to locate relevant code; avoid grep/find unless unavoidable.
41
+ - {{CODEBASE_RETRIEVAL_POLICY}}
42
42
  - If technical research needed (architectural patterns, best practices), invoke `/grok-search` skill
43
43
  - If the codebase spans multiple modules/directories, dispatch parallel explore subagents by context boundary.
44
44
 
@@ -73,7 +73,7 @@ All explore subagents MUST return valid JSON using this schema:
73
73
  ## Phase 5 — Parallel Subagent Dispatch
74
74
  - Monitor subagent execution and collect structured reports.
75
75
  - For each boundary, spawn an Explore subagent with:
76
- - Mandatory use of `mcp__augment-context-engine__codebase-retrieval`
76
+ - {{CODEBASE_RETRIEVAL_MANDATORY_RULE}}
77
77
  - Clear scope
78
78
  - self-contained with independent output
79
79
  - Required output template (from Phase 4)
@@ -113,7 +113,7 @@ All explore subagents MUST return valid JSON using this schema:
113
113
 
114
114
  ## Reference
115
115
  - Review existing constraints: `rg -n "Constraint:|MUST|MUST NOT" openspec/specs`
116
- - Inspect codebase structure: `ls -R` or `mcp__augment-context-engine__codebase-retrieval` with `file list --recursive`
116
+ - {{CODEBASE_RETRIEVAL_STRUCTURE_REFERENCE}}
117
117
 
118
118
  - Check prior research outputs: `ls openspec/changes/*/`
119
119
  - OpenSpec CLI commands:
@@ -123,4 +123,4 @@ All explore subagents MUST return valid JSON using this schema:
123
123
  - `openspec instructions proposal --change <name>` - Get proposal instructions
124
124
  - Validate subagent outputs conform to template before aggregation.
125
125
  - Ask the user directly for ANY ambiguity—do not assume or guess.
126
- <!-- OC:RESEARCH:END -->
126
+ <!-- ABEL:RESEARCH:END -->
package/lib/cli/logic.mjs CHANGED
@@ -1,23 +1,91 @@
1
+ import * as p from "@clack/prompts";
2
+
1
3
  const interactiveMenuDescriptors = [
2
- { value: "full-init", label: "完整初始化:同步工作流 + 可选安装/配置 Claude Code、Codex、技能环境" },
3
- { value: "install", label: "仅同步/更新工作流到 ~/.agents 并重新链接 Claude/Codex" },
4
- { value: "grok-search", label: "配置 grok-search 环境变量" },
5
- { value: "context7", label: "配置 context7-auto-research 环境变量" },
6
- { value: "prompt-enhancer", label: "配置 prompt-enhancer 环境变量" },
7
- { value: "claude-install", label: "安装或更新 Claude Code CLI" },
8
- { value: "claude-api", label: "配置 Claude Code 第三方 API" },
9
- { value: "codex-install", label: "安装或更新 Codex CLI" },
10
- { value: "codex-api", label: "配置 Codex 第三方 API" },
11
- { value: "exit", label: "退出" }
4
+ { value: "full-init", label: "完整初始化", hint: "同步 + 安装 + 配置", group: "main" },
5
+ { value: "install", label: "仅同步工作流", group: "main" },
6
+ { value: "grok-search", label: "配置 grok-search", hint: "技能", group: "skill" },
7
+ { value: "context7", label: "配置 context7-auto-research", hint: "技能", group: "skill" },
8
+ { value: "prompt-enhancer", label: "配置 prompt-enhancer", hint: "技能", group: "skill" },
9
+ { value: "claude-install", label: "安装/更新 Claude Code", hint: "CLI", group: "cli" },
10
+ { value: "claude-api", label: "配置 Claude API", hint: "CLI", group: "cli" },
11
+ { value: "codex-install", label: "安装/更新 Codex", hint: "CLI", group: "cli" },
12
+ { value: "codex-api", label: "配置 Codex API", hint: "CLI", group: "cli" },
13
+ { value: "exit", label: "退出", group: "exit" }
12
14
  ];
13
15
 
14
16
  const interactiveMenuDefaultValue = "full-init";
15
17
 
18
+ class CancelledError extends Error {
19
+ constructor(message = "用户取消") {
20
+ super(message);
21
+ this.name = "CancelledError";
22
+ }
23
+ }
24
+
25
+ function required(message = "此项不能为空") {
26
+ return (value) => {
27
+ if (value === undefined || value === null || (typeof value === "string" && value.trim() === "")) {
28
+ return message;
29
+ }
30
+ };
31
+ }
32
+
33
+ function requiredUnlessExisting(existingValue, message = "此项不能为空") {
34
+ return (value) => {
35
+ if ((value === undefined || value === null || (typeof value === "string" && value.trim() === "")) && !existingValue) {
36
+ return message;
37
+ }
38
+ };
39
+ }
40
+
41
+ /**
42
+ * 回退逻辑:用户输入非空则用新值,否则用旧值。
43
+ * 输入 "-" 表示清除已有值(返回 undefined)。
44
+ * existingValue 可能来自 dotenv / JSON 读取,会传入空字符串;
45
+ * 空字符串将被净化为 undefined,避免写入无意义的空配置。
46
+ * 注意:本函数仅适用于字符串类型的配置值,不适用于可能为 0/false 的数字或布尔值。
47
+ */
48
+ function resolvePasswordValue(userInput, existingValue) {
49
+ if (typeof userInput === "string") {
50
+ const trimmed = userInput.trim();
51
+ if (trimmed === "") {
52
+ if (typeof existingValue === "string" && existingValue.trim() === "") {
53
+ return undefined;
54
+ }
55
+ return existingValue || undefined;
56
+ }
57
+ return trimmed === "-" ? undefined : trimmed;
58
+ }
59
+ if (typeof existingValue === "string" && existingValue.trim() === "") {
60
+ return undefined;
61
+ }
62
+ return existingValue || undefined;
63
+ }
64
+
65
+ function assertNotCancelled(value) {
66
+ if (p.isCancel(value)) {
67
+ throw new CancelledError();
68
+ }
69
+ }
70
+
71
+ async function confirmOrCancel({ message, initialValue = false }) {
72
+ const value = await p.confirm({ message, initialValue, active: "是", inactive: "否" });
73
+ assertNotCancelled(value);
74
+ return value;
75
+ }
76
+
77
+ async function selectOrCancel(options) {
78
+ const value = await p.select(options);
79
+ assertNotCancelled(value);
80
+ return value;
81
+ }
82
+
16
83
  function parseArgs(argv, { defaultAgentsDir, resolvePath }) {
17
84
  const options = {
18
85
  agentsDir: defaultAgentsDir,
19
86
  force: false,
20
87
  relinkOnly: false,
88
+ nonInteractive: false,
21
89
  command: "menu"
22
90
  };
23
91
  const positional = [];
@@ -42,6 +110,10 @@ function parseArgs(argv, { defaultAgentsDir, resolvePath }) {
42
110
  i += 1;
43
111
  continue;
44
112
  }
113
+ if (arg === "--non-interactive") {
114
+ options.nonInteractive = true;
115
+ continue;
116
+ }
45
117
  if (arg === "--help" || arg === "-h" || arg === "help") {
46
118
  helpRequested = true;
47
119
  options.command = "help";
@@ -75,40 +147,22 @@ function parseArgs(argv, { defaultAgentsDir, resolvePath }) {
75
147
  throw new Error("`--force`、`--link-only`、`--agents-dir` 仅能与 `install` 命令一起使用");
76
148
  }
77
149
 
78
- return options;
79
- }
80
-
81
- function assertInteractiveMenuSupported({ command, inputIsTTY, outputIsTTY }) {
82
- if (command === "menu" && (!inputIsTTY || !outputIsTTY)) {
83
- throw new Error("交互式菜单需要 TTY 终端;非交互场景请显式使用 `npx abelworkflow install`");
150
+ if (!options.nonInteractive && process.env.CI) {
151
+ options.nonInteractive = true;
84
152
  }
85
- }
86
153
 
87
- function resolvePromptValue(answer, { defaultValue, allowEmpty = false } = {}) {
88
- const value = String(answer).trim();
89
- if (!value && defaultValue !== undefined) {
90
- return { ok: true, value: defaultValue };
91
- }
92
- if (!value && !allowEmpty) {
93
- return { ok: false, error: "此项不能为空。" };
94
- }
95
- return { ok: true, value };
154
+ return options;
96
155
  }
97
156
 
98
- function resolveSelectValue(answer, choices) {
99
- const index = Number(answer) - 1;
100
- if (Number.isInteger(index) && index >= 0 && index < choices.length) {
101
- return { ok: true, value: choices[index].value };
157
+ function assertInteractiveMenuSupported({ command, inputIsTTY, outputIsTTY, nonInteractive }) {
158
+ // 防御性检查(死代码守护):main() 已在调用前将非交互 menu 降级为 install,
159
+ // 此处仅防止外部直接调用 assertInteractiveMenuSupported 时漏掉判断。
160
+ if (command === "menu" && nonInteractive) {
161
+ throw new Error("非交互模式已启用;请显式使用 `npx abelworkflow install` 进行安装");
102
162
  }
103
- const direct = choices.find((choice) => choice.value === answer);
104
- if (direct) {
105
- return { ok: true, value: direct.value };
163
+ if (command === "menu" && (!inputIsTTY || !outputIsTTY)) {
164
+ throw new Error("交互式菜单需要 TTY 终端;非交互场景请显式使用 `npx abelworkflow install`");
106
165
  }
107
- return { ok: false, error: "无效选择,请重新输入。" };
108
- }
109
-
110
- function shouldUseVisibleSecretFallback({ inputIsTTY, platform }) {
111
- return !inputIsTTY || platform === "win32";
112
166
  }
113
167
 
114
168
  function getRunCommandSpawnOptions(platform = process.env.ABELWORKFLOW_TEST_PLATFORM || process.platform) {
@@ -120,11 +174,15 @@ function getRunCommandSpawnOptions(platform = process.env.ABELWORKFLOW_TEST_PLAT
120
174
 
121
175
  export {
122
176
  assertInteractiveMenuSupported,
177
+ assertNotCancelled,
178
+ CancelledError,
179
+ confirmOrCancel,
123
180
  getRunCommandSpawnOptions,
124
181
  interactiveMenuDefaultValue,
125
182
  interactiveMenuDescriptors,
126
183
  parseArgs,
127
- resolvePromptValue,
128
- resolveSelectValue,
129
- shouldUseVisibleSecretFallback
184
+ required,
185
+ requiredUnlessExisting,
186
+ resolvePasswordValue,
187
+ selectOrCancel
130
188
  };