edit プロパティによるファイル編集制御、ステップ完了時のレポートログ出力、resolveContentPath 追加
- edit: true/false をワークフローステップに追加し、エージェントへの編集許可/禁止プロンプトを自動注入 - ステップ完了時に step:report イベントを発火し、レポート内容をコンソール出力 - resolveContentPath() で format/instruction_template の .md ファイル参照に対応 - writeStepReport() を削除し、レポート出力はエージェント責務に統一 - 全8ワークフローYAMLに edit フィールドを付与 resolves #6, resolves #21, resolves #22
This commit is contained in:
parent
6fe6491948
commit
706a59d3b6
@ -28,6 +28,7 @@ initial_step: plan
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -91,6 +92,7 @@ steps:
|
|||||||
3. Decide implementation approach
|
3. Decide implementation approach
|
||||||
|
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -149,6 +151,7 @@ steps:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -202,6 +205,7 @@ steps:
|
|||||||
- Scope creep detection
|
- Scope creep detection
|
||||||
|
|
||||||
- name: ai_fix
|
- name: ai_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -231,6 +235,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: review
|
- name: review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/architecture-reviewer.md
|
agent: ~/.takt/agents/default/architecture-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-architect-review.md
|
name: 04-architect-review.md
|
||||||
@ -285,6 +290,7 @@ steps:
|
|||||||
Review the changes and provide feedback.
|
Review the changes and provide feedback.
|
||||||
|
|
||||||
- name: improve
|
- name: improve
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -316,6 +322,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: fix
|
- name: fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -342,6 +349,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: security_review
|
- name: security_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/security-reviewer.md
|
agent: ~/.takt/agents/default/security-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 05-security-review.md
|
name: 05-security-review.md
|
||||||
@ -398,6 +406,7 @@ steps:
|
|||||||
- Cryptographic weaknesses
|
- Cryptographic weaknesses
|
||||||
|
|
||||||
- name: security_fix
|
- name: security_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -423,6 +432,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/supervisor.md
|
agent: ~/.takt/agents/default/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 06-supervisor-validation.md
|
- Validation: 06-supervisor-validation.md
|
||||||
|
|||||||
@ -31,6 +31,7 @@ steps:
|
|||||||
# Phase 0: Planning
|
# Phase 0: Planning
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -91,6 +92,7 @@ steps:
|
|||||||
# Phase 1: Implementation
|
# Phase 1: Implementation
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -151,6 +153,7 @@ steps:
|
|||||||
# Phase 2: AI Review
|
# Phase 2: AI Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -204,6 +207,7 @@ steps:
|
|||||||
next: ai_fix
|
next: ai_fix
|
||||||
|
|
||||||
- name: ai_fix
|
- name: ai_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -235,6 +239,7 @@ steps:
|
|||||||
# Phase 3: CQRS+ES Review
|
# Phase 3: CQRS+ES Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: cqrs_es_review
|
- name: cqrs_es_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert-cqrs/cqrs-es-reviewer.md
|
agent: ~/.takt/agents/expert-cqrs/cqrs-es-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-cqrs-es-review.md
|
name: 04-cqrs-es-review.md
|
||||||
@ -292,6 +297,7 @@ steps:
|
|||||||
next: fix_cqrs_es
|
next: fix_cqrs_es
|
||||||
|
|
||||||
- name: fix_cqrs_es
|
- name: fix_cqrs_es
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -325,6 +331,7 @@ steps:
|
|||||||
# Phase 4: Frontend Review
|
# Phase 4: Frontend Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: frontend_review
|
- name: frontend_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 05-frontend-review.md
|
name: 05-frontend-review.md
|
||||||
@ -382,6 +389,7 @@ steps:
|
|||||||
next: fix_frontend
|
next: fix_frontend
|
||||||
|
|
||||||
- name: fix_frontend
|
- name: fix_frontend
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -415,6 +423,7 @@ steps:
|
|||||||
# Phase 5: Security Review
|
# Phase 5: Security Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: security_review
|
- name: security_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/security-reviewer.md
|
agent: ~/.takt/agents/expert/security-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 06-security-review.md
|
name: 06-security-review.md
|
||||||
@ -469,6 +478,7 @@ steps:
|
|||||||
next: fix_security
|
next: fix_security
|
||||||
|
|
||||||
- name: fix_security
|
- name: fix_security
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -512,6 +522,7 @@ steps:
|
|||||||
# Phase 6: QA Review
|
# Phase 6: QA Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: qa_review
|
- name: qa_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/qa-reviewer.md
|
agent: ~/.takt/agents/expert/qa-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 07-qa-review.md
|
name: 07-qa-review.md
|
||||||
@ -566,6 +577,7 @@ steps:
|
|||||||
next: fix_qa
|
next: fix_qa
|
||||||
|
|
||||||
- name: fix_qa
|
- name: fix_qa
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -613,6 +625,7 @@ steps:
|
|||||||
# Phase 7: Supervision
|
# Phase 7: Supervision
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/supervisor.md
|
agent: ~/.takt/agents/expert/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 08-supervisor-validation.md
|
- Validation: 08-supervisor-validation.md
|
||||||
@ -709,6 +722,7 @@ steps:
|
|||||||
next: fix_supervisor
|
next: fix_supervisor
|
||||||
|
|
||||||
- name: fix_supervisor
|
- name: fix_supervisor
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
|
|||||||
@ -43,6 +43,7 @@ steps:
|
|||||||
# Phase 0: Planning
|
# Phase 0: Planning
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -103,6 +104,7 @@ steps:
|
|||||||
# Phase 1: Implementation
|
# Phase 1: Implementation
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -163,6 +165,7 @@ steps:
|
|||||||
# Phase 2: AI Review
|
# Phase 2: AI Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -216,6 +219,7 @@ steps:
|
|||||||
next: ai_fix
|
next: ai_fix
|
||||||
|
|
||||||
- name: ai_fix
|
- name: ai_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -247,6 +251,7 @@ steps:
|
|||||||
# Phase 3: Architecture Review
|
# Phase 3: Architecture Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: architect_review
|
- name: architect_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/architecture-reviewer.md
|
agent: ~/.takt/agents/default/architecture-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-architect-review.md
|
name: 04-architect-review.md
|
||||||
@ -310,6 +315,7 @@ steps:
|
|||||||
next: fix_architect
|
next: fix_architect
|
||||||
|
|
||||||
- name: fix_architect
|
- name: fix_architect
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -339,6 +345,7 @@ steps:
|
|||||||
# Phase 4: Frontend Review
|
# Phase 4: Frontend Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: frontend_review
|
- name: frontend_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 05-frontend-review.md
|
name: 05-frontend-review.md
|
||||||
@ -396,6 +403,7 @@ steps:
|
|||||||
next: fix_frontend
|
next: fix_frontend
|
||||||
|
|
||||||
- name: fix_frontend
|
- name: fix_frontend
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -429,6 +437,7 @@ steps:
|
|||||||
# Phase 5: Security Review
|
# Phase 5: Security Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: security_review
|
- name: security_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/security-reviewer.md
|
agent: ~/.takt/agents/expert/security-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 06-security-review.md
|
name: 06-security-review.md
|
||||||
@ -483,6 +492,7 @@ steps:
|
|||||||
next: fix_security
|
next: fix_security
|
||||||
|
|
||||||
- name: fix_security
|
- name: fix_security
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -526,6 +536,7 @@ steps:
|
|||||||
# Phase 6: QA Review
|
# Phase 6: QA Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: qa_review
|
- name: qa_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/qa-reviewer.md
|
agent: ~/.takt/agents/expert/qa-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 07-qa-review.md
|
name: 07-qa-review.md
|
||||||
@ -580,6 +591,7 @@ steps:
|
|||||||
next: fix_qa
|
next: fix_qa
|
||||||
|
|
||||||
- name: fix_qa
|
- name: fix_qa
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -627,6 +639,7 @@ steps:
|
|||||||
# Phase 7: Supervision
|
# Phase 7: Supervision
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/supervisor.md
|
agent: ~/.takt/agents/expert/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 08-supervisor-validation.md
|
- Validation: 08-supervisor-validation.md
|
||||||
@ -723,6 +736,7 @@ steps:
|
|||||||
next: fix_supervisor
|
next: fix_supervisor
|
||||||
|
|
||||||
- name: fix_supervisor
|
- name: fix_supervisor
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
|
|||||||
@ -25,6 +25,7 @@ initial_step: plan
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -84,6 +85,7 @@ steps:
|
|||||||
3. Decide implementation approach
|
3. Decide implementation approach
|
||||||
|
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -142,6 +144,7 @@ steps:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -195,6 +198,7 @@ steps:
|
|||||||
- Scope creep detection
|
- Scope creep detection
|
||||||
|
|
||||||
- name: review
|
- name: review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/architecture-reviewer.md
|
agent: ~/.takt/agents/default/architecture-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-architect-review.md
|
name: 04-architect-review.md
|
||||||
@ -250,6 +254,7 @@ steps:
|
|||||||
If there are minor suggestions, use APPROVE + comments.
|
If there are minor suggestions, use APPROVE + comments.
|
||||||
|
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/supervisor.md
|
agent: ~/.takt/agents/default/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 05-supervisor-validation.md
|
- Validation: 05-supervisor-validation.md
|
||||||
|
|||||||
@ -19,6 +19,7 @@ initial_step: plan
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -82,6 +83,7 @@ steps:
|
|||||||
3. 実装アプローチを決める
|
3. 実装アプローチを決める
|
||||||
|
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -145,6 +147,7 @@ steps:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -198,6 +201,7 @@ steps:
|
|||||||
- スコープクリープの検出
|
- スコープクリープの検出
|
||||||
|
|
||||||
- name: ai_fix
|
- name: ai_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -227,6 +231,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: review
|
- name: review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/architecture-reviewer.md
|
agent: ~/.takt/agents/default/architecture-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-architect-review.md
|
name: 04-architect-review.md
|
||||||
@ -292,6 +297,7 @@ steps:
|
|||||||
- 呼び出しチェーン検証
|
- 呼び出しチェーン検証
|
||||||
|
|
||||||
- name: improve
|
- name: improve
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -323,6 +329,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: fix
|
- name: fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -348,6 +355,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: security_review
|
- name: security_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/security-reviewer.md
|
agent: ~/.takt/agents/default/security-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 05-security-review.md
|
name: 05-security-review.md
|
||||||
@ -404,6 +412,7 @@ steps:
|
|||||||
- 暗号化の弱点
|
- 暗号化の弱点
|
||||||
|
|
||||||
- name: security_fix
|
- name: security_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -429,6 +438,7 @@ steps:
|
|||||||
pass_previous_response: true
|
pass_previous_response: true
|
||||||
|
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/supervisor.md
|
agent: ~/.takt/agents/default/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 06-supervisor-validation.md
|
- Validation: 06-supervisor-validation.md
|
||||||
|
|||||||
@ -40,6 +40,7 @@ steps:
|
|||||||
# Phase 0: Planning
|
# Phase 0: Planning
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -100,6 +101,7 @@ steps:
|
|||||||
# Phase 1: Implementation
|
# Phase 1: Implementation
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -117,7 +119,7 @@ steps:
|
|||||||
planステップで立てた計画に従って実装してください。
|
planステップで立てた計画に従って実装してください。
|
||||||
計画レポート(00-plan.md)を参照し、実装を進めてください。
|
計画レポート(00-plan.md)を参照し、実装を進めてください。
|
||||||
|
|
||||||
**レポート出力:** 上記の `Report Files` に出力してください。
|
**レポート出力:** Report Files に出力してください。
|
||||||
- ファイルが存在しない場合: 新規作成
|
- ファイルが存在しない場合: 新規作成
|
||||||
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
||||||
|
|
||||||
@ -160,6 +162,7 @@ steps:
|
|||||||
# Phase 2: AI Review
|
# Phase 2: AI Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -213,6 +216,7 @@ steps:
|
|||||||
next: ai_fix
|
next: ai_fix
|
||||||
|
|
||||||
- name: ai_fix
|
- name: ai_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -244,6 +248,7 @@ steps:
|
|||||||
# Phase 3: CQRS+ES Review
|
# Phase 3: CQRS+ES Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: cqrs_es_review
|
- name: cqrs_es_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert-cqrs/cqrs-es-reviewer.md
|
agent: ~/.takt/agents/expert-cqrs/cqrs-es-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-cqrs-es-review.md
|
name: 04-cqrs-es-review.md
|
||||||
@ -301,6 +306,7 @@ steps:
|
|||||||
next: fix_cqrs_es
|
next: fix_cqrs_es
|
||||||
|
|
||||||
- name: fix_cqrs_es
|
- name: fix_cqrs_es
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -334,6 +340,7 @@ steps:
|
|||||||
# Phase 4: Frontend Review
|
# Phase 4: Frontend Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: frontend_review
|
- name: frontend_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 05-frontend-review.md
|
name: 05-frontend-review.md
|
||||||
@ -391,6 +398,7 @@ steps:
|
|||||||
next: fix_frontend
|
next: fix_frontend
|
||||||
|
|
||||||
- name: fix_frontend
|
- name: fix_frontend
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -424,6 +432,7 @@ steps:
|
|||||||
# Phase 5: Security Review
|
# Phase 5: Security Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: security_review
|
- name: security_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/security-reviewer.md
|
agent: ~/.takt/agents/expert/security-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 06-security-review.md
|
name: 06-security-review.md
|
||||||
@ -478,6 +487,7 @@ steps:
|
|||||||
next: fix_security
|
next: fix_security
|
||||||
|
|
||||||
- name: fix_security
|
- name: fix_security
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -521,6 +531,7 @@ steps:
|
|||||||
# Phase 6: QA Review
|
# Phase 6: QA Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: qa_review
|
- name: qa_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/qa-reviewer.md
|
agent: ~/.takt/agents/expert/qa-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 07-qa-review.md
|
name: 07-qa-review.md
|
||||||
@ -575,6 +586,7 @@ steps:
|
|||||||
next: fix_qa
|
next: fix_qa
|
||||||
|
|
||||||
- name: fix_qa
|
- name: fix_qa
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -622,6 +634,7 @@ steps:
|
|||||||
# Phase 7: Supervision
|
# Phase 7: Supervision
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/supervisor.md
|
agent: ~/.takt/agents/expert/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 08-supervisor-validation.md
|
- Validation: 08-supervisor-validation.md
|
||||||
@ -652,7 +665,7 @@ steps:
|
|||||||
**レポートの確認:** Report Directory内の全レポートを読み、
|
**レポートの確認:** Report Directory内の全レポートを読み、
|
||||||
未対応の改善提案がないか確認してください。
|
未対応の改善提案がないか確認してください。
|
||||||
|
|
||||||
**レポート出力:** 上記の `Report Files` に出力してください。
|
**レポート出力:** Report Files に出力してください。
|
||||||
- ファイルが存在しない場合: 新規作成
|
- ファイルが存在しない場合: 新規作成
|
||||||
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
||||||
|
|
||||||
@ -718,6 +731,7 @@ steps:
|
|||||||
next: fix_supervisor
|
next: fix_supervisor
|
||||||
|
|
||||||
- name: fix_supervisor
|
- name: fix_supervisor
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
|
|||||||
@ -31,6 +31,7 @@ steps:
|
|||||||
# Phase 0: Planning
|
# Phase 0: Planning
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -91,6 +92,7 @@ steps:
|
|||||||
# Phase 1: Implementation
|
# Phase 1: Implementation
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -108,7 +110,7 @@ steps:
|
|||||||
planステップで立てた計画に従って実装してください。
|
planステップで立てた計画に従って実装してください。
|
||||||
計画レポート(00-plan.md)を参照し、実装を進めてください。
|
計画レポート(00-plan.md)を参照し、実装を進めてください。
|
||||||
|
|
||||||
**レポート出力:** 上記の `Report Files` に出力してください。
|
**レポート出力:** Report Files に出力してください。
|
||||||
- ファイルが存在しない場合: 新規作成
|
- ファイルが存在しない場合: 新規作成
|
||||||
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
||||||
|
|
||||||
@ -151,6 +153,7 @@ steps:
|
|||||||
# Phase 2: AI Review
|
# Phase 2: AI Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -204,6 +207,7 @@ steps:
|
|||||||
next: ai_fix
|
next: ai_fix
|
||||||
|
|
||||||
- name: ai_fix
|
- name: ai_fix
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -235,6 +239,7 @@ steps:
|
|||||||
# Phase 3: Architecture Review
|
# Phase 3: Architecture Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: architect_review
|
- name: architect_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/architecture-reviewer.md
|
agent: ~/.takt/agents/default/architecture-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-architect-review.md
|
name: 04-architect-review.md
|
||||||
@ -298,6 +303,7 @@ steps:
|
|||||||
next: fix_architect
|
next: fix_architect
|
||||||
|
|
||||||
- name: fix_architect
|
- name: fix_architect
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -327,6 +333,7 @@ steps:
|
|||||||
# Phase 4: Frontend Review
|
# Phase 4: Frontend Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: frontend_review
|
- name: frontend_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
agent: ~/.takt/agents/expert/frontend-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 05-frontend-review.md
|
name: 05-frontend-review.md
|
||||||
@ -384,6 +391,7 @@ steps:
|
|||||||
next: fix_frontend
|
next: fix_frontend
|
||||||
|
|
||||||
- name: fix_frontend
|
- name: fix_frontend
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -417,6 +425,7 @@ steps:
|
|||||||
# Phase 5: Security Review
|
# Phase 5: Security Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: security_review
|
- name: security_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/security-reviewer.md
|
agent: ~/.takt/agents/expert/security-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 06-security-review.md
|
name: 06-security-review.md
|
||||||
@ -471,6 +480,7 @@ steps:
|
|||||||
next: fix_security
|
next: fix_security
|
||||||
|
|
||||||
- name: fix_security
|
- name: fix_security
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -514,6 +524,7 @@ steps:
|
|||||||
# Phase 6: QA Review
|
# Phase 6: QA Review
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: qa_review
|
- name: qa_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/qa-reviewer.md
|
agent: ~/.takt/agents/expert/qa-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 07-qa-review.md
|
name: 07-qa-review.md
|
||||||
@ -568,6 +579,7 @@ steps:
|
|||||||
next: fix_qa
|
next: fix_qa
|
||||||
|
|
||||||
- name: fix_qa
|
- name: fix_qa
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
@ -615,6 +627,7 @@ steps:
|
|||||||
# Phase 7: Supervision
|
# Phase 7: Supervision
|
||||||
# ===========================================
|
# ===========================================
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/expert/supervisor.md
|
agent: ~/.takt/agents/expert/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 08-supervisor-validation.md
|
- Validation: 08-supervisor-validation.md
|
||||||
@ -645,7 +658,7 @@ steps:
|
|||||||
**レポートの確認:** Report Directory内の全レポートを読み、
|
**レポートの確認:** Report Directory内の全レポートを読み、
|
||||||
未対応の改善提案がないか確認してください。
|
未対応の改善提案がないか確認してください。
|
||||||
|
|
||||||
**レポート出力:** 上記の `Report Files` に出力してください。
|
**レポート出力:** Report Files に出力してください。
|
||||||
- ファイルが存在しない場合: 新規作成
|
- ファイルが存在しない場合: 新規作成
|
||||||
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
||||||
|
|
||||||
@ -711,6 +724,7 @@ steps:
|
|||||||
next: fix_supervisor
|
next: fix_supervisor
|
||||||
|
|
||||||
- name: fix_supervisor
|
- name: fix_supervisor
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
allowed_tools:
|
allowed_tools:
|
||||||
- Read
|
- Read
|
||||||
|
|||||||
@ -20,6 +20,7 @@ initial_step: plan
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: plan
|
- name: plan
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/planner.md
|
agent: ~/.takt/agents/default/planner.md
|
||||||
report:
|
report:
|
||||||
name: 00-plan.md
|
name: 00-plan.md
|
||||||
@ -83,6 +84,7 @@ steps:
|
|||||||
- {質問2}
|
- {質問2}
|
||||||
|
|
||||||
- name: implement
|
- name: implement
|
||||||
|
edit: true
|
||||||
agent: ~/.takt/agents/default/coder.md
|
agent: ~/.takt/agents/default/coder.md
|
||||||
report:
|
report:
|
||||||
- Scope: 01-coder-scope.md
|
- Scope: 01-coder-scope.md
|
||||||
@ -101,6 +103,10 @@ steps:
|
|||||||
planステップで立てた計画に従って実装してください。
|
planステップで立てた計画に従って実装してください。
|
||||||
計画レポート(00-plan.md)を参照し、実装を進めてください。
|
計画レポート(00-plan.md)を参照し、実装を進めてください。
|
||||||
|
|
||||||
|
**レポート出力:** Report Files に出力してください。
|
||||||
|
- ファイルが存在しない場合: 新規作成
|
||||||
|
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
||||||
|
|
||||||
**Scopeレポートフォーマット(実装開始時に作成):**
|
**Scopeレポートフォーマット(実装開始時に作成):**
|
||||||
```markdown
|
```markdown
|
||||||
# 変更スコープ宣言
|
# 変更スコープ宣言
|
||||||
@ -137,6 +143,7 @@ steps:
|
|||||||
next: plan
|
next: plan
|
||||||
|
|
||||||
- name: ai_review
|
- name: ai_review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
agent: ~/.takt/agents/default/ai-antipattern-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 03-ai-review.md
|
name: 03-ai-review.md
|
||||||
@ -190,6 +197,7 @@ steps:
|
|||||||
next: plan
|
next: plan
|
||||||
|
|
||||||
- name: review
|
- name: review
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/architecture-reviewer.md
|
agent: ~/.takt/agents/default/architecture-reviewer.md
|
||||||
report:
|
report:
|
||||||
name: 04-architect-review.md
|
name: 04-architect-review.md
|
||||||
@ -245,6 +253,7 @@ steps:
|
|||||||
next: plan
|
next: plan
|
||||||
|
|
||||||
- name: supervise
|
- name: supervise
|
||||||
|
edit: false
|
||||||
agent: ~/.takt/agents/default/supervisor.md
|
agent: ~/.takt/agents/default/supervisor.md
|
||||||
report:
|
report:
|
||||||
- Validation: 05-supervisor-validation.md
|
- Validation: 05-supervisor-validation.md
|
||||||
@ -268,6 +277,10 @@ steps:
|
|||||||
**レポートの確認:** Report Directory内の全レポートを読み、
|
**レポートの確認:** Report Directory内の全レポートを読み、
|
||||||
未対応の改善提案がないか確認してください。
|
未対応の改善提案がないか確認してください。
|
||||||
|
|
||||||
|
**レポート出力:** Report Files に出力してください。
|
||||||
|
- ファイルが存在しない場合: 新規作成
|
||||||
|
- ファイルが存在する場合: `## Iteration {step_iteration}` セクションを追記
|
||||||
|
|
||||||
**Validationレポートフォーマット:**
|
**Validationレポートフォーマット:**
|
||||||
```markdown
|
```markdown
|
||||||
# 最終検証結果
|
# 最終検証結果
|
||||||
|
|||||||
175
src/__tests__/engine-report.test.ts
Normal file
175
src/__tests__/engine-report.test.ts
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/**
|
||||||
|
* Tests for engine report event emission (step:report)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||||
|
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
import { tmpdir } from 'node:os';
|
||||||
|
import { EventEmitter } from 'node:events';
|
||||||
|
import { existsSync } from 'node:fs';
|
||||||
|
import { isReportObjectConfig } from '../workflow/instruction-builder.js';
|
||||||
|
import type { WorkflowStep, ReportObjectConfig, ReportConfig } from '../models/types.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracted emitStepReports logic for unit testing.
|
||||||
|
* Mirrors engine.ts emitStepReports + emitIfReportExists.
|
||||||
|
*/
|
||||||
|
function emitStepReports(
|
||||||
|
emitter: EventEmitter,
|
||||||
|
step: WorkflowStep,
|
||||||
|
reportDir: string,
|
||||||
|
projectCwd: string,
|
||||||
|
): void {
|
||||||
|
if (!step.report || !reportDir) return;
|
||||||
|
const baseDir = join(projectCwd, '.takt', 'reports', reportDir);
|
||||||
|
|
||||||
|
if (typeof step.report === 'string') {
|
||||||
|
emitIfReportExists(emitter, step, baseDir, step.report);
|
||||||
|
} else if (isReportObjectConfig(step.report)) {
|
||||||
|
emitIfReportExists(emitter, step, baseDir, step.report.name);
|
||||||
|
} else {
|
||||||
|
for (const rc of step.report) {
|
||||||
|
emitIfReportExists(emitter, step, baseDir, rc.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitIfReportExists(
|
||||||
|
emitter: EventEmitter,
|
||||||
|
step: WorkflowStep,
|
||||||
|
baseDir: string,
|
||||||
|
fileName: string,
|
||||||
|
): void {
|
||||||
|
const filePath = join(baseDir, fileName);
|
||||||
|
if (existsSync(filePath)) {
|
||||||
|
emitter.emit('step:report', step, filePath, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a minimal WorkflowStep for testing */
|
||||||
|
function createStep(overrides: Partial<WorkflowStep> = {}): WorkflowStep {
|
||||||
|
return {
|
||||||
|
name: 'test-step',
|
||||||
|
agent: 'coder',
|
||||||
|
agentDisplayName: 'Coder',
|
||||||
|
instructionTemplate: '',
|
||||||
|
passPreviousResponse: false,
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('emitStepReports', () => {
|
||||||
|
let tmpDir: string;
|
||||||
|
let reportBaseDir: string;
|
||||||
|
const reportDirName = 'test-report-dir';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tmpDir = join(tmpdir(), `takt-report-test-${Date.now()}`);
|
||||||
|
reportBaseDir = join(tmpDir, '.takt', 'reports', reportDirName);
|
||||||
|
mkdirSync(reportBaseDir, { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rmSync(tmpDir, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit step:report when string report file exists', () => {
|
||||||
|
// Given: a step with string report and the file exists
|
||||||
|
const step = createStep({ report: 'plan.md' });
|
||||||
|
writeFileSync(join(reportBaseDir, 'plan.md'), '# Plan', 'utf-8');
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const handler = vi.fn();
|
||||||
|
emitter.on('step:report', handler);
|
||||||
|
|
||||||
|
// When
|
||||||
|
emitStepReports(emitter, step, reportDirName, tmpDir);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(handler).toHaveBeenCalledOnce();
|
||||||
|
expect(handler).toHaveBeenCalledWith(step, join(reportBaseDir, 'plan.md'), 'plan.md');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit when string report file does not exist', () => {
|
||||||
|
// Given: a step with string report but file doesn't exist
|
||||||
|
const step = createStep({ report: 'missing.md' });
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const handler = vi.fn();
|
||||||
|
emitter.on('step:report', handler);
|
||||||
|
|
||||||
|
// When
|
||||||
|
emitStepReports(emitter, step, reportDirName, tmpDir);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(handler).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit step:report when ReportObjectConfig report file exists', () => {
|
||||||
|
// Given: a step with ReportObjectConfig and the file exists
|
||||||
|
const report: ReportObjectConfig = { name: '03-review.md', format: '# Review' };
|
||||||
|
const step = createStep({ report });
|
||||||
|
writeFileSync(join(reportBaseDir, '03-review.md'), '# Review\nOK', 'utf-8');
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const handler = vi.fn();
|
||||||
|
emitter.on('step:report', handler);
|
||||||
|
|
||||||
|
// When
|
||||||
|
emitStepReports(emitter, step, reportDirName, tmpDir);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(handler).toHaveBeenCalledOnce();
|
||||||
|
expect(handler).toHaveBeenCalledWith(step, join(reportBaseDir, '03-review.md'), '03-review.md');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit for each existing file in ReportConfig[] array', () => {
|
||||||
|
// Given: a step with array report, two files exist, one missing
|
||||||
|
const report: ReportConfig[] = [
|
||||||
|
{ label: 'Scope', path: '01-scope.md' },
|
||||||
|
{ label: 'Decisions', path: '02-decisions.md' },
|
||||||
|
{ label: 'Missing', path: '03-missing.md' },
|
||||||
|
];
|
||||||
|
const step = createStep({ report });
|
||||||
|
writeFileSync(join(reportBaseDir, '01-scope.md'), '# Scope', 'utf-8');
|
||||||
|
writeFileSync(join(reportBaseDir, '02-decisions.md'), '# Decisions', 'utf-8');
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const handler = vi.fn();
|
||||||
|
emitter.on('step:report', handler);
|
||||||
|
|
||||||
|
// When
|
||||||
|
emitStepReports(emitter, step, reportDirName, tmpDir);
|
||||||
|
|
||||||
|
// Then: emitted for scope and decisions, not for missing
|
||||||
|
expect(handler).toHaveBeenCalledTimes(2);
|
||||||
|
expect(handler).toHaveBeenCalledWith(step, join(reportBaseDir, '01-scope.md'), '01-scope.md');
|
||||||
|
expect(handler).toHaveBeenCalledWith(step, join(reportBaseDir, '02-decisions.md'), '02-decisions.md');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit when step has no report', () => {
|
||||||
|
// Given: a step without report
|
||||||
|
const step = createStep({ report: undefined });
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const handler = vi.fn();
|
||||||
|
emitter.on('step:report', handler);
|
||||||
|
|
||||||
|
// When
|
||||||
|
emitStepReports(emitter, step, reportDirName, tmpDir);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(handler).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit when reportDir is empty', () => {
|
||||||
|
// Given: a step with report but empty reportDir
|
||||||
|
const step = createStep({ report: 'plan.md' });
|
||||||
|
writeFileSync(join(reportBaseDir, 'plan.md'), '# Plan', 'utf-8');
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
const handler = vi.fn();
|
||||||
|
emitter.on('step:report', handler);
|
||||||
|
|
||||||
|
// When: empty reportDir
|
||||||
|
emitStepReports(emitter, step, '', tmpDir);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(handler).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -9,6 +9,7 @@ import {
|
|||||||
renderExecutionMetadata,
|
renderExecutionMetadata,
|
||||||
renderStatusRulesHeader,
|
renderStatusRulesHeader,
|
||||||
generateStatusRulesFromRules,
|
generateStatusRulesFromRules,
|
||||||
|
isReportObjectConfig,
|
||||||
type InstructionContext,
|
type InstructionContext,
|
||||||
} from '../workflow/instruction-builder.js';
|
} from '../workflow/instruction-builder.js';
|
||||||
import type { WorkflowStep, WorkflowRule } from '../models/types.js';
|
import type { WorkflowStep, WorkflowRule } from '../models/types.js';
|
||||||
@ -75,6 +76,34 @@ describe('instruction-builder', () => {
|
|||||||
|
|
||||||
expect(metadataIndex).toBeLessThan(bodyIndex);
|
expect(metadataIndex).toBeLessThan(bodyIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should include edit enabled prompt when step.edit is true', () => {
|
||||||
|
const step = { ...createMinimalStep('Implement feature'), edit: true as const };
|
||||||
|
const context = createMinimalContext({ cwd: '/project' });
|
||||||
|
|
||||||
|
const result = buildInstruction(step, context);
|
||||||
|
|
||||||
|
expect(result).toContain('Editing is ENABLED');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include edit disabled prompt when step.edit is false', () => {
|
||||||
|
const step = { ...createMinimalStep('Review code'), edit: false as const };
|
||||||
|
const context = createMinimalContext({ cwd: '/project' });
|
||||||
|
|
||||||
|
const result = buildInstruction(step, context);
|
||||||
|
|
||||||
|
expect(result).toContain('Editing is DISABLED');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include edit prompt when step.edit is undefined', () => {
|
||||||
|
const step = createMinimalStep('Do some work');
|
||||||
|
const context = createMinimalContext({ cwd: '/project' });
|
||||||
|
|
||||||
|
const result = buildInstruction(step, context);
|
||||||
|
|
||||||
|
expect(result).not.toContain('Editing is ENABLED');
|
||||||
|
expect(result).not.toContain('Editing is DISABLED');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('report_dir replacement', () => {
|
describe('report_dir replacement', () => {
|
||||||
@ -176,6 +205,20 @@ describe('instruction-builder', () => {
|
|||||||
|
|
||||||
expect(metadata.language).toBe('ja');
|
expect(metadata.language).toBe('ja');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should propagate edit field when provided', () => {
|
||||||
|
const context = createMinimalContext({ cwd: '/project' });
|
||||||
|
|
||||||
|
expect(buildExecutionMetadata(context, true).edit).toBe(true);
|
||||||
|
expect(buildExecutionMetadata(context, false).edit).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should leave edit undefined when not provided', () => {
|
||||||
|
const context = createMinimalContext({ cwd: '/project' });
|
||||||
|
const metadata = buildExecutionMetadata(context);
|
||||||
|
|
||||||
|
expect(metadata.edit).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('renderExecutionMetadata', () => {
|
describe('renderExecutionMetadata', () => {
|
||||||
@ -212,6 +255,43 @@ describe('instruction-builder', () => {
|
|||||||
expect(enRendered).toContain('Note:');
|
expect(enRendered).toContain('Note:');
|
||||||
expect(jaRendered).not.toContain('Note:');
|
expect(jaRendered).not.toContain('Note:');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should include edit enabled prompt when edit is true (en)', () => {
|
||||||
|
const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'en', edit: true });
|
||||||
|
|
||||||
|
expect(rendered).toContain('Editing is ENABLED');
|
||||||
|
expect(rendered).not.toContain('Editing is DISABLED');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include edit disabled prompt when edit is false (en)', () => {
|
||||||
|
const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'en', edit: false });
|
||||||
|
|
||||||
|
expect(rendered).toContain('Editing is DISABLED');
|
||||||
|
expect(rendered).not.toContain('Editing is ENABLED');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not include edit prompt when edit is undefined', () => {
|
||||||
|
const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'en' });
|
||||||
|
|
||||||
|
expect(rendered).not.toContain('Editing is ENABLED');
|
||||||
|
expect(rendered).not.toContain('Editing is DISABLED');
|
||||||
|
expect(rendered).not.toContain('編集が許可');
|
||||||
|
expect(rendered).not.toContain('編集が禁止');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render edit enabled prompt in Japanese when language is ja', () => {
|
||||||
|
const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'ja', edit: true });
|
||||||
|
|
||||||
|
expect(rendered).toContain('編集が許可されています');
|
||||||
|
expect(rendered).not.toContain('編集が禁止');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render edit disabled prompt in Japanese when language is ja', () => {
|
||||||
|
const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'ja', edit: false });
|
||||||
|
|
||||||
|
expect(rendered).toContain('編集が禁止されています');
|
||||||
|
expect(rendered).not.toContain('編集が許可');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('renderStatusRulesHeader', () => {
|
describe('renderStatusRulesHeader', () => {
|
||||||
@ -746,4 +826,22 @@ describe('instruction-builder', () => {
|
|||||||
expect(result).toContain('Run #2');
|
expect(result).toContain('Run #2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isReportObjectConfig', () => {
|
||||||
|
it('should return true for ReportObjectConfig', () => {
|
||||||
|
expect(isReportObjectConfig({ name: '00-plan.md' })).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for ReportObjectConfig with order/format', () => {
|
||||||
|
expect(isReportObjectConfig({ name: '00-plan.md', order: 'output to...', format: '# Plan' })).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for string', () => {
|
||||||
|
expect(isReportObjectConfig('00-plan.md')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for ReportConfig[] (array)', () => {
|
||||||
|
expect(isReportObjectConfig([{ label: 'Scope', path: '01-scope.md' }])).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
* Workflow execution logic
|
* Workflow execution logic
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
import { WorkflowEngine } from '../workflow/engine.js';
|
import { WorkflowEngine } from '../workflow/engine.js';
|
||||||
import type { WorkflowConfig, Language } from '../models/types.js';
|
import type { WorkflowConfig, Language } from '../models/types.js';
|
||||||
import type { IterationLimitRequest } from '../workflow/types.js';
|
import type { IterationLimitRequest } from '../workflow/types.js';
|
||||||
@ -223,6 +224,12 @@ export async function executeWorkflow(
|
|||||||
updateLatestPointer(sessionLog, workflowSessionId, projectCwd);
|
updateLatestPointer(sessionLog, workflowSessionId, projectCwd);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
engine.on('step:report', (_step, filePath, fileName) => {
|
||||||
|
const content = readFileSync(filePath, 'utf-8');
|
||||||
|
console.log(`\n📄 Report: ${fileName}\n`);
|
||||||
|
console.log(content);
|
||||||
|
});
|
||||||
|
|
||||||
engine.on('workflow:complete', (state) => {
|
engine.on('workflow:complete', (state) => {
|
||||||
log.info('Workflow completed successfully', { iterations: state.iteration });
|
log.info('Workflow completed successfully', { iterations: state.iteration });
|
||||||
finalizeSessionLog(sessionLog, 'completed');
|
finalizeSessionLog(sessionLog, 'completed');
|
||||||
|
|||||||
@ -54,6 +54,31 @@ function extractAgentDisplayName(agentPath: string): string {
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a string value that may be a file path.
|
||||||
|
* If the value ends with .md and the file exists (resolved relative to workflowDir),
|
||||||
|
* read and return the file contents. Otherwise return the value as-is.
|
||||||
|
*/
|
||||||
|
function resolveContentPath(value: string | undefined, workflowDir: string): string | undefined {
|
||||||
|
if (value == null) return undefined;
|
||||||
|
if (value.endsWith('.md')) {
|
||||||
|
// Resolve path relative to workflow directory
|
||||||
|
let resolvedPath = value;
|
||||||
|
if (value.startsWith('./')) {
|
||||||
|
resolvedPath = join(workflowDir, value.slice(2));
|
||||||
|
} else if (value.startsWith('~')) {
|
||||||
|
const homedir = process.env.HOME || process.env.USERPROFILE || '';
|
||||||
|
resolvedPath = join(homedir, value.slice(1));
|
||||||
|
} else if (!value.startsWith('/')) {
|
||||||
|
resolvedPath = join(workflowDir, value);
|
||||||
|
}
|
||||||
|
if (existsSync(resolvedPath)) {
|
||||||
|
return readFileSync(resolvedPath, 'utf-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a raw report value is the object form (has 'name' property).
|
* Check if a raw report value is the object form (has 'name' property).
|
||||||
*/
|
*/
|
||||||
@ -78,11 +103,16 @@ function isReportObject(raw: unknown): raw is { name: string; order?: string; fo
|
|||||||
*/
|
*/
|
||||||
function normalizeReport(
|
function normalizeReport(
|
||||||
raw: string | Record<string, string>[] | { name: string; order?: string; format?: string } | undefined,
|
raw: string | Record<string, string>[] | { name: string; order?: string; format?: string } | undefined,
|
||||||
|
workflowDir: string,
|
||||||
): string | ReportConfig[] | ReportObjectConfig | undefined {
|
): string | ReportConfig[] | ReportObjectConfig | undefined {
|
||||||
if (raw == null) return undefined;
|
if (raw == null) return undefined;
|
||||||
if (typeof raw === 'string') return raw;
|
if (typeof raw === 'string') return raw;
|
||||||
if (isReportObject(raw)) {
|
if (isReportObject(raw)) {
|
||||||
return { name: raw.name, order: raw.order, format: raw.format };
|
return {
|
||||||
|
name: raw.name,
|
||||||
|
order: resolveContentPath(raw.order, workflowDir),
|
||||||
|
format: resolveContentPath(raw.format, workflowDir),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// Convert [{Scope: "01-scope.md"}, ...] to [{label: "Scope", path: "01-scope.md"}, ...]
|
// Convert [{Scope: "01-scope.md"}, ...] to [{label: "Scope", path: "01-scope.md"}, ...]
|
||||||
return (raw as Record<string, string>[]).flatMap((entry) =>
|
return (raw as Record<string, string>[]).flatMap((entry) =>
|
||||||
@ -113,9 +143,10 @@ function normalizeWorkflowConfig(raw: unknown, workflowDir: string): WorkflowCon
|
|||||||
provider: step.provider,
|
provider: step.provider,
|
||||||
model: step.model,
|
model: step.model,
|
||||||
permissionMode: step.permission_mode,
|
permissionMode: step.permission_mode,
|
||||||
instructionTemplate: step.instruction_template || step.instruction || '{task}',
|
edit: step.edit,
|
||||||
|
instructionTemplate: resolveContentPath(step.instruction_template, workflowDir) || step.instruction || '{task}',
|
||||||
rules,
|
rules,
|
||||||
report: normalizeReport(step.report),
|
report: normalizeReport(step.report, workflowDir),
|
||||||
passPreviousResponse: step.pass_previous_response,
|
passPreviousResponse: step.pass_previous_response,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -92,6 +92,8 @@ export const WorkflowStepRawSchema = z.object({
|
|||||||
model: z.string().optional(),
|
model: z.string().optional(),
|
||||||
/** Permission mode for tool execution in this step */
|
/** Permission mode for tool execution in this step */
|
||||||
permission_mode: PermissionModeSchema.optional(),
|
permission_mode: PermissionModeSchema.optional(),
|
||||||
|
/** Whether this step is allowed to edit project files */
|
||||||
|
edit: z.boolean().optional(),
|
||||||
instruction: z.string().optional(),
|
instruction: z.string().optional(),
|
||||||
instruction_template: z.string().optional(),
|
instruction_template: z.string().optional(),
|
||||||
/** Rules for step routing */
|
/** Rules for step routing */
|
||||||
|
|||||||
@ -88,6 +88,8 @@ export interface WorkflowStep {
|
|||||||
model?: string;
|
model?: string;
|
||||||
/** Permission mode for tool execution in this step */
|
/** Permission mode for tool execution in this step */
|
||||||
permissionMode?: PermissionMode;
|
permissionMode?: PermissionMode;
|
||||||
|
/** Whether this step is allowed to edit project files (true=allowed, false=prohibited, undefined=no prompt) */
|
||||||
|
edit?: boolean;
|
||||||
instructionTemplate: string;
|
instructionTemplate: string;
|
||||||
/** Rules for step routing */
|
/** Rules for step routing */
|
||||||
rules?: WorkflowRule[];
|
rules?: WorkflowRule[];
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import { COMPLETE_STEP, ABORT_STEP, ERROR_MESSAGES } from './constants.js';
|
|||||||
import type { WorkflowEngineOptions } from './types.js';
|
import type { WorkflowEngineOptions } from './types.js';
|
||||||
import { determineNextStepByRules } from './transitions.js';
|
import { determineNextStepByRules } from './transitions.js';
|
||||||
import { detectRuleIndex } from '../claude/client.js';
|
import { detectRuleIndex } from '../claude/client.js';
|
||||||
import { buildInstruction as buildInstructionFromTemplate } from './instruction-builder.js';
|
import { buildInstruction as buildInstructionFromTemplate, isReportObjectConfig } from './instruction-builder.js';
|
||||||
import { LoopDetector } from './loop-detector.js';
|
import { LoopDetector } from './loop-detector.js';
|
||||||
import { handleBlocked } from './blocked-handler.js';
|
import { handleBlocked } from './blocked-handler.js';
|
||||||
import {
|
import {
|
||||||
@ -168,6 +168,34 @@ export class WorkflowEngine extends EventEmitter {
|
|||||||
return step;
|
return step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit step:report events for each report file that exists after step completion.
|
||||||
|
* The UI layer (workflowExecution.ts) listens and displays the content.
|
||||||
|
*/
|
||||||
|
private emitStepReports(step: WorkflowStep): void {
|
||||||
|
if (!step.report || !this.reportDir) return;
|
||||||
|
const baseDir = join(this.projectCwd, '.takt', 'reports', this.reportDir);
|
||||||
|
|
||||||
|
if (typeof step.report === 'string') {
|
||||||
|
this.emitIfReportExists(step, baseDir, step.report);
|
||||||
|
} else if (isReportObjectConfig(step.report)) {
|
||||||
|
this.emitIfReportExists(step, baseDir, step.report.name);
|
||||||
|
} else {
|
||||||
|
// ReportConfig[] (array)
|
||||||
|
for (const rc of step.report) {
|
||||||
|
this.emitIfReportExists(step, baseDir, rc.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Emit step:report if the report file exists */
|
||||||
|
private emitIfReportExists(step: WorkflowStep, baseDir: string, fileName: string): void {
|
||||||
|
const filePath = join(baseDir, fileName);
|
||||||
|
if (existsSync(filePath)) {
|
||||||
|
this.emit('step:report', step, filePath, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Run a single step */
|
/** Run a single step */
|
||||||
private async runStep(step: WorkflowStep): Promise<{ response: AgentResponse; instruction: string }> {
|
private async runStep(step: WorkflowStep): Promise<{ response: AgentResponse; instruction: string }> {
|
||||||
const stepIteration = incrementStepIteration(this.state, step.name);
|
const stepIteration = incrementStepIteration(this.state, step.name);
|
||||||
@ -214,6 +242,7 @@ export class WorkflowEngine extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.state.stepOutputs.set(step.name, response);
|
this.state.stepOutputs.set(step.name, response);
|
||||||
|
this.emitStepReports(step);
|
||||||
return { response, instruction };
|
return { response, instruction };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,17 +43,20 @@ export interface ExecutionMetadata {
|
|||||||
readonly workingDirectory: string;
|
readonly workingDirectory: string;
|
||||||
/** Language for metadata rendering */
|
/** Language for metadata rendering */
|
||||||
readonly language: Language;
|
readonly language: Language;
|
||||||
|
/** Whether file editing is allowed for this step (undefined = no prompt) */
|
||||||
|
readonly edit?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build execution metadata from instruction context.
|
* Build execution metadata from instruction context and step config.
|
||||||
*
|
*
|
||||||
* Pure function: InstructionContext → ExecutionMetadata.
|
* Pure function: (InstructionContext, edit?) → ExecutionMetadata.
|
||||||
*/
|
*/
|
||||||
export function buildExecutionMetadata(context: InstructionContext): ExecutionMetadata {
|
export function buildExecutionMetadata(context: InstructionContext, edit?: boolean): ExecutionMetadata {
|
||||||
return {
|
return {
|
||||||
workingDirectory: context.cwd,
|
workingDirectory: context.cwd,
|
||||||
language: context.language ?? 'en',
|
language: context.language ?? 'en',
|
||||||
|
edit,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +175,8 @@ const METADATA_STRINGS = {
|
|||||||
rulesHeading: '## Execution Rules',
|
rulesHeading: '## Execution Rules',
|
||||||
noCommit: '**Do NOT run git commit.** Commits are handled automatically by the system after workflow completion.',
|
noCommit: '**Do NOT run git commit.** Commits are handled automatically by the system after workflow completion.',
|
||||||
noCd: '**Do NOT use `cd` in Bash commands.** Your working directory is already set correctly. Run commands directly without changing directories.',
|
noCd: '**Do NOT use `cd` in Bash commands.** Your working directory is already set correctly. Run commands directly without changing directories.',
|
||||||
|
editEnabled: '**Editing is ENABLED for this step.** You may create, modify, and delete files as needed to fulfill the user\'s request.',
|
||||||
|
editDisabled: '**Editing is DISABLED for this step.** Do NOT create, modify, or delete any project source files. You may only read/search code and write to report files in the Report Directory.',
|
||||||
note: 'Note: This section is metadata. Follow the language used in the rest of the prompt.',
|
note: 'Note: This section is metadata. Follow the language used in the rest of the prompt.',
|
||||||
},
|
},
|
||||||
ja: {
|
ja: {
|
||||||
@ -180,6 +185,8 @@ const METADATA_STRINGS = {
|
|||||||
rulesHeading: '## 実行ルール',
|
rulesHeading: '## 実行ルール',
|
||||||
noCommit: '**git commit を実行しないでください。** コミットはワークフロー完了後にシステムが自動で行います。',
|
noCommit: '**git commit を実行しないでください。** コミットはワークフロー完了後にシステムが自動で行います。',
|
||||||
noCd: '**Bashコマンドで `cd` を使用しないでください。** 作業ディレクトリは既に正しく設定されています。ディレクトリを変更せずにコマンドを実行してください。',
|
noCd: '**Bashコマンドで `cd` を使用しないでください。** 作業ディレクトリは既に正しく設定されています。ディレクトリを変更せずにコマンドを実行してください。',
|
||||||
|
editEnabled: '**このステップでは編集が許可されています。** ユーザーの要求に応じて、ファイルの作成・変更・削除を行ってください。',
|
||||||
|
editDisabled: '**このステップでは編集が禁止されています。** プロジェクトのソースファイルを作成・変更・削除しないでください。コードの読み取り・検索と、Report Directoryへのレポート出力のみ行えます。',
|
||||||
note: '',
|
note: '',
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
@ -201,6 +208,11 @@ export function renderExecutionMetadata(metadata: ExecutionMetadata): string {
|
|||||||
`- ${strings.noCommit}`,
|
`- ${strings.noCommit}`,
|
||||||
`- ${strings.noCd}`,
|
`- ${strings.noCd}`,
|
||||||
];
|
];
|
||||||
|
if (metadata.edit === true) {
|
||||||
|
lines.push(`- ${strings.editEnabled}`);
|
||||||
|
} else if (metadata.edit === false) {
|
||||||
|
lines.push(`- ${strings.editDisabled}`);
|
||||||
|
}
|
||||||
if (strings.note) {
|
if (strings.note) {
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push(strings.note);
|
lines.push(strings.note);
|
||||||
@ -219,7 +231,7 @@ function escapeTemplateChars(str: string): string {
|
|||||||
/**
|
/**
|
||||||
* Check if a report config is the object form (ReportObjectConfig).
|
* Check if a report config is the object form (ReportObjectConfig).
|
||||||
*/
|
*/
|
||||||
function isReportObjectConfig(report: string | ReportConfig[] | ReportObjectConfig): report is ReportObjectConfig {
|
export function isReportObjectConfig(report: string | ReportConfig[] | ReportObjectConfig): report is ReportObjectConfig {
|
||||||
return typeof report === 'object' && !Array.isArray(report) && 'name' in report;
|
return typeof report === 'object' && !Array.isArray(report) && 'name' in report;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,8 +396,8 @@ export function buildInstruction(
|
|||||||
const s = SECTION_STRINGS[language];
|
const s = SECTION_STRINGS[language];
|
||||||
const sections: string[] = [];
|
const sections: string[] = [];
|
||||||
|
|
||||||
// 1. Execution context metadata (working directory + rules)
|
// 1. Execution context metadata (working directory + rules + edit permission)
|
||||||
const metadata = buildExecutionMetadata(context);
|
const metadata = buildExecutionMetadata(context, step.edit);
|
||||||
sections.push(renderExecutionMetadata(metadata));
|
sections.push(renderExecutionMetadata(metadata));
|
||||||
|
|
||||||
// 2. Workflow Context (iteration, step, report info)
|
// 2. Workflow Context (iteration, step, report info)
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import type { PermissionHandler, AskUserQuestionHandler } from '../claude/proces
|
|||||||
export interface WorkflowEvents {
|
export interface WorkflowEvents {
|
||||||
'step:start': (step: WorkflowStep, iteration: number) => void;
|
'step:start': (step: WorkflowStep, iteration: number) => void;
|
||||||
'step:complete': (step: WorkflowStep, response: AgentResponse, instruction: string) => void;
|
'step:complete': (step: WorkflowStep, response: AgentResponse, instruction: string) => void;
|
||||||
|
'step:report': (step: WorkflowStep, filePath: string, fileName: string) => void;
|
||||||
'step:blocked': (step: WorkflowStep, response: AgentResponse) => void;
|
'step:blocked': (step: WorkflowStep, response: AgentResponse) => void;
|
||||||
'step:user_input': (step: WorkflowStep, userInput: string) => void;
|
'step:user_input': (step: WorkflowStep, userInput: string) => void;
|
||||||
'workflow:complete': (state: WorkflowState) => void;
|
'workflow:complete': (state: WorkflowState) => void;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user