@einja/dev-cli 0.1.41 → 0.1.44
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/dist/commands/task-loop/lib/github-client.test.js.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.js +2 -2
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.js.map +1 -1
- package/dist/lib/preset-update/file-copier.js +3 -3
- package/dist/lib/preset-update/file-copier.js.map +1 -1
- package/dist/lib/sync/marker-processor.js.map +1 -1
- package/dist/lib/sync/metadata-manager.js +1 -1
- package/dist/lib/sync/metadata-manager.js.map +1 -1
- package/dist/lib/sync/metadata-manager.test.js +3 -2
- package/dist/lib/sync/metadata-manager.test.js.map +1 -1
- package/dist/lib/sync/project-private-synchronizer.d.ts.map +1 -1
- package/dist/lib/sync/project-private-synchronizer.js +5 -1
- package/dist/lib/sync/project-private-synchronizer.js.map +1 -1
- package/package.json +1 -1
- package/presets/default/.claude/agents/einja/backend-architect.md +17 -1
- package/presets/default/.claude/agents/einja/codex-agent.md +1 -1
- package/presets/default/.claude/agents/einja/design-engineer.md +1 -1
- package/presets/default/.claude/agents/einja/docs/docs-updater.md +3 -93
- package/presets/default/.claude/agents/einja/frontend-architect.md +17 -1
- package/presets/default/.claude/agents/einja/frontend-coder.md +1 -1
- package/presets/default/.claude/agents/einja/{specs/spec-design-generator.md → issue-specs/design-generator.md} +12 -7
- package/presets/default/.claude/agents/einja/{specs/spec-qa-generator.md → issue-specs/qa-generator.md} +6 -4
- package/presets/default/.claude/agents/einja/{specs/spec-requirements-generator.md → issue-specs/requirements-generator.md} +5 -5
- package/presets/default/.claude/agents/einja/{specs/spec-tasks-generator.md → issue-specs/tasks-generator.md} +13 -14
- package/presets/default/.claude/agents/einja/{specs/spec-tasks-validator.md → issue-specs/tasks-validator.md} +9 -9
- package/presets/default/.claude/agents/einja/issue-specs/ui-design-generator.md +114 -0
- package/presets/default/.claude/agents/einja/task/task-executer.md +9 -3
- package/presets/default/.claude/agents/einja/task/task-modification-analyzer.md +2 -2
- package/presets/default/.claude/agents/einja/task/task-qa.md +3 -3
- package/presets/default/.claude/agents/einja/task/task-reviewer.md +13 -1
- package/presets/default/.claude/commands/einja/einja-sync.md +119 -44
- package/presets/default/.claude/commands/einja/issue-exec.md +29 -19
- package/presets/default/.claude/commands/einja/sync-cursor-commands.md +6 -6
- package/presets/default/.claude/commands/einja/{update-docs-by-task-specs.md → update-docs-by-issue-specs.md} +58 -58
- package/presets/default/.claude/hooks/einja/plan-mode-skill-loader.sh +5 -1
- package/presets/default/.claude/settings.json +14 -4
- package/presets/default/.claude/skills/{einja-general-context-loader → _einja-general-context-loader}/SKILL.md +2 -2
- package/presets/default/.claude/skills/{einja-output-format → _einja-output-format}/SKILL.md +1 -1
- package/presets/default/.claude/skills/_einja-project-overview/SKILL.md +29 -0
- package/presets/default/.claude/skills/{einja-spec-context-loader → _einja-spec-context-loader}/SKILL.md +5 -5
- package/presets/default/.claude/skills/einja-coding-standards/references/testing-strategy.md +899 -0
- package/presets/default/.claude/skills/einja-conflict-resolver/SKILL.md +1 -1
- package/presets/default/.claude/skills/einja-create-pr/SKILL.md +138 -0
- package/presets/default/.claude/skills/einja-infra-maintenance/SKILL.md +779 -0
- package/presets/default/.claude/{commands/einja/spec-create.md → skills/einja-issue-spec-create/SKILL.md} +47 -24
- package/presets/default/.claude/skills/einja-issue-spec-generator/SKILL.md +105 -0
- package/presets/default/.claude/skills/einja-issue-spec-generator/references/format-rules.md +35 -0
- package/presets/default/.claude/skills/einja-issue-spec-validator/SKILL.md +130 -0
- package/presets/default/.claude/skills/einja-issue-spec-validator/references/validation-rules.md +52 -0
- package/presets/default/.claude/skills/einja-npm-release/SKILL.md +242 -0
- package/presets/default/.claude/skills/einja-skill-creator/SKILL.md +68 -12
- package/presets/default/.claude/skills/einja-skill-creator/scripts/aggregate_benchmark.py +368 -121
- package/presets/default/.claude/skills/einja-skill-creator/scripts/compare_runs.py +154 -0
- package/presets/default/.claude/skills/einja-skill-creator/scripts/generate_report.py +14 -7
- package/presets/default/.claude/skills/einja-skill-creator/scripts/improve_description.py +2 -7
- package/presets/default/.claude/skills/einja-skill-creator/scripts/run_loop.py +263 -183
- package/presets/default/.claude/skills/einja-skill-first/SKILL.md +265 -0
- package/presets/default/.claude/skills/einja-subagent-question-protocol/SKILL.md +98 -0
- package/presets/default/.claude/skills/einja-task-commit/SKILL.md +7 -7
- package/presets/default/.claude/{commands/einja/task-exec.md → skills/einja-task-exec/SKILL.md} +3 -78
- package/presets/default/.claude/skills/einja-task-qa/SKILL.md +4 -4
- package/presets/default/.claude/skills/einja-task-qa/references/troubleshooting.md +1 -1
- package/presets/default/.claude/skills/einja-task-qa/references/usage-patterns.md +2 -2
- package/presets/default/.claude/skills/einja-team-exec/SKILL.md +165 -0
- package/presets/default/CLAUDE.md.template +21 -6
- package/presets/default/docs/einja/instructions/deployment-setup.md +1 -1
- package/presets/default/docs/einja/instructions/issue-exec-workflow.md +11 -11
- package/presets/default/docs/einja/instructions/local-server-environment-and-worktree.md +1 -1
- package/presets/default/docs/einja/instructions/setup-flow.md +279 -0
- package/presets/default/docs/einja/instructions/task-execute.md +42 -42
- package/presets/default/docs/einja/steering/acceptance-criteria-and-qa-guide.md +1 -1
- package/presets/default/docs/einja/steering/branch-strategy.md +1 -1
- package/presets/default/docs/einja/steering/development-workflow.md +93 -25
- package/presets/default/docs/einja/steering/infrastructure/deployment.md +107 -0
- package/presets/default/docs/einja/steering/task-management.md +9 -13
- package/presets/default/scripts/ensure-serena.sh +2 -2
- package/presets/default/scripts/env-rotate-secrets.ts +66 -6
- package/presets/default/scripts/init-github.ts +363 -0
- package/presets/default/scripts/init.sh +11 -5
- package/presets/default/scripts/setup-dev.ts +16 -1
- package/presets/default/.claude/agents/einja/git/conflict-resolver.md +0 -152
- package/presets/default/.claude/hooks/einja/validate-git-commit.sh +0 -239
- package/presets/default/.claude/skills/einja-project-overview/SKILL.md +0 -39
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""複数スキルのベンチマーク結果を集約。
|
|
3
|
+
|
|
4
|
+
複数のrun_loop.py出力を受け取り、全スキルのスコアを
|
|
5
|
+
サマリーテーブルとして表示する。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import json
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def aggregate_results(result_files: list[str]) -> dict:
|
|
15
|
+
"""複数のrun_loop.py出力ファイルを集約する。"""
|
|
16
|
+
skills = []
|
|
17
|
+
|
|
18
|
+
for filepath in result_files:
|
|
19
|
+
try:
|
|
20
|
+
data = json.loads(Path(filepath).read_text())
|
|
21
|
+
except (json.JSONDecodeError, FileNotFoundError) as e:
|
|
22
|
+
print(f"警告: {filepath} の読み込みに失敗しました: {e}", file=sys.stderr)
|
|
23
|
+
continue
|
|
24
|
+
|
|
25
|
+
history = data.get("history", [])
|
|
26
|
+
if not history:
|
|
27
|
+
print(f"警告: {filepath} に履歴がありません", file=sys.stderr)
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
# 最良のイテレーションを見つける(テスト > トレーニングで優先)
|
|
31
|
+
best_idx = 0
|
|
32
|
+
best_test = -1
|
|
33
|
+
best_train = -1
|
|
34
|
+
for i, h in enumerate(history):
|
|
35
|
+
t_passed = h.get("test_passed", -1)
|
|
36
|
+
tr_passed = h.get("train_passed", h.get("passed", 0))
|
|
37
|
+
if t_passed > best_test or (t_passed == best_test and tr_passed > best_train):
|
|
38
|
+
best_test = t_passed
|
|
39
|
+
best_train = tr_passed
|
|
40
|
+
best_idx = i
|
|
41
|
+
|
|
42
|
+
best = history[best_idx]
|
|
43
|
+
original = history[0]
|
|
44
|
+
|
|
45
|
+
skill_entry = {
|
|
46
|
+
"skill_name": data.get("skill_name", Path(filepath).stem),
|
|
47
|
+
"file": filepath,
|
|
48
|
+
"iterations": len(history),
|
|
49
|
+
"best_iteration": best_idx,
|
|
50
|
+
"original_description": data.get("original_description", ""),
|
|
51
|
+
"best_description": best.get("description", ""),
|
|
52
|
+
"original_train_score": f"{original.get('train_passed', original.get('passed', 0))}/{original.get('train_total', original.get('total', 0))}",
|
|
53
|
+
"best_train_score": f"{best.get('train_passed', best.get('passed', 0))}/{best.get('train_total', best.get('total', 0))}",
|
|
54
|
+
"original_train_passed": original.get("train_passed", original.get("passed", 0)),
|
|
55
|
+
"original_train_total": original.get("train_total", original.get("total", 0)),
|
|
56
|
+
"best_train_passed": best.get("train_passed", best.get("passed", 0)),
|
|
57
|
+
"best_train_total": best.get("train_total", best.get("total", 0)),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# テストスコア(存在する場合)
|
|
61
|
+
if best.get("test_passed") is not None:
|
|
62
|
+
skill_entry["original_test_score"] = f"{original.get('test_passed', '?')}/{original.get('test_total', '?')}"
|
|
63
|
+
skill_entry["best_test_score"] = f"{best.get('test_passed', '?')}/{best.get('test_total', '?')}"
|
|
64
|
+
skill_entry["best_test_passed"] = best.get("test_passed", 0)
|
|
65
|
+
skill_entry["best_test_total"] = best.get("test_total", 0)
|
|
66
|
+
|
|
67
|
+
skills.append(skill_entry)
|
|
68
|
+
|
|
69
|
+
# トレーニングスコアでソート(降順)
|
|
70
|
+
skills.sort(
|
|
71
|
+
key=lambda s: (
|
|
72
|
+
s.get("best_test_passed", 0) / max(s.get("best_test_total", 1), 1),
|
|
73
|
+
s["best_train_passed"] / max(s["best_train_total"], 1),
|
|
74
|
+
),
|
|
75
|
+
reverse=True,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# 全体サマリーの計算
|
|
79
|
+
total_train_passed = sum(s["best_train_passed"] for s in skills)
|
|
80
|
+
total_train_total = sum(s["best_train_total"] for s in skills)
|
|
81
|
+
total_test_passed = sum(s.get("best_test_passed", 0) for s in skills if "best_test_passed" in s)
|
|
82
|
+
total_test_total = sum(s.get("best_test_total", 0) for s in skills if "best_test_total" in s)
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
"skills": skills,
|
|
86
|
+
"summary": {
|
|
87
|
+
"total_skills": len(skills),
|
|
88
|
+
"total_train_passed": total_train_passed,
|
|
89
|
+
"total_train_total": total_train_total,
|
|
90
|
+
"total_train_score": f"{total_train_passed}/{total_train_total}",
|
|
91
|
+
"total_test_passed": total_test_passed,
|
|
92
|
+
"total_test_total": total_test_total,
|
|
93
|
+
"total_test_score": f"{total_test_passed}/{total_test_total}" if total_test_total > 0 else None,
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def print_table(aggregated: dict, verbose: bool = False) -> None:
|
|
99
|
+
"""集約結果をテーブル形式でstderrに出力する。"""
|
|
100
|
+
skills = aggregated["skills"]
|
|
101
|
+
summary = aggregated["summary"]
|
|
102
|
+
|
|
103
|
+
has_test = any("best_test_score" in s for s in skills)
|
|
104
|
+
|
|
105
|
+
# ヘッダー
|
|
106
|
+
header = f"{'スキル名':<30} {'トレーニング(元)':<14} {'トレーニング(最良)':<14}"
|
|
107
|
+
if has_test:
|
|
108
|
+
header += f" {'テスト(元)':<12} {'テスト(最良)':<12}"
|
|
109
|
+
header += f" {'回数':<6} {'最良回':<6}"
|
|
110
|
+
print(header, file=sys.stderr)
|
|
111
|
+
print("-" * len(header), file=sys.stderr)
|
|
112
|
+
|
|
113
|
+
# 各スキル
|
|
114
|
+
for s in skills:
|
|
115
|
+
line = f"{s['skill_name']:<30} {s['original_train_score']:<14} {s['best_train_score']:<14}"
|
|
116
|
+
if has_test:
|
|
117
|
+
orig_test = s.get("original_test_score", "-")
|
|
118
|
+
best_test = s.get("best_test_score", "-")
|
|
119
|
+
line += f" {orig_test:<12} {best_test:<12}"
|
|
120
|
+
line += f" {s['iterations']:<6} {s['best_iteration']:<6}"
|
|
121
|
+
print(line, file=sys.stderr)
|
|
122
|
+
|
|
123
|
+
if verbose:
|
|
124
|
+
print(f" オリジナル: {s['original_description'][:80]}...", file=sys.stderr)
|
|
125
|
+
print(f" 最良: {s['best_description'][:80]}...", file=sys.stderr)
|
|
126
|
+
|
|
127
|
+
# サマリー
|
|
128
|
+
print("-" * len(header), file=sys.stderr)
|
|
129
|
+
total_line = f"{'合計':<30} {'':<14} {summary['total_train_score']:<14}"
|
|
130
|
+
if has_test and summary.get("total_test_score"):
|
|
131
|
+
total_line += f" {'':<12} {summary['total_test_score']:<12}"
|
|
132
|
+
total_line += f" {summary['total_skills']} スキル"
|
|
133
|
+
print(total_line, file=sys.stderr)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def main():
|
|
137
|
+
parser = argparse.ArgumentParser(description="複数スキルのベンチマーク結果を集約")
|
|
138
|
+
parser.add_argument("files", nargs="+", help="run_loop.pyのJSON出力ファイル(複数指定可)")
|
|
139
|
+
parser.add_argument("--verbose", action="store_true", help="各スキルのdescriptionも表示")
|
|
140
|
+
parser.add_argument("--json", action="store_true", help="JSON形式で標準出力に出力")
|
|
141
|
+
args = parser.parse_args()
|
|
142
|
+
|
|
143
|
+
aggregated = aggregate_results(args.files)
|
|
144
|
+
|
|
145
|
+
# テーブル表示
|
|
146
|
+
print_table(aggregated, verbose=args.verbose)
|
|
147
|
+
|
|
148
|
+
# JSON出力
|
|
149
|
+
if args.json:
|
|
150
|
+
print(json.dumps(aggregated, indent=2, ensure_ascii=False))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
main()
|
|
@@ -249,16 +249,23 @@ def generate_html(data: dict, auto_refresh: bool = False, skill_name: str = "")
|
|
|
249
249
|
|
|
250
250
|
def main():
|
|
251
251
|
parser = argparse.ArgumentParser(description="run_loop.pyの出力からHTMLレポートを生成")
|
|
252
|
-
parser.add_argument("
|
|
253
|
-
parser.add_argument("--output",
|
|
254
|
-
parser.add_argument("--auto-refresh", action="store_true", help="5秒ごとの自動リフレッシュを有効化(ライブモニタリング用)")
|
|
252
|
+
parser.add_argument("input", help="run_loop.pyのJSON出力へのパス('-'でstdinから読み込み)")
|
|
253
|
+
parser.add_argument("-o", "--output", default=None, help="HTMLレポートの出力先パス(未指定時はstdout)")
|
|
255
254
|
parser.add_argument("--skill-name", default="", help="レポートタイトルに表示するスキル名")
|
|
256
255
|
args = parser.parse_args()
|
|
257
256
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
257
|
+
if args.input == "-":
|
|
258
|
+
data = json.load(sys.stdin)
|
|
259
|
+
else:
|
|
260
|
+
data = json.loads(Path(args.input).read_text())
|
|
261
|
+
|
|
262
|
+
html_content = generate_html(data, skill_name=args.skill_name)
|
|
263
|
+
|
|
264
|
+
if args.output:
|
|
265
|
+
Path(args.output).write_text(html_content)
|
|
266
|
+
print(f"レポートを生成しました: {args.output}", file=sys.stderr)
|
|
267
|
+
else:
|
|
268
|
+
print(html_content)
|
|
262
269
|
|
|
263
270
|
|
|
264
271
|
if __name__ == "__main__":
|
|
@@ -27,7 +27,6 @@ def improve_description(
|
|
|
27
27
|
eval_results: dict,
|
|
28
28
|
history: list[dict],
|
|
29
29
|
model: str,
|
|
30
|
-
test_results: dict | None = None,
|
|
31
30
|
log_dir: Path | None = None,
|
|
32
31
|
iteration: int | None = None,
|
|
33
32
|
) -> str:
|
|
@@ -41,13 +40,9 @@ def improve_description(
|
|
|
41
40
|
if not r["should_trigger"] and not r["pass"]
|
|
42
41
|
]
|
|
43
42
|
|
|
44
|
-
#
|
|
43
|
+
# スコアサマリーの構築(テストスコアはblinded_historyで隠蔽されるためトレーニングスコアのみ表示)
|
|
45
44
|
train_score = f"{eval_results['summary']['passed']}/{eval_results['summary']['total']}"
|
|
46
|
-
|
|
47
|
-
test_score = f"{test_results['summary']['passed']}/{test_results['summary']['total']}"
|
|
48
|
-
scores_summary = f"Train: {train_score}, Test: {test_score}"
|
|
49
|
-
else:
|
|
50
|
-
scores_summary = f"Train: {train_score}"
|
|
45
|
+
scores_summary = f"Train: {train_score}"
|
|
51
46
|
|
|
52
47
|
# NOTE: Claude APIへのプロンプトは精度維持のため英語のまま
|
|
53
48
|
prompt = f"""You are optimizing a skill description for a Claude Code skill called "{skill_name}". A "skill" is sort of like a prompt, but with progressive disclosure -- there's a title and description that Claude sees when deciding whether to use the skill, and then if it does use the skill, it reads the .md file which has lots more details and potentially links to other resources in the skill folder like helper files and scripts and additional documentation or examples.
|