easy-coding-harness 0.1.6 → 0.1.8
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 +27 -0
- package/dist/cli.js +49 -25
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/templates/claude/agents/ec-fixer.md +36 -0
- package/templates/codex/agents/ec-fixer.toml +25 -0
- package/templates/common/bundled-skills/ec-meta/references/local-architecture/README.md +5 -0
- package/templates/common/skills/ec-analysis/SKILL.md +62 -33
- package/templates/common/skills/ec-brainstorming/SKILL.md +16 -4
- package/templates/common/skills/ec-implementing/SKILL.md +26 -3
- package/templates/common/skills/ec-memory/SKILL.md +31 -11
- package/templates/common/skills/ec-reviewing/SKILL.md +39 -10
- package/templates/common/skills/ec-task-close/SKILL.md +2 -0
- package/templates/common/skills/ec-task-management/SKILL.md +5 -3
- package/templates/common/skills/ec-verification/SKILL.md +12 -7
- package/templates/common/skills/ec-workflow/SKILL.md +58 -13
- package/templates/main-constraint/AGENTS.md.tpl +2 -2
- package/templates/main-constraint/CLAUDE.md.tpl +2 -2
- package/templates/qoder/agents/ec-fixer.md +36 -0
- package/templates/shared-hooks/easy_coding_status.py +68 -20
- package/templates/shared-hooks/inject-subagent-context.py +2 -2
- package/templates/shared-hooks/inject-workflow-state.py +5 -15
- package/templates/shared-hooks/session-start.py +90 -17
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ec-fixer
|
|
3
|
+
model: sonnet
|
|
4
|
+
description: Easy Coding fix sub-agent. Applies targeted fixes to specific issues identified during review. Returns structured results with changed files.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are an Easy Coding fix sub-agent. You receive a fix card listing specific issues
|
|
8
|
+
(with file:line locations) and apply the fixes. Your reply content IS the return value,
|
|
9
|
+
not a message to a human.
|
|
10
|
+
|
|
11
|
+
## Hard constraints
|
|
12
|
+
|
|
13
|
+
- Fix ONLY the issues listed in the fix card. Do not refactor or "improve" surrounding code.
|
|
14
|
+
- Modify ONLY the files listed in the fix card's scope.
|
|
15
|
+
- Do not call any Skill tool.
|
|
16
|
+
- Do not read `.claude/skills/`, `.agents/skills/`, or any `.easy-coding/` file.
|
|
17
|
+
- Make no workflow stage-transition decisions.
|
|
18
|
+
- Preserve file encoding.
|
|
19
|
+
|
|
20
|
+
## Output (return exactly this structure)
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"changed_files": ["file1.ts", "file2.ts"],
|
|
25
|
+
"fixes_applied": [
|
|
26
|
+
{"file": "file1.ts", "line": 42, "original_issue": "...", "fix_description": "..."}
|
|
27
|
+
],
|
|
28
|
+
"issues": [],
|
|
29
|
+
"needs_attention": []
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- `changed_files`: files you actually modified
|
|
34
|
+
- `fixes_applied`: what you fixed with file:line reference
|
|
35
|
+
- `issues`: problems you hit that prevented a fix (empty if none)
|
|
36
|
+
- `needs_attention`: anything requiring a design decision that should escalate to the user
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[agent]
|
|
2
|
+
name = "ec-fixer"
|
|
3
|
+
model = "sonnet"
|
|
4
|
+
description = "Easy Coding fix sub-agent. Applies targeted fixes to specific issues identified during review."
|
|
5
|
+
sandbox = "workspace-write"
|
|
6
|
+
|
|
7
|
+
[agent.instructions]
|
|
8
|
+
text = """
|
|
9
|
+
You are an Easy Coding fix sub-agent. You receive a fix card listing specific issues
|
|
10
|
+
(with file:line locations) and apply the fixes. Your reply content IS the return value.
|
|
11
|
+
|
|
12
|
+
Hard constraints:
|
|
13
|
+
- Fix ONLY the issues listed in the fix card. No refactoring.
|
|
14
|
+
- Modify ONLY the files listed in the fix card's scope.
|
|
15
|
+
- Do not call any Skill tool.
|
|
16
|
+
- Do not read .agents/skills/ or any .easy-coding/ file.
|
|
17
|
+
- Make no workflow stage-transition decisions.
|
|
18
|
+
- Preserve file encoding.
|
|
19
|
+
|
|
20
|
+
Output structure (return as JSON):
|
|
21
|
+
- changed_files: files you modified
|
|
22
|
+
- fixes_applied: [{file, line, original_issue, fix_description}]
|
|
23
|
+
- issues: problems preventing a fix (empty if none)
|
|
24
|
+
- needs_attention: design decisions needing user escalation (empty if none)
|
|
25
|
+
"""
|
|
@@ -47,6 +47,11 @@ MEMORY_LONG → COMPLETE`, plus `CLOSED` (user abort, no memory flow). WAITING_C
|
|
|
47
47
|
VERIFICATION are hard gates. The current stage persists in `state.json`; hooks inject it as a
|
|
48
48
|
breadcrumb so every reply can render the status line.
|
|
49
49
|
|
|
50
|
+
Task switching: `state.json.current_task` is a single slot, but the user can switch between
|
|
51
|
+
tasks at any time. When a user's prompt doesn't match the active task, ec-workflow's intent
|
|
52
|
+
router offers to suspend the current task and switch. The suspended task retains its stage in
|
|
53
|
+
`task.json`; no data is lost. Each task folder is self-contained.
|
|
54
|
+
|
|
50
55
|
## Task persistence
|
|
51
56
|
|
|
52
57
|
Each task is a folder. `task.json` is metadata; `dev-spec.md` is the human-readable plan;
|
|
@@ -10,6 +10,23 @@ to implement, and present a plan the user can confirm. You do not write business
|
|
|
10
10
|
|
|
11
11
|
Communicate with the user in the user's language.
|
|
12
12
|
|
|
13
|
+
## HARD RULES (non-negotiable, violations = failed analysis)
|
|
14
|
+
|
|
15
|
+
1. **Your FIRST tool call** in this skill MUST be a file-write that creates
|
|
16
|
+
`.easy-coding/tasks/{task-id}/dev-spec.md` with the COMPLETE template skeleton from the
|
|
17
|
+
"Required output" section below. No reading, no thinking out loud, no "let me analyze
|
|
18
|
+
first" — skeleton file FIRST. If this file does not exist after your first tool call, you
|
|
19
|
+
have already failed.
|
|
20
|
+
2. **All subsequent analysis** fills sections of this file via edits. You do NOT hold analysis
|
|
21
|
+
in your head and dump it at the end — you write each section into the file as you go.
|
|
22
|
+
3. **Your chat output to the user** MUST be the final content of dev-spec.md (copy it into
|
|
23
|
+
your reply or reference it). You MUST NOT invent a different, abbreviated format. No
|
|
24
|
+
"执行计划" summary tables, no bullet-point plans, no freestyle answers. The template IS
|
|
25
|
+
the format. If your reply to the user does not contain every mandatory section header from
|
|
26
|
+
the template, you have failed.
|
|
27
|
+
4. **Three files must exist** in `.easy-coding/tasks/{task-id}/` when you finish:
|
|
28
|
+
`dev-spec.md`, `execution.jsonl` (plan record), `test-strategy.md`. Missing any one = failed.
|
|
29
|
+
|
|
13
30
|
## Inputs to load (in this order)
|
|
14
31
|
|
|
15
32
|
1. `.easy-coding/SOUL.md`, `.easy-coding/RULES.md` (always).
|
|
@@ -17,7 +34,10 @@ Communicate with the user in the user's language.
|
|
|
17
34
|
adds a feature. A single-file bugfix or doc edit can skip it.
|
|
18
35
|
3. Long memory: read `MEMORY.md` index, then only the `BUSINESS.md`/`TECHNICAL.md` entries
|
|
19
36
|
whose domain/tags/related_files match this task. No unbounded full scans.
|
|
20
|
-
4.
|
|
37
|
+
4. `.easy-coding/spec/` — scan for design docs (`*-design.md`) whose topic matches this task.
|
|
38
|
+
If found, use the design as a primary input for the analysis. The design doc defines the
|
|
39
|
+
direction; your job is to turn it into a concrete implementation plan.
|
|
40
|
+
5. The actual source files the task touches — read them. A plan that does not cite real
|
|
21
41
|
files, classes, and call paths is rejected by your own self-check below.
|
|
22
42
|
|
|
23
43
|
## Cross-repo handling
|
|
@@ -27,32 +47,35 @@ by **name**, never local paths). For each involved repo, read its ABSTRACT to un
|
|
|
27
47
|
interface. Cache any local path the user provides only in `state.json.repo_paths`. If a repo
|
|
28
48
|
name cannot be located locally, ask the user for the path before proceeding.
|
|
29
49
|
|
|
30
|
-
## Analysis procedure (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
2.
|
|
38
|
-
3.
|
|
39
|
-
4.
|
|
40
|
-
|
|
41
|
-
5.
|
|
42
|
-
6.
|
|
43
|
-
7.
|
|
44
|
-
8.
|
|
45
|
-
9. **
|
|
46
|
-
|
|
47
|
-
10. **
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
## Analysis procedure (mandatory sequence)
|
|
51
|
+
|
|
52
|
+
You MUST execute these steps in exact order. Do not rearrange, skip, or combine steps.
|
|
53
|
+
|
|
54
|
+
1. **Write skeleton** — FIRST tool call: write `.easy-coding/tasks/{task-id}/dev-spec.md`
|
|
55
|
+
using the full template from the next section. Every section header and every `{待填写}`
|
|
56
|
+
placeholder must be present. This is not optional.
|
|
57
|
+
2. **Fill 项目模式 + 任务类型** — edit dev-spec.md in place.
|
|
58
|
+
3. **Fill 需求解析** — edit dev-spec.md: 目标 / 输入 / 输出 / 边界.
|
|
59
|
+
4. **Read source code, fill 现状** — read the actual files, then edit dev-spec.md with
|
|
60
|
+
evidence. Every claim must cite file:line. No file references = invalid section.
|
|
61
|
+
5. **Fill 冲突摘要 + 待用户决策** — edit dev-spec.md.
|
|
62
|
+
6. **Fill 影响面分析 + 改动范围** — edit dev-spec.md, fill the table with encoding evidence.
|
|
63
|
+
7. **Fill 修改方案 + 实施拆解** — edit dev-spec.md, design approach and decompose units.
|
|
64
|
+
8. **Fill 测试策略 + 风险与注意事项** — edit dev-spec.md.
|
|
65
|
+
9. **Fill conditional sections** — edit dev-spec.md: 背景数据应用 / 核心改动明细 /
|
|
66
|
+
前端实现映射 only if applicable. Remove inapplicable conditional sections entirely.
|
|
67
|
+
10. **Write execution.jsonl** — append the plan record (see section below).
|
|
68
|
+
11. **Write test-strategy.md** — write the testability table (see section below).
|
|
69
|
+
12. **Self-check** — run the gates below. Fix any failure in the files.
|
|
70
|
+
13. **Present to user** — output the FINAL content of dev-spec.md to the user as your reply.
|
|
71
|
+
Do not summarize, abbreviate, or reformat. The dev-spec.md content IS your reply.
|
|
51
72
|
|
|
52
73
|
## Required output: dev-spec.md template
|
|
53
74
|
|
|
54
|
-
The skeleton below is the
|
|
55
|
-
|
|
75
|
+
The skeleton below is the EXACT file you MUST write as step 1. Copy it character-for-character
|
|
76
|
+
into `.easy-coding/tasks/{task-id}/dev-spec.md`. Do not rephrase headers, do not omit
|
|
77
|
+
sections, do not invent alternative formats. Later steps fill the `{待填写}` placeholders
|
|
78
|
+
via edits. Conditional sections are added only if applicable.
|
|
56
79
|
|
|
57
80
|
````markdown
|
|
58
81
|
[阶段:ANALYSIS]
|
|
@@ -198,14 +221,19 @@ with reason (missing infra, data, credentials, or API contract).
|
|
|
198
221
|
Write the confirmed strategy to `.easy-coding/tasks/{task-id}/test-strategy.md` (the
|
|
199
222
|
VERIFICATION baseline).
|
|
200
223
|
|
|
201
|
-
## Self-check gates (reject your own
|
|
224
|
+
## Self-check gates (ALL must pass — reject your own output if ANY fails)
|
|
202
225
|
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
226
|
+
- [ ] `dev-spec.md` 文件是否已写入 `.easy-coding/tasks/{task-id}/`?
|
|
227
|
+
- [ ] `execution.jsonl` 文件是否已写入?
|
|
228
|
+
- [ ] `test-strategy.md` 文件是否已写入?
|
|
229
|
+
- [ ] dev-spec.md 是否包含全部 12 个核心章节标题?
|
|
230
|
+
- [ ] 每个"现状"断言是否引用了真实文件/类/行号?
|
|
231
|
+
- [ ] 是否有具体的修改方案,而非仅罗列"已加载的文件"?
|
|
232
|
+
- [ ] 不适用的条件章节是否已完全省略(而非留空)?
|
|
233
|
+
- [ ] 实施拆解的单元、依赖、策略是否与改动范围表一致?
|
|
234
|
+
- [ ] 改动范围表中每行是否填写了文件编码及证据?
|
|
235
|
+
- [ ] 所有 `{待填写}` 占位符是否已替换为实际内容?
|
|
236
|
+
- [ ] 回复给用户的内容是否是 dev-spec.md 的完整内容(而非自创的缩略格式)?
|
|
209
237
|
|
|
210
238
|
## Revision handling
|
|
211
239
|
|
|
@@ -222,5 +250,6 @@ Re-output the COMPLETE revised dev-spec.md:
|
|
|
222
250
|
|
|
223
251
|
## End state
|
|
224
252
|
|
|
225
|
-
|
|
226
|
-
|
|
253
|
+
Output the COMPLETE content of dev-spec.md as your reply to the user — not a summary, not a
|
|
254
|
+
different format, not a table you invented. Then set stage to WAITING_CONFIRM and hand
|
|
255
|
+
control back to ec-workflow. Never start implementing from this skill.
|
|
@@ -57,14 +57,26 @@ can be three sentences for a truly simple idea, but you MUST present it and get
|
|
|
57
57
|
the user to review the written doc before proceeding. Make requested changes and re-run
|
|
58
58
|
the self-review. Proceed only on explicit approval.
|
|
59
59
|
|
|
60
|
-
##
|
|
60
|
+
## After approval — handoff to ec-workflow
|
|
61
61
|
|
|
62
62
|
The confirmed design doc is an INPUT to ec-workflow's ANALYSIS stage — it does not replace
|
|
63
|
-
ANALYSIS (brainstorming is design; ANALYSIS is the implementation plan).
|
|
64
|
-
|
|
63
|
+
ANALYSIS (brainstorming is design; ANALYSIS is the implementation plan).
|
|
64
|
+
|
|
65
|
+
After saving the design doc, ask the user: "Design confirmed. Start a task based on this
|
|
66
|
+
design now?" Offer two options:
|
|
67
|
+
|
|
68
|
+
1. **Start task now** — invoke `{{skill_trigger}}ec-workflow` with the design topic as the
|
|
69
|
+
task prompt. ec-workflow will create the task (step 4) and enter INIT → ANALYSIS.
|
|
70
|
+
ec-analysis will discover the design doc in `.easy-coding/spec/` and use it as input.
|
|
71
|
+
2. **Later** — tell the user the design is saved and they can run
|
|
72
|
+
`{{skill_trigger}}ec-workflow` whenever ready.
|
|
73
|
+
|
|
74
|
+
If `current_task` is set when the user chooses option 1, mention that the current task will
|
|
75
|
+
be suspended (ec-workflow's intent routing handles the rest).
|
|
65
76
|
|
|
66
77
|
## Boundaries
|
|
67
78
|
|
|
68
79
|
- Write no implementation code, scaffold nothing, take no implementation action.
|
|
69
|
-
-
|
|
80
|
+
- The only ec-* skill you may invoke is `ec-workflow` (on user confirmation after approval).
|
|
81
|
+
Do not touch state.json or the state machine directly.
|
|
70
82
|
- One question per message — never overwhelm.
|
|
@@ -31,13 +31,28 @@ Communicate with the user in the user's language.
|
|
|
31
31
|
7. **Tests (soft rule).** Write tests for [must-test]/[should-test] items per
|
|
32
32
|
test-strategy.md. Soft means: no project test infra → not forced; infra exists → required.
|
|
33
33
|
|
|
34
|
-
## Sub-agent dispatch
|
|
34
|
+
## Sub-agent dispatch
|
|
35
35
|
|
|
36
|
-
Read the `plan` record. Then:
|
|
36
|
+
Read the `plan` record's `strategy` field. Then:
|
|
37
37
|
|
|
38
38
|
- `single` → main agent implements directly, no sub-agents.
|
|
39
39
|
- `sequential` → main agent implements units one by one in dependency order.
|
|
40
|
-
- `parallel` →
|
|
40
|
+
- `parallel` → sub-agents are MANDATORY (see gate below).
|
|
41
|
+
|
|
42
|
+
<HARD-GATE>
|
|
43
|
+
PARALLEL STRATEGY = MANDATORY SUB-AGENT DISPATCH. NO EXCEPTIONS.
|
|
44
|
+
|
|
45
|
+
If the plan record says `"strategy":"parallel"`, you MUST dispatch sub-agents using
|
|
46
|
+
{{sub_agent_dispatch}}. You are FORBIDDEN from implementing parallel units yourself.
|
|
47
|
+
Doing the work inline instead of dispatching is a protocol violation equivalent to
|
|
48
|
+
skipping WAITING_CONFIRM.
|
|
49
|
+
|
|
50
|
+
Self-check before writing ANY implementation code:
|
|
51
|
+
- Is strategy "parallel"? → Did I dispatch via {{sub_agent_dispatch}}? If no → STOP.
|
|
52
|
+
- Am I working on a unit in a parallel level without dispatching? → STOP.
|
|
53
|
+
|
|
54
|
+
The ONLY case where you implement code directly is strategy "single" or "sequential".
|
|
55
|
+
</HARD-GATE>
|
|
41
56
|
|
|
42
57
|
Parallel dispatch loop:
|
|
43
58
|
1. Sort `parallel_groups` by level.
|
|
@@ -87,3 +102,11 @@ let sub-agents re-dispatch each other.
|
|
|
87
102
|
|
|
88
103
|
All units done and self-audited → hand back to ec-workflow to advance to REVIEW. If you
|
|
89
104
|
hit something that invalidates the plan, return to ANALYSIS instead of improvising.
|
|
105
|
+
|
|
106
|
+
## Self-check gates (before handing back)
|
|
107
|
+
|
|
108
|
+
- [ ] Strategy was "parallel" → ALL units dispatched via sub-agents? (VIOLATION if no)
|
|
109
|
+
- [ ] Strategy was "sequential" → units implemented in dependency order?
|
|
110
|
+
- [ ] Each dispatched unit has a `dispatch` record in execution.jsonl?
|
|
111
|
+
- [ ] Each returned unit has a `result` record?
|
|
112
|
+
- [ ] No files modified outside the change-scope table?
|
|
@@ -32,27 +32,47 @@ result/verify records, not from a fuzzy memory of the conversation.}
|
|
|
32
32
|
|
|
33
33
|
If the task was cross-repo, record the repo names involved and the collaboration reason.
|
|
34
34
|
|
|
35
|
-
**Sliding window:**
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
**Sliding window (informational):** The short memory directory has a soft cap defined by
|
|
36
|
+
`memory.short_term_max` (default 10). MEMORY_SHORT only WRITES one entry per completed task
|
|
37
|
+
— it never counts, trims, or triggers distillation. Trimming is exclusively MEMORY_LONG's
|
|
38
|
+
responsibility and only runs when the threshold is exceeded.
|
|
38
39
|
|
|
39
|
-
## MEMORY_LONG — distill durable knowledge
|
|
40
|
+
## MEMORY_LONG — distill durable knowledge (CONDITIONAL)
|
|
41
|
+
|
|
42
|
+
<HARD-GATE>
|
|
43
|
+
MEMORY_LONG IS A NO-OP WHEN SHORT MEMORY COUNT <= threshold.
|
|
44
|
+
|
|
45
|
+
Before performing ANY distillation work:
|
|
46
|
+
1. Count `.md` files in `.easy-coding/memory/short/` (only files with schema-v2 frontmatter).
|
|
47
|
+
2. Read `memory.short_term_max` from `.easy-coding/config.yaml` (default: 10).
|
|
48
|
+
3. If count <= short_term_max: output "MEMORY_LONG: no-op (short memory count = {N},
|
|
49
|
+
threshold = {short_term_max})" and immediately hand back to ec-workflow to advance to
|
|
50
|
+
COMPLETE. Do NOT read long memory files, do NOT attempt distillation, do NOT modify any file.
|
|
51
|
+
4. If count > short_term_max: proceed with distillation below.
|
|
52
|
+
|
|
53
|
+
This gate is absolute. Even a single short memory entry below threshold does NOT trigger
|
|
54
|
+
long-term compression regardless of any other signal.
|
|
55
|
+
</HARD-GATE>
|
|
56
|
+
|
|
57
|
+
### When count > threshold: distillation flow
|
|
40
58
|
|
|
41
59
|
Three-file long memory:
|
|
42
60
|
- `MEMORY.md` — index of all entries with status (active | deprecated | superseded | deleted).
|
|
43
61
|
- `BUSINESS.md` — business rules, domain knowledge, product decisions.
|
|
44
62
|
- `TECHNICAL.md` — architecture decisions, implementation patterns, gotchas.
|
|
45
63
|
|
|
46
|
-
Distillation
|
|
47
|
-
1. Read
|
|
48
|
-
|
|
64
|
+
Distillation steps:
|
|
65
|
+
1. Read `memory.short_term_keep` from config (default: 5). Keep the latest N entries;
|
|
66
|
+
the older entries become distillation candidates.
|
|
67
|
+
2. Read the `target_long` of candidate short memories; route to business/technical.
|
|
68
|
+
3. **Progressive loading** — read only the existing long entries matching this round's
|
|
49
69
|
domain/tags/related_files. No unbounded whole-repo memory scan.
|
|
50
|
-
|
|
70
|
+
4. **Conflict resolution** by priority: current code > latest user confirmation > this
|
|
51
71
|
round's candidate > older long memory. On conflict, explain it before consolidating —
|
|
52
72
|
never silently pick a side.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
73
|
+
5. **Retirement check**: for older entries decide delete (no value) / merge (semantic
|
|
74
|
+
duplicate) / deprecate (was valid, now superseded).
|
|
75
|
+
6. Update the `MEMORY.md` index to reflect every change.
|
|
56
76
|
|
|
57
77
|
## ABSTRACT backfill / update
|
|
58
78
|
|
|
@@ -31,28 +31,57 @@ result. No finding without a location.
|
|
|
31
31
|
## Verdict (exactly one)
|
|
32
32
|
|
|
33
33
|
- `accept` — all dimensions pass. Advance to VERIFICATION.
|
|
34
|
-
- `fix` — problems found, fixable within the current plan.
|
|
35
|
-
to IMPLEMENT against that list.
|
|
34
|
+
- `fix` — problems found, fixable within the current plan. Auto-fix via sub-agents (see below).
|
|
36
35
|
- `replan` — the plan itself is flawed (wrong approach, missing design). Return to ANALYSIS.
|
|
37
36
|
- `blocked` — external blocker (missing dependency, environment). Pause and report.
|
|
38
37
|
|
|
38
|
+
## Auto-fix flow (on `fix` verdict)
|
|
39
|
+
|
|
40
|
+
<HARD-GATE>
|
|
41
|
+
Bug-level issues (correctness errors, compliance violations, missing edge-case handling)
|
|
42
|
+
are fixed DIRECTLY by dispatching fix sub-agents. Do NOT ask the user for permission to
|
|
43
|
+
fix bugs. The user confirmed the plan — bugs in that plan's execution are implementation
|
|
44
|
+
defects, not design decisions.
|
|
45
|
+
|
|
46
|
+
ONLY escalate to the user when:
|
|
47
|
+
- The fix requires a DESIGN CHOICE (two equally valid approaches, ambiguous requirement)
|
|
48
|
+
- The fix would change the public API contract beyond what the dev-spec specifies
|
|
49
|
+
- The finding contradicts something the user explicitly stated during WAITING_CONFIRM
|
|
50
|
+
</HARD-GATE>
|
|
51
|
+
|
|
52
|
+
Fix dispatch flow:
|
|
53
|
+
1. Collect all `fix`-worthy findings from review sub-agents.
|
|
54
|
+
2. Group findings by file. For each group, build a fix task card:
|
|
55
|
+
- Files to fix (from the findings)
|
|
56
|
+
- The specific issues with file:line citations
|
|
57
|
+
- The suggested fix direction from the reviewer
|
|
58
|
+
- Relevant RULES sections
|
|
59
|
+
3. Dispatch fix sub-agents (ec-fixer, one per file group) via {{sub_agent_dispatch}}.
|
|
60
|
+
Platform spawn rule: {{platform_spawn_instruction}}
|
|
61
|
+
4. On return: merge results, append `result` records to execution.jsonl.
|
|
62
|
+
5. Re-enter REVIEW (counts toward the fix-loop ceiling of 3).
|
|
63
|
+
|
|
39
64
|
## Fix-loop ceiling
|
|
40
65
|
|
|
41
|
-
A `fix` verdict carries a concrete checklist; IMPLEMENT addresses it and re-enters REVIEW.
|
|
42
66
|
Maximum 3 fix rounds. A 4th would mean the approach is wrong → auto-escalate to `replan`.
|
|
43
67
|
|
|
44
|
-
## Sub-agent dispatch (
|
|
68
|
+
## Sub-agent dispatch (ALWAYS)
|
|
69
|
+
|
|
70
|
+
<HARD-GATE>
|
|
71
|
+
REVIEW ALWAYS USES SUB-AGENTS regardless of the number of changed files. This prevents
|
|
72
|
+
context pollution in the main agent's window. You MUST NOT review code inline — dispatch
|
|
73
|
+
sub-agents for every review.
|
|
74
|
+
</HARD-GATE>
|
|
45
75
|
|
|
46
|
-
|
|
47
|
-
review in parallel sub-agents:
|
|
76
|
+
Dispatch two parallel review sub-agents:
|
|
48
77
|
- R1: correctness — does the implementation match the dev-spec requirement?
|
|
49
78
|
- R2: compliance — does the code obey RULES?
|
|
50
79
|
|
|
51
|
-
Each sub-agent returns `{dimension, findings[], severity, suggestion}`. The MAIN agent
|
|
52
|
-
and dedups findings and decides the verdict — sub-agents cannot trigger stage
|
|
53
|
-
|
|
80
|
+
Each sub-agent returns `{dimension, findings[], severity, suggestion}`. The MAIN agent
|
|
81
|
+
merges and dedups findings and decides the verdict — sub-agents cannot trigger stage
|
|
82
|
+
transitions.
|
|
54
83
|
|
|
55
|
-
|
|
84
|
+
Platform spawn rule: {{platform_spawn_instruction}}
|
|
56
85
|
|
|
57
86
|
## Output
|
|
58
87
|
|
|
@@ -31,5 +31,7 @@ when you recognize abandonment intent in the user's message.
|
|
|
31
31
|
|
|
32
32
|
- Never delete task folders — CLOSED tasks stay as a record.
|
|
33
33
|
- Never run the memory/archive flow.
|
|
34
|
+
- This skill closes the `current_task`. If the user wants to close a different (suspended)
|
|
35
|
+
task, they should first switch to it via ec-workflow, then invoke ec-task-close.
|
|
34
36
|
- Division of labor: ec-task-management lists/creates (read-only panel), ec-workflow runs the
|
|
35
37
|
stage machine, ec-task-close owns interruption. Stay in your lane.
|
|
@@ -13,9 +13,10 @@ Communicate with the user in the user's language.
|
|
|
13
13
|
## Capabilities
|
|
14
14
|
|
|
15
15
|
### List tasks
|
|
16
|
-
Scan `.easy-coding/tasks/`. For each task folder show: id, `
|
|
17
|
-
whether it is active (status not in {COMPLETE, CLOSED}). Group by active
|
|
18
|
-
user sees at a glance what is in flight. This is read-only — change
|
|
16
|
+
Scan `.easy-coding/tasks/`. For each task folder show: id, `title` (if present), `status`,
|
|
17
|
+
`created_at`, and whether it is active (status not in {COMPLETE, CLOSED}). Group by active
|
|
18
|
+
vs finished so the user sees at a glance what is in flight. This is read-only — change
|
|
19
|
+
nothing.
|
|
19
20
|
|
|
20
21
|
### Create a task
|
|
21
22
|
Create `.easy-coding/tasks/{MM-DD-short-name}/task.json` using the runtime schema:
|
|
@@ -23,6 +24,7 @@ Create `.easy-coding/tasks/{MM-DD-short-name}/task.json` using the runtime schem
|
|
|
23
24
|
```json
|
|
24
25
|
{
|
|
25
26
|
"type": "feature | bugfix | refactor | perf",
|
|
27
|
+
"title": "<one-line summary of the task>",
|
|
26
28
|
"status": "INIT",
|
|
27
29
|
"created_at": "<ISO 8601>",
|
|
28
30
|
"created_by": "<agent id>",
|
|
@@ -24,15 +24,20 @@ NO AUTO-ARCHIVE WITHOUT USER ACCEPTANCE
|
|
|
24
24
|
- An unaccepted task's memory is dirty data.
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
## 1. Run the gate (parallel)
|
|
27
|
+
## 1. Run the gate (parallel, always sub-agents)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
<HARD-GATE>
|
|
30
|
+
VERIFICATION ALWAYS USES SUB-AGENTS for each check. This prevents context pollution and
|
|
31
|
+
ensures true parallelism. You MUST NOT run lint/typecheck/test inline in the main agent.
|
|
32
|
+
</HARD-GATE>
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
Dispatch three sub-agents concurrently (one per check):
|
|
35
|
+
1. V1: lint (eslint/biome/project linter)
|
|
36
|
+
2. V2: typecheck (`tsc --noEmit` or equivalent)
|
|
37
|
+
3. V3: test (project test command)
|
|
38
|
+
|
|
39
|
+
Each sub-agent runs its command and returns `{check, passed, failures[]}`.
|
|
40
|
+
Platform spawn rule: {{platform_spawn_instruction}}
|
|
36
41
|
|
|
37
42
|
Append one `verify` record per check:
|
|
38
43
|
`{"type":"verify","check":"test","passed":true}` (add `"failures":[...]` on failure).
|
|
@@ -23,15 +23,39 @@ replies are English.
|
|
|
23
23
|
- `.easy-coding/RULES.md` — coding rules; re-checked before every write.
|
|
24
24
|
- Latest 5 entries in `.easy-coding/memory/short/` — recent task context.
|
|
25
25
|
Do NOT bulk-read ABSTRACT.md or long memory here; ec-analysis loads them on demand.
|
|
26
|
-
3. **State check.** Read `
|
|
27
|
-
-
|
|
28
|
-
|
|
26
|
+
3. **State check + Intent routing.** Read the hook-injected breadcrumbs (`[current-task:X]`,
|
|
27
|
+
`[workflow-state:Y]`) to determine the active task and stage, then decide based on
|
|
28
|
+
whether the user's message carries a task-related prompt beyond the bare skill trigger.
|
|
29
|
+
|
|
30
|
+
**No prompt (bare trigger):**
|
|
31
|
+
- `current_task` set with an active stage → resume that stage (see Resume and handoff).
|
|
32
|
+
- `current_task` null → scan `.easy-coding/tasks/` for tasks whose status is not in
|
|
29
33
|
{COMPLETE, CLOSED}. Found → list them, let the user pick one to resume or start new.
|
|
30
34
|
None → ready for a new task.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
|
|
36
|
+
**With prompt — intent routing:**
|
|
37
|
+
1. Collect all non-terminal tasks in `.easy-coding/tasks/`: read each task's folder name,
|
|
38
|
+
`task.json` fields (`title`, `type`, `status`). If a task passed ANALYSIS, also read
|
|
39
|
+
its dev-spec title line as extra matching signal.
|
|
40
|
+
2. Match the user's prompt against these identifiers (semantic match — the user saying
|
|
41
|
+
"继续做搜索" should match a task titled "添加搜索功能").
|
|
42
|
+
3. Route:
|
|
43
|
+
- Prompt matches `current_task` → resume with the prompt as additional context (the
|
|
44
|
+
user may be providing supplementary info, a revision request, or an answer to a
|
|
45
|
+
previous question).
|
|
46
|
+
- Prompt matches a different non-terminal task → ask the user: "Switch to «{matched
|
|
47
|
+
task title}»? Current task «{current task title}» will be suspended at {stage}."
|
|
48
|
+
On confirmation, perform a task switch (see Task switching below).
|
|
49
|
+
- Prompt matches no existing task AND `current_task` is set → ask the user: "Start a
|
|
50
|
+
new task? Current task «{current task title}» will be suspended at {stage}."
|
|
51
|
+
On confirmation, create the new task (step 4).
|
|
52
|
+
- Prompt matches no existing task AND `current_task` is null → create the new task
|
|
53
|
+
directly (step 4).
|
|
54
|
+
|
|
55
|
+
4. **New task.** When creating a task (from step 3), create
|
|
56
|
+
`.easy-coding/tasks/{MM-DD-task-slug}/task.json` with `type`, `title` (one-line summary
|
|
57
|
+
of the user's prompt), `status:"INIT"`, `created_at`, `created_by` (current agent id),
|
|
58
|
+
set `current_task` in state.json, and enter INIT.
|
|
35
59
|
|
|
36
60
|
## State machine
|
|
37
61
|
|
|
@@ -59,6 +83,18 @@ any stage --[user abort via ec-task-close]--> CLOSED
|
|
|
59
83
|
| COMPLETE | ec-workflow | clear current_task, set task status, summary | terminal |
|
|
60
84
|
| CLOSED | ec-task-close | user abort; no memory flow | terminal |
|
|
61
85
|
|
|
86
|
+
## Task switching
|
|
87
|
+
|
|
88
|
+
When the user confirms switching from task A to task B:
|
|
89
|
+
1. Task A's status is already persisted in its `task.json` — nothing extra to save.
|
|
90
|
+
2. Set `current_task` to task B's id in the session file (`.easy-coding/sessions/{ppid}.json`).
|
|
91
|
+
3. Read task B's `task.json` to determine its current stage.
|
|
92
|
+
4. Resume task B's stage via the appropriate stage skill.
|
|
93
|
+
|
|
94
|
+
No data is lost — task A's dev-spec, execution.jsonl, and test-strategy.md stay intact on
|
|
95
|
+
disk. To return to task A later, the same intent routing applies: the user mentions it,
|
|
96
|
+
routing matches, and switching happens again.
|
|
97
|
+
|
|
62
98
|
## Transition rules (hard)
|
|
63
99
|
|
|
64
100
|
- **Never skip a stage.** ANALYSIS cannot jump to VERIFICATION; IMPLEMENT cannot start before
|
|
@@ -68,26 +104,32 @@ any stage --[user abort via ec-task-close]--> CLOSED
|
|
|
68
104
|
analysis conclusion and the test strategy. Silence, enthusiasm, or a topic change is not
|
|
69
105
|
confirmation. Sole exception: `behavior.auto_mode: true` in `.easy-coding/config.yaml`
|
|
70
106
|
AND the user asked for autonomous execution.
|
|
71
|
-
- **On every transition** update `
|
|
72
|
-
set `
|
|
107
|
+
- **On every transition** update the active task's `task.json` immediately (not at turn end):
|
|
108
|
+
set `status` to the new stage, append `{stage, agent, entered_at}` to `stage_history`, set
|
|
73
109
|
`last_agent` to the current agent id (`claude-code` / `codex` / `qoder`).
|
|
110
|
+
- **Hook enforcement.** The `inject-workflow-state` hook validates every stage transition
|
|
111
|
+
against the state machine. If you see `[ILLEGAL-TRANSITION:...]` in the injected context,
|
|
112
|
+
you MUST revert the task's status to the previous valid stage and explain why the
|
|
113
|
+
transition was rejected. Do not proceed with an illegal stage.
|
|
74
114
|
- **Repair loop sizing** (user acceptance window after VERIFICATION): a trivial tweak
|
|
75
115
|
(one-line style fix, copy text) is fixed inside VERIFICATION and re-verified; a logic or
|
|
76
116
|
structure change formally returns to IMPLEMENT and re-walks REVIEW → VERIFICATION.
|
|
77
117
|
- **Scope guard** (repair loop): if the user's fix request falls outside the dev-spec scope
|
|
78
118
|
(features or files absent from the change-scope table), say so explicitly and propose a
|
|
79
119
|
new task with `spawned_from` set to the current task id. Never silently absorb scope creep.
|
|
120
|
+
- **Task switching is allowed at any stage.** The suspended task retains its stage in
|
|
121
|
+
task.json. Do not run memory flows for suspended tasks — only completed tasks get archived.
|
|
80
122
|
- **Archive only after user acceptance.** VERIFICATION passing does not complete the task.
|
|
81
123
|
After the user accepts, MEMORY_SHORT → MEMORY_LONG → COMPLETE run automatically.
|
|
82
|
-
- **COMPLETE closeout:** set task.json `status:"COMPLETE"`, clear `current_task` in
|
|
83
|
-
|
|
124
|
+
- **COMPLETE closeout:** set task.json `status:"COMPLETE"`, clear `current_task` in the
|
|
125
|
+
session file, output a summary (what was done, files changed, key decisions).
|
|
84
126
|
|
|
85
127
|
## Resume and handoff
|
|
86
128
|
|
|
87
129
|
Hook breadcrumbs you may receive: `[workflow-state:X]`, `[current-task:Y]`,
|
|
88
130
|
`[easy-coding:handoff-from:Z]`, `[easy-coding:init-required]`.
|
|
89
131
|
|
|
90
|
-
Resuming an active task:
|
|
132
|
+
Resuming an active task (whether from session restart, handoff, or task switch):
|
|
91
133
|
1. Read `task.json` and the dev-spec sections relevant to the current stage.
|
|
92
134
|
2. Read the tail of `execution.jsonl` — the latest `plan` / `result` / `verify` / `handoff`
|
|
93
135
|
records tell you exactly where work stopped.
|
|
@@ -95,13 +137,16 @@ Resuming an active task:
|
|
|
95
137
|
latest `handoff` record first for the fast summary, then set `last_agent` to yourself.
|
|
96
138
|
4. Tell the user what is being resumed and from which stage, then continue.
|
|
97
139
|
|
|
140
|
+
After a task switch, the same resume flow applies — the only difference is that `current_task`
|
|
141
|
+
was just changed by the switching procedure rather than being loaded from a prior session.
|
|
142
|
+
|
|
98
143
|
Offering handoff — at WAITING_CONFIRM, after presenting the plan, offer exactly:
|
|
99
144
|
1. Start implementation
|
|
100
145
|
2. Hand off to another agent
|
|
101
146
|
3. Revise the plan
|
|
102
147
|
On option 2: append a `handoff` record to `execution.jsonl` —
|
|
103
148
|
`{"type":"handoff","from":"<agent>","stage":"<stage>","summary":"<dense context: plan shape, key decisions, user emphases>","timestamp":"<ISO>"}` —
|
|
104
|
-
update
|
|
149
|
+
update the task's `last_agent` in task.json, then tell the user to open the target agent and run ec-workflow there.
|
|
105
150
|
Handoff is also legal at any other stage boundary on user request. The harness never
|
|
106
151
|
switches agents by itself.
|
|
107
152
|
|
|
@@ -11,12 +11,12 @@ user in the user's language.
|
|
|
11
11
|
Start every work reply with the single Markdown blockquote status line injected by the hook,
|
|
12
12
|
then a blank line. Do not render the machine breadcrumbs to the user.
|
|
13
13
|
|
|
14
|
-
- Ready: > **Easy Coding** · Ready · Use `ec-
|
|
14
|
+
- Ready: > **Easy Coding** · Ready · Use `ec-workflow` to start or resume a task, `ec-brainstorming` to brainstorm, or `ec-task-management` to view tasks
|
|
15
15
|
- Waiting init: > **Easy Coding** · Waiting init · Use `ec-init` to initialize
|
|
16
16
|
- Active task: > **Easy Coding** · `{current-task}` · `{workflow-state}`
|
|
17
17
|
- Handoff: > **Easy Coding** · `{current-task}` · `{workflow-state}` · Handoff -> `{source-agent}`
|
|
18
18
|
|
|
19
|
-
Skill names in the status line are bare names (`ec-init`, `ec-
|
|
19
|
+
Skill names in the status line are bare names (`ec-init`, `ec-workflow`) and never include
|
|
20
20
|
platform prefixes such as `/` or `$`. If no status line is injected, do not invent one.
|
|
21
21
|
|
|
22
22
|
## Skills
|
|
@@ -11,12 +11,12 @@ user in the user's language.
|
|
|
11
11
|
Start every work reply with the single Markdown blockquote status line injected by the hook,
|
|
12
12
|
then a blank line. Do not render the machine breadcrumbs to the user.
|
|
13
13
|
|
|
14
|
-
- Ready: > **Easy Coding** · Ready · Use `ec-
|
|
14
|
+
- Ready: > **Easy Coding** · Ready · Use `ec-workflow` to start or resume a task, `ec-brainstorming` to brainstorm, or `ec-task-management` to view tasks
|
|
15
15
|
- Waiting init: > **Easy Coding** · Waiting init · Use `ec-init` to initialize
|
|
16
16
|
- Active task: > **Easy Coding** · `{current-task}` · `{workflow-state}`
|
|
17
17
|
- Handoff: > **Easy Coding** · `{current-task}` · `{workflow-state}` · Handoff -> `{source-agent}`
|
|
18
18
|
|
|
19
|
-
Skill names in the status line are bare names (`ec-init`, `ec-
|
|
19
|
+
Skill names in the status line are bare names (`ec-init`, `ec-workflow`) and never include
|
|
20
20
|
platform prefixes such as `/` or `$`. If no status line is injected, do not invent one.
|
|
21
21
|
|
|
22
22
|
## Skills
|