abelworkflow 0.9.2 → 1.0.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/README.md +54 -182
- package/bin/abelworkflow.mjs +5 -3
- package/extensions/pi-gpt-responses-compat/index.ts +1 -1
- package/lib/cli/args.mjs +76 -0
- package/lib/cli/main.mjs +385 -0
- package/lib/cli/prompts.mjs +106 -0
- package/lib/config/dotenv.mjs +102 -0
- package/lib/config/jsonc.mjs +80 -0
- package/lib/config/store.mjs +310 -0
- package/lib/config/toml.mjs +638 -0
- package/lib/installer/assets.mjs +324 -0
- package/lib/installer/install.mjs +153 -0
- package/lib/installer/links.mjs +427 -0
- package/lib/installer/state.mjs +163 -0
- package/lib/paths.mjs +99 -0
- package/lib/providers/claude.mjs +197 -0
- package/lib/providers/codex.mjs +433 -0
- package/lib/providers/pi.mjs +577 -0
- package/lib/providers/skills.mjs +105 -0
- package/lib/templates/codex/agents/default.toml +7 -0
- package/lib/templates/codex/agents/explorer.toml +7 -0
- package/lib/templates/codex/agents/planner.toml +7 -0
- package/lib/templates/codex/agents/reviewer.toml +7 -0
- package/lib/templates/codex/agents/worker.toml +7 -0
- package/lib/templates/codex/config-base.toml +11 -3
- package/lib/templates/workflow/AGENTS.md +50 -0
- package/lib/templates/workflow/commands/abel-design.md +175 -0
- package/{commands → lib/templates/workflow/commands}/abel-diagnose.md +5 -5
- package/lib/templates/workflow/commands/abel-implement.md +170 -0
- package/{commands → lib/templates/workflow/commands}/abel-init.md +3 -5
- package/{.gitignore → lib/templates/workflow/gitignore.template} +0 -2
- package/lib/tools/cli-installer.mjs +277 -0
- package/package.json +37 -10
- package/skills/context7-auto-research/SKILL.md +5 -5
- package/skills/context7-auto-research/{context7-api.js → context7-api.cjs} +5 -8
- package/skills/dev-browser/SKILL.md +53 -33
- package/skills/dev-browser/dist/scripts/start.d.ts +2 -0
- package/skills/dev-browser/dist/scripts/start.d.ts.map +1 -0
- package/skills/dev-browser/dist/scripts/start.js +118 -0
- package/skills/dev-browser/dist/scripts/start.js.map +1 -0
- package/skills/dev-browser/dist/src/client.d.ts +93 -0
- package/skills/dev-browser/dist/src/client.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/client.js +310 -0
- package/skills/dev-browser/dist/src/client.js.map +1 -0
- package/skills/dev-browser/dist/src/entrypoint.d.ts +29 -0
- package/skills/dev-browser/dist/src/entrypoint.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/entrypoint.js +106 -0
- package/skills/dev-browser/dist/src/entrypoint.js.map +1 -0
- package/skills/dev-browser/dist/src/index.d.ts +4 -0
- package/skills/dev-browser/dist/src/index.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/index.js +2 -0
- package/skills/dev-browser/dist/src/index.js.map +1 -0
- package/skills/dev-browser/dist/src/page-api.d.ts +25 -0
- package/skills/dev-browser/dist/src/page-api.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/page-api.js +104 -0
- package/skills/dev-browser/dist/src/page-api.js.map +1 -0
- package/skills/dev-browser/dist/src/relay.d.ts +27 -0
- package/skills/dev-browser/dist/src/relay.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/relay.js +521 -0
- package/skills/dev-browser/dist/src/relay.js.map +1 -0
- package/skills/dev-browser/dist/src/runtime.d.ts +45 -0
- package/skills/dev-browser/dist/src/runtime.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/runtime.js +54 -0
- package/skills/dev-browser/dist/src/runtime.js.map +1 -0
- package/skills/dev-browser/dist/src/snapshot/browser-script.d.ts +23 -0
- package/skills/dev-browser/dist/src/snapshot/browser-script.d.ts.map +1 -0
- package/skills/dev-browser/{src/snapshot/browser-script.ts → dist/src/snapshot/browser-script.js} +21 -30
- package/skills/dev-browser/dist/src/snapshot/browser-script.js.map +1 -0
- package/skills/dev-browser/dist/src/snapshot/index.d.ts +14 -0
- package/skills/dev-browser/dist/src/snapshot/index.d.ts.map +1 -0
- package/skills/dev-browser/{src/snapshot/index.ts → dist/src/snapshot/index.js} +2 -2
- package/skills/dev-browser/dist/src/snapshot/index.js.map +1 -0
- package/skills/dev-browser/dist/src/snapshot/inject.d.ts +13 -0
- package/skills/dev-browser/dist/src/snapshot/inject.d.ts.map +1 -0
- package/skills/dev-browser/{src/snapshot/inject.ts → dist/src/snapshot/inject.js} +2 -2
- package/skills/dev-browser/dist/src/snapshot/inject.js.map +1 -0
- package/skills/dev-browser/dist/src/standalone.d.ts +32 -0
- package/skills/dev-browser/dist/src/standalone.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/standalone.js +174 -0
- package/skills/dev-browser/dist/src/standalone.js.map +1 -0
- package/skills/dev-browser/dist/src/startup.d.ts +55 -0
- package/skills/dev-browser/dist/src/startup.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/startup.js +81 -0
- package/skills/dev-browser/dist/src/startup.js.map +1 -0
- package/skills/dev-browser/dist/src/target-registry.d.ts +29 -0
- package/skills/dev-browser/dist/src/target-registry.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/target-registry.js +135 -0
- package/skills/dev-browser/dist/src/target-registry.js.map +1 -0
- package/skills/dev-browser/dist/src/types.d.ts +27 -0
- package/skills/dev-browser/dist/src/types.d.ts.map +1 -0
- package/skills/dev-browser/dist/src/types.js +2 -0
- package/skills/dev-browser/dist/src/types.js.map +1 -0
- package/skills/dev-browser/package-lock.json +67 -1510
- package/skills/dev-browser/package.json +18 -14
- package/skills/dev-browser/references/scraping.md +94 -105
- package/skills/grok-search/.env.example +3 -3
- package/skills/grok-search/SKILL.md +1 -1
- package/skills/grok-search/defaults.json +3 -0
- package/skills/grok-search/gitignore.template +4 -0
- package/skills/grok-search/scripts/_dotenv.py +5 -1
- package/skills/grok-search/scripts/groksearch_cli.py +15 -33
- package/skills/prompt-enhancer/SKILL.md +2 -27
- package/skills/prompt-enhancer/TEMPLATE.md +0 -4
- package/.skill-lock.json +0 -29
- package/AGENTS.md +0 -45
- package/commands/abel-implement.md +0 -157
- package/commands/abel-plan.md +0 -88
- package/commands/abel-research.md +0 -126
- package/lib/cli/logic.mjs +0 -213
- package/lib/cli.mjs +0 -3016
- package/skills/confidence-check/SKILL.md +0 -34
- package/skills/confidence-check/confidence.ts +0 -276
- package/skills/dev-browser/bun.lock +0 -460
- package/skills/dev-browser/scripts/start.ts +0 -280
- package/skills/dev-browser/src/client.ts +0 -474
- package/skills/dev-browser/src/entrypoint.ts +0 -157
- package/skills/dev-browser/src/index.ts +0 -289
- package/skills/dev-browser/src/relay.ts +0 -731
- package/skills/dev-browser/src/runtime.test.ts +0 -60
- package/skills/dev-browser/src/runtime.ts +0 -171
- package/skills/dev-browser/src/startup.test.ts +0 -95
- package/skills/dev-browser/src/startup.ts +0 -153
- package/skills/dev-browser/src/types.ts +0 -35
- package/skills/dev-browser/tsconfig.json +0 -36
- package/skills/dev-browser/vitest.config.ts +0 -12
- package/skills/prompt-enhancer/.env.example +0 -12
- package/skills/prompt-enhancer/ADVANCED.md +0 -103
- package/skills/prompt-enhancer/requirements.txt +0 -2
- package/skills/prompt-enhancer/scripts/_dotenv.py +0 -28
- package/skills/prompt-enhancer/scripts/enhance.py +0 -191
- package/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py +0 -253
- package/skills/sequential-think/SKILL.md +0 -198
- package/skills/sequential-think/scripts/.env.example +0 -5
- package/skills/sequential-think/scripts/sequential_think_cli.py +0 -253
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: abel-implement
|
|
3
|
-
description: Implement approved changes with mandatory TDD.
|
|
4
|
-
category: abel
|
|
5
|
-
tags: [abel, implementation, TDD]
|
|
6
|
-
argument-hint: [change_name]
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
<!-- ABEL:START -->
|
|
10
|
-
**Arguments**
|
|
11
|
-
- Requested: `<change_name>`
|
|
12
|
-
|
|
13
|
-
**Guardrails**
|
|
14
|
-
|
|
15
|
-
**Guardrails**
|
|
16
|
-
|
|
17
|
-
- Keep changes tightly scoped to the requested outcome; enforce side-effect review before applying any modification.
|
|
18
|
-
- Minimize documentation—avoid unnecessary comments; prefer self-explanatory code.
|
|
19
|
-
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) for additional OpenSpec conventions or clarifications.
|
|
20
|
-
|
|
21
|
-
**TDD Guardrails (mandatory)**
|
|
22
|
-
- **Red Phase**: Generate failing tests ONLY; implementation code is FORBIDDEN.
|
|
23
|
-
- **Green Phase**: Write MINIMAL code to pass tests; over-engineering is FORBIDDEN.
|
|
24
|
-
- **Refactor Phase**: Optimize code quality while keeping ALL tests passing.
|
|
25
|
-
- **Mandatory**: Run tests after EVERY code change; never skip verification.
|
|
26
|
-
- **Test-First**: Each task MUST have a failing test before implementation begins.
|
|
27
|
-
|
|
28
|
-
**Skill Integration**: See `Stage Skill Matrix` (Implement column)
|
|
29
|
-
|
|
30
|
-
**Tool Routing**:
|
|
31
|
-
- **TDD Cycle**: Autonomous refactoring
|
|
32
|
-
- **Final Review** (after all tasks):
|
|
33
|
-
- Backend refactor (subagents)
|
|
34
|
-
- Frontend refactor (subagents)
|
|
35
|
-
- **E2E tasks** → `/dev-browser`
|
|
36
|
-
|
|
37
|
-
1. Run `openspec view` to inspect current project status and review `Active Changes`; ask the user to confirm which change folder (`<change_name>`) they want to implement.
|
|
38
|
-
2. Check artifact status: `openspec status --change <change_name>`
|
|
39
|
-
3. Get apply instructions: `openspec instructions apply --change <change_name>`
|
|
40
|
-
4. Detect test framework: identify project's testing setup (pytest/jest/vitest/etc.)
|
|
41
|
-
5. Work through tasks sequentially; for each task, execute the **TDD Cycle** below.
|
|
42
|
-
|
|
43
|
-
**TDD Cycle (per task)**
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
┌─────────────────────────────────────────────────────────┐
|
|
47
|
-
│ Step 0: Pre-Check │
|
|
48
|
-
│ └─ /confidence-check → require ≥90% to proceed │
|
|
49
|
-
├─────────────────────────────────────────────────────────┤
|
|
50
|
-
│ Step 1: 🔴 Red Phase - Generate Failing Test │
|
|
51
|
-
│ ├─ Analyze task → determine test type │
|
|
52
|
-
│ │ ├─ Backend → pytest/jest │
|
|
53
|
-
│ │ ├─ Frontend → vitest/jest │
|
|
54
|
-
│ │ └─ E2E → dev-browser │
|
|
55
|
-
│ ├─ Generate test via │
|
|
56
|
-
│ │ PROMPT: "Generate failing test for: {task} │
|
|
57
|
-
│ │ Context: {code_context} │
|
|
58
|
-
│ │ Output: unified diff patch │
|
|
59
|
-
│ │ FORBIDDEN: implementation code" │
|
|
60
|
-
│ ├─ Apply test code (after review) │
|
|
61
|
-
│ ├─ Run test → MUST FAIL │
|
|
62
|
-
│ └─ If passes → test invalid, regenerate │
|
|
63
|
-
├─────────────────────────────────────────────────────────┤
|
|
64
|
-
│ Step 2: 🟢 Green Phase - Minimal Implementation │
|
|
65
|
-
│ ├─ Generate minimal implementation │
|
|
66
|
-
│ │ PROMPT: "Generate minimal code to pass test: │
|
|
67
|
-
│ │ Test: {test_code} │
|
|
68
|
-
│ │ Context: {code_context} │
|
|
69
|
-
│ │ Output: unified diff patch │
|
|
70
|
-
│ │ FORBIDDEN: over-engineering" │
|
|
71
|
-
│ ├─ Apply implementation (after review & rewrite) │
|
|
72
|
-
│ ├─ Run test → MUST PASS │
|
|
73
|
-
│ └─ If fails → analyze error, fix, retry │
|
|
74
|
-
├─────────────────────────────────────────────────────────┤
|
|
75
|
-
│ Step 3: 🔵 Refactor Phase │
|
|
76
|
-
│ ├─ Analyzes code quality │
|
|
77
|
-
│ ├─ Apply standard refactoring techniques: │
|
|
78
|
-
│ │ ├─ Eliminate code duplication │
|
|
79
|
-
│ │ ├─ Improve naming and structure │
|
|
80
|
-
│ │ ├─ Enhance readability │
|
|
81
|
-
│ │ └─ Simplify logic where possible │
|
|
82
|
-
│ ├─ Apply refactoring changes │
|
|
83
|
-
│ ├─ Run test → MUST STILL PASS │
|
|
84
|
-
│ └─ If fails → rollback refactoring │
|
|
85
|
-
└─────────────────────────────────────────────────────────┘
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
6. Before applying any change, perform mandatory side-effect review.
|
|
89
|
-
|
|
90
|
-
7. After TDD cycle completes for a task, mark as `- [x]` in `tasks.md`.
|
|
91
|
-
|
|
92
|
-
**Final Review & Refactor** (after all tasks complete)
|
|
93
|
-
|
|
94
|
-
8. Run all tests to ensure everything passes.
|
|
95
|
-
|
|
96
|
-
9. Execute global code review via subagents:
|
|
97
|
-
|
|
98
|
-
10. Wait for background tasks to complete; review diff patches.
|
|
99
|
-
11. Rewrite patches into production-grade code (per rewriting principle).
|
|
100
|
-
12. Apply refactoring changes.
|
|
101
|
-
13. Run all tests → MUST ALL PASS.
|
|
102
|
-
14. If any test fails → analyze root cause, fix or rollback.
|
|
103
|
-
15. Perform final side-effect review.
|
|
104
|
-
16. Run `openspec archive <change_name>` or `/opsx:archive`.
|
|
105
|
-
|
|
106
|
-
**TDD Output Format**
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
## /oc:implementation (TDD Mode)
|
|
110
|
-
|
|
111
|
-
### Task 1/N: {task_description}
|
|
112
|
-
|
|
113
|
-
📋 Confidence Check: {score}% {status}
|
|
114
|
-
|
|
115
|
-
🔴 Red Phase
|
|
116
|
-
├─ Generated: tests/{test_file}
|
|
117
|
-
├─ Run: {test_command}
|
|
118
|
-
└─ Result: {count} failed ✓ (expected)
|
|
119
|
-
|
|
120
|
-
🟢 Green Phase
|
|
121
|
-
├─ Generated: src/{impl_file}
|
|
122
|
-
├─ Run: {test_command}
|
|
123
|
-
└─ Result: {count} passed ✓
|
|
124
|
-
|
|
125
|
-
🔵 Refactor Phase (Agent autonomous)
|
|
126
|
-
├─ Optimized: {description}
|
|
127
|
-
├─ Run: {test_command}
|
|
128
|
-
└─ Result: {count} passed ✓
|
|
129
|
-
|
|
130
|
-
✓ Task complete → Next task
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
### All Tasks Complete
|
|
135
|
-
|
|
136
|
-
🔍 Final Review & Refactor
|
|
137
|
-
|
|
138
|
-
Backend Review
|
|
139
|
-
├─ Files: {backend_files}
|
|
140
|
-
├─ Status: Running in background...
|
|
141
|
-
└─ Task ID: {task_id}
|
|
142
|
-
|
|
143
|
-
Frontend Review
|
|
144
|
-
├─ Files: {frontend_files}
|
|
145
|
-
├─ Status: Running in background...
|
|
146
|
-
└─ Task ID: {task_id}
|
|
147
|
-
|
|
148
|
-
[Waiting for completion...]
|
|
149
|
-
|
|
150
|
-
✓ Reviews complete
|
|
151
|
-
├─ Applied: {refactoring_summary}
|
|
152
|
-
├─ Tests: {count} passed ✓
|
|
153
|
-
└─ Ready for archive
|
|
154
|
-
|
|
155
|
-
✓ Implementation complete
|
|
156
|
-
```
|
|
157
|
-
<!-- ABEL:END -->
|
package/commands/abel-plan.md
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: abel-plan
|
|
3
|
-
description: Refine approved change into a zero-decision executable plan.
|
|
4
|
-
category: abel
|
|
5
|
-
tags: [abel, plan, PBT]
|
|
6
|
-
argument-hint: [change_name]
|
|
7
|
-
---
|
|
8
|
-
<!-- ABEL:START -->
|
|
9
|
-
**Guardrails**
|
|
10
|
-
- Strictly adhere to **OpenSpec** rules when writing **standardized spec-structured projects**.
|
|
11
|
-
- The goal of this phase is to eliminate ALL decision points from the task flow—implementation should be pure mechanical execution.
|
|
12
|
-
- Do not proceed to implementation until every ambiguity is resolved and every constraint is explicitly documented.
|
|
13
|
-
- Every requirement must have Property-Based Testing (PBT) properties defined—focus on invariants, not just example-based tests.
|
|
14
|
-
- If constraints cannot be fully specified, escalate back to the user or return to the research phase rather than making assumptions.
|
|
15
|
-
- Refer to `openspec/AGENTS.md` for additional conventions; run `openspec update` if the file is missing.
|
|
16
|
-
|
|
17
|
-
**Skill Integration**: See `Stage Skill Matrix` (Plan column)
|
|
18
|
-
|
|
19
|
-
**FORBIDDEN**: Direct implementation code generation
|
|
20
|
-
|
|
21
|
-
**Steps**
|
|
22
|
-
1. Run `openspec view` to display all **Active Changes**, then confirm with the user which change folder (`<change_name>`) they wish to refine into a zero-decision plan.
|
|
23
|
-
|
|
24
|
-
2. Navigate to `openspec/changes/<change_name>/` and review existing artifacts:
|
|
25
|
-
- Check `openspec status --change <change_name>` for artifact completion
|
|
26
|
-
- Use `openspec instructions specs --change <change_name>` for specs guidance
|
|
27
|
-
|
|
28
|
-
3. **Implementation Analysis**: Invoke skills to perform systematic analysis to derive a plan:
|
|
29
|
-
```
|
|
30
|
-
# First, invoke /sequential-think skill for systematic analysis if proposal has 3+ interconnected requirements
|
|
31
|
-
|
|
32
|
-
/sequential-think: "Analyze change <change_name> systematically: Break down into components, identify dependencies, evaluate architectural trade-offs, and surface potential conflicts."
|
|
33
|
-
|
|
34
|
-
# Then invoke /context7-auto-research skill to validate framework/library choices
|
|
35
|
-
|
|
36
|
-
/context7-auto-research: "For each technology mentioned in change <change_name>, retrieve official documentation patterns and best practices."
|
|
37
|
-
```
|
|
38
|
-
Produce a consolidated, constraint-complete plan and list any missing constraints as questions to the user.
|
|
39
|
-
|
|
40
|
-
4. **Uncertainty Elimination Audit**: Invoke skills to detect and eliminate remaining ambiguities:
|
|
41
|
-
```
|
|
42
|
-
# First, validate against existing codebase patterns
|
|
43
|
-
{{CODEBASE_RETRIEVAL_PATTERN_AUDIT}}
|
|
44
|
-
# Then audit for ambiguities directly and list them explicitly
|
|
45
|
-
Review change <change_name> for decision points that remain unspecified. For each: [AMBIGUITY] <description> → [REQUIRED CONSTRAINT] <what must be specified>.
|
|
46
|
-
Identify implicit assumptions in change <change_name>. For each: [ASSUMPTION] <description> → [EXPLICIT CONSTRAINT NEEDED] <concrete specification>.
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**Anti-Pattern Detection** (flag and reject):
|
|
50
|
-
- Information collection without decision boundaries (e.g., "JWT vs OAuth2 vs session—all viable")
|
|
51
|
-
- Technical comparisons without selection criteria
|
|
52
|
-
- Deferred decisions marked as "to be determined during implementation"
|
|
53
|
-
|
|
54
|
-
**Target Pattern** (required for approval):
|
|
55
|
-
- Explicit technology choices with parameters (e.g., "JWT with accessToken TTL=15min, refreshToken TTL=7days")
|
|
56
|
-
- Concrete algorithm selections with configurations (e.g., "bcrypt with cost factor=12")
|
|
57
|
-
- Precise behavioral rules (e.g., "Lock account for 30min after 5 failed login attempts")
|
|
58
|
-
|
|
59
|
-
Iterate with user until ALL ambiguities are resolved into explicit constraints.
|
|
60
|
-
|
|
61
|
-
5. **PBT Property Extraction**: Invoke skills to derive testable invariants:
|
|
62
|
-
```
|
|
63
|
-
"Extract Property-Based Testing properties from change <change_name>. For each requirement: [INVARIANT] <must always hold> → [FALSIFICATION STRATEGY] <how to generate counterexamples>."
|
|
64
|
-
"Define system properties for change <change_name>: [PROPERTY] <name> | [DEFINITION] <formal description> | [BOUNDARY CONDITIONS] <edge cases> | [COUNTEREXAMPLE GENERATION] <approach>."
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**PBT Property Categories to Extract**:
|
|
68
|
-
- **Commutativity/Associativity**: Order-independent operations
|
|
69
|
-
- **Idempotency**: Repeated operations yield same result
|
|
70
|
-
- **Round-trip**: Encode→Decode returns original
|
|
71
|
-
- **Invariant Preservation**: State constraints maintained across operations
|
|
72
|
-
- **Monotonicity**: Ordering guarantees (e.g., timestamps always increase)
|
|
73
|
-
- **Bounds**: Value ranges, size limits, rate constraints
|
|
74
|
-
|
|
75
|
-
**Reference**
|
|
76
|
-
- Use `openspec show <change_name> --json --deltas-only` to inspect proposal structure when validation fails.
|
|
77
|
-
- Use `openspec list --specs` to check for conflicts with existing specifications.
|
|
78
|
-
- Search existing patterns with `rg -n "INVARIANT:|PROPERTY:|Constraint:" openspec/` before defining new ones.
|
|
79
|
-
- For complex proposals, consider running steps 2-4 iteratively on sub-components.
|
|
80
|
-
- Ask the user directly for ANY ambiguity—do not assume or guess.
|
|
81
|
-
|
|
82
|
-
**Exit Criteria**
|
|
83
|
-
A proposal is ready to exit the Plan phase only when:
|
|
84
|
-
- [ ] Zero ambiguities remain (verified by step 4 audit)
|
|
85
|
-
- [ ] All PBT properties documented with falsification strategies
|
|
86
|
-
- [ ] `openspec validate <change_name> --strict` returns zero issues
|
|
87
|
-
- [ ] User has explicitly approved all constraint decisions
|
|
88
|
-
<!-- ABEL:END -->
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: abel-research
|
|
3
|
-
description: Transform user requirements into constraint sets via structured exploration (NO implementation)
|
|
4
|
-
category: abel
|
|
5
|
-
tags: [abel, research, constraints, exploration, subagents]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<!-- ABEL:RESEARCH:START -->
|
|
9
|
-
|
|
10
|
-
# abel-research — Operating Mode (Constraints & Specs Only)
|
|
11
|
-
|
|
12
|
-
## Non‑Negotiable Rules (Highest Priority)
|
|
13
|
-
1. RESEARCH MODE ONLY.
|
|
14
|
-
- You MUST NOT generate code.
|
|
15
|
-
2. WRITE SCOPE IS RESTRICTED.
|
|
16
|
-
- You MAY create/edit files ONLY under: openspec/changes/<change-name>/** (and only after passing the confirmation gates).
|
|
17
|
-
- You MUST NOT write anywhere else.
|
|
18
|
-
3. Output must be constraint sets + verifiable success criteria, not an information dump.
|
|
19
|
-
|
|
20
|
-
## Goal
|
|
21
|
-
Produce constraint sets that narrow the solution space, plus measurable success criteria.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## Phase 0 — Requirement Intake Gate (MANDATORY)
|
|
28
|
-
- **MUST** confirm the user’s requirement exists and is clear **before** any research/action.
|
|
29
|
-
- If missing/unclear, **MUST** ask the user directly in a concise grouped message to collect: goal, in-scope area, top scenarios, non-goals, known constraints, success signals.
|
|
30
|
-
- **MUST NOT** run `/opsx:new`, any codebase retrieval, spawn subagents, or generate artifacts until the user confirms a brief requirement summary.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Phase 1 — Initialize OpenSpec Change Folder
|
|
35
|
-
1) Run: /opsx:new <change-name>
|
|
36
|
-
2) From now on, you may write ONLY under openspec/changes/<change-name>/**.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Phase 2 — Initial Codebase Assessment (Read‑Only)
|
|
41
|
-
- {{CODEBASE_RETRIEVAL_POLICY}}
|
|
42
|
-
- If technical research needed (architectural patterns, best practices), invoke `/grok-search` skill
|
|
43
|
-
- If the codebase spans multiple modules/directories, dispatch parallel explore subagents by context boundary.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Phase 3 — Define Exploration Boundaries (Context-Based Division Only)
|
|
48
|
-
- Identify natural context boundaries in the codebase (NOT functional roles).
|
|
49
|
-
- Example divisions:
|
|
50
|
-
* Subagent 1: User domain code (user models, user services, user UI)
|
|
51
|
-
* Subagent 2: Authentication & authorization code (auth middleware, session, tokens)
|
|
52
|
-
* Subagent 3: Configuration & infrastructure (configs, deployments, build scripts)
|
|
53
|
-
- Each boundary should be self-contained: no cross-communication needed between subagents.
|
|
54
|
-
- Define exploration scope and expected output for each subagent.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Phase 4 — Subagent Output Template (MANDATORY JSON)
|
|
59
|
-
All explore subagents MUST return valid JSON using this schema:
|
|
60
|
-
{
|
|
61
|
-
"module_name": "字符串 - 所探索的上下文边界",
|
|
62
|
-
"existing_structures": ["发现的关键结构/模式列表"],
|
|
63
|
-
"existing_conventions": ["当前使用的约定/标准列表"],
|
|
64
|
-
"constraints_discovered": ["限制解决方案空间的硬约束列表"],
|
|
65
|
-
"open_questions": ["需要用户输入的歧义问题列表"],
|
|
66
|
-
"dependencies": ["对其他模块/系统的依赖列表"],
|
|
67
|
-
"risks": ["潜在风险或阻碍列表"],
|
|
68
|
-
"success_criteria_hints": ["指示成功的可观察行为列表"]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Phase 5 — Parallel Subagent Dispatch
|
|
74
|
-
- Monitor subagent execution and collect structured reports.
|
|
75
|
-
- For each boundary, spawn an Explore subagent with:
|
|
76
|
-
- {{CODEBASE_RETRIEVAL_MANDATORY_RULE}}
|
|
77
|
-
- Clear scope
|
|
78
|
-
- self-contained with independent output
|
|
79
|
-
- Required output template (from Phase 4)
|
|
80
|
-
- If boundary involves 3+ interconnected components, invoke `/sequential-think` skill
|
|
81
|
-
- Clear success criteria: complete analysis of assigned boundary
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Phase 6 — Aggregate & Synthesize
|
|
87
|
-
- Collect all subagent JSON outputs.
|
|
88
|
-
- Merge findings into unified constraint sets:
|
|
89
|
-
* **Hard constraints**: Technical limitations, existing patterns that cannot be violated.
|
|
90
|
-
* **Soft constraints**: Conventions, preferences, style guides.
|
|
91
|
-
* **Dependencies**: Cross-module relationships that affect implementation order.
|
|
92
|
-
* **Risks**: Potential blockers that need mitigation.
|
|
93
|
-
- Identify **open questions** from all reports that require user clarification.
|
|
94
|
-
- Synthesize **success criteria** from scenario hints across all contexts.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Phase 7 — User Interaction for Ambiguity Resolution
|
|
99
|
-
- Compile prioritized list of open questions from aggregated reports.
|
|
100
|
-
- Present questions directly to the user in a concise grouped message:
|
|
101
|
-
* Group related questions together.
|
|
102
|
-
* Provide context for each question.
|
|
103
|
-
* Suggest default answers when applicable.
|
|
104
|
-
- Capture user responses as additional constraints.
|
|
105
|
-
- Update constraint sets with confirmed decisions.
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Phase 8 — Generate OpenSpec Artifacts
|
|
110
|
-
- Transform finalized constraint sets into OpenSpec proposal/specs/design/tasks.
|
|
111
|
-
- Every requirement MUST have a verifiable scenario and success criteria.
|
|
112
|
-
- Keep all writes inside openspec/changes/<change-name>/**.
|
|
113
|
-
|
|
114
|
-
## Reference
|
|
115
|
-
- Review existing constraints: `rg -n "Constraint:|MUST|MUST NOT" openspec/specs`
|
|
116
|
-
- {{CODEBASE_RETRIEVAL_STRUCTURE_REFERENCE}}
|
|
117
|
-
|
|
118
|
-
- Check prior research outputs: `ls openspec/changes/*/`
|
|
119
|
-
- OpenSpec CLI commands:
|
|
120
|
-
- `openspec view` - Interactive dashboard to browse changes
|
|
121
|
-
- `openspec list --changes` - List all active changes
|
|
122
|
-
- `openspec status --change <name>` - Check artifact completion status
|
|
123
|
-
- `openspec instructions proposal --change <name>` - Get proposal instructions
|
|
124
|
-
- Validate subagent outputs conform to template before aggregation.
|
|
125
|
-
- Ask the user directly for ANY ambiguity—do not assume or guess.
|
|
126
|
-
<!-- ABEL:RESEARCH:END -->
|
package/lib/cli/logic.mjs
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts";
|
|
2
|
-
|
|
3
|
-
const interactiveMenuDescriptors = [
|
|
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: "pi-cli", label: "安装/配置 Pi", hint: "CLI", group: "cli" },
|
|
10
|
-
{ value: "codex-cli", label: "安装/配置 Codex", hint: "CLI", group: "cli" },
|
|
11
|
-
{ value: "claude-cli", label: "安装/配置 Claude Code", hint: "CLI", group: "cli" },
|
|
12
|
-
{ value: "exit", label: "退出", group: "exit" }
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
const interactiveMenuDefaultValue = "full-init";
|
|
16
|
-
const cliToolMenuDescriptorMap = {
|
|
17
|
-
pi: [
|
|
18
|
-
{ value: "pi-install", label: "安装/更新 Pi" },
|
|
19
|
-
{ value: "pi-api", label: "配置 Pi API" },
|
|
20
|
-
{ value: "back", label: "返回上一级" }
|
|
21
|
-
],
|
|
22
|
-
codex: [
|
|
23
|
-
{ value: "codex-install", label: "安装/更新 Codex" },
|
|
24
|
-
{ value: "codex-api", label: "配置 Codex API" },
|
|
25
|
-
{ value: "back", label: "返回上一级" }
|
|
26
|
-
],
|
|
27
|
-
claude: [
|
|
28
|
-
{ value: "claude-install", label: "安装/更新 Claude Code" },
|
|
29
|
-
{ value: "claude-api", label: "配置 Claude Code API" },
|
|
30
|
-
{ value: "back", label: "返回上一级" }
|
|
31
|
-
]
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
function buildCliToolMenuDescriptors(tool) {
|
|
35
|
-
const descriptors = cliToolMenuDescriptorMap[tool];
|
|
36
|
-
if (!descriptors) {
|
|
37
|
-
throw new Error(`Unknown CLI tool: ${tool}`);
|
|
38
|
-
}
|
|
39
|
-
return descriptors.map((descriptor) => ({ ...descriptor }));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
class CancelledError extends Error {
|
|
43
|
-
constructor(message = "用户取消") {
|
|
44
|
-
super(message);
|
|
45
|
-
this.name = "CancelledError";
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function required(message = "此项不能为空") {
|
|
50
|
-
return (value) => {
|
|
51
|
-
if (value === undefined || value === null || (typeof value === "string" && value.trim() === "")) {
|
|
52
|
-
return message;
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function requiredUnlessExisting(existingValue, message = "此项不能为空") {
|
|
58
|
-
return (value) => {
|
|
59
|
-
if ((value === undefined || value === null || (typeof value === "string" && value.trim() === "")) && !existingValue) {
|
|
60
|
-
return message;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 回退逻辑:用户输入非空则用新值,否则用旧值。
|
|
67
|
-
* 输入 "-" 表示清除已有值(返回 undefined)。
|
|
68
|
-
* existingValue 可能来自 dotenv / JSON 读取,会传入空字符串;
|
|
69
|
-
* 空字符串将被净化为 undefined,避免写入无意义的空配置。
|
|
70
|
-
* 注意:本函数仅适用于字符串类型的配置值,不适用于可能为 0/false 的数字或布尔值。
|
|
71
|
-
*/
|
|
72
|
-
function resolvePasswordValue(userInput, existingValue) {
|
|
73
|
-
if (typeof userInput === "string") {
|
|
74
|
-
const trimmed = userInput.trim();
|
|
75
|
-
if (trimmed === "") {
|
|
76
|
-
if (typeof existingValue === "string" && existingValue.trim() === "") {
|
|
77
|
-
return undefined;
|
|
78
|
-
}
|
|
79
|
-
return existingValue || undefined;
|
|
80
|
-
}
|
|
81
|
-
return trimmed === "-" ? undefined : trimmed;
|
|
82
|
-
}
|
|
83
|
-
if (typeof existingValue === "string" && existingValue.trim() === "") {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
return existingValue || undefined;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function assertNotCancelled(value) {
|
|
90
|
-
if (p.isCancel(value)) {
|
|
91
|
-
throw new CancelledError();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async function confirmOrCancel({ message, initialValue = false }) {
|
|
96
|
-
const value = await p.confirm({ message, initialValue, active: "是", inactive: "否" });
|
|
97
|
-
assertNotCancelled(value);
|
|
98
|
-
return value;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
async function selectOrCancel(options) {
|
|
102
|
-
const value = await p.select(options);
|
|
103
|
-
assertNotCancelled(value);
|
|
104
|
-
return value;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function parseArgs(argv, { defaultAgentsDir, resolvePath }) {
|
|
108
|
-
const options = {
|
|
109
|
-
agentsDir: defaultAgentsDir,
|
|
110
|
-
force: false,
|
|
111
|
-
relinkOnly: false,
|
|
112
|
-
nonInteractive: false,
|
|
113
|
-
command: "menu"
|
|
114
|
-
};
|
|
115
|
-
const positional = [];
|
|
116
|
-
let helpRequested = false;
|
|
117
|
-
|
|
118
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
119
|
-
const arg = argv[i];
|
|
120
|
-
if (arg === "--force" || arg === "-f") {
|
|
121
|
-
options.force = true;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
if (arg === "--link-only") {
|
|
125
|
-
options.relinkOnly = true;
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
if (arg === "--agents-dir") {
|
|
129
|
-
const value = argv[i + 1];
|
|
130
|
-
if (!value) {
|
|
131
|
-
throw new Error("--agents-dir requires a path");
|
|
132
|
-
}
|
|
133
|
-
options.agentsDir = resolvePath(value);
|
|
134
|
-
i += 1;
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
if (arg === "--non-interactive") {
|
|
138
|
-
options.nonInteractive = true;
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
if (arg === "--help" || arg === "-h" || arg === "help") {
|
|
142
|
-
helpRequested = true;
|
|
143
|
-
options.command = "help";
|
|
144
|
-
continue;
|
|
145
|
-
}
|
|
146
|
-
if (arg.startsWith("-")) {
|
|
147
|
-
throw new Error(`Unknown argument: ${arg}`);
|
|
148
|
-
}
|
|
149
|
-
positional.push(arg);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (positional.length > 1) {
|
|
153
|
-
throw new Error(`Unknown argument: ${positional.slice(1).join(" ")}`);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (positional[0]) {
|
|
157
|
-
if (["menu", "init"].includes(positional[0])) {
|
|
158
|
-
if (!helpRequested) {
|
|
159
|
-
options.command = "menu";
|
|
160
|
-
}
|
|
161
|
-
} else if (["install", "sync"].includes(positional[0])) {
|
|
162
|
-
if (!helpRequested) {
|
|
163
|
-
options.command = "install";
|
|
164
|
-
}
|
|
165
|
-
} else {
|
|
166
|
-
throw new Error(`Unknown command: ${positional[0]}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (options.command !== "install" && (options.force || options.relinkOnly || options.agentsDir !== defaultAgentsDir)) {
|
|
171
|
-
throw new Error("`--force`、`--link-only`、`--agents-dir` 仅能与 `install` 命令一起使用");
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (!options.nonInteractive && process.env.CI) {
|
|
175
|
-
options.nonInteractive = true;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return options;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function assertInteractiveMenuSupported({ command, inputIsTTY, outputIsTTY, nonInteractive }) {
|
|
182
|
-
// 防御性检查(死代码守护):main() 已在调用前将非交互 menu 降级为 install,
|
|
183
|
-
// 此处仅防止外部直接调用 assertInteractiveMenuSupported 时漏掉判断。
|
|
184
|
-
if (command === "menu" && nonInteractive) {
|
|
185
|
-
throw new Error("非交互模式已启用;请显式使用 `npx abelworkflow install` 进行安装");
|
|
186
|
-
}
|
|
187
|
-
if (command === "menu" && (!inputIsTTY || !outputIsTTY)) {
|
|
188
|
-
throw new Error("交互式菜单需要 TTY 终端;非交互场景请显式使用 `npx abelworkflow install`");
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function getRunCommandSpawnOptions(platform = process.env.ABELWORKFLOW_TEST_PLATFORM || process.platform) {
|
|
193
|
-
return {
|
|
194
|
-
stdio: "inherit",
|
|
195
|
-
shell: platform === "win32"
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export {
|
|
200
|
-
assertInteractiveMenuSupported,
|
|
201
|
-
assertNotCancelled,
|
|
202
|
-
buildCliToolMenuDescriptors,
|
|
203
|
-
CancelledError,
|
|
204
|
-
confirmOrCancel,
|
|
205
|
-
getRunCommandSpawnOptions,
|
|
206
|
-
interactiveMenuDefaultValue,
|
|
207
|
-
interactiveMenuDescriptors,
|
|
208
|
-
parseArgs,
|
|
209
|
-
required,
|
|
210
|
-
requiredUnlessExisting,
|
|
211
|
-
resolvePasswordValue,
|
|
212
|
-
selectOrCancel
|
|
213
|
-
};
|