harness-crafter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1979 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+ import chalk from "chalk";
6
+
7
+ // src/commands/generate.ts
8
+ import fs from "fs";
9
+ import path from "path";
10
+
11
+ // src/schema/harness_config.schema.ts
12
+ import { z } from "zod";
13
+ var PROJECT_DOMAINS = [
14
+ "product_dev",
15
+ "realtime_monitor",
16
+ "cron_job",
17
+ "design_web",
18
+ "marketing_ads",
19
+ "outsourced_dev",
20
+ "research_rd"
21
+ ];
22
+ var USER_LEVELS = ["expert", "competent", "novice"];
23
+ var COST_MODE_KEYS = ["ECO", "BALANCED", "PRO"];
24
+ var ARCHETYPES = [
25
+ "personal_tool",
26
+ "saas_product",
27
+ "marketing_site",
28
+ "data_analysis",
29
+ "outsourced_dev",
30
+ "learning",
31
+ "business_automation",
32
+ "sales_dx",
33
+ "youtube_content",
34
+ "article_writing",
35
+ "seo_marketing",
36
+ "finance_bot",
37
+ "data_collection"
38
+ ];
39
+ var ARCHETYPE_LABELS = {
40
+ personal_tool: "\u500B\u4EBA\u30C4\u30FC\u30EB\u30FB\u81EA\u52D5\u5316",
41
+ saas_product: "SaaS\u30FB\u30D7\u30ED\u30C0\u30AF\u30C8\u958B\u767A",
42
+ marketing_site: "LP\u30FB\u30DE\u30FC\u30B1\u30B5\u30A4\u30C8",
43
+ data_analysis: "\u30C7\u30FC\u30BF\u5206\u6790\u30FB\u30EC\u30DD\u30FC\u30C8",
44
+ outsourced_dev: "\u53D7\u8A17\u30FB\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u30EF\u30FC\u30AF",
45
+ learning: "\u5B66\u7FD2\u30FB\u5B9F\u9A13",
46
+ business_automation: "\u696D\u52D9\u81EA\u52D5\u5316",
47
+ sales_dx: "\u55B6\u696DDX\u30FB\u55B6\u696D\u30C4\u30FC\u30EB",
48
+ youtube_content: "YouTube\u52D5\u753B\u4F5C\u6210\u30FB\u7DE8\u96C6",
49
+ article_writing: "\u8A18\u4E8B\u57F7\u7B46\u30FB\u30D6\u30ED\u30B0\u30FB\u30E1\u30C7\u30A3\u30A2",
50
+ seo_marketing: "SEO\u6539\u5584\u30FB\u30DE\u30FC\u30B1\u30C6\u30A3\u30F3\u30B0",
51
+ finance_bot: "\u91D1\u878D\u30B7\u30B9\u30C6\u30E0\u30FBBOT\u958B\u767A",
52
+ data_collection: "\u30C7\u30FC\u30BF\u53CE\u96C6\u30FB\u6574\u7406\u30FB\u5171\u6709"
53
+ };
54
+ var CostModeSettingSchema = z.object({
55
+ output_style: z.enum(["code_only", "concise", "detailed"]).describe("Claude \u306E\u51FA\u529B\u30B9\u30BF\u30A4\u30EB: code_only=\u30B3\u30FC\u30C9\u306E\u307F / concise=\u7C21\u6F54 / detailed=\u8A73\u7D30"),
56
+ reasoning_depth: z.enum(["minimal", "on_error", "always"]).describe("\u601D\u8003\u306E\u6DF1\u3055: minimal=\u6700\u5C0F\u9650 / on_error=\u30A8\u30E9\u30FC\u6642\u306E\u307F / always=\u5E38\u6642"),
57
+ test_coverage: z.enum(["skip", "critical_only", "comprehensive"]).describe("\u30C6\u30B9\u30C8\u30AB\u30D0\u30EC\u30C3\u30B8: skip=\u7701\u7565 / critical_only=\u91CD\u8981\u30D1\u30B9\u306E\u307F / comprehensive=\u7DB2\u7F85"),
58
+ token_budget_ratio: z.number().min(0).max(1).describe("\u30C8\u30FC\u30AF\u30F3\u4E88\u7B97\u306E\u4F7F\u7528\u7387 (0.0\u301C1.0)"),
59
+ security_check: z.boolean().optional().describe("\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30C1\u30A7\u30C3\u30AF\u3092\u5E38\u6642\u5B9F\u65BD\u3059\u308B\u304B (PRO\u5C02\u7528)")
60
+ });
61
+ var RulePrioritySchema = z.object({
62
+ rule: z.string().min(1).describe("\u30EB\u30FC\u30EB\u540D"),
63
+ weight: z.number().int().min(0).max(100).describe("\u512A\u5148\u5EA6 (0\u301C100, 100\u304C\u6700\u9AD8)"),
64
+ locked: z.boolean().optional().default(false).describe("\u30ED\u30C3\u30AF\u3055\u308C\u305F\u30EB\u30FC\u30EB\u306F\u5909\u66F4\u4E0D\u53EF")
65
+ });
66
+ var HarnessConfigSchema = z.object({
67
+ schema_version: z.string().regex(/^\d+\.\d+\.\d+$/).describe("\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306E\u30B9\u30AD\u30FC\u30DE\u30D0\u30FC\u30B8\u30E7\u30F3 (semver)"),
68
+ organization_id: z.string().min(1).describe("\u7D44\u7E54ID (\u30DE\u30EB\u30C1\u30C6\u30CA\u30F3\u30C8\u7BA1\u7406\u7528)"),
69
+ project_id: z.string().min(1).describe("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID"),
70
+ generated_at: z.string().datetime({ offset: true }).describe("\u6700\u7D42\u751F\u6210\u65E5\u6642 (ISO 8601)"),
71
+ project: z.object({
72
+ name: z.string().min(1).describe("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D"),
73
+ domain: z.enum(PROJECT_DOMAINS).describe(
74
+ "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30C9\u30E1\u30A4\u30F3: product_dev / realtime_monitor / cron_job / design_web / marketing_ads / outsourced_dev / research_rd"
75
+ ),
76
+ user_level: z.enum(USER_LEVELS).describe("\u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB: expert=\u5C02\u9580\u5BB6 / competent=\u5B9F\u52D9\u8005 / novice=\u521D\u5FC3\u8005"),
77
+ language: z.string().default("ja").describe("\u5FDC\u7B54\u8A00\u8A9E\u30B3\u30FC\u30C9 (ja / en \u306A\u3069)"),
78
+ description: z.string().optional().describe("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u6982\u8981 (\u4EFB\u610F)")
79
+ }).describe("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u57FA\u672C\u60C5\u5831"),
80
+ cost_mode: z.object({
81
+ current: z.enum(COST_MODE_KEYS).describe("\u73FE\u5728\u306E\u30B3\u30B9\u30C8\u30E2\u30FC\u30C9: ECO=\u7BC0\u7D04 / BALANCED=\u6A19\u6E96 / PRO=\u6700\u9AD8\u54C1\u8CEA"),
82
+ subscription_plan: z.enum(["free", "premium"]).default("free").describe("\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u30D7\u30E9\u30F3"),
83
+ modes: z.object({
84
+ ECO: CostModeSettingSchema,
85
+ BALANCED: CostModeSettingSchema,
86
+ PRO: CostModeSettingSchema
87
+ }).describe("\u5404\u30B3\u30B9\u30C8\u30E2\u30FC\u30C9\u306E\u8A2D\u5B9A")
88
+ }).describe("\u30B3\u30B9\u30C8\u30E2\u30FC\u30C9\u8A2D\u5B9A"),
89
+ session_mirroring: z.object({
90
+ enabled: z.boolean().default(true).describe("\u30BB\u30C3\u30B7\u30E7\u30F3\u30DF\u30E9\u30FC\u30EA\u30F3\u30B0\u3092\u6709\u52B9\u306B\u3059\u308B\u304B"),
91
+ id_format: z.string().default("#{MMDD}-{SEQ}").describe("\u30BB\u30C3\u30B7\u30E7\u30F3ID\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8"),
92
+ output_path: z.string().default(".claude/sessions/current_session.md").describe("\u30BB\u30C3\u30B7\u30E7\u30F3\u30ED\u30B0\u306E\u51FA\u529B\u30D1\u30B9"),
93
+ auto_search_on_mention: z.boolean().default(true).describe("ID\u8A00\u53CA\u6642\u306B\u81EA\u52D5\u3067\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u691C\u7D22\u3059\u308B\u304B")
94
+ }).optional().describe("\u30E9\u30A4\u30D6\u30BB\u30C3\u30B7\u30E7\u30F3\u30DF\u30E9\u30FC\u30EA\u30F3\u30B0\u8A2D\u5B9A (\u7701\u7565\u6642\u306F\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u3092\u4F7F\u7528)"),
95
+ telemetry: z.object({
96
+ enabled: z.boolean().default(false).describe("\u30C6\u30EC\u30E1\u30C8\u30EA\u9001\u4FE1\u3092\u6709\u52B9\u306B\u3059\u308B\u304B"),
97
+ endpoint: z.string().url().nullable().default(null).describe("\u30C7\u30FC\u30BF\u9001\u4FE1\u5148URL (null=\u30ED\u30FC\u30AB\u30EB\u306E\u307F)"),
98
+ mask_patterns: z.array(z.string()).describe("\u30DE\u30B9\u30AD\u30F3\u30B0\u3059\u308B\u6B63\u898F\u8868\u73FE\u30D1\u30BF\u30FC\u30F3\u306E\u30EA\u30B9\u30C8"),
99
+ anonymize_fields: z.array(z.string()).describe("\u533F\u540D\u5316\u3059\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u540D\u306E\u30EA\u30B9\u30C8")
100
+ }).optional().describe("\u30C6\u30EC\u30E1\u30C8\u30EA\u30FB\u30C7\u30FC\u30BF\u53CE\u96C6\u8A2D\u5B9A (\u7701\u7565\u6642\u306F\u7121\u52B9)"),
101
+ rule_priorities: z.array(RulePrioritySchema).optional().describe("\u30EB\u30FC\u30EB\u512A\u5148\u5EA6\u30EA\u30B9\u30C8 (\u7701\u7565\u6642\u306F\u30C7\u30D5\u30A9\u30EB\u30C8\u512A\u5148\u5EA6\u3092\u4F7F\u7528)"),
102
+ dynamic_loading: z.object({
103
+ strategy: z.enum(["lazy", "eager"]).default("lazy").describe("\u30EB\u30FC\u30EB\u8AAD\u307F\u8FBC\u307F\u6226\u7565: lazy=\u5FC5\u8981\u6642\u306E\u307F / eager=\u8D77\u52D5\u6642\u306B\u5168\u3066"),
104
+ triggers: z.object({
105
+ domain_rules: z.enum(["always", "on_demand"]).describe("\u30C9\u30E1\u30A4\u30F3\u30EB\u30FC\u30EB\u306E\u8AAD\u8FBC\u30BF\u30A4\u30DF\u30F3\u30B0"),
106
+ user_level_rules: z.enum(["always", "on_demand"]).describe("\u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB\u30EB\u30FC\u30EB\u306E\u8AAD\u8FBC\u30BF\u30A4\u30DF\u30F3\u30B0"),
107
+ cost_mode_rules: z.enum(["always", "on_mode_change", "on_demand"]).describe("\u30B3\u30B9\u30C8\u30E2\u30FC\u30C9\u30EB\u30FC\u30EB\u306E\u8AAD\u8FBC\u30BF\u30A4\u30DF\u30F3\u30B0"),
108
+ evaluator: z.enum(["always", "on_implementation", "on_demand"]).describe("\u8A55\u4FA1\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306E\u8D77\u52D5\u30BF\u30A4\u30DF\u30F3\u30B0")
109
+ }).describe("\u5404\u30EB\u30FC\u30EB\u306E\u52D5\u7684\u8AAD\u8FBC\u30C8\u30EA\u30AC\u30FC\u8A2D\u5B9A")
110
+ }).optional().describe("\u52D5\u7684\u30EB\u30FC\u30EB\u8AAD\u307F\u8FBC\u307F\u8A2D\u5B9A (\u7701\u7565\u6642\u306F lazy + always \u3092\u4F7F\u7528)"),
111
+ // ─── v2: インタビューから生成される差別化フィールド ────────────────────
112
+ archetype: z.enum(ARCHETYPES).optional().describe("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30A2\u30FC\u30AD\u30BF\u30A4\u30D7\uFF08setup\u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u3067\u81EA\u52D5\u691C\u51FA\uFF09"),
113
+ workflow: z.object({
114
+ confirmation_frequency: z.enum(["high", "medium", "low"]).default("medium").describe("Claude\u304C\u78BA\u8A8D\u3092\u631F\u3080\u983B\u5EA6: high=\u3053\u307E\u3081 / medium=\u6A19\u6E96 / low=\u4EFB\u305B\u308B"),
115
+ autonomy_level: z.enum(["conservative", "balanced", "autonomous"]).default("balanced").describe("Claude\u306E\u81EA\u5F8B\u5EA6: conservative=\u614E\u91CD / balanced=\u6A19\u6E96 / autonomous=\u7A4D\u6975\u7684"),
116
+ scope_guard: z.boolean().default(false).describe("\u6307\u793A\u7BC4\u56F2\u5916\u306E\u30D5\u30A1\u30A4\u30EB\u5909\u66F4\u3092\u9632\u6B62\u3059\u308B\u304B"),
117
+ completion_criteria: z.string().optional().describe("\u30BF\u30B9\u30AF\u5B8C\u4E86\u306E\u5224\u65AD\u57FA\u6E96\uFF08\u81EA\u7531\u8A18\u8FF0\uFF09")
118
+ }).optional().describe("\u4F5C\u696D\u30B9\u30BF\u30A4\u30EB\u8A2D\u5B9A\uFF08\u7701\u7565\u6642\u306F\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u3092\u4F7F\u7528\uFF09"),
119
+ communication: z.object({
120
+ verbosity: z.enum(["minimal", "normal", "detailed"]).default("normal").describe("\u5FDC\u7B54\u306E\u8A73\u3057\u3055: minimal=\u30B3\u30FC\u30C9\u306E\u307F / normal=\u8981\u70B9\u306E\u307F / detailed=\u4E01\u5BE7\u306B\u8AAC\u660E"),
121
+ preserve_voice: z.boolean().default(false).describe("\u30E6\u30FC\u30B6\u30FC\u306E\u6587\u4F53\u30FB\u30C8\u30FC\u30F3\u3092\u7DAD\u6301\u3059\u308B\u304B\uFF08\u8A18\u4E8B\u57F7\u7B46\u7B49\u3067\u4F7F\u7528\uFF09"),
122
+ error_notification: z.enum(["stop", "notify", "continue"]).default("notify").describe("\u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044: stop=\u5373\u505C\u6B62 / notify=\u5831\u544A\u3057\u3066\u7D9A\u884C / continue=\u81EA\u52D5\u7D99\u7D9A"),
123
+ report_frequency: z.enum(["always", "on_milestone", "on_error", "never"]).default("on_milestone").describe("\u9032\u6357\u5831\u544A\u306E\u30BF\u30A4\u30DF\u30F3\u30B0")
124
+ }).optional().describe("\u30B3\u30DF\u30E5\u30CB\u30B1\u30FC\u30B7\u30E7\u30F3\u30B9\u30BF\u30A4\u30EB\u8A2D\u5B9A"),
125
+ automation: z.object({
126
+ enabled: z.boolean().default(false).describe("\u5B9A\u671F\u5B9F\u884C\u30FB\u81EA\u52D5\u5316\u6A5F\u80FD\u3092\u6709\u52B9\u306B\u3059\u308B\u304B"),
127
+ schedule: z.string().nullable().default(null).describe("\u5B9F\u884C\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\uFF08cron\u5F62\u5F0F or \u81EA\u7136\u8A00\u8A9E\uFF09"),
128
+ retry_on_error: z.boolean().default(false).describe("\u30A8\u30E9\u30FC\u6642\u306B\u81EA\u52D5\u30EA\u30C8\u30E9\u30A4\u3059\u308B\u304B"),
129
+ error_escalation: z.enum(["stop", "retry", "notify"]).default("stop").describe("\u30A8\u30E9\u30FC\u6642\u306E\u30A8\u30B9\u30AB\u30EC\u30FC\u30B7\u30E7\u30F3: stop=\u5373\u505C\u6B62 / retry=\u30EA\u30C8\u30E9\u30A4 / notify=\u901A\u77E5"),
130
+ max_retries: z.number().int().min(0).max(10).default(3).describe("\u6700\u5927\u30EA\u30C8\u30E9\u30A4\u56DE\u6570")
131
+ }).optional().describe("\u81EA\u52D5\u5316\u30FB\u5B9A\u671F\u5B9F\u884C\u8A2D\u5B9A\uFF08\u7701\u7565\u6642\u306F\u7121\u52B9\uFF09")
132
+ });
133
+
134
+ // src/converters/claudeMdGenerator.ts
135
+ var LANGUAGE_MAP = {
136
+ ja: "Japanese (\u65E5\u672C\u8A9E)",
137
+ en: "English",
138
+ zh: "Chinese (\u4E2D\u6587)",
139
+ ko: "Korean (\uD55C\uAD6D\uC5B4)"
140
+ };
141
+ var COST_MODE_DESCRIPTIONS = {
142
+ ECO: {
143
+ style: "code_only \u2014 output code without explanations",
144
+ details: "- Skip explanations unless fatal error\n- No docstrings on unchanged code\n- Minimal test scaffolding"
145
+ },
146
+ BALANCED: {
147
+ style: "concise \u2014 key points with brief context",
148
+ details: "- Normal: lightweight output\n- On error: switch to deep Chain-of-Thought (CoT) reasoning\n- Tests: critical paths only"
149
+ },
150
+ PRO: {
151
+ style: "detailed \u2014 comprehensive with full reasoning",
152
+ details: "- Always use deep reasoning\n- Comprehensive test coverage required\n- security check on every implementation\n- Always review for OWASP Top 10"
153
+ }
154
+ };
155
+ function generateClaudeMd(config) {
156
+ const { project, cost_mode } = config;
157
+ const session_mirroring = config.session_mirroring ?? {
158
+ output_path: ".claude/sessions/current_session.md"
159
+ };
160
+ const lang = LANGUAGE_MAP[project.language] ?? project.language;
161
+ const modeDesc = COST_MODE_DESCRIPTIONS[cost_mode.current];
162
+ const archetypeLabel = config.archetype ? ARCHETYPE_LABELS[config.archetype] : null;
163
+ const extraRules = [];
164
+ if (config.archetype) {
165
+ extraRules.push(`- Archetype rules: \`.claude/rules/archetype_rules.md\``);
166
+ }
167
+ if (config.workflow) {
168
+ extraRules.push(`- Workflow rules: \`.claude/rules/workflow_rules.md\``);
169
+ }
170
+ if (config.communication) {
171
+ extraRules.push(`- Communication style: \`.claude/rules/communication_style.md\``);
172
+ }
173
+ if (config.automation?.enabled) {
174
+ extraRules.push(`- Automation rules: \`.claude/rules/automation_rules.md\``);
175
+ }
176
+ const extraRulesSection = extraRules.length > 0 ? `${extraRules.join("\n")}
177
+ ` : "";
178
+ const tuneSection = config.archetype ? `
179
+ ## Tune (\u30CF\u30FC\u30CD\u30B9\u8ABF\u6574)
180
+ - \u30CF\u30FC\u30CD\u30B9\u3092\u8ABF\u6574\u3057\u305F\u3044\u6642\u306F \`.claude/commands/tune.md\` \u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044
181
+ - \u307E\u305F\u306F \`/tune <\u8ABF\u6574\u3057\u305F\u3044\u5185\u5BB9>\` \u3068\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
182
+ ` : "";
183
+ return `# Project Harness \u2014 ${project.name}
184
+ <!-- Generated by HarnessCrafter v1.0.0 | DO NOT EDIT MANUALLY -->
185
+ <!-- Config: .claude/harness_config.json | Regenerate: npx harness-crafter generate -->
186
+
187
+ ## Core Rules (always active)
188
+ - Response language: ${lang}
189
+ - Cost mode: ${cost_mode.current} \u2014 ${modeDesc.style}
190
+ - Domain: ${project.domain}
191
+ - User level: ${project.user_level}${archetypeLabel ? `
192
+ - Archetype: ${config.archetype} (${archetypeLabel})` : ""}
193
+
194
+ ## Dynamic Rule Loading
195
+ At the start of each session, load relevant rules via the Read tool:
196
+ - Domain rules: \`.claude/rules/domain_rules.md\`
197
+ - User level rules: \`.claude/rules/user_level_rules.md\`
198
+ - Cost mode rules: \`.claude/rules/cost_mode_rules.md\`
199
+ ${extraRulesSection}
200
+ These files are NOT loaded automatically \u2014 you MUST read them when starting work.
201
+
202
+ ## Session ID Protocol
203
+ - All significant code outputs MUST include a unique ID: \`[ID: #MMDD-SEQ]\` (e.g., \`[ID: #0520-A]\`)
204
+ - When the user references an ID (e.g., "ID: #0520-A \u306E\u4EF6"), search \`${session_mirroring.output_path}\` for that ID and restore context before responding
205
+ - IDs are sequential within a session: A, B, C, ..., Z, AA, AB, ...
206
+
207
+ ## Cost Mode: ${cost_mode.current}
208
+ ${modeDesc.details}
209
+
210
+ ## Sub-Agents (invoke when needed)
211
+ - Evaluator: \`.claude/sub-agents/evaluator.md\` \u2014 invoke after each implementation phase
212
+ - Code Reviewer: \`.claude/sub-agents/code_reviewer.md\` \u2014 invoke before finalizing code
213
+ - Session Summarizer: \`.claude/sub-agents/session_summarizer.md\` \u2014 invoke at session end
214
+
215
+ ## Memory Bank
216
+ At session start: read \`memory-bank/activeContext.md\` and \`memory-bank/progress.md\`
217
+ At session end: update both files and \`memory-bank/decisions.md\` if key decisions were made
218
+ ${tuneSection}`;
219
+ }
220
+
221
+ // src/converters/_generated/domainTemplates.ts
222
+ var DOMAIN_RULES = {
223
+ product_dev: `# Domain Rules: Product Development (product_dev)
224
+
225
+ ## Primary Focus
226
+ - **robust** architecture: prioritize testability, maintainability, and reliability
227
+ - **test-driven development**: write tests before implementation (RED \u2192 GREEN \u2192 REFACTOR)
228
+ - All critical paths must have unit + integration tests
229
+ - Use type-safe code; avoid \`any\` types
230
+
231
+ ## Code Quality
232
+ - Test coverage target: 80%+ for business logic
233
+ - Document public APIs with JSDoc/type annotations
234
+ - Handle edge cases and error states explicitly
235
+ - Prefer immutable data structures
236
+
237
+ ## Workflow
238
+ - Before implementing: read existing patterns, avoid duplication
239
+ - After implementing: run tests, verify coverage
240
+ - On breaking changes: update CHANGELOG.md
241
+ - Security: validate all external inputs, never trust user data
242
+ `,
243
+ realtime_monitor: `# Domain Rules: Realtime Monitor / Bot (realtime_monitor)
244
+
245
+ ## Primary Focus
246
+ - **error handling**: assume failure at every integration point \u2014 wrap with try/catch, use circuit breakers
247
+ - **real-time responsiveness**: minimize latency; prefer async/non-blocking patterns
248
+ - Graceful degradation when dependencies are unavailable
249
+ - Structured logging on every significant event
250
+
251
+ ## Reliability Patterns
252
+ - Implement retry logic with exponential backoff
253
+ - Use health check endpoints
254
+ - Alert thresholds must be configurable (not hardcoded)
255
+ - Dead letter queues for failed messages
256
+
257
+ ## Monitoring
258
+ - Log at DEBUG/INFO/WARN/ERROR levels appropriately
259
+ - Include correlation IDs in all log entries
260
+ - Metrics: latency p50/p95/p99, error rate, throughput
261
+ `,
262
+ cron_job: `# Domain Rules: Cron Job / Scheduled Task (cron_job)
263
+
264
+ ## Primary Focus
265
+ - **log every execution**: start time, end time, records processed, errors
266
+ - **resource efficiency**: minimize memory and CPU; clean up temp files
267
+ - Idempotency: jobs must be safe to re-run without double-processing
268
+
269
+ ## Error Handling
270
+ - On failure: log full stack trace, send alert, preserve state for resume
271
+ - Implement lock mechanism to prevent concurrent runs
272
+ - Timeout protection: long-running jobs must have max-duration limits
273
+
274
+ ## Observability
275
+ - Report execution summary to monitoring dashboard
276
+ - Retain logs for minimum 30 days
277
+ - Track trend metrics: duration over time, record counts
278
+ `,
279
+ design_web: `# Domain Rules: Design / Web (design_web)
280
+
281
+ ## Primary Focus
282
+ - **UI/UX**: pixel-perfect implementation from design specs (Figma)
283
+ - **responsive**: mobile-first, test at 320px / 768px / 1440px breakpoints
284
+ - Accessibility: WCAG 2.1 AA compliance (aria-labels, keyboard navigation, contrast ratios)
285
+
286
+ ## Frontend Standards
287
+ - Use design tokens (CSS variables or theme tokens) \u2014 no hardcoded hex values
288
+ - Component-based architecture; single responsibility principle
289
+ - Performance: Core Web Vitals targets (LCP < 2.5s, CLS < 0.1, INP < 200ms)
290
+ - Cross-browser: Chrome, Firefox, Safari, Edge
291
+
292
+ ## Figma Integration
293
+ - When given a Figma URL, use get_design_context first
294
+ - Map Figma components to existing codebase components before creating new ones
295
+ - Preserve exact spacing, typography, and color from design
296
+ `,
297
+ marketing_ads: `# Domain Rules: Marketing / Ads Management (marketing_ads)
298
+
299
+ ## Primary Focus
300
+ - **data analysis**: support A/B testing, funnel analysis, attribution modeling
301
+ - **copywriting**: persuasive, clear, audience-targeted text
302
+ - Effect measurement: always define KPIs before implementation
303
+
304
+ ## Analytics
305
+ - Track conversion events with proper UTM parameters
306
+ - Implement attribution windows correctly
307
+ - Data privacy: GDPR/CCPA compliance for user tracking
308
+ - Support for multiple ad platforms (Google Ads, Meta, etc.)
309
+
310
+ ## Content
311
+ - A/B test variants must be statistically significant before declaring winner
312
+ - Copy must match brand voice guidelines
313
+ - Localization support for multi-region campaigns
314
+ `,
315
+ outsourced_dev: `# Domain Rules: Outsourced Development (outsourced_dev)
316
+
317
+ ## Primary Focus
318
+ - **spec compliance**: never deviate from client specifications without explicit approval
319
+ - **communication (\u5831\u9023\u76F8)**: report, consult, and inform at every milestone
320
+ - Maintain CHANGELOG.md with every significant change
321
+
322
+ ## Process
323
+ - Before starting: confirm requirements are unambiguous; ask if unclear
324
+ - During development: daily/weekly status reports
325
+ - Before delivery: full regression test + acceptance criteria checklist
326
+ - Code review by senior developer before client delivery
327
+
328
+ ## Documentation
329
+ - Inline comments for non-obvious logic
330
+ - README must include: setup, configuration, deployment, troubleshooting
331
+ - API documentation: OpenAPI/Swagger spec for all endpoints
332
+ `,
333
+ research_rd: `# Domain Rules: Research & Development (research_rd)
334
+
335
+ ## Primary Focus
336
+ - **hypothesis-driven**: every experiment starts with a clear hypothesis
337
+ - **multiple approaches**: present at least 2-3 alternative implementations with trade-off analysis
338
+ - Cite relevant papers/sources (use arxiv IDs, DOIs)
339
+
340
+ ## Experimentation
341
+ - Document experimental setup: parameters, dataset, baseline
342
+ - Track results in structured format (CSV/JSON) for reproducibility
343
+ - Statistical significance: report confidence intervals, p-values where applicable
344
+ - Version control for experiments: tag or branch each experiment run
345
+
346
+ ## Knowledge Management
347
+ - Summarize findings in a research log
348
+ - Link to related prior work
349
+ - Clearly distinguish proven results from hypotheses
350
+ `
351
+ };
352
+
353
+ // src/converters/domainRulesGenerator.ts
354
+ function generateDomainRules(domain) {
355
+ return DOMAIN_RULES[domain];
356
+ }
357
+
358
+ // src/converters/_generated/userLevelTemplates.ts
359
+ var USER_LEVEL_RULES = {
360
+ expert: `# User Level Rules: expert
361
+
362
+ ## Communication Style
363
+ - Target user: expert-level developer/architect
364
+ - No explanation of basic concepts \u2014 assume deep knowledge
365
+ - Provide conclusion + code only; omit reasoning unless asked
366
+ - Use precise technical terminology without simplification
367
+ - Skip setup instructions, environment configuration steps
368
+
369
+ ## Response Format
370
+ - Lead with the answer or the code
371
+ - Brief inline comments only for non-obvious logic
372
+ - No verbose docstrings on standard patterns
373
+ - Reference advanced patterns (design patterns, distributed systems concepts) by name
374
+ `,
375
+ competent: `# User Level Rules: competent practitioner
376
+
377
+ ## Communication Style
378
+ - Target user: working developer with solid foundations
379
+ - concise explanations of non-obvious choices
380
+ - Standard technical terminology; define specialized terms briefly when first used
381
+ - Include relevant best practices and "why" for important decisions
382
+ - Skip step-by-step basics (Git basics, npm install, etc.)
383
+
384
+ ## Response Format
385
+ - Lead with the key insight, follow with code
386
+ - Explain trade-offs when multiple approaches exist
387
+ - Mention common pitfalls for the current task
388
+ - Include brief inline comments on complex logic
389
+ `,
390
+ novice: `# User Level Rules: novice / non-engineer
391
+
392
+ ## Communication Style
393
+ - Target user: beginner or non-technical user
394
+ - Explain from first principles \u2014 "what is X" before "how to use X"
395
+ - step-by-step instructions for every terminal command
396
+ - Use plain Japanese (\u65E5\u672C\u8A9E); avoid English jargon without translation
397
+ - Confirm understanding before moving to the next step
398
+
399
+ ## Response Format
400
+ - Start with a plain-language summary of what will happen
401
+ - Numbered steps for any multi-step process
402
+ - Show exact commands with copy-paste format
403
+ - Explain error messages in plain language when they occur
404
+ - Celebrate small wins to keep motivation up
405
+ - Avoid: raw HTTP requests, technical acronyms without explanation, code without context
406
+ `
407
+ };
408
+
409
+ // src/converters/userLevelAdapter.ts
410
+ function generateUserLevelRules(level) {
411
+ return USER_LEVEL_RULES[level];
412
+ }
413
+
414
+ // src/converters/costModeAdapter.ts
415
+ var COST_MODE_RULES = {
416
+ ECO: `# Cost Mode Rules: ECO
417
+
418
+ ## Output Policy
419
+ - **code_only**: output code with NO prose explanations
420
+ - Skip all docstrings, inline comments (except non-obvious logic)
421
+ - skip test generation unless explicitly requested
422
+ - No architecture discussion, no trade-off analysis
423
+ - Omit "let me explain..." preambles entirely
424
+
425
+ ## Token Conservation
426
+ - Minimal response length \u2014 answer the question, stop
427
+ - No summaries or recaps at the end of responses
428
+ - Avoid repeating code that was already shown
429
+ - Use terse variable/function names where unambiguous
430
+
431
+ ## When to Break ECO Rules
432
+ - Fatal errors: brief explanation of root cause is allowed
433
+ - Security vulnerabilities: must flag even in ECO mode
434
+ `,
435
+ BALANCED: `# Cost Mode Rules: BALANCED
436
+
437
+ ## Output Policy
438
+ - **concise**: key points with enough context to understand
439
+ - Normal operation: lightweight, focused responses
440
+ - On error or unexpected behavior: switch to deep **Chain-of-Thought (CoT)** reasoning
441
+ - Tests: generate for critical paths only (happy path + 1-2 edge cases)
442
+
443
+ ## Reasoning Trigger
444
+ Switch to deep reasoning when:
445
+ - A bug or unexpected output occurs
446
+ - The approach is non-obvious or has significant trade-offs
447
+ - The user asks "why" or "explain"
448
+
449
+ ## Response Format
450
+ - Lead with the direct answer
451
+ - Include brief "why" for important decisions
452
+ - Summarize changes if they affect multiple files
453
+ `,
454
+ PRO: `# Cost Mode Rules: PRO
455
+
456
+ ## Output Policy
457
+ - **detailed**: comprehensive output with full reasoning
458
+ - **always** use deep Chain-of-Thought reasoning before responding
459
+ - Comprehensive test coverage: unit + integration + edge cases
460
+ - security check on every implementation \u2014 review OWASP Top 10
461
+ - Full docstrings and inline comments
462
+
463
+ ## Quality Gates
464
+ - Before finalizing code: invoke \`.claude/sub-agents/evaluator.md\`
465
+ - After significant changes: invoke \`.claude/sub-agents/code_reviewer.md\`
466
+ - Explicitly check for: SQL injection, XSS, CSRF, insecure deserialization, broken auth
467
+
468
+ ## Response Format
469
+ - Start with a design overview
470
+ - Include trade-off analysis for key decisions
471
+ - List assumptions explicitly
472
+ - End with a verification checklist
473
+ `
474
+ };
475
+ function generateCostModeRules(mode) {
476
+ return COST_MODE_RULES[mode];
477
+ }
478
+
479
+ // src/converters/workflowRulesGenerator.ts
480
+ var CONFIRMATION_RULES = {
481
+ high: `## \u78BA\u8A8D\u983B\u5EA6: \u3053\u307E\u3081\u306B\u78BA\u8A8D\u3059\u308B
482
+ - \u4F5C\u696D\u306E\u5404\u30B9\u30C6\u30C3\u30D7\u3092\u59CB\u3081\u308B\u524D\u306B\u3001\u65B9\u5411\u6027\u3092\u78BA\u8A8D\u3057\u3066\u304B\u3089\u9032\u3080
483
+ - \u8907\u6570\u306E\u9078\u629E\u80A2\u304C\u3042\u308B\u5834\u5408\u306F\u5FC5\u305A\u63D0\u793A\u3057\u3066\u9078\u3070\u305B\u308B
484
+ - \u30D5\u30A1\u30A4\u30EB\u3092\u5909\u66F4\u3059\u308B\u524D\u306B\u300C\u301C\u3092\u5909\u66F4\u3057\u3066\u3088\u3044\u3067\u3059\u304B\uFF1F\u300D\u3068\u78BA\u8A8D\u3059\u308B
485
+ - \u4E88\u60F3\u5916\u306E\u72B6\u6CC1\u306B\u906D\u9047\u3057\u305F\u3089\u3001\u5373\u5EA7\u306B\u5831\u544A\u3057\u3066\u6307\u793A\u3092\u4EF0\u3050`,
486
+ medium: `## \u78BA\u8A8D\u983B\u5EA6: \u6A19\u6E96\uFF08\u7BC0\u76EE\u3067\u78BA\u8A8D\uFF09
487
+ - \u5927\u304D\u306A\u65B9\u5411\u8EE2\u63DB\u304C\u5FC5\u8981\u306A\u5834\u5408\u306E\u307F\u78BA\u8A8D\u3059\u308B
488
+ - \u8EFD\u5FAE\u306A\u5909\u66F4\u306F\u5831\u544A\u3057\u306A\u304C\u3089\u9032\u3081\u308B
489
+ - \u4F5C\u696D\u306E\u7BC0\u76EE\uFF08\u30D5\u30A7\u30FC\u30BA\u5B8C\u4E86\u6642\uFF09\u306B\u307E\u3068\u3081\u3066\u78BA\u8A8D\u3059\u308B`,
490
+ low: `## \u78BA\u8A8D\u983B\u5EA6: \u4EFB\u305B\u308B\uFF08\u5B8C\u6210\u3057\u3066\u304B\u3089\u898B\u305B\u308B\uFF09
491
+ - \u5B8C\u6210\u3057\u3066\u304B\u3089\u898B\u305B\u308B\u3002\u9014\u4E2D\u306E\u78BA\u8A8D\u306F\u6700\u5C0F\u9650\u306B\u3059\u308B
492
+ - \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u305F\u5834\u5408\u306E\u307F\u505C\u6B62\u3057\u3066\u5831\u544A\u3059\u308B
493
+ - \u5168\u4F53\u50CF\u304C\u898B\u3048\u305F\u30BF\u30A4\u30DF\u30F3\u30B0\u3067\u30EC\u30D3\u30E5\u30FC\u3092\u6C42\u3081\u308B`
494
+ };
495
+ var AUTONOMY_RULES = {
496
+ conservative: `## \u81EA\u5F8B\u5EA6: \u614E\u91CD\uFF08\u6307\u793A\u3055\u308C\u305F\u7BC4\u56F2\u306E\u307F\uFF09
497
+ - \u6307\u793A\u3055\u308C\u305F\u7BC4\u56F2\u3060\u3051\u3092\u5909\u66F4\u3059\u308B\u3002\u95A2\u9023\u7B87\u6240\u3067\u3082\u52DD\u624B\u306B\u5909\u3048\u306A\u3044
498
+ - \u300C\u5FF5\u306E\u305F\u3081\u6539\u5584\u3057\u3066\u304A\u304D\u307E\u3057\u305F\u300D\u306F\u3057\u306A\u3044
499
+ - \u3084\u308A\u3059\u304E\u306E\u6C17\u914D\u304C\u3042\u308C\u3070\u81EA\u5206\u3067\u6B62\u307E\u308B`,
500
+ balanced: `## \u81EA\u5F8B\u5EA6: \u6A19\u6E96\uFF08\u76F4\u63A5\u95A2\u4FC2\u3059\u308B\u7BC4\u56F2\u306F\u81EA\u5F8B\uFF09
501
+ - \u76F4\u63A5\u95A2\u4FC2\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u306F\u5224\u65AD\u3067\u5909\u66F4\u3057\u3066\u3088\u3044
502
+ - \u660E\u3089\u304B\u306A\u30D0\u30B0\u3084\u554F\u984C\u306F\u6307\u6458\u3057\u3064\u3064\u4FEE\u6B63\u3059\u308B
503
+ - \u5927\u304D\u306A\u69CB\u9020\u5909\u66F4\u306F\u78BA\u8A8D\u3092\u53D6\u308B`,
504
+ autonomous: `## \u81EA\u5F8B\u5EA6: \u7A4D\u6975\u7684\uFF08\u76EE\u6A19\u9054\u6210\u3092\u512A\u5148\uFF09
505
+ - \u76EE\u6A19\u9054\u6210\u306E\u305F\u3081\u306B\u5FC5\u8981\u306A\u5909\u66F4\u306F\u81EA\u5F8B\u7684\u306B\u884C\u3046
506
+ - \u30D9\u30B9\u30C8\u30D7\u30E9\u30AF\u30C6\u30A3\u30B9\u306B\u6CBF\u3063\u305F\u6539\u5584\u306F\u7A4D\u6975\u7684\u306B\u884C\u3046
507
+ - \u5B8C\u4E86\u5F8C\u306B\u307E\u3068\u3081\u3066\u5909\u66F4\u5185\u5BB9\u3092\u5831\u544A\u3059\u308B`
508
+ };
509
+ function generateWorkflowRules(config) {
510
+ const workflow = config.workflow ?? {
511
+ confirmation_frequency: "medium",
512
+ autonomy_level: "balanced",
513
+ scope_guard: false
514
+ };
515
+ const lines = [
516
+ `# Workflow Rules`,
517
+ `<!-- Generated by HarnessCrafter | archetype: ${config.archetype ?? "none"} -->`,
518
+ "",
519
+ CONFIRMATION_RULES[workflow.confirmation_frequency],
520
+ "",
521
+ AUTONOMY_RULES[workflow.autonomy_level]
522
+ ];
523
+ if (workflow.scope_guard) {
524
+ lines.push(
525
+ "",
526
+ `## \u30B9\u30B3\u30FC\u30D7\u30AC\u30FC\u30C9\uFF08\u6709\u52B9\uFF09`,
527
+ `- \u660E\u793A\u7684\u306B\u6307\u793A\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u4EE5\u5916\u306F\u5909\u66F4\u3057\u306A\u3044`,
528
+ `- \u5909\u66F4\u524D\u306B\u5BFE\u8C61\u30D5\u30A1\u30A4\u30EB\u306E\u4E00\u89A7\u3092\u63D0\u793A\u3059\u308B`,
529
+ `- \u610F\u56F3\u3057\u306A\u3044\u5909\u66F4\u3092\u30BC\u30ED\u306B\u3059\u308B\u3053\u3068\u3092\u6700\u512A\u5148\u306B\u3059\u308B`
530
+ );
531
+ }
532
+ if (workflow.completion_criteria) {
533
+ lines.push("", `## \u5B8C\u4E86\u6761\u4EF6`, workflow.completion_criteria);
534
+ }
535
+ lines.push("");
536
+ return lines.join("\n");
537
+ }
538
+
539
+ // src/converters/communicationStyleGenerator.ts
540
+ var VERBOSITY_RULES = {
541
+ minimal: `## \u5FDC\u7B54\u306E\u8A73\u3057\u3055: \u6700\u5C0F\u9650\uFF08\u30B3\u30FC\u30C9\u3068\u7D50\u679C\u3060\u3051\uFF09
542
+ - \u30B3\u30FC\u30C9\u3068\u7D50\u679C\u3060\u3051\u51FA\u3059\u3002\u8AAC\u660E\u306F\u6C42\u3081\u3089\u308C\u305F\u6642\u3060\u3051
543
+ - \u300C\u301C\u306E\u305F\u3081\u301C\u3057\u307E\u3057\u305F\u300D\u306E\u8AAC\u660E\u6587\u306F\u7701\u7565\u3059\u308B
544
+ - \u30A8\u30E9\u30FC\u306F\u539F\u56E0\u3068\u4FEE\u6B63\u65B9\u6CD5\u30921\u884C\u305A\u3064\u3067`,
545
+ normal: `## \u5FDC\u7B54\u306E\u8A73\u3057\u3055: \u6A19\u6E96\uFF08\u8981\u70B9\u306E\u307F\uFF09
546
+ - \u8981\u70B9\u3060\u3051\u4F1D\u3048\u308B\u3002\u9577\u3044\u8AAC\u660E\u306F\u907F\u3051\u308B
547
+ - \u91CD\u8981\u306A\u5224\u65AD\u306B\u306F\u77ED\u3044\u7406\u7531\u3092\u6DFB\u3048\u308B
548
+ - \u8907\u6570\u30D5\u30A1\u30A4\u30EB\u306E\u5909\u66F4\u306F\u30B5\u30DE\u30EA\u30FC\u30921\u6BB5\u843D\u3067`,
549
+ detailed: `## \u5FDC\u7B54\u306E\u8A73\u3057\u3055: \u8A73\u7D30\uFF08\u4E01\u5BE7\u306B\u8AAC\u660E\uFF09
550
+ - \u4F55\u3092\u306A\u305C\u884C\u3063\u3066\u3044\u308B\u304B\u3092\u4E01\u5BE7\u306B\u8AAC\u660E\u3059\u308B
551
+ - \u521D\u3081\u3066\u51FA\u3066\u304F\u308B\u6982\u5FF5\u306F\u7C21\u5358\u306B\u89E3\u8AAC\u3059\u308B
552
+ - \u9078\u629E\u80A2\u304C\u3042\u308B\u5834\u5408\u306F\u6BD4\u8F03\u3057\u3066\u8AAC\u660E\u3059\u308B`
553
+ };
554
+ var ERROR_NOTIFICATION_RULES = {
555
+ stop: `## \u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044: \u5373\u505C\u6B62
556
+ - \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u305F\u3089\u5373\u5EA7\u306B\u4F5C\u696D\u3092\u6B62\u3081\u308B
557
+ - \u4F55\u304C\u8D77\u304D\u305F\u304B\u3001\u3069\u3053\u3067\u8D77\u304D\u305F\u304B\u3092\u660E\u78BA\u306B\u5831\u544A\u3059\u308B
558
+ - \u4FEE\u6B63\u65B9\u6CD5\u306E\u9078\u629E\u80A2\u3092\u63D0\u793A\u3057\u3066\u5224\u65AD\u3092\u4EF0\u3050`,
559
+ notify: `## \u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044: \u5831\u544A\u3057\u3066\u7D9A\u884C
560
+ - \u30A8\u30E9\u30FC\u3092\u691C\u77E5\u3057\u305F\u3089\u5831\u544A\u3059\u308B\u304C\u3001\u8EFD\u5FAE\u306A\u3082\u306E\u306F\u81EA\u52D5\u4FEE\u6B63\u3059\u308B
561
+ - \u91CD\u5927\u306A\u30A8\u30E9\u30FC\uFF08\u30C7\u30FC\u30BF\u6D88\u5931\u30FB\u91D1\u92AD\u7684\u5F71\u97FF\u306E\u53EF\u80FD\u6027\uFF09\u306F\u5FC5\u305A\u505C\u6B62\u3059\u308B
562
+ - \u4FEE\u6B63\u3057\u305F\u5834\u5408\u306F\u4F55\u3092\u5909\u3048\u305F\u304B\u3092\u5831\u544A\u3059\u308B`,
563
+ continue: `## \u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044: \u81EA\u52D5\u7D99\u7D9A
564
+ - \u81EA\u52D5\u3067\u4FEE\u6B63\u3092\u8A66\u307F\u308B
565
+ - \u4FEE\u6B63\u3067\u304D\u306A\u3044\u5834\u5408\u306E\u307F\u5831\u544A\u3059\u308B
566
+ - \u30A8\u30E9\u30FC\u30ED\u30B0\u306F\u5225\u9014\u8A18\u9332\u3057\u3066\u304A\u304F`
567
+ };
568
+ var REPORT_FREQUENCY_RULES = {
569
+ always: `## \u9032\u6357\u5831\u544A: \u5E38\u6642\u5831\u544A
570
+ - \u5404\u30B9\u30C6\u30C3\u30D7\u306E\u958B\u59CB\u3068\u5B8C\u4E86\u3092\u5831\u544A\u3059\u308B`,
571
+ on_milestone: `## \u9032\u6357\u5831\u544A: \u7BC0\u76EE\u3067\u5831\u544A
572
+ - \u30D5\u30A7\u30FC\u30BA\u306E\u5B8C\u4E86\u6642\u306B\u307E\u3068\u3081\u3066\u5831\u544A\u3059\u308B`,
573
+ on_error: `## \u9032\u6357\u5831\u544A: \u30A8\u30E9\u30FC\u6642\u306E\u307F
574
+ - \u30A8\u30E9\u30FC\u30FB\u554F\u984C\u304C\u767A\u751F\u3057\u305F\u6642\u3060\u3051\u5831\u544A\u3059\u308B`,
575
+ never: `## \u9032\u6357\u5831\u544A: \u5B8C\u6210\u6642\u306E\u307F
576
+ - \u5B8C\u6210\u3057\u305F\u3082\u306E\u3060\u3051\u898B\u305B\u308B`
577
+ };
578
+ function generateCommunicationStyle(config) {
579
+ const comm = config.communication ?? {
580
+ verbosity: "normal",
581
+ preserve_voice: false,
582
+ error_notification: "notify",
583
+ report_frequency: "on_milestone"
584
+ };
585
+ const lines = [
586
+ `# Communication Style Rules`,
587
+ `<!-- Generated by HarnessCrafter | archetype: ${config.archetype ?? "none"} -->`,
588
+ "",
589
+ VERBOSITY_RULES[comm.verbosity],
590
+ "",
591
+ ERROR_NOTIFICATION_RULES[comm.error_notification],
592
+ "",
593
+ REPORT_FREQUENCY_RULES[comm.report_frequency]
594
+ ];
595
+ if (comm.preserve_voice) {
596
+ lines.push(
597
+ "",
598
+ `## \u6587\u4F53\u30FB\u30C8\u30FC\u30F3\u306E\u4FDD\u6301`,
599
+ `- \u30E6\u30FC\u30B6\u30FC\u304C\u904E\u53BB\u306B\u4F7F\u7528\u3057\u305F\u8868\u73FE\u30FB\u8A00\u3044\u56DE\u3057\u3092\u53C2\u7167\u3057\u3066\u6587\u4F53\u3092\u5408\u308F\u305B\u308B`,
600
+ `- \u300C\u3067\u3059\u307E\u3059\u300D\u304B\u300C\u3060\u30FB\u3067\u3042\u308B\u300D\u304B\u3092\u7D71\u4E00\u3059\u308B`,
601
+ `- \u30D6\u30E9\u30F3\u30C9\u30DC\u30A4\u30B9\u3084\u65E2\u5B58\u30B3\u30F3\u30C6\u30F3\u30C4\u306E\u30C8\u30FC\u30F3\u3092\u7DAD\u6301\u3059\u308B`
602
+ );
603
+ }
604
+ lines.push("");
605
+ return lines.join("\n");
606
+ }
607
+
608
+ // src/converters/automationRulesGenerator.ts
609
+ var ERROR_ESCALATION_RULES = {
610
+ stop: `- \u30A8\u30E9\u30FC\u767A\u751F\u6642\u306F\u5373\u5EA7\u306B\u505C\u6B62\u3059\u308B\u3002\u6B21\u56DE\u306E\u5B9F\u884C\u307E\u3067\u5F85\u6A5F\u3059\u308B`,
611
+ retry: `- \u30A8\u30E9\u30FC\u767A\u751F\u6642\u306F\u81EA\u52D5\u30EA\u30C8\u30E9\u30A4\u3092\u8A66\u307F\u308B\uFF08\u6700\u5927\u56DE\u6570\u307E\u3067\uFF09`,
612
+ notify: `- \u30A8\u30E9\u30FC\u767A\u751F\u6642\u306F\u901A\u77E5\u3092\u9001\u308A\u3001\u6B21\u306E\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u5B9F\u884C\u307E\u3067\u7D99\u7D9A\u3059\u308B`
613
+ };
614
+ function generateAutomationRules(config) {
615
+ const auto = config.automation ?? {
616
+ enabled: false,
617
+ schedule: null,
618
+ retry_on_error: false,
619
+ error_escalation: "stop",
620
+ max_retries: 3
621
+ };
622
+ const lines = [
623
+ `# Automation Rules`,
624
+ `<!-- Generated by HarnessCrafter | archetype: ${config.archetype ?? "none"} -->`,
625
+ ""
626
+ ];
627
+ if (!auto.enabled) {
628
+ lines.push(
629
+ `## \u81EA\u52D5\u5316: \u7121\u52B9`,
630
+ `- \u5B9A\u671F\u5B9F\u884C\u30FB\u81EA\u52D5\u5316\u306F\u73FE\u5728\u7121\u52B9\u3067\u3059`,
631
+ `- \u30BF\u30B9\u30AF\u306F\u624B\u52D5\u3067\u30C8\u30EA\u30AC\u30FC\u3057\u3066\u304F\u3060\u3055\u3044`,
632
+ ""
633
+ );
634
+ return lines.join("\n");
635
+ }
636
+ lines.push(`## \u81EA\u52D5\u5316: \u6709\u52B9`);
637
+ if (auto.schedule) {
638
+ lines.push(`- \u5B9F\u884C\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB: \`${auto.schedule}\``);
639
+ }
640
+ lines.push("");
641
+ lines.push(
642
+ `## \u30A8\u30E9\u30FC\u51E6\u7406`,
643
+ ERROR_ESCALATION_RULES[auto.error_escalation]
644
+ );
645
+ if (auto.retry_on_error) {
646
+ lines.push(
647
+ `- \u30EA\u30C8\u30E9\u30A4: \u6709\u52B9\uFF08\u6700\u5927 ${auto.max_retries} \u56DE\uFF09`,
648
+ `- \u30EA\u30C8\u30E9\u30A4\u9593\u9694: \u6307\u6570\u30D0\u30C3\u30AF\u30AA\u30D5\uFF08\u5931\u6557\u3054\u3068\u306B\u5F85\u6A5F\u6642\u9593\u3092\u500D\u5897\uFF09`
649
+ );
650
+ } else {
651
+ lines.push(`- \u30EA\u30C8\u30E9\u30A4: \u7121\u52B9`);
652
+ }
653
+ lines.push(
654
+ "",
655
+ `## \u5B9F\u884C\u539F\u5247`,
656
+ `- \u51AA\u7B49\u6027\u3092\u4FDD\u8A3C\u3059\u308B\uFF08\u4F55\u5EA6\u5B9F\u884C\u3057\u3066\u3082\u540C\u3058\u7D50\u679C\u306B\u306A\u308B\u3088\u3046\u8A2D\u8A08\u3059\u308B\uFF09`,
657
+ `- \u5B9F\u884C\u30ED\u30B0\u3092\u5FC5\u305A\u8A18\u9332\u3059\u308B\uFF08\u958B\u59CB\u6642\u523B\u30FB\u7D42\u4E86\u6642\u523B\u30FB\u51E6\u7406\u4EF6\u6570\u30FB\u30A8\u30E9\u30FC\u5185\u5BB9\uFF09`,
658
+ `- \u5916\u90E8API\u3078\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u306F\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3092\u8A2D\u5B9A\u3059\u308B`,
659
+ `- \u672C\u756A\u30C7\u30FC\u30BF\u3092\u5909\u66F4\u3059\u308B\u524D\u306B\u30C9\u30E9\u30A4\u30E9\u30F3\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u5B9F\u88C5\u3059\u308B`,
660
+ ""
661
+ );
662
+ return lines.join("\n");
663
+ }
664
+
665
+ // src/converters/archetypeRulesGenerator.ts
666
+ var ARCHETYPE_RULES = {
667
+ personal_tool: `# Archetype Rules: \u500B\u4EBA\u30C4\u30FC\u30EB\u30FB\u81EA\u52D5\u5316
668
+
669
+ ## \u512A\u5148\u539F\u5247
670
+ - **\u30B9\u30D4\u30FC\u30C9\u512A\u5148**: \u52D5\u304F\u3082\u306E\u3092\u7D20\u65E9\u304F\u4F5C\u308B\u3053\u3068\u3002\u5B8C\u74A7\u3055\u3088\u308A\u5B9F\u7528\u6027
671
+ - **\u81EA\u5206\u3060\u3051\u304C\u4F7F\u3046**: \u30E6\u30FC\u30B6\u30FC\u5411\u3051\u30A8\u30E9\u30FC\u30E1\u30C3\u30BB\u30FC\u30B8\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306F\u6700\u5C0F\u9650\u3067\u3088\u3044
672
+ - **\u58CA\u308C\u3066\u3082\u76F4\u305B\u308B**: \u5B89\u5168\u7DB2\u3088\u308A\u53CD\u5FA9\u901F\u5EA6\u3092\u512A\u5148\u3059\u308B
673
+ - \u30C7\u30D7\u30ED\u30A4\u30FBCI/CD \u306F\u5FC5\u9808\u3067\u306F\u306A\u3044\u3002\u30ED\u30FC\u30AB\u30EB\u5B9F\u884C\u3067\u5341\u5206
674
+
675
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
676
+ - \u30CF\u30FC\u30C9\u30B3\u30FC\u30C9\u306F\u8A31\u5BB9\u3002\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u5316\u306F\u5FC5\u8981\u306B\u306A\u3063\u3066\u304B\u3089
677
+ - \u30C6\u30B9\u30C8\u306F\u66F8\u304B\u306A\u304F\u3066\u3088\u3044\u304C\u3001\u624B\u52D5\u3067\u306E\u52D5\u4F5C\u78BA\u8A8D\u306F\u5FC5\u9808
678
+ - \u30ED\u30B0\u306F print/console.log \u3067\u5341\u5206\u3002\u69CB\u9020\u5316\u30ED\u30B0\u306F\u4E0D\u8981
679
+ - \u4F9D\u5B58\u30E9\u30A4\u30D6\u30E9\u30EA\u306F\u60DC\u3057\u307E\u305A\u4F7F\u3046\uFF08\u5F8C\u3067\u6574\u7406\u3059\u308B\uFF09
680
+
681
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
682
+ - \u30B9\u30AF\u30EA\u30D7\u30C8\u30FB\u30EF\u30F3\u30E9\u30A4\u30CA\u30FC\u306E\u4F5C\u6210
683
+ - \u30ED\u30FC\u30AB\u30EB\u30D5\u30A1\u30A4\u30EB/\u30C7\u30FC\u30BF\u306E\u81EA\u52D5\u51E6\u7406
684
+ - API \u3092\u53E9\u304F\u30B9\u30CB\u30DA\u30C3\u30C8
685
+ - \u7E70\u308A\u8FD4\u3057\u4F5C\u696D\u306E\u81EA\u52D5\u5316
686
+ `,
687
+ saas_product: `# Archetype Rules: SaaS\u30FB\u30D7\u30ED\u30C0\u30AF\u30C8\u958B\u767A
688
+
689
+ ## \u512A\u5148\u539F\u5247
690
+ - **\u4FE1\u983C\u6027 > \u901F\u5EA6**: \u30C0\u30A6\u30F3\u30BF\u30A4\u30E0\u306F\u30E6\u30FC\u30B6\u30FC\u96E2\u8131\u30FB\u89E3\u7D04\u306B\u76F4\u7D50\u3059\u308B
691
+ - **\u30DE\u30EB\u30C1\u30C6\u30CA\u30F3\u30C8\u524D\u63D0**: \u30C7\u30FC\u30BF\u5206\u96E2\u30FB\u30C6\u30CA\u30F3\u30C8\u8B58\u5225\u3092\u8A2D\u8A08\u306E\u8D77\u70B9\u306B\u7F6E\u304F
692
+ - **\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30D5\u30A1\u30FC\u30B9\u30C8**: \u8A8D\u8A3C\u30FB\u8A8D\u53EF\u30FB\u5165\u529B\u691C\u8A3C\u30FB\u30B7\u30FC\u30AF\u30EC\u30C3\u30C8\u7BA1\u7406\u3092\u6700\u512A\u5148\u306B
693
+
694
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
695
+ - \u30A8\u30E9\u30FC\u306F\u5FC5\u305A\u30AD\u30E3\u30C3\u30C1\u3057\u3066\u30E6\u30FC\u30B6\u30FC\u30D5\u30EC\u30F3\u30C9\u30EA\u30FC\u306A\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8FD4\u3059
696
+ - \u8AB2\u91D1\u30FB\u6C7A\u6E08\u30B3\u30FC\u30C9\u306B\u306F\u8FFD\u52A0\u306E\u5B89\u5168\u78BA\u8A8D\u3092\u884C\u3046
697
+ - DB\u30DE\u30A4\u30B0\u30EC\u30FC\u30B7\u30E7\u30F3\u306F\u5FC5\u305A\u30ED\u30FC\u30EB\u30D0\u30C3\u30AF\u53EF\u80FD\u306A\u5F62\u3067\u4F5C\u6210\u3059\u308B
698
+ - API \u306F versioning \u3059\u308B\uFF08/v1/...\uFF09
699
+ - \u74B0\u5883\u5909\u6570\u3067\u30B7\u30FC\u30AF\u30EC\u30C3\u30C8\u3092\u7BA1\u7406\u3059\u308B\u3002\u30B3\u30FC\u30C9\u306B\u76F4\u66F8\u304D\u53B3\u7981
700
+
701
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
702
+ - API \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u8A2D\u8A08\u30FB\u5B9F\u88C5
703
+ - \u8A8D\u8A3C\u30D5\u30ED\u30FC\uFF08JWT/OAuth/\u30BB\u30C3\u30B7\u30E7\u30F3\uFF09
704
+ - \u8AB2\u91D1\u30FB\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u7BA1\u7406
705
+ - \u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u30FB\u7BA1\u7406\u753B\u9762
706
+ - Webhook \u53D7\u4FE1\u30FB\u51E6\u7406
707
+ `,
708
+ marketing_site: `# Archetype Rules: LP\u30FB\u30DE\u30FC\u30B1\u30B5\u30A4\u30C8
709
+
710
+ ## \u512A\u5148\u539F\u5247
711
+ - **Core Web Vitals \u6700\u512A\u5148**: LCP < 2.5s, FID < 100ms, CLS < 0.1
712
+ - **\u30B3\u30F3\u30D0\u30FC\u30B8\u30E7\u30F3\u91CD\u8996**: \u3059\u3079\u3066\u306E\u8A2D\u8A08\u5224\u65AD\u3092CTA\u9054\u6210\u7387\u3067\u8A55\u4FA1\u3059\u308B
713
+ - **SEO \u306F\u8A2D\u8A08\u306E\u4E00\u90E8**: \u5F8C\u4ED8\u3051\u3067\u306A\u304F\u6700\u521D\u304B\u3089\u7D44\u307F\u8FBC\u3080
714
+
715
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
716
+ - \u753B\u50CF\u306F\u5FC5\u305A next/image \u307E\u305F\u306F\u9069\u5207\u306A\u9045\u5EF6\u8AAD\u307F\u8FBC\u307F\u3092\u4F7F\u7528\u3059\u308B
717
+ - \u30D5\u30A9\u30FC\u30EB\u30C9\u3088\u308A\u4E0A\u306E\u30B3\u30F3\u30C6\u30F3\u30C4\u306F Server-side rendering \u3092\u512A\u5148
718
+ - \u30D5\u30A9\u30F3\u30C8\u30FBCSS \u306F Critical \u30D1\u30B9\u304B\u3089\u5916\u3059
719
+ - OG \u30BF\u30B0\u30FB\u69CB\u9020\u5316\u30C7\u30FC\u30BF\uFF08JSON-LD\uFF09\u306F\u5FC5\u9808
720
+ - A/B \u30C6\u30B9\u30C8\u306E\u30D5\u30C3\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u8A08\u6BB5\u968E\u3067\u8003\u616E\u3059\u308B
721
+
722
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
723
+ - LP / \u30E9\u30F3\u30C7\u30A3\u30F3\u30B0\u30DA\u30FC\u30B8\u4F5C\u6210
724
+ - CTA \u30DC\u30BF\u30F3\u30FB\u30D5\u30A9\u30FC\u30E0\u6700\u9069\u5316
725
+ - SEO \u30E1\u30BF\u30BF\u30B0\u30FB\u30B5\u30A4\u30C8\u30DE\u30C3\u30D7
726
+ - \u30A2\u30CA\u30EA\u30C6\u30A3\u30AF\u30B9\u8A08\u6E2C\u5B9F\u88C5
727
+ - \u30DA\u30FC\u30B8\u30B9\u30D4\u30FC\u30C9\u6539\u5584
728
+ `,
729
+ data_analysis: `# Archetype Rules: \u30C7\u30FC\u30BF\u5206\u6790\u30FB\u30EC\u30DD\u30FC\u30C8
730
+
731
+ ## \u512A\u5148\u539F\u5247
732
+ - **\u518D\u73FE\u6027**: \u540C\u3058\u30C7\u30FC\u30BF\u3067\u540C\u3058\u7D50\u679C\u304C\u51FA\u308B\u3053\u3068\u3092\u4FDD\u8A3C\u3059\u308B
733
+ - **\u30C7\u30FC\u30BF\u54C1\u8CEA**: \u5206\u6790\u524D\u306B\u5FC5\u305A\u30C7\u30FC\u30BF\u691C\u8A3C\u3092\u884C\u3046\uFF08\u6B20\u640D\u5024\u30FB\u5916\u308C\u5024\u30FB\u578B\u30C1\u30A7\u30C3\u30AF\uFF09
734
+ - **\u53EF\u8AAD\u6027**: \u30B3\u30FC\u30C9\u3088\u308A\u7D50\u679C\u306E\u89E3\u91C8\u304C\u91CD\u8981\u3002\u30D3\u30B8\u30E5\u30A2\u30E9\u30A4\u30BC\u30FC\u30B7\u30E7\u30F3\u3092\u7A4D\u6975\u6D3B\u7528
735
+
736
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
737
+ - \u4E71\u6570\u30B7\u30FC\u30C9\u306F\u5FC5\u305A\u56FA\u5B9A\u3059\u308B\uFF08\`random.seed(42)\` \u7B49\uFF09
738
+ - \u30C7\u30FC\u30BF\u5909\u63DB\u306F\u30D1\u30A4\u30D7\u30E9\u30A4\u30F3\u3068\u3057\u3066\u8A18\u8FF0\u3057\u3001\u5404\u30B9\u30C6\u30C3\u30D7\u3092\u691C\u8A3C\u53EF\u80FD\u306B\u3059\u308B
739
+ - \u4E2D\u9593\u30C7\u30FC\u30BF\u3092\u30AD\u30E3\u30C3\u30B7\u30E5\u3057\u3066\u518D\u5B9F\u884C\u30B3\u30B9\u30C8\u3092\u4E0B\u3052\u308B
740
+ - \u5206\u6790\u30CE\u30FC\u30C8\u30D6\u30C3\u30AF\u306B\u306F\u5B9F\u884C\u65E5\u6642\u3068\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u8A18\u9332\u3059\u308B
741
+ - \u96C6\u8A08\u7D50\u679C\u306B\u306F\u5FC5\u305A\u30B5\u30F3\u30D7\u30EB\u30B5\u30A4\u30BA\uFF08n=X\uFF09\u3092\u660E\u793A\u3059\u308B
742
+
743
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
744
+ - \u30C7\u30FC\u30BF\u30AF\u30EC\u30F3\u30B8\u30F3\u30B0\u30FB\u524D\u51E6\u7406
745
+ - \u96C6\u8A08\u30FB\u7D71\u8A08\u5206\u6790
746
+ - \u30B0\u30E9\u30D5\u30FB\u30C1\u30E3\u30FC\u30C8\u4F5C\u6210
747
+ - \u5B9A\u671F\u30EC\u30DD\u30FC\u30C8\u81EA\u52D5\u751F\u6210
748
+ - \u30C7\u30FC\u30BF\u30D1\u30A4\u30D7\u30E9\u30A4\u30F3\u69CB\u7BC9
749
+ `,
750
+ outsourced_dev: `# Archetype Rules: \u53D7\u8A17\u30FB\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u30EF\u30FC\u30AF
751
+
752
+ ## \u512A\u5148\u539F\u5247
753
+ - **\u30B9\u30B3\u30FC\u30D7\u7BA1\u7406**: \u8981\u4EF6\u5916\u306E\u5909\u66F4\u306F\u5FC5\u305A\u78BA\u8A8D\u3092\u53D6\u308B\u3002\u30B9\u30B3\u30FC\u30D7\u30AF\u30EA\u30FC\u30D7\u3092\u9632\u3050
754
+ - **\u7D0D\u54C1\u7269\u306E\u54C1\u8CEA**: \u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304C\u5F15\u304D\u7D99\u3052\u308B\u30B3\u30FC\u30C9\u3002\u30B3\u30E1\u30F3\u30C8\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u5FC5\u9808
755
+ - **\u900F\u660E\u6027**: \u9032\u6357\u30FB\u554F\u984C\u30FB\u30EA\u30B9\u30AF\u3092\u7A4D\u6975\u7684\u306B\u5171\u6709\u3059\u308B
756
+
757
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
758
+ - \u30B3\u30FC\u30C9\u306B\u65E5\u672C\u8A9E\u30B3\u30E1\u30F3\u30C8\u3092\u7A4D\u6975\u7684\u306B\u66F8\u304F\uFF08\u5F15\u304D\u7D99\u304E\u3092\u8003\u616E\uFF09
759
+ - README \u3068\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806\u3092\u5FC5\u305A\u4F5C\u6210\u3059\u308B
760
+ - \u74B0\u5883\u5DEE\u7570\uFF08\u958B\u767A/\u30B9\u30C6\u30FC\u30B8\u30F3\u30B0/\u672C\u756A\uFF09\u3092\u660E\u793A\u7684\u306B\u7BA1\u7406\u3059\u308B
761
+ - \u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u306E\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u898F\u7D04\u30FB\u30B9\u30BF\u30C3\u30AF\u5236\u7D04\u3092\u512A\u5148\u3059\u308B
762
+ - \u7D0D\u54C1\u524D\u306B\u672C\u756A\u74B0\u5883\u76F8\u5F53\u3067\u306E\u30C6\u30B9\u30C8\u3092\u5B9F\u65BD\u3059\u308B
763
+
764
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
765
+ - \u8981\u4EF6\u5B9A\u7FA9\u66F8\u304B\u3089\u306E\u6A5F\u80FD\u5B9F\u88C5
766
+ - \u65E2\u5B58\u30B7\u30B9\u30C6\u30E0\u3078\u306E\u6A5F\u80FD\u8FFD\u52A0
767
+ - \u30D0\u30B0\u4FEE\u6B63\u30FB\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u6539\u5584
768
+ - \u30B3\u30FC\u30C9\u30EC\u30D3\u30E5\u30FC\u30FB\u54C1\u8CEA\u6539\u5584
769
+ - \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u6574\u5099
770
+ `,
771
+ learning: `# Archetype Rules: \u5B66\u7FD2\u30FB\u5B9F\u9A13
772
+
773
+ ## \u512A\u5148\u539F\u5247
774
+ - **\u7406\u89E3\u512A\u5148**: \u52D5\u304F\u3053\u3068\u3088\u308A\u300C\u306A\u305C\u52D5\u304F\u304B\u300D\u3092\u5B66\u3076\u3053\u3068\u3092\u512A\u5148\u3059\u308B
775
+ - **\u5B9F\u9A13\u6B53\u8FCE**: \u5931\u6557\u3092\u6050\u308C\u305A\u8A66\u3059\u3002\u30B3\u30FC\u30C9\u304C\u58CA\u308C\u3066\u3082\u5B66\u3073\u304C\u3042\u308B
776
+ - **\u6BB5\u968E\u7684\u8907\u96D1\u5316**: \u30B7\u30F3\u30D7\u30EB\u306B\u59CB\u3081\u3066\u3001\u7406\u89E3\u3057\u305F\u3089\u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u3078
777
+
778
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
779
+ - \u30B3\u30FC\u30C9\u306B\u306F\u6982\u5FF5\u3092\u7406\u89E3\u3059\u308B\u305F\u3081\u306E\u30B3\u30E1\u30F3\u30C8\u3092\u8C4A\u5BCC\u306B\u66F8\u304F
780
+ - \u307E\u305A\u52D5\u304F\u6700\u5C0F\u5B9F\u88C5\u3092\u4F5C\u308A\u3001\u305D\u306E\u5F8C\u30EA\u30D5\u30A1\u30AF\u30BF\u30EA\u30F3\u30B0\u3057\u3066\u5B66\u3076
781
+ - \u516C\u5F0F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u7A4D\u6975\u7684\u306B\u53C2\u7167\u30FB\u5F15\u7528\u3059\u308B
782
+ - \u300C\u306A\u305C\u3053\u306E\u8A2D\u8A08\u304B\u300D\u306E\u7406\u7531\u3092\u8AAC\u660E\u3057\u3066\u304B\u3089\u5B9F\u88C5\u3059\u308B
783
+ - \u4EE3\u66FF\u30A2\u30D7\u30ED\u30FC\u30C1\u3082\u63D0\u793A\u3057\u3066\u6BD4\u8F03\u5B66\u7FD2\u3092\u4FC3\u3059
784
+
785
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
786
+ - \u30C1\u30E5\u30FC\u30C8\u30EA\u30A2\u30EB\u306E\u5B9F\u88C5\u30FB\u6539\u9020
787
+ - \u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u30FB\u30C7\u30FC\u30BF\u69CB\u9020\u306E\u5B9F\u88C5
788
+ - \u65B0\u3057\u3044\u30E9\u30A4\u30D6\u30E9\u30EA\u30FB\u30D5\u30EC\u30FC\u30E0\u30EF\u30FC\u30AF\u306E\u8A66\u7528
789
+ - \u30B3\u30FC\u30C9\u30EA\u30FC\u30C7\u30A3\u30F3\u30B0\u30FB\u89E3\u8AAC
790
+ - \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u578B\u5B66\u7FD2
791
+ `,
792
+ business_automation: `# Archetype Rules: \u696D\u52D9\u81EA\u52D5\u5316
793
+
794
+ ## \u512A\u5148\u539F\u5247
795
+ - **\u4FE1\u983C\u6027 = \u696D\u52D9\u7D99\u7D9A**: \u6B62\u307E\u308B\u3068\u696D\u52D9\u304C\u6B62\u307E\u308B\u3002\u5805\u7262\u3055\u3092\u6700\u512A\u5148\u306B
796
+ - **\u53EF\u89B3\u6E2C\u6027**: \u4F55\u304C\u3044\u3064\u5B9F\u884C\u3055\u308C\u3001\u6210\u529F/\u5931\u6557\u3057\u305F\u304B\u5FC5\u305A\u30C8\u30EC\u30FC\u30B9\u3067\u304D\u308B\u3053\u3068
797
+ - **\u62C5\u5F53\u8005\u304C\u7406\u89E3\u3067\u304D\u308B**: IT\u62C5\u5F53\u8005\u4EE5\u5916\u304C\u904B\u7528\u3067\u304D\u308B\u8A2D\u8A08
798
+
799
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
800
+ - \u3059\u3079\u3066\u306E\u81EA\u52D5\u51E6\u7406\u306B\u30ED\u30B0\u3092\u6B8B\u3059\uFF08\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u30FB\u51E6\u7406\u4EF6\u6570\u30FB\u30A8\u30E9\u30FC\u8A73\u7D30\uFF09
801
+ - \u4F8B\u5916\u30B1\u30FC\u30B9\u306E\u51E6\u7406\u3092\u8A2D\u8A08\u6BB5\u968E\u3067\u8003\u616E\u3059\u308B
802
+ - \u901A\u77E5\u6A5F\u80FD\u3092\u5FC5\u305A\u7D44\u307F\u8FBC\u3080\uFF08Slack/\u30E1\u30FC\u30EB/LINE\uFF09
803
+ - \u624B\u52D5\u3067\u540C\u3058\u51E6\u7406\u304C\u3067\u304D\u308B\u300C\u8131\u51FA\u30CF\u30C3\u30C1\u300D\u3092\u6B8B\u3059
804
+ - \u672C\u756A\u30C7\u30FC\u30BF\u3092\u89E6\u308B\u51E6\u7406\u306B\u306F\u30C9\u30E9\u30A4\u30E9\u30F3\u30E2\u30FC\u30C9\u3092\u5B9F\u88C5\u3059\u308B
805
+
806
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
807
+ - \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u2192DB\u9023\u643A
808
+ - \u5B9A\u671F\u30E1\u30FC\u30EB\u30FB\u30EC\u30DD\u30FC\u30C8\u9001\u4FE1
809
+ - \u30D5\u30A9\u30FC\u30E0\u2192DB\u767B\u9332\u306E\u81EA\u52D5\u5316
810
+ - \u30D5\u30A1\u30A4\u30EB\u51E6\u7406\u30FB\u5909\u63DB\u306E\u81EA\u52D5\u5316
811
+ - \u793E\u5185\u30B7\u30B9\u30C6\u30E0\u9023\u643A
812
+ `,
813
+ sales_dx: `# Archetype Rules: \u55B6\u696DDX\u30FB\u55B6\u696D\u30C4\u30FC\u30EB
814
+
815
+ ## \u512A\u5148\u539F\u5247
816
+ - **\u55B6\u696D\u6D3B\u52D5\u3092\u90AA\u9B54\u3057\u306A\u3044**: \u30C4\u30FC\u30EB\u304C\u91CD\u3044\u30FB\u8907\u96D1\u3060\u3068\u4F7F\u308F\u308C\u306A\u304F\u306A\u308B\u3002UX\u6700\u512A\u5148
817
+ - **\u30C7\u30FC\u30BF\u306E\u9BAE\u5EA6**: \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u307E\u305F\u306F\u6E96\u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u3067CRM\u3068\u540C\u671F\u3059\u308B
818
+ - **\u884C\u52D5\u53EF\u80FD\u306A\u30A4\u30F3\u30B5\u30A4\u30C8**: \u30C7\u30FC\u30BF\u3092\u898B\u305B\u308B\u3060\u3051\u3067\u306A\u304F\u3001\u6B21\u306E\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u63D0\u793A\u3059\u308B
819
+
820
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
821
+ - \u30E2\u30D0\u30A4\u30EB\u30D5\u30A1\u30FC\u30B9\u30C8\u8A2D\u8A08\uFF08\u55B6\u696D\u306F\u5916\u51FA\u5148\u3067\u30B9\u30DE\u30DB\u3092\u4F7F\u3046\uFF09
822
+ - CRM\uFF08Salesforce/HubSpot\u7B49\uFF09\u306EAPI\u30EC\u30FC\u30C8\u5236\u9650\u3092\u610F\u8B58\u3057\u305F\u5B9F\u88C5
823
+ - \u500B\u4EBA\u60C5\u5831\u30FB\u5546\u8AC7\u60C5\u5831\u306F\u6697\u53F7\u5316\u3057\u3066\u7BA1\u7406\u3059\u308B
824
+ - \u30AA\u30D5\u30E9\u30A4\u30F3\u5BFE\u5FDC\u3092\u8003\u616E\u3059\u308B\uFF08\u63A5\u7D9A\u4E0D\u5B89\u5B9A\u306A\u74B0\u5883\u3067\u306E\u4F7F\u7528\uFF09
825
+ - \u30EF\u30F3\u30AF\u30EA\u30C3\u30AF\u30FB\u30EF\u30F3\u30BF\u30C3\u30D7\u3067\u4E3B\u8981\u64CD\u4F5C\u304C\u5B8C\u7D50\u3059\u308BUI\u3092\u76EE\u6307\u3059
826
+
827
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
828
+ - \u9867\u5BA2\u7BA1\u7406\u30FB\u5546\u8AC7\u7BA1\u7406\u30C4\u30FC\u30EB
829
+ - \u55B6\u696D\u65E5\u5831\u30FB\u6D3B\u52D5\u30ED\u30B0\u306E\u81EA\u52D5\u5316
830
+ - \u63D0\u6848\u66F8\u30FB\u898B\u7A4D\u66F8\u306E\u81EA\u52D5\u751F\u6210
831
+ - \u30EA\u30FC\u30C9\u7372\u5F97\u30FB\u30B9\u30B3\u30A2\u30EA\u30F3\u30B0
832
+ - \u6210\u7D04\u7387\u5206\u6790\u30FB\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9
833
+ `,
834
+ youtube_content: `# Archetype Rules: YouTube\u52D5\u753B\u4F5C\u6210\u30FB\u7DE8\u96C6
835
+
836
+ ## \u512A\u5148\u539F\u5247
837
+ - **\u6700\u521D\u306E15\u79D2\u304C\u547D**: \u30D5\u30C3\u30AF\u3092\u6700\u512A\u5148\u306B\u8A2D\u8A08\u3059\u308B\u3002\u8996\u8074\u7DAD\u6301\u7387\u3092\u610F\u8B58\u3059\u308B
838
+ - **\u691C\u7D22\u3055\u308C\u308B\u52D5\u753B**: \u30BF\u30A4\u30C8\u30EB\u30FB\u8AAC\u660E\u6587\u30FB\u30BF\u30B0\u306ESEO\u3092\u5FB9\u5E95\u3059\u308B
839
+ - **\u884C\u52D5\u559A\u8D77**: \u52D5\u753B\u306E\u7D42\u308F\u308A\u306B\u8996\u8074\u8005\u306B\u4F55\u3092\u3057\u3066\u307B\u3057\u3044\u304B\u660E\u78BA\u306B\u3059\u308B
840
+
841
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u30FB\u5236\u4F5C\u65B9\u91DD
842
+ - \u30B9\u30AF\u30EA\u30D7\u30C8\u306F\u300C\u30D5\u30C3\u30AF \u2192 \u554F\u984C\u63D0\u8D77 \u2192 \u89E3\u6C7A\u7B56 \u2192 \u884C\u52D5\u559A\u8D77\u300D\u306E\u69CB\u6210\u3092\u57FA\u672C\u306B
843
+ - \u30B5\u30E0\u30CD\u30A4\u30EB\u306F\u611F\u60C5\u30FB\u6570\u5B57\u30FB\u9854\u3092\u7D44\u307F\u5408\u308F\u305B\u308B\uFF08\u30AF\u30EA\u30C3\u30AF\u7387\u5411\u4E0A\uFF09
844
+ - \u52D5\u753B\u8AAC\u660E\u6587\u306F\u691C\u7D22\u30AD\u30FC\u30EF\u30FC\u30C9\u3092\u81EA\u7136\u306B\u542B\u3080300\u6587\u5B57\u4EE5\u4E0A
845
+ - \u30C1\u30E3\u30D7\u30BF\u30FC\uFF08\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\uFF09\u3092\u5FC5\u305A\u8FFD\u52A0\u3059\u308B
846
+ - \u30A8\u30F3\u30C9\u30B9\u30AF\u30EA\u30FC\u30F3\u30FB\u30AB\u30FC\u30C9\u3067\u30C1\u30E3\u30F3\u30CD\u30EB\u56DE\u904A\u3092\u8A2D\u8A08\u3059\u308B
847
+
848
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
849
+ - \u52D5\u753B\u30B9\u30AF\u30EA\u30D7\u30C8\u4F5C\u6210
850
+ - \u30B5\u30E0\u30CD\u30A4\u30EB\u30B3\u30F3\u30BB\u30D7\u30C8\u8A2D\u8A08
851
+ - \u52D5\u753B\u8AAC\u660E\u6587\u30FB\u30BF\u30B0\u6700\u9069\u5316
852
+ - \u5B57\u5E55\u30FB\u30C6\u30ED\u30C3\u30D7\u4F5C\u6210
853
+ - \u6295\u7A3F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u7BA1\u7406
854
+ `,
855
+ article_writing: `# Archetype Rules: \u8A18\u4E8B\u57F7\u7B46\u30FB\u30D6\u30ED\u30B0\u30FB\u30E1\u30C7\u30A3\u30A2
856
+
857
+ ## \u512A\u5148\u539F\u5247
858
+ - **\u8AAD\u8005\u306E\u8AB2\u984C\u89E3\u6C7A**: \u8AAD\u8005\u304C\u691C\u7D22\u3057\u305F\u7406\u7531\uFF08\u691C\u7D22\u610F\u56F3\uFF09\u3092\u6700\u521D\u306B\u6E80\u305F\u3059
859
+ - **\u8AAD\u307F\u3084\u3059\u3055**: \u4E00\u6587\u4E00\u610F\u30FB\u9069\u5207\u306A\u898B\u51FA\u3057\u30FB\u77ED\u3044\u6BB5\u843D
860
+ - **\u30D6\u30E9\u30F3\u30C9\u30DC\u30A4\u30B9\u306E\u4E00\u8CAB\u6027**: \u5A92\u4F53\u306E\u30C8\u30FC\u30F3\u3092\u7DAD\u6301\u3059\u308B\uFF08\u3067\u3059\u307E\u3059 or \u3060\u30FB\u3067\u3042\u308B\uFF09
861
+
862
+ ## \u57F7\u7B46\u65B9\u91DD
863
+ - \u5C0E\u5165\u90E8\u3067\u300C\u3053\u306E\u8A18\u4E8B\u3092\u8AAD\u3080\u3068XXX\u304C\u308F\u304B\u308B\u300D\u3092\u660E\u793A\u3059\u308B
864
+ - H2/H3 \u898B\u51FA\u3057\u306F\u691C\u7D22\u30AF\u30A8\u30EA\u3068\u4E00\u81F4\u3055\u305B\u308B
865
+ - \u5177\u4F53\u7684\u306A\u6570\u5B57\u30FB\u4E8B\u4F8B\u30FB\u56FA\u6709\u540D\u8A5E\u3067\u8AAC\u5F97\u529B\u3092\u9AD8\u3081\u308B
866
+ - \u4E00\u6BB5\u843D\u306F3\u301C5\u6587\u3092\u76EE\u5B89\u306B\u3059\u308B
867
+ - \u7DE0\u3081\u306B\u306F\u5FC5\u305A\u300C\u307E\u3068\u3081\u300D\u307E\u305F\u306F\u300C\u6B21\u306E\u30A2\u30AF\u30B7\u30E7\u30F3\u300D\u3092\u5165\u308C\u308B
868
+ - \u30D5\u30A1\u30AF\u30C8\u30C1\u30A7\u30C3\u30AF\u53EF\u80FD\u306A\u60C5\u5831\u306B\u306F\u51FA\u5178\u3092\u660E\u8A18\u3059\u308B
869
+
870
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
871
+ - \u30D6\u30ED\u30B0\u8A18\u4E8B\u30FB\u30B3\u30E9\u30E0\u57F7\u7B46
872
+ - \u30E1\u30EB\u30DE\u30AC\u30FB\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u4F5C\u6210
873
+ - \u30D7\u30EC\u30B9\u30EA\u30EA\u30FC\u30B9\u30FB\u30CB\u30E5\u30FC\u30B9\u539F\u7A3F
874
+ - SNS\u6295\u7A3F\u6587\u4F5C\u6210
875
+ - \u53D6\u6750\u30FB\u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u8A18\u4E8B\u69CB\u6210
876
+ `,
877
+ seo_marketing: `# Archetype Rules: SEO\u6539\u5584\u30FB\u30DE\u30FC\u30B1\u30C6\u30A3\u30F3\u30B0
878
+
879
+ ## \u512A\u5148\u539F\u5247
880
+ - **\u691C\u7D22\u610F\u56F3\u306E\u5B8C\u5168\u5145\u8DB3**: \u30E9\u30F3\u30AD\u30F3\u30B0 1 \u4F4D\u306E\u30B3\u30F3\u30C6\u30F3\u30C4\u3088\u308A\u8A73\u3057\u304F\u30FB\u6B63\u78BA\u306B\u7B54\u3048\u308B
881
+ - **E-E-A-T**: \u7D4C\u9A13\u30FB\u5C02\u9580\u6027\u30FB\u6A29\u5A01\u6027\u30FB\u4FE1\u983C\u6027\u3092\u6587\u7AE0\u30FB\u69CB\u9020\u3067\u793A\u3059
882
+ - **\u6280\u8853SEO\u3068\u5185\u5BB9SEO\u306E\u4E21\u7ACB**: \u30B3\u30F3\u30C6\u30F3\u30C4\u3060\u3051\u3067\u306A\u304F\u5B9F\u88C5\u9762\u3082\u91CD\u8981
883
+
884
+ ## \u5B9F\u88C5\u65B9\u91DD
885
+ - \u69CB\u9020\u5316\u30C7\u30FC\u30BF\uFF08JSON-LD: Article/Product/FAQPage\u7B49\uFF09\u3092\u5FC5\u305A\u5B9F\u88C5\u3059\u308B
886
+ - Core Web Vitals \u3092\u3059\u3079\u3066\u306E\u65BD\u7B56\u3067\u8A08\u6E2C\u30FB\u6539\u5584\u306E\u57FA\u6E96\u306B\u3059\u308B
887
+ - \u5185\u90E8\u30EA\u30F3\u30AF\u8A2D\u8A08\u306F\u300C\u95A2\u9023\u6027\u306E\u9AD8\u3044\u30DA\u30FC\u30B8\u30923\u30EA\u30F3\u30AF\u4EE5\u4E0A\u300D\u3092\u76EE\u6A19\u306B
888
+ - \u30E1\u30BF\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u306FCTR\u3092\u610F\u8B58\u3057\u3066120\u6587\u5B57\u4EE5\u5185\u3067\u9B45\u529B\u7684\u306B\u66F8\u304F
889
+ - \u753B\u50CF\u306E alt \u30C6\u30AD\u30B9\u30C8\u306F SEO \u3068 accessibility \u3092\u4E21\u7ACB\u3055\u305B\u308B
890
+ - \u30B5\u30A4\u30C8\u30DE\u30C3\u30D7\u30FBrobots.txt \u306E\u7BA1\u7406\u3092\u5FD8\u308C\u306A\u3044
891
+
892
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
893
+ - \u30AD\u30FC\u30EF\u30FC\u30C9\u8ABF\u67FB\u30FB\u7AF6\u5408\u5206\u6790
894
+ - \u30B3\u30F3\u30C6\u30F3\u30C4\u6700\u9069\u5316\u30FB\u30EA\u30E9\u30A4\u30C8
895
+ - \u6280\u8853SEO\u76E3\u67FB\uFF08\u901F\u5EA6\u30FB\u69CB\u9020\u5316\u30C7\u30FC\u30BF\u30FB\u30E2\u30D0\u30A4\u30EB\u5BFE\u5FDC\uFF09
896
+ - \u88AB\u30EA\u30F3\u30AF\u7372\u5F97\u65BD\u7B56
897
+ - Google Search Console / Analytics \u5206\u6790
898
+ `,
899
+ finance_bot: `# Archetype Rules: \u91D1\u878D\u30B7\u30B9\u30C6\u30E0\u30FBBOT\u958B\u767A
900
+
901
+ ## \u512A\u5148\u539F\u5247
902
+ - **\u8A08\u7B97\u7CBE\u5EA6 = \u547D**: \u6D6E\u52D5\u5C0F\u6570\u70B9\u6F14\u7B97\u3092\u907F\u3051\u3001\u6574\u6570\u6F14\u7B97\u307E\u305F\u306F Decimal \u578B\u3092\u4F7F\u3046
903
+ - **\u76E3\u67FB\u8A3C\u8DE1**: \u3059\u3079\u3066\u306E\u91D1\u92AD\u64CD\u4F5C\u306B\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u30FB\u30E6\u30FC\u30B6\u30FCID\u3092\u8A18\u9332\u3059\u308B
904
+ - **\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u6700\u512A\u5148**: \u91D1\u878D\u30C7\u30FC\u30BF\u306F\u6700\u9AD8\u30EC\u30D9\u30EB\u306E\u4FDD\u8B77\u3092\u65BD\u3059
905
+
906
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
907
+ - \u91D1\u984D\u306F\u5FC5\u305A\u6700\u5C0F\u5358\u4F4D\uFF08\u5186\u30FB\u30BB\u30F3\u30C8\uFF09\u306E\u6574\u6570\u3067\u6271\u3046
908
+ - \u30C8\u30E9\u30F3\u30B6\u30AF\u30B7\u30E7\u30F3\u306F\u5FC5\u305A\u30A2\u30C8\u30DF\u30C3\u30AF\u306B\u51E6\u7406\u3059\u308B\uFF08DB: BEGIN/COMMIT/ROLLBACK\uFF09
909
+ - API\u30AD\u30FC\u30FB\u30B7\u30FC\u30AF\u30EC\u30C3\u30C8\u306F\u74B0\u5883\u5909\u6570 + \u30B7\u30FC\u30AF\u30EC\u30C3\u30C8\u30DE\u30CD\u30FC\u30B8\u30E3\u30FC\u3067\u7BA1\u7406
910
+ - \u6295\u8CC7\u30FB\u53D6\u5F15\u30ED\u30B8\u30C3\u30AF\u306B\u306F\u5FC5\u305A\u30DA\u30FC\u30D1\u30FC\u30C8\u30EC\u30FC\u30C9\uFF08\u6A21\u64EC\u53D6\u5F15\uFF09\u30E2\u30FC\u30C9\u3092\u5B9F\u88C5\u3059\u308B
911
+ - \u672C\u756A\u74B0\u5883\u3067\u306E\u5909\u66F4\u306F\u6BB5\u968E\u7684\u30C7\u30D7\u30ED\u30A4\uFF08\u30AB\u30CA\u30EA\u30A2\u30EA\u30EA\u30FC\u30B9\u7B49\uFF09\u3067\u5B9F\u65BD
912
+ - \u898F\u5236\u8981\u4EF6\uFF08\u91D1\u5546\u6CD5\u30FB\u500B\u4EBA\u60C5\u5831\u4FDD\u8B77\u6CD5\u7B49\uFF09\u3078\u306E\u6E96\u62E0\u3092\u5E38\u306B\u610F\u8B58\u3059\u308B
913
+
914
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
915
+ - \u53D6\u5F15BOT\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u53D6\u5F15
916
+ - \u30DD\u30FC\u30C8\u30D5\u30A9\u30EA\u30AA\u7BA1\u7406\u30FB\u640D\u76CA\u8A08\u7B97
917
+ - \u5E02\u5834\u30C7\u30FC\u30BF\u53D6\u5F97\u30FB\u5206\u6790
918
+ - \u30EA\u30B9\u30AF\u7BA1\u7406\u30FB\u30A2\u30E9\u30FC\u30C8\u30B7\u30B9\u30C6\u30E0
919
+ - \u6C7A\u7B97\u30FB\u30EC\u30DD\u30FC\u30C8\u81EA\u52D5\u5316
920
+ `,
921
+ data_collection: `# Archetype Rules: \u30C7\u30FC\u30BF\u53CE\u96C6\u30FB\u6574\u7406\u30FB\u5171\u6709
922
+
923
+ ## \u512A\u5148\u539F\u5247
924
+ - **\u30C7\u30FC\u30BF\u54C1\u8CEA\u30D5\u30A1\u30FC\u30B9\u30C8**: \u53CE\u96C6\u91CF\u3088\u308A\u6B63\u78BA\u3055\u3068\u4E00\u8CAB\u6027\u3092\u512A\u5148\u3059\u308B
925
+ - **\u30BD\u30FC\u30B9\u3078\u306E\u656C\u610F**: robots.txt \u9075\u5B88\u30FB\u30EC\u30FC\u30C8\u5236\u9650\u30FB\u5229\u7528\u898F\u7D04\u306E\u78BA\u8A8D\u3092\u5FC5\u305A\u884C\u3046
926
+ - **\u5171\u6709\u3057\u3084\u3059\u3044\u5F62\u5F0F**: \u53D7\u3051\u53D6\u308B\u4EBA\u304C\u4F7F\u3044\u3084\u3059\u3044\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3067\u51FA\u529B\u3059\u308B
927
+
928
+ ## \u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u65B9\u91DD
929
+ - \u30B9\u30AF\u30EC\u30A4\u30D4\u30F3\u30B0\u306B\u306F\u5FC5\u305A\u9069\u5207\u306A\u30A6\u30A7\u30A4\u30C8\uFF081\u301C3\u79D2\uFF09\u3092\u5165\u308C\u308B
930
+ - \u53CE\u96C6\u30C7\u30FC\u30BF\u306B\u306F\u53D6\u5F97\u65E5\u6642\u30FB\u30BD\u30FC\u30B9URL\u3092\u5FC5\u305A\u4ED8\u4E0E\u3059\u308B
931
+ - \u91CD\u8907\u30C7\u30FC\u30BF\u306E\u30C7\u30C7\u30E5\u30FC\u30D7\u51E6\u7406\u3092\u8A2D\u8A08\u6BB5\u968E\u3067\u7D44\u307F\u8FBC\u3080
932
+ - \u30A8\u30E9\u30FC\u6642\u306F\u51E6\u7406\u3092\u4E2D\u65AD\u305B\u305A\u3001\u30A8\u30E9\u30FC\u30ED\u30B0\u306B\u8A18\u9332\u3057\u3066\u7D99\u7D9A\u3059\u308B
933
+ - \u30C7\u30FC\u30BF\u30B9\u30AD\u30FC\u30DE\u306F\u5909\u66F4\u3055\u308C\u3084\u3059\u3044\u305F\u3081\u3001\u30D0\u30EA\u30C7\u30FC\u30B7\u30E7\u30F3\u3092\u67D4\u8EDF\u306B\u8A2D\u8A08\u3059\u308B
934
+ - \u500B\u4EBA\u60C5\u5831\uFF08\u6C0F\u540D\u30FB\u30E1\u30FC\u30EB\u30FB\u96FB\u8A71\u756A\u53F7\uFF09\u306F\u30DE\u30B9\u30AD\u30F3\u30B0\u307E\u305F\u306F\u533F\u540D\u5316\u3059\u308B
935
+
936
+ ## \u5178\u578B\u7684\u306A\u30BF\u30B9\u30AF
937
+ - Web\u30B9\u30AF\u30EC\u30A4\u30D4\u30F3\u30B0\u30FB\u30AF\u30ED\u30FC\u30EA\u30F3\u30B0
938
+ - API \u30C7\u30FC\u30BF\u53CE\u96C6\u30FB\u7D71\u5408
939
+ - \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u30FBCSV \u6574\u7406\u30FB\u5909\u63DB
940
+ - \u30C7\u30FC\u30BF\u30AB\u30BF\u30ED\u30B0\u30FB\u8F9E\u66F8\u4F5C\u6210
941
+ - \u30C1\u30FC\u30E0\u3078\u306E\u5B9A\u671F\u30C7\u30FC\u30BF\u5171\u6709
942
+ `
943
+ };
944
+ function generateArchetypeRules(archetype) {
945
+ return ARCHETYPE_RULES[archetype];
946
+ }
947
+
948
+ // src/converters/tuneCommandGenerator.ts
949
+ function generateTuneCommand(config) {
950
+ return `# /tune \u2014 \u30CF\u30FC\u30CD\u30B9\u8ABF\u6574\u30B3\u30DE\u30F3\u30C9
951
+ <!-- Generated by HarnessCrafter | project: ${config.project.name} -->
952
+
953
+ ## \u4F7F\u3044\u65B9
954
+ \`\`\`
955
+ /tune <\u8ABF\u6574\u3057\u305F\u3044\u5185\u5BB9>
956
+ \`\`\`
957
+
958
+ \u4F8B:
959
+ - \`/tune \u3082\u3063\u3068\u78BA\u8A8D\u3092\u6E1B\u3089\u3057\u3066\u3002\u4EFB\u305B\u305F\u3044\`
960
+ - \`/tune \u30A8\u30E9\u30FC\u306E\u305F\u3073\u306B\u6B62\u3081\u306A\u3044\u3067\u3001\u81EA\u52D5\u4FEE\u6B63\u3057\u3066\`
961
+ - \`/tune \u30B3\u30FC\u30C9\u3060\u3051\u8FD4\u3057\u3066\u3002\u8AAC\u660E\u306F\u8981\u3089\u306A\u3044\`
962
+ - \`/tune \u30C6\u30B9\u30C8\u3092\u7701\u7565\u3057\u306A\u3044\u3067\`
963
+
964
+ ## \u3053\u306E\u30B3\u30DE\u30F3\u30C9\u304C\u884C\u3046\u3053\u3068
965
+ 1. \u73FE\u5728\u306E\u30CF\u30FC\u30CD\u30B9\u8A2D\u5B9A\uFF08\`.claude/harness_config.json\`\uFF09\u3092\u8AAD\u307F\u8FBC\u3080
966
+ 2. \u3042\u306A\u305F\u306E\u8981\u671B\u3092\u5206\u6790\u3057\u3001\u3069\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u5909\u66F4\u3059\u3079\u304D\u304B\u63D0\u6848\u3059\u308B
967
+ 3. \u627F\u8A8D\u5F8C\u3001\u8A2D\u5B9A\u3092\u66F4\u65B0\u3057\u3066 \`npx harness-crafter generate\` \u3092\u5B9F\u884C\u3059\u308B
968
+
969
+ ## \u73FE\u5728\u306E\u8A2D\u5B9A\u30B5\u30DE\u30EA\u30FC
970
+ - \u30A2\u30FC\u30AD\u30BF\u30A4\u30D7: ${config.archetype ?? "\u672A\u8A2D\u5B9A"}
971
+ - \u78BA\u8A8D\u983B\u5EA6: ${config.workflow?.confirmation_frequency ?? "medium"}
972
+ - \u81EA\u5F8B\u5EA6: ${config.workflow?.autonomy_level ?? "balanced"}
973
+ - \u5FDC\u7B54\u306E\u8A73\u3057\u3055: ${config.communication?.verbosity ?? "normal"}
974
+ - \u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044: ${config.communication?.error_notification ?? "notify"}
975
+ - \u9032\u6357\u5831\u544A: ${config.communication?.report_frequency ?? "on_milestone"}
976
+
977
+ ## \u8ABF\u6574\u53EF\u80FD\u306A\u9805\u76EE
978
+
979
+ ### \u4F5C\u696D\u30B9\u30BF\u30A4\u30EB (workflow)
980
+ | \u8A2D\u5B9A | \u9078\u629E\u80A2 | \u73FE\u5728\u5024 |
981
+ |------|--------|--------|
982
+ | \u78BA\u8A8D\u983B\u5EA6 | high / medium / low | ${config.workflow?.confirmation_frequency ?? "medium"} |
983
+ | \u81EA\u5F8B\u5EA6 | conservative / balanced / autonomous | ${config.workflow?.autonomy_level ?? "balanced"} |
984
+ | \u30B9\u30B3\u30FC\u30D7\u30AC\u30FC\u30C9 | true / false | ${config.workflow?.scope_guard ?? false} |
985
+
986
+ ### \u30B3\u30DF\u30E5\u30CB\u30B1\u30FC\u30B7\u30E7\u30F3 (communication)
987
+ | \u8A2D\u5B9A | \u9078\u629E\u80A2 | \u73FE\u5728\u5024 |
988
+ |------|--------|--------|
989
+ | \u5FDC\u7B54\u306E\u8A73\u3057\u3055 | minimal / normal / detailed | ${config.communication?.verbosity ?? "normal"} |
990
+ | \u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044 | stop / notify / continue | ${config.communication?.error_notification ?? "notify"} |
991
+ | \u9032\u6357\u5831\u544A | always / on_milestone / on_error / never | ${config.communication?.report_frequency ?? "on_milestone"} |
992
+ | \u6587\u4F53\u4FDD\u6301 | true / false | ${config.communication?.preserve_voice ?? false} |
993
+
994
+ ## \u8ABF\u6574\u624B\u9806
995
+ 1. \`/tune <\u8981\u671B>\` \u3092\u5165\u529B\u3059\u308B
996
+ 2. Claude\u304C\u5909\u66F4\u6848\u3092\u63D0\u793A\u3059\u308B
997
+ 3. \u627F\u8A8D\u3057\u305F\u3089 \`.claude/harness_config.json\` \u304C\u66F4\u65B0\u3055\u308C\u308B
998
+ 4. \u81EA\u52D5\u7684\u306B \`npx harness-crafter generate\` \u3067\u30EB\u30FC\u30EB\u30D5\u30A1\u30A4\u30EB\u304C\u518D\u751F\u6210\u3055\u308C\u308B
999
+
1000
+ ---
1001
+ \u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB: \`.claude/harness_config.json\`
1002
+ \u518D\u751F\u6210\u30B3\u30DE\u30F3\u30C9: \`npx harness-crafter generate\`
1003
+ `;
1004
+ }
1005
+
1006
+ // src/utils/tokenCounter.ts
1007
+ import { getEncoding as tiktokenGetEncoding } from "js-tiktoken";
1008
+ var enc = null;
1009
+ function getEncoding() {
1010
+ if (!enc) {
1011
+ enc = tiktokenGetEncoding("cl100k_base");
1012
+ }
1013
+ return enc;
1014
+ }
1015
+ function countTokens(text) {
1016
+ try {
1017
+ const encoding = getEncoding();
1018
+ return encoding.encode(text).length;
1019
+ } catch {
1020
+ return Math.ceil(text.length / 4);
1021
+ }
1022
+ }
1023
+ function formatTokenCount(count, budget) {
1024
+ const pct = Math.round(count / budget * 100);
1025
+ const status = count <= budget ? "OK" : "OVER";
1026
+ return `${count} / ${budget} tokens (${pct}%) [${status}]`;
1027
+ }
1028
+
1029
+ // src/commands/generate.ts
1030
+ var CLAUDE_MD_TOKEN_LIMIT = 3e3;
1031
+ function generateHarness(config, options = {}) {
1032
+ const outDir = options.outputDir ?? ".claude";
1033
+ const warnings = [];
1034
+ const claudeMd = generateClaudeMd(config);
1035
+ const domainRules = generateDomainRules(config.project.domain);
1036
+ const userLevelRules = generateUserLevelRules(config.project.user_level);
1037
+ const costModeRules = generateCostModeRules(config.cost_mode.current);
1038
+ const evaluatorPrompt = generateEvaluatorPrompt(config);
1039
+ const codeReviewerPrompt = generateCodeReviewerPrompt();
1040
+ const sessionSummarizerPrompt = generateSessionSummarizerPrompt();
1041
+ const files = {
1042
+ [`${outDir}/CLAUDE.md`]: claudeMd,
1043
+ [`${outDir}/rules/domain_rules.md`]: domainRules,
1044
+ [`${outDir}/rules/user_level_rules.md`]: userLevelRules,
1045
+ [`${outDir}/rules/cost_mode_rules.md`]: costModeRules,
1046
+ [`${outDir}/sub-agents/evaluator.md`]: evaluatorPrompt,
1047
+ [`${outDir}/sub-agents/code_reviewer.md`]: codeReviewerPrompt,
1048
+ [`${outDir}/sub-agents/session_summarizer.md`]: sessionSummarizerPrompt
1049
+ };
1050
+ if (config.archetype) {
1051
+ files[`${outDir}/rules/archetype_rules.md`] = generateArchetypeRules(config.archetype);
1052
+ files[`${outDir}/commands/tune.md`] = generateTuneCommand(config);
1053
+ }
1054
+ if (config.workflow) {
1055
+ files[`${outDir}/rules/workflow_rules.md`] = generateWorkflowRules(config);
1056
+ }
1057
+ if (config.communication) {
1058
+ files[`${outDir}/rules/communication_style.md`] = generateCommunicationStyle(config);
1059
+ }
1060
+ if (config.automation) {
1061
+ files[`${outDir}/rules/automation_rules.md`] = generateAutomationRules(config);
1062
+ }
1063
+ const tokenCounts = {};
1064
+ for (const [filePath, content] of Object.entries(files)) {
1065
+ tokenCounts[filePath] = countTokens(content);
1066
+ }
1067
+ const claudeMdTokens = tokenCounts[`${outDir}/CLAUDE.md`];
1068
+ if (claudeMdTokens > CLAUDE_MD_TOKEN_LIMIT) {
1069
+ warnings.push(
1070
+ `CLAUDE.md exceeds token limit: ${claudeMdTokens} / ${CLAUDE_MD_TOKEN_LIMIT} tokens`
1071
+ );
1072
+ }
1073
+ if (!options.dryRun) {
1074
+ for (const [filePath, content] of Object.entries(files)) {
1075
+ const dir = path.dirname(filePath);
1076
+ fs.mkdirSync(dir, { recursive: true });
1077
+ fs.writeFileSync(filePath, content, "utf8");
1078
+ }
1079
+ const profile = {
1080
+ schema_version: "1.0.0",
1081
+ project_id: config.project_id,
1082
+ organization_id: config.organization_id,
1083
+ current_mode: config.cost_mode.current,
1084
+ subscription_plan: config.cost_mode.subscription_plan,
1085
+ generated_at: (/* @__PURE__ */ new Date()).toISOString()
1086
+ };
1087
+ const profilePath = `${outDir}/harness_profile.json`;
1088
+ fs.mkdirSync(path.dirname(profilePath), { recursive: true });
1089
+ fs.writeFileSync(profilePath, JSON.stringify(profile, null, 2), "utf8");
1090
+ fs.mkdirSync(`${outDir}/sessions`, { recursive: true });
1091
+ }
1092
+ return { files, tokenCounts, warnings };
1093
+ }
1094
+ function ensureGitignore(projectRoot) {
1095
+ const gitignorePath = path.join(projectRoot, ".gitignore");
1096
+ const entry = ".claude/sessions/";
1097
+ if (fs.existsSync(gitignorePath)) {
1098
+ const content = fs.readFileSync(gitignorePath, "utf8");
1099
+ if (content.includes(entry)) return;
1100
+ const separator = content.endsWith("\n") ? "" : "\n";
1101
+ fs.appendFileSync(gitignorePath, `${separator}# HarnessCrafter: session logs (local only)
1102
+ ${entry}
1103
+ `, "utf8");
1104
+ } else {
1105
+ fs.writeFileSync(gitignorePath, `# HarnessCrafter: session logs (local only)
1106
+ ${entry}
1107
+ `, "utf8");
1108
+ }
1109
+ }
1110
+ function loadConfig(configPath) {
1111
+ if (!fs.existsSync(configPath)) {
1112
+ throw new Error(`Config file not found: ${configPath}`);
1113
+ }
1114
+ const raw = JSON.parse(fs.readFileSync(configPath, "utf8"));
1115
+ const result = HarnessConfigSchema.safeParse(raw);
1116
+ if (!result.success) {
1117
+ const errors = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
1118
+ throw new Error(`Invalid harness_config.json:
1119
+ ${errors}`);
1120
+ }
1121
+ return result.data;
1122
+ }
1123
+ function generateEvaluatorPrompt(config) {
1124
+ return `# Evaluator Sub-Agent
1125
+ <!-- Generated by HarnessCrafter for ${config.project.name} -->
1126
+
1127
+ You are an expert code evaluator. When invoked, perform a systematic review of the recent implementation.
1128
+
1129
+ ## Evaluation Criteria
1130
+
1131
+ ### 1. Token Efficiency
1132
+ - CLAUDE.md must be < 3000 tokens \u2014 flag if exceeded
1133
+ - Rule files should be focused, not bloated
1134
+ - Check for redundant context
1135
+
1136
+ ### 2. JSON-Driven Design Consistency
1137
+ - All behavior must trace back to \`harness_config.json\`
1138
+ - No hardcoded values that belong in config
1139
+ - Converter functions must be pure (no side effects)
1140
+
1141
+ ### 3. Security
1142
+ - PII/API key masking: verify no secrets leak through
1143
+ - OWASP Top 10: check relevant vulnerabilities for this domain (${config.project.domain})
1144
+ - Input validation at system boundaries
1145
+
1146
+ ### 4. Web Portability
1147
+ - Converter layer must be Node.js-agnostic (importable in browser/edge)
1148
+ - No fs/path imports in converter functions
1149
+ - Pure functions only in src/converters/
1150
+
1151
+ ### 5. SaaS/Multi-Tenant Readiness
1152
+ - organization_id and project_id are present and used
1153
+ - No cross-tenant data leakage risks
1154
+ - Settings isolation between organizations
1155
+
1156
+ ## Output Format
1157
+ Provide a structured report:
1158
+ \`\`\`
1159
+ EVALUATION REPORT [ID: {ID}]
1160
+ Score: X/10
1161
+
1162
+ \u2713 Passed:
1163
+ - [list passing criteria]
1164
+
1165
+ \u26A0 Warnings:
1166
+ - [list non-critical issues]
1167
+
1168
+ \u2717 Failed:
1169
+ - [list critical issues with fix suggestions]
1170
+
1171
+ Recommendation: [APPROVE | APPROVE_WITH_CHANGES | REJECT]
1172
+ \`\`\`
1173
+ `;
1174
+ }
1175
+ function generateCodeReviewerPrompt() {
1176
+ return `# Code Reviewer Sub-Agent
1177
+ <!-- Generated by HarnessCrafter -->
1178
+
1179
+ You are a senior code reviewer. When invoked, review the most recent code changes.
1180
+
1181
+ ## Review Checklist
1182
+
1183
+ - [ ] Logic is correct and handles edge cases
1184
+ - [ ] Error handling is explicit (no silent failures)
1185
+ - [ ] Types are precise (no \`any\`, no implicit types)
1186
+ - [ ] Functions are single-responsibility
1187
+ - [ ] No code duplication (DRY principle)
1188
+ - [ ] Tests cover happy path + 2+ edge cases
1189
+ - [ ] No security vulnerabilities introduced
1190
+ - [ ] Performance: no N+1 queries, no unnecessary loops
1191
+ - [ ] Naming is clear and consistent
1192
+
1193
+ ## Output Format
1194
+ \`\`\`
1195
+ CODE REVIEW [file: {filename}, lines: {range}]
1196
+ Status: APPROVED | NEEDS_CHANGES | BLOCKED
1197
+
1198
+ Issues:
1199
+ - [CRITICAL/MAJOR/MINOR] {description} \u2192 {suggestion}
1200
+
1201
+ Approved changes:
1202
+ - {description}
1203
+ \`\`\`
1204
+ `;
1205
+ }
1206
+ function generateSessionSummarizerPrompt() {
1207
+ return `# Session Summarizer Sub-Agent
1208
+ <!-- Generated by HarnessCrafter -->
1209
+
1210
+ You are a session summarizer. When invoked at the end of a session:
1211
+
1212
+ 1. Read \`memory-bank/activeContext.md\` and \`memory-bank/progress.md\`
1213
+ 2. Review the current session's \`.claude/sessions/current_session.md\`
1214
+ 3. Update both memory-bank files with:
1215
+ - What was accomplished this session
1216
+ - Key decisions made (with rationale)
1217
+ - Blockers encountered
1218
+ - Next steps (specific enough to resume immediately)
1219
+ 4. If context > 50%: suggest running \`/compact\`
1220
+
1221
+ ## Output Format
1222
+ \`\`\`
1223
+ SESSION SUMMARY
1224
+ Duration: {start} \u2192 {end}
1225
+ IDs issued: {first} \u2192 {last}
1226
+
1227
+ Completed:
1228
+ - [x] {item}
1229
+
1230
+ Decisions:
1231
+ - {decision}: {rationale}
1232
+
1233
+ Next steps:
1234
+ 1. {specific action}
1235
+ \`\`\`
1236
+ `;
1237
+ }
1238
+
1239
+ // src/commands/sync.ts
1240
+ import fs2 from "fs";
1241
+ import path2 from "path";
1242
+ function syncHarness(configPath, outputDir, options = {}) {
1243
+ const config = loadConfig(configPath);
1244
+ const generated = generateHarness(config, { outputDir, dryRun: true });
1245
+ const updated = [];
1246
+ const skipped = [];
1247
+ for (const [filePath, content] of Object.entries(generated.files)) {
1248
+ const diskContent = fs2.existsSync(filePath) ? fs2.readFileSync(filePath, "utf8") : null;
1249
+ if (diskContent === content) {
1250
+ skipped.push(filePath);
1251
+ } else {
1252
+ updated.push(filePath);
1253
+ if (!options.dryRun) {
1254
+ const dir = path2.dirname(filePath);
1255
+ fs2.mkdirSync(dir, { recursive: true });
1256
+ fs2.writeFileSync(filePath, content, "utf8");
1257
+ }
1258
+ }
1259
+ }
1260
+ return { updated, skipped, warnings: generated.warnings };
1261
+ }
1262
+
1263
+ // src/session/searcher.ts
1264
+ import fs3 from "fs";
1265
+ function searchById(filePath, targetId) {
1266
+ if (!fs3.existsSync(filePath)) return null;
1267
+ const content = fs3.readFileSync(filePath, "utf8");
1268
+ const lines = content.split("\n");
1269
+ const idPattern = new RegExp(`\\[ID:\\s*${targetId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\]`);
1270
+ let foundLineIdx = -1;
1271
+ for (let i = 0; i < lines.length; i++) {
1272
+ if (idPattern.test(lines[i])) {
1273
+ foundLineIdx = i;
1274
+ break;
1275
+ }
1276
+ }
1277
+ if (foundLineIdx === -1) return null;
1278
+ const blockStart = foundLineIdx;
1279
+ let blockEnd = lines.length - 1;
1280
+ for (let i = foundLineIdx + 1; i < lines.length; i++) {
1281
+ if (lines[i] === "---") {
1282
+ blockEnd = i;
1283
+ break;
1284
+ }
1285
+ }
1286
+ const blockLines = lines.slice(blockStart, blockEnd);
1287
+ const tsLine = blockLines.find((l) => l.startsWith("<!-- ts:"));
1288
+ const timestamp = tsLine ? tsLine.replace(/<!-- ts:\s*/, "").replace(/\s*-->/, "") : "";
1289
+ const contentLines = blockLines.filter(
1290
+ (l) => !l.startsWith("###") && !l.startsWith("<!--") && l !== ""
1291
+ );
1292
+ const contextStart = Math.max(0, blockStart - 10);
1293
+ const context = lines.slice(contextStart, blockStart).filter((l) => l.trim());
1294
+ return {
1295
+ id: targetId,
1296
+ content: contentLines.join("\n").trim(),
1297
+ timestamp,
1298
+ context
1299
+ };
1300
+ }
1301
+
1302
+ // src/commands/session.ts
1303
+ function sessionSearch(targetId, sessionFilePath) {
1304
+ const result = searchById(sessionFilePath, targetId);
1305
+ if (!result) {
1306
+ return { found: false, id: targetId, content: "", timestamp: "", context: [] };
1307
+ }
1308
+ return {
1309
+ found: true,
1310
+ id: result.id,
1311
+ content: result.content,
1312
+ timestamp: result.timestamp,
1313
+ context: result.context
1314
+ };
1315
+ }
1316
+
1317
+ // src/commands/audit.ts
1318
+ import fs4 from "fs";
1319
+ var CLAUDE_MD_TOKEN_LIMIT2 = 3e3;
1320
+ var RULE_FILE_TOKEN_LIMIT = 2e3;
1321
+ function auditHarness(claudeDir = ".claude") {
1322
+ const checks = [];
1323
+ const claudeMdPath = `${claudeDir}/CLAUDE.md`;
1324
+ if (fs4.existsSync(claudeMdPath)) {
1325
+ const content = fs4.readFileSync(claudeMdPath, "utf8");
1326
+ const tokens = countTokens(content);
1327
+ checks.push({
1328
+ name: "CLAUDE.md token count",
1329
+ status: tokens <= CLAUDE_MD_TOKEN_LIMIT2 ? "pass" : "fail",
1330
+ message: formatTokenCount(tokens, CLAUDE_MD_TOKEN_LIMIT2)
1331
+ });
1332
+ } else {
1333
+ checks.push({ name: "CLAUDE.md token count", status: "fail", message: "CLAUDE.md not found \u2014 run: harness-crafter generate" });
1334
+ }
1335
+ const ruleFiles = ["domain_rules.md", "user_level_rules.md", "cost_mode_rules.md"];
1336
+ for (const ruleFile of ruleFiles) {
1337
+ const filePath = `${claudeDir}/rules/${ruleFile}`;
1338
+ if (fs4.existsSync(filePath)) {
1339
+ const content = fs4.readFileSync(filePath, "utf8");
1340
+ const tokens = countTokens(content);
1341
+ checks.push({
1342
+ name: `rules/${ruleFile}`,
1343
+ status: tokens <= RULE_FILE_TOKEN_LIMIT ? "pass" : "warn",
1344
+ message: formatTokenCount(tokens, RULE_FILE_TOKEN_LIMIT)
1345
+ });
1346
+ } else {
1347
+ checks.push({ name: `rules/${ruleFile}`, status: "warn", message: "File not found" });
1348
+ }
1349
+ }
1350
+ const configPath = `${claudeDir}/harness_config.json`;
1351
+ checks.push({
1352
+ name: "harness_config.json",
1353
+ status: fs4.existsSync(configPath) ? "pass" : "fail",
1354
+ message: fs4.existsSync(configPath) ? "Present" : "Missing \u2014 run: harness-crafter init"
1355
+ });
1356
+ const subAgents = ["evaluator.md", "code_reviewer.md", "session_summarizer.md"];
1357
+ const missingAgents = subAgents.filter((a) => !fs4.existsSync(`${claudeDir}/sub-agents/${a}`));
1358
+ checks.push({
1359
+ name: "sub-agents",
1360
+ status: missingAgents.length === 0 ? "pass" : "warn",
1361
+ message: missingAgents.length === 0 ? "All present" : `Missing: ${missingAgents.join(", ")}`
1362
+ });
1363
+ const passed = checks.every((c) => c.status !== "fail");
1364
+ return { passed, checks };
1365
+ }
1366
+
1367
+ // src/commands/mode.ts
1368
+ import fs5 from "fs";
1369
+ function switchMode(mode, configPath = ".claude/harness_config.json") {
1370
+ if (!fs5.existsSync(configPath)) {
1371
+ throw new Error(`Config not found: ${configPath}. Run: harness-crafter init`);
1372
+ }
1373
+ const raw = JSON.parse(fs5.readFileSync(configPath, "utf8"));
1374
+ const previous = raw.cost_mode?.current;
1375
+ raw.cost_mode.current = mode;
1376
+ raw.generated_at = (/* @__PURE__ */ new Date()).toISOString();
1377
+ const result = HarnessConfigSchema.safeParse(raw);
1378
+ if (!result.success) {
1379
+ throw new Error("Invalid config after mode switch");
1380
+ }
1381
+ fs5.writeFileSync(configPath, JSON.stringify(raw, null, 2), "utf8");
1382
+ const outputDir = configPath.replace("/harness_config.json", "");
1383
+ generateHarness(result.data, { outputDir });
1384
+ return { previous, current: mode };
1385
+ }
1386
+
1387
+ // src/commands/setup.ts
1388
+ import * as readline from "readline/promises";
1389
+ import { stdin as input, stdout as output } from "process";
1390
+ import path3 from "path";
1391
+ import Anthropic from "@anthropic-ai/sdk";
1392
+
1393
+ // src/commands/init.ts
1394
+ import fs6 from "fs";
1395
+ function nameToSlug(name) {
1396
+ const slug = name.toLowerCase().replace(/[\s\-]+/g, "_").replace(/[^a-z0-9_]/g, "").replace(/^_+|_+$/g, "");
1397
+ return slug || "project";
1398
+ }
1399
+ function buildDefaultConfig(overrides = {}) {
1400
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1401
+ const slug = nameToSlug(overrides.name ?? "project");
1402
+ const orgId = overrides.organization_id ?? `org_${slug}`;
1403
+ const projId = overrides.project_id ?? `proj_${slug}_app`;
1404
+ return {
1405
+ schema_version: "1.0.0",
1406
+ organization_id: orgId,
1407
+ project_id: projId,
1408
+ generated_at: now,
1409
+ project: {
1410
+ name: overrides.name ?? "MyProject",
1411
+ domain: overrides.domain ?? "product_dev",
1412
+ user_level: overrides.user_level ?? "competent",
1413
+ language: overrides.language ?? "ja"
1414
+ },
1415
+ cost_mode: {
1416
+ current: overrides.cost_mode ?? "BALANCED",
1417
+ subscription_plan: "free",
1418
+ modes: {
1419
+ ECO: { output_style: "code_only", reasoning_depth: "minimal", test_coverage: "skip", token_budget_ratio: 0.4 },
1420
+ BALANCED: { output_style: "concise", reasoning_depth: "on_error", test_coverage: "critical_only", token_budget_ratio: 0.65 },
1421
+ PRO: { output_style: "detailed", reasoning_depth: "always", test_coverage: "comprehensive", security_check: true, token_budget_ratio: 1 }
1422
+ }
1423
+ },
1424
+ session_mirroring: {
1425
+ enabled: true,
1426
+ id_format: "#{MMDD}-{SEQ}",
1427
+ output_path: ".claude/sessions/current_session.md",
1428
+ auto_search_on_mention: true
1429
+ },
1430
+ telemetry: {
1431
+ enabled: false,
1432
+ endpoint: null,
1433
+ mask_patterns: [
1434
+ `(?i)(api[_-]?key|secret|password|token|credential)\\s*[:=]\\s*['"]?[\\w-]{8,}`,
1435
+ "sk-[\\w]{8,}"
1436
+ ],
1437
+ anonymize_fields: ["organization_id", "project_id", "file_paths"]
1438
+ },
1439
+ rule_priorities: [
1440
+ { rule: "safety_constraints", weight: 100, locked: true },
1441
+ { rule: "domain_specific", weight: 80, locked: false },
1442
+ { rule: "cost_mode", weight: 70, locked: false },
1443
+ { rule: "user_level_adaptation", weight: 60, locked: false },
1444
+ { rule: "output_format", weight: 50, locked: false }
1445
+ ],
1446
+ dynamic_loading: {
1447
+ strategy: "lazy",
1448
+ triggers: {
1449
+ domain_rules: "always",
1450
+ user_level_rules: "always",
1451
+ cost_mode_rules: "on_mode_change",
1452
+ evaluator: "on_implementation"
1453
+ }
1454
+ }
1455
+ };
1456
+ }
1457
+ function writeConfig(config, outputPath = ".claude/harness_config.json") {
1458
+ const dir = outputPath.replace(/\/[^/]+$/, "");
1459
+ fs6.mkdirSync(dir, { recursive: true });
1460
+ fs6.writeFileSync(outputPath, JSON.stringify(config, null, 2), "utf8");
1461
+ }
1462
+ var DOMAIN_LABELS = {
1463
+ product_dev: "Product Development (\u30C6\u30B9\u30C8\u91CD\u8996\u30FB\u5805\u7262\u6027)",
1464
+ realtime_monitor: "Realtime Monitor / Bot (\u30A8\u30E9\u30FC\u30CF\u30F3\u30C9\u30EA\u30F3\u30B0\u30FB\u5373\u6642\u6027)",
1465
+ cron_job: "Cron Job (\u30ED\u30B0\u8A18\u9332\u30FB\u30EA\u30BD\u30FC\u30B9\u52B9\u7387)",
1466
+ design_web: "Design / Web (UI/UX\u30FBFigma\u518D\u73FE)",
1467
+ marketing_ads: "Marketing / Ads (\u30C7\u30FC\u30BF\u5206\u6790\u30FB\u6587\u7AE0\u4F5C\u6210)",
1468
+ outsourced_dev: "Outsourced Dev (\u4ED5\u69D8\u66F8\u53B3\u5B88\u30FB\u5831\u9023\u76F8)",
1469
+ research_rd: "Research & R&D (\u4EEE\u8AAC\u691C\u8A3C\u30FB\u8AD6\u6587\u53C2\u7167)"
1470
+ };
1471
+ var USER_LEVEL_LABELS = {
1472
+ expert: "Expert (\u30B3\u30FC\u30C9\u3068\u7D50\u8AD6\u306E\u307F)",
1473
+ competent: "Competent (\u8981\u70B9\u3092\u7D5E\u3063\u305F\u89E3\u8AAC)",
1474
+ novice: "Novice (\u4E01\u5BE7\u306A\u89E3\u8AAC\u30FB\u65E5\u672C\u8A9E\u5FB9\u5E95)"
1475
+ };
1476
+
1477
+ // src/commands/setup.ts
1478
+ var SYSTEM_PROMPT = `\u3042\u306A\u305F\u306F\u30CF\u30FC\u30CD\u30B9\u8A2D\u5B9A\u30A4\u30F3\u30BF\u30D3\u30E5\u30A2\u30FC\u3067\u3059\u3002
1479
+ Claude Code \u3092\u4F7F\u3046\u4EBA\u304C\u300C\u3069\u3093\u306A\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3067\u3001\u3069\u3093\u306A\u50CD\u304D\u65B9\u304C\u5408\u3063\u3066\u3044\u308B\u304B\u300D\u3092\u805E\u304D\u51FA\u3057\u307E\u3059\u3002
1480
+
1481
+ ## \u30EB\u30FC\u30EB
1482
+ - \u8CEA\u554F\u306F1\u3064\u305A\u3064\u3001\u65E5\u672C\u8A9E\u3067\u805E\u304F
1483
+ - \u9078\u629E\u80A2\u304C\u3042\u308B\u5834\u5408\u306F\u756A\u53F7\u4ED8\u304D\u3067\u63D0\u793A\u3059\u308B\uFF08\u4F8B: 1. \u30B3\u30FC\u30C9\u3060\u3051 2. \u8981\u70B9\u3082\u307B\u3057\u3044 3. \u4E01\u5BE7\u306B\uFF09
1484
+ - \u6700\u59278\u554F\u3067\u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u3092\u7D42\u3048\u308B
1485
+ - \u6280\u8853\u7684\u306A\u5C02\u9580\u7528\u8A9E\uFF08JSON\u30FB\u30D5\u30A1\u30A4\u30EB\u30D1\u30B9\u30FBschema\u7B49\uFF09\u306F\u7D76\u5BFE\u306B\u4F7F\u308F\u306A\u3044
1486
+ - \u30E6\u30FC\u30B6\u30FC\u306E\u53E3\u8A9E\u7684\u306A\u7B54\u3048\u304B\u3089\u30A2\u30FC\u30AD\u30BF\u30A4\u30D7\u30FB\u4F5C\u696D\u30B9\u30BF\u30A4\u30EB\u3092\u63A8\u6E2C\u3059\u308B
1487
+ - \u5341\u5206\u306A\u60C5\u5831\u304C\u96C6\u307E\u3063\u305F\u3089\uFF088\u554F\u672A\u6E80\u3067\u3082OK\uFF09finish_interview \u30C4\u30FC\u30EB\u3092\u547C\u3073\u51FA\u3059
1488
+
1489
+ ## \u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u306E\u6D41\u308C\uFF088\u554F\u4EE5\u5185\uFF09
1490
+
1491
+ ### Phase A: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u7406\u89E3\uFF082-3\u554F\uFF09
1492
+ 1. \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D\u3068\u4F55\u3092\u4F5C\u3063\u3066\u3044\u308B\u304B\uFF08\u81EA\u7531\u8A18\u8FF0\uFF09
1493
+ 2. \u4E3B\u306A\u6210\u679C\u7269\u306E\u7A2E\u985E\uFF08\u30B3\u30FC\u30C9\u30FB\u8A18\u4E8B\u30FB\u30C7\u30FC\u30BF\u30FB\u52D5\u753B\u306A\u3069\uFF09
1494
+ 3. \u8AB0\u306E\u305F\u3081\u306B\u4F5C\u3063\u3066\u3044\u308B\u304B\uFF08\u81EA\u5206\u7528\u30FB\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u5411\u3051\u30FB\u4E00\u822C\u30E6\u30FC\u30B6\u30FC\u5411\u3051\u7B49\uFF09
1495
+
1496
+ ### Phase B: \u50CD\u304D\u65B9\u306E\u597D\u307F\uFF083\u554F\uFF09
1497
+ 4. Claude\u306B\u9014\u4E2D\u3067\u78BA\u8A8D\u3057\u3066\u307B\u3057\u3044\u304B\u3001\u305D\u308C\u3068\u3082\u6700\u5F8C\u307E\u3067\u4EFB\u305B\u305F\u3044\u304B
1498
+ 5. Claude\u306E\u8FD4\u7B54\u306E\u91CF\uFF08\u30B3\u30FC\u30C9\u3060\u3051 / \u8981\u70B9 / \u4E01\u5BE7\u306A\u8AAC\u660E\uFF09
1499
+ 6. \u30A8\u30E9\u30FC\u304C\u51FA\u305F\u3068\u304D\u6B62\u3081\u3066\u307B\u3057\u3044\u304B\u3001\u81EA\u52D5\u4FEE\u6B63\u3057\u3066\u7D9A\u3051\u3066\u307B\u3057\u3044\u304B
1500
+
1501
+ ### Phase D: \u30EA\u30B9\u30AF\u628A\u63E1\uFF081-2\u554F\u3001\u5DEE\u5225\u5316\u306B\u6700\u91CD\u8981\uFF09
1502
+ 7. \u300C\u3053\u308C\u304C\u58CA\u308C\u308B\u3068\u4F55\u304C\u8D77\u304D\u307E\u3059\u304B\uFF1F\u300D\u2014 \u5F71\u97FF\u7BC4\u56F2\u3067\u30EA\u30B9\u30AF\u611F\u5EA6\u3092\u6E2C\u308B
1503
+ - \u81EA\u5206\u3060\u3051\u56F0\u308B \u2192 scope_guard=false, error_notification=continue
1504
+ - \u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u3084\u9867\u5BA2\u306B\u5F71\u97FF \u2192 scope_guard=true, error_notification=stop
1505
+
1506
+ ### Phase E: \u904E\u53BB\u306E\u6469\u64E6\uFF081\u554F\uFF09
1507
+ 8. Claude \u306B\u300C\u3084\u308A\u3059\u304E\u305F\u300D\u300C\u4F59\u8A08\u306A\u3053\u3068\u3092\u3055\u308C\u305F\u300D\u7D4C\u9A13\u304C\u3042\u308B\u304B
1508
+ - \u3088\u304F\u3042\u308B \u2192 conservative + scope_guard=true
1509
+ - \u306A\u3044\u30FB\u4EFB\u305B\u305F\u3044 \u2192 autonomous
1510
+
1511
+ ## \u30A2\u30FC\u30AD\u30BF\u30A4\u30D7\u5224\u5B9A\u57FA\u6E96
1512
+ - \u500B\u4EBA\u306E\u81EA\u52D5\u5316\u30FB\u30B9\u30AF\u30EA\u30D7\u30C8 \u2192 personal_tool
1513
+ - SaaS\u30FBWeb\u30A2\u30D7\u30EA\u958B\u767A \u2192 saas_product
1514
+ - LP\u30FB\u30DE\u30FC\u30B1\u30C6\u30A3\u30F3\u30B0\u30B5\u30A4\u30C8 \u2192 marketing_site
1515
+ - \u30C7\u30FC\u30BF\u96C6\u8A08\u30FB\u5206\u6790\u30FB\u30EC\u30DD\u30FC\u30C8 \u2192 data_analysis
1516
+ - \u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u5411\u3051\u53D7\u8A17\u958B\u767A \u2192 outsourced_dev
1517
+ - \u5B66\u7FD2\u30FB\u5B9F\u9A13\u30FB\u52C9\u5F37 \u2192 learning
1518
+ - \u793E\u5185\u696D\u52D9\u81EA\u52D5\u5316\u30FB\u30D0\u30C3\u30AF\u30AA\u30D5\u30A3\u30B9 \u2192 business_automation
1519
+ - \u55B6\u696D\u30C4\u30FC\u30EB\u30FB\u9867\u5BA2\u7BA1\u7406 \u2192 sales_dx
1520
+ - YouTube\u52D5\u753B\u5236\u4F5C\u30FB\u7DE8\u96C6 \u2192 youtube_content
1521
+ - \u30D6\u30ED\u30B0\u30FB\u8A18\u4E8B\u30FB\u30E1\u30C7\u30A3\u30A2 \u2192 article_writing
1522
+ - SEO\u30FB\u30DE\u30FC\u30B1\u30C6\u30A3\u30F3\u30B0\u65BD\u7B56 \u2192 seo_marketing
1523
+ - \u91D1\u878D\u30FB\u30C8\u30EC\u30FC\u30C9\u30FBBOT \u2192 finance_bot
1524
+ - \u30C7\u30FC\u30BF\u53CE\u96C6\u30FB\u30B9\u30AF\u30EC\u30A4\u30D4\u30F3\u30B0\u30FB\u6574\u7406 \u2192 data_collection
1525
+
1526
+ ## \u30C9\u30E1\u30A4\u30F3\u5224\u5B9A\u57FA\u6E96
1527
+ - \u30A2\u30D7\u30EA\u30FBSaaS\u30FB\u30D7\u30ED\u30C0\u30AF\u30C8\u958B\u767A \u2192 product_dev
1528
+ - \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u76E3\u8996\u30FBBot \u2192 realtime_monitor
1529
+ - \u5B9A\u671F\u5B9F\u884C\u30FB\u30D0\u30C3\u30C1\u51E6\u7406 \u2192 cron_job
1530
+ - \u30C7\u30B6\u30A4\u30F3\u30FBWeb\u30D5\u30ED\u30F3\u30C8 \u2192 design_web
1531
+ - \u30DE\u30FC\u30B1\u30C6\u30A3\u30F3\u30B0\u30FB\u5E83\u544A \u2192 marketing_ads
1532
+ - \u53D7\u8A17\u30FB\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u30EF\u30FC\u30AF \u2192 outsourced_dev
1533
+ - \u30EA\u30B5\u30FC\u30C1\u30FBR&D \u2192 research_rd
1534
+
1535
+ ## \u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB\u5224\u5B9A
1536
+ - \u30A8\u30F3\u30B8\u30CB\u30A2\u30FB\u958B\u767A\u8005 \u2192 expert
1537
+ - \u5B9F\u52D9\u3067\u4F7F\u3063\u3066\u3044\u308B\u975E\u30A8\u30F3\u30B8\u30CB\u30A2 \u2192 competent
1538
+ - \u59CB\u3081\u305F\u3070\u304B\u308A\u30FB\u30BF\u30FC\u30DF\u30CA\u30EB\u64CD\u4F5C\u304C\u4E0D\u6163\u308C \u2192 novice`;
1539
+ var FINISH_INTERVIEW_TOOL = {
1540
+ name: "finish_interview",
1541
+ description: "\u5341\u5206\u306A\u60C5\u5831\u304C\u96C6\u307E\u3063\u305F\u3089\u3053\u306E\u30C4\u30FC\u30EB\u3092\u547C\u3073\u51FA\u3057\u3066\u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u3092\u7D42\u4E86\u3057\u3001\u30CF\u30FC\u30CD\u30B9\u3092\u751F\u6210\u3059\u308B",
1542
+ input_schema: {
1543
+ type: "object",
1544
+ properties: {
1545
+ project_name: {
1546
+ type: "string",
1547
+ description: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D"
1548
+ },
1549
+ archetype: {
1550
+ type: "string",
1551
+ enum: [...ARCHETYPES],
1552
+ description: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30A2\u30FC\u30AD\u30BF\u30A4\u30D7"
1553
+ },
1554
+ domain: {
1555
+ type: "string",
1556
+ enum: [...PROJECT_DOMAINS],
1557
+ description: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30C9\u30E1\u30A4\u30F3"
1558
+ },
1559
+ user_level: {
1560
+ type: "string",
1561
+ enum: [...USER_LEVELS],
1562
+ description: "\u30E6\u30FC\u30B6\u30FC\u306E\u6280\u8853\u30EC\u30D9\u30EB"
1563
+ },
1564
+ confirmation_frequency: {
1565
+ type: "string",
1566
+ enum: ["high", "medium", "low"],
1567
+ description: "Claude\u304C\u78BA\u8A8D\u3092\u631F\u3080\u983B\u5EA6"
1568
+ },
1569
+ autonomy_level: {
1570
+ type: "string",
1571
+ enum: ["conservative", "balanced", "autonomous"],
1572
+ description: "Claude\u306E\u81EA\u5F8B\u5EA6"
1573
+ },
1574
+ verbosity: {
1575
+ type: "string",
1576
+ enum: ["minimal", "normal", "detailed"],
1577
+ description: "\u5FDC\u7B54\u306E\u8A73\u3057\u3055"
1578
+ },
1579
+ error_notification: {
1580
+ type: "string",
1581
+ enum: ["stop", "notify", "continue"],
1582
+ description: "\u30A8\u30E9\u30FC\u6642\u306E\u632F\u308B\u821E\u3044"
1583
+ },
1584
+ report_frequency: {
1585
+ type: "string",
1586
+ enum: ["always", "on_milestone", "on_error", "never"],
1587
+ description: "\u9032\u6357\u5831\u544A\u306E\u983B\u5EA6"
1588
+ },
1589
+ scope_guard: {
1590
+ type: "boolean",
1591
+ description: "\u6307\u793A\u7BC4\u56F2\u5916\u306E\u30D5\u30A1\u30A4\u30EB\u5909\u66F4\u3092\u9632\u6B62\u3059\u308B\u304B"
1592
+ },
1593
+ automation_needed: {
1594
+ type: "boolean",
1595
+ description: "\u81EA\u52D5\u5316\u30FB\u5B9A\u671F\u5B9F\u884C\u304C\u5FC5\u8981\u304B"
1596
+ },
1597
+ preserve_voice: {
1598
+ type: "boolean",
1599
+ description: "\u6587\u7AE0\u306E\u6587\u4F53\u30FB\u30C8\u30FC\u30F3\u3092\u4FDD\u6301\u3059\u308B\u304B"
1600
+ }
1601
+ },
1602
+ required: [
1603
+ "project_name",
1604
+ "archetype",
1605
+ "domain",
1606
+ "user_level",
1607
+ "confirmation_frequency",
1608
+ "autonomy_level",
1609
+ "verbosity",
1610
+ "error_notification",
1611
+ "report_frequency",
1612
+ "scope_guard",
1613
+ "automation_needed",
1614
+ "preserve_voice"
1615
+ ]
1616
+ }
1617
+ };
1618
+ function buildConfigFromInterview(result) {
1619
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1620
+ const projectId = `proj_${Math.random().toString(36).slice(2, 10)}`;
1621
+ const orgId = `org_local`;
1622
+ return {
1623
+ schema_version: "2.0.0",
1624
+ organization_id: orgId,
1625
+ project_id: projectId,
1626
+ generated_at: now,
1627
+ project: {
1628
+ name: result.project_name,
1629
+ domain: result.domain,
1630
+ user_level: result.user_level,
1631
+ language: "ja"
1632
+ },
1633
+ cost_mode: {
1634
+ current: "BALANCED",
1635
+ subscription_plan: "free",
1636
+ modes: {
1637
+ ECO: {
1638
+ output_style: "code_only",
1639
+ reasoning_depth: "minimal",
1640
+ test_coverage: "skip",
1641
+ token_budget_ratio: 0.4
1642
+ },
1643
+ BALANCED: {
1644
+ output_style: "concise",
1645
+ reasoning_depth: "on_error",
1646
+ test_coverage: "critical_only",
1647
+ token_budget_ratio: 0.65
1648
+ },
1649
+ PRO: {
1650
+ output_style: "detailed",
1651
+ reasoning_depth: "always",
1652
+ test_coverage: "comprehensive",
1653
+ security_check: true,
1654
+ token_budget_ratio: 1
1655
+ }
1656
+ }
1657
+ },
1658
+ archetype: result.archetype,
1659
+ workflow: {
1660
+ confirmation_frequency: result.confirmation_frequency,
1661
+ autonomy_level: result.autonomy_level,
1662
+ scope_guard: result.scope_guard
1663
+ },
1664
+ communication: {
1665
+ verbosity: result.verbosity,
1666
+ preserve_voice: result.preserve_voice,
1667
+ error_notification: result.error_notification,
1668
+ report_frequency: result.report_frequency
1669
+ },
1670
+ automation: result.automation_needed ? {
1671
+ enabled: true,
1672
+ schedule: null,
1673
+ retry_on_error: true,
1674
+ error_escalation: "notify",
1675
+ max_retries: 3
1676
+ } : {
1677
+ enabled: false,
1678
+ schedule: null,
1679
+ retry_on_error: false,
1680
+ error_escalation: "stop",
1681
+ max_retries: 0
1682
+ },
1683
+ session_mirroring: {
1684
+ enabled: true,
1685
+ id_format: "#{MMDD}-{SEQ}",
1686
+ output_path: ".claude/sessions/current_session.md",
1687
+ auto_search_on_mention: true
1688
+ },
1689
+ telemetry: {
1690
+ enabled: false,
1691
+ endpoint: null,
1692
+ mask_patterns: [
1693
+ `(?i)(api[_-]?key|secret|password|token|credential)\\s*[:=]\\s*['"]?[\\w-]{8,}`,
1694
+ "sk-[\\w]{8,}"
1695
+ ],
1696
+ anonymize_fields: ["organization_id", "project_id", "file_paths"]
1697
+ },
1698
+ rule_priorities: [
1699
+ { rule: "safety_constraints", weight: 100, locked: true },
1700
+ { rule: "domain_specific", weight: 80, locked: false },
1701
+ { rule: "cost_mode", weight: 70, locked: false },
1702
+ { rule: "user_level_adaptation", weight: 60, locked: false },
1703
+ { rule: "output_format", weight: 50, locked: false }
1704
+ ],
1705
+ dynamic_loading: {
1706
+ strategy: "lazy",
1707
+ triggers: {
1708
+ domain_rules: "always",
1709
+ user_level_rules: "always",
1710
+ cost_mode_rules: "on_mode_change",
1711
+ evaluator: "on_implementation"
1712
+ }
1713
+ }
1714
+ };
1715
+ }
1716
+ async function runSetup(options = {}) {
1717
+ const apiKey = process.env.ANTHROPIC_API_KEY;
1718
+ if (!apiKey) {
1719
+ console.error(
1720
+ "\n\u274C ANTHROPIC_API_KEY \u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\n export ANTHROPIC_API_KEY=sk-ant-... \u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n"
1721
+ );
1722
+ process.exit(1);
1723
+ }
1724
+ const outDir = options.outputDir ?? ".claude";
1725
+ const model = options.model ?? "claude-sonnet-4-6";
1726
+ const client = new Anthropic({ apiKey });
1727
+ const rl = readline.createInterface({ input, output });
1728
+ console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
1729
+ console.log(" HarnessCrafter \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7");
1730
+ console.log(" Claude \u304C\u3042\u306A\u305F\u306B\u5408\u3063\u305F\u30CF\u30FC\u30CD\u30B9\u3092\u4F5C\u308A\u307E\u3059");
1731
+ console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
1732
+ const messages = [
1733
+ {
1734
+ role: "user",
1735
+ content: "\u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u3092\u958B\u59CB\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u6700\u521D\u306E\u8CEA\u554F\u3092\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
1736
+ }
1737
+ ];
1738
+ let interviewResult = null;
1739
+ const MAX_TURNS = 12;
1740
+ for (let turn = 0; turn < MAX_TURNS; turn++) {
1741
+ let response;
1742
+ try {
1743
+ response = await client.messages.create({
1744
+ model,
1745
+ max_tokens: 1024,
1746
+ system: SYSTEM_PROMPT,
1747
+ tools: [FINISH_INTERVIEW_TOOL],
1748
+ tool_choice: { type: "auto" },
1749
+ messages
1750
+ });
1751
+ } catch (err) {
1752
+ if (err instanceof Anthropic.AuthenticationError) {
1753
+ console.error("\n\u274C API\u30AD\u30FC\u304C\u7121\u52B9\u3067\u3059\u3002ANTHROPIC_API_KEY \u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
1754
+ } else if (err instanceof Anthropic.RateLimitError) {
1755
+ console.error("\n\u274C API\u306E\u30EC\u30FC\u30C8\u5236\u9650\u306B\u9054\u3057\u307E\u3057\u305F\u3002\u3057\u3070\u3089\u304F\u5F85\u3063\u3066\u304B\u3089\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
1756
+ } else {
1757
+ console.error("\n\u274C API\u30A8\u30E9\u30FC:", err instanceof Error ? err.message : err);
1758
+ }
1759
+ rl.close();
1760
+ process.exit(1);
1761
+ }
1762
+ messages.push({ role: "assistant", content: response.content });
1763
+ const textBlock = response.content.find((b) => b.type === "text");
1764
+ if (textBlock && textBlock.type === "text" && textBlock.text.trim()) {
1765
+ console.log(`
1766
+ Claude: ${textBlock.text}`);
1767
+ }
1768
+ const toolUse = response.content.find(
1769
+ (b) => b.type === "tool_use" && b.name === "finish_interview"
1770
+ );
1771
+ if (toolUse) {
1772
+ interviewResult = toolUse.input;
1773
+ break;
1774
+ }
1775
+ const userInput = await rl.question("\n\u3042\u306A\u305F: ");
1776
+ if (userInput.toLowerCase() === "quit" || userInput.toLowerCase() === "exit") {
1777
+ console.log("\n\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3057\u305F\u3002");
1778
+ rl.close();
1779
+ return;
1780
+ }
1781
+ messages.push({ role: "user", content: userInput });
1782
+ }
1783
+ rl.close();
1784
+ if (!interviewResult) {
1785
+ console.error("\n\u274C \u30A4\u30F3\u30BF\u30D3\u30E5\u30FC\u304C\u6B63\u5E38\u306B\u5B8C\u4E86\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u518D\u5EA6 setup \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
1786
+ process.exit(1);
1787
+ }
1788
+ console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
1789
+ console.log(" \u30CF\u30FC\u30CD\u30B9\u3092\u751F\u6210\u3057\u3066\u3044\u307E\u3059...");
1790
+ console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
1791
+ const config = buildConfigFromInterview(interviewResult);
1792
+ const configPath = path3.join(outDir, "harness_config.json");
1793
+ writeConfig(config, configPath);
1794
+ const result = generateHarness(config, {
1795
+ outputDir: outDir,
1796
+ dryRun: false
1797
+ });
1798
+ const fileCount = Object.keys(result.files).length;
1799
+ const warnings = result.warnings;
1800
+ console.log(`\u2705 \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B8C\u4E86\uFF01
1801
+ `);
1802
+ console.log(` \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8: ${interviewResult.project_name}`);
1803
+ console.log(` \u30A2\u30FC\u30AD\u30BF\u30A4\u30D7: ${interviewResult.archetype}`);
1804
+ console.log(` \u751F\u6210\u30D5\u30A1\u30A4\u30EB: ${fileCount}\u4EF6
1805
+ `);
1806
+ if (warnings.length > 0) {
1807
+ for (const w of warnings) {
1808
+ console.log(` \u26A0 ${w}`);
1809
+ }
1810
+ console.log();
1811
+ }
1812
+ console.log(` \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:`);
1813
+ console.log(` 1. Claude Code \u3092\u8D77\u52D5\u3059\u308B`);
1814
+ console.log(` 2. Claude \u304C\u81EA\u52D5\u7684\u306B\u30CF\u30FC\u30CD\u30B9\u3092\u8AAD\u307F\u8FBC\u307F\u307E\u3059`);
1815
+ console.log(` 3. \u8ABF\u6574\u3057\u305F\u3044\u5834\u5408\u306F /tune <\u5185\u5BB9> \u3067\u5909\u66F4\u3067\u304D\u307E\u3059
1816
+ `);
1817
+ }
1818
+
1819
+ // src/index.ts
1820
+ var program = new Command();
1821
+ program.name("harness-crafter").description("AI Agent Harness Builder & Adjuster for Claude Code").version("1.0.0");
1822
+ program.command("setup").description("Interactive interview to generate a personalized harness (requires ANTHROPIC_API_KEY)").option("--dir <path>", "Output directory", ".claude").option("--model <model>", "Claude model to use", "claude-sonnet-4-6").action(async (opts) => {
1823
+ await runSetup({ outputDir: opts.dir, model: opts.model });
1824
+ ensureGitignore(process.cwd());
1825
+ });
1826
+ program.command("init").description("Initialize HarnessCrafter in the current project").option("--name <name>", "Project name").option("--domain <domain>", `Domain: ${PROJECT_DOMAINS.join("|")}`).option("--level <level>", `User level: ${USER_LEVELS.join("|")}`).option("--mode <mode>", `Cost mode: ${COST_MODE_KEYS.join("|")}`).option("--yes", "Use defaults without prompting").action(async (opts) => {
1827
+ console.log(chalk.cyan("\n HarnessCrafter \u2014 Init\n"));
1828
+ let answers = {
1829
+ name: opts.name ?? "",
1830
+ domain: opts.domain ?? "",
1831
+ user_level: opts.level ?? "",
1832
+ cost_mode: opts.mode ?? ""
1833
+ };
1834
+ if (!opts.yes && (!opts.name || !opts.domain || !opts.level || !opts.mode)) {
1835
+ const { default: inquirer } = await import("inquirer");
1836
+ const questions = [];
1837
+ if (!opts.name) {
1838
+ questions.push({ type: "input", name: "name", message: "Project name:", default: "MyProject" });
1839
+ }
1840
+ if (!opts.domain) {
1841
+ questions.push({
1842
+ type: "list",
1843
+ name: "domain",
1844
+ message: "Project domain:",
1845
+ choices: PROJECT_DOMAINS.map((d) => ({ value: d, name: DOMAIN_LABELS[d] }))
1846
+ });
1847
+ }
1848
+ if (!opts.level) {
1849
+ questions.push({
1850
+ type: "list",
1851
+ name: "user_level",
1852
+ message: "User level:",
1853
+ choices: USER_LEVELS.map((l) => ({ value: l, name: USER_LEVEL_LABELS[l] }))
1854
+ });
1855
+ }
1856
+ if (!opts.mode) {
1857
+ questions.push({
1858
+ type: "list",
1859
+ name: "cost_mode",
1860
+ message: "Cost mode:",
1861
+ choices: [
1862
+ { value: "ECO", name: "ECO \u2014 Code only, minimal tokens" },
1863
+ { value: "BALANCED", name: "BALANCED \u2014 Normal + CoT on error (recommended)" },
1864
+ { value: "PRO", name: "PRO \u2014 Maximum quality, security checks, tests" }
1865
+ ]
1866
+ });
1867
+ }
1868
+ const prompted = await inquirer.prompt(questions);
1869
+ answers = { ...answers, ...prompted };
1870
+ } else if (opts.yes) {
1871
+ answers = {
1872
+ name: opts.name ?? "MyProject",
1873
+ domain: opts.domain ?? "product_dev",
1874
+ user_level: opts.level ?? "competent",
1875
+ cost_mode: opts.mode ?? "BALANCED"
1876
+ };
1877
+ }
1878
+ const config = buildDefaultConfig({
1879
+ name: answers.name,
1880
+ domain: answers.domain,
1881
+ user_level: answers.user_level,
1882
+ cost_mode: answers.cost_mode
1883
+ });
1884
+ writeConfig(config, ".claude/harness_config.json");
1885
+ console.log(chalk.green(" \u2713 .claude/harness_config.json created"));
1886
+ const result = generateHarness(config, { outputDir: ".claude" });
1887
+ console.log(chalk.green(` \u2713 Generated ${Object.keys(result.files).length} files in .claude/`));
1888
+ if (result.warnings.length > 0) {
1889
+ result.warnings.forEach((w) => console.log(chalk.yellow(` \u26A0 ${w}`)));
1890
+ }
1891
+ ensureGitignore(process.cwd());
1892
+ console.log(chalk.green(" \u2713 .gitignore updated (.claude/sessions/ \u3092\u9664\u5916)"));
1893
+ console.log(chalk.cyan("\n Run `harness-crafter audit` to verify your harness.\n"));
1894
+ });
1895
+ program.command("generate").description("Regenerate .claude/ files from harness_config.json").option("--config <path>", "Config file path", ".claude/harness_config.json").option("--dry-run", "Preview without writing files").action((opts) => {
1896
+ const config = loadConfig(opts.config);
1897
+ const result = generateHarness(config, { outputDir: ".claude", dryRun: opts.dryRun });
1898
+ const prefix = opts.dryRun ? "[DRY RUN] " : "";
1899
+ console.log(chalk.cyan(`
1900
+ ${prefix}Generated files:
1901
+ `));
1902
+ for (const [filePath, count] of Object.entries(result.tokenCounts)) {
1903
+ const status = count > 3e3 ? chalk.red("OVER") : chalk.green("OK");
1904
+ console.log(` ${filePath.padEnd(50)} ${count} tokens [${status}]`);
1905
+ }
1906
+ if (result.warnings.length > 0) {
1907
+ result.warnings.forEach((w) => console.log(chalk.yellow(`
1908
+ \u26A0 ${w}`)));
1909
+ }
1910
+ console.log();
1911
+ });
1912
+ program.command("audit").description("Check harness health (token counts, missing files)").option("--dir <path>", "Claude directory", ".claude").action((opts) => {
1913
+ const result = auditHarness(opts.dir);
1914
+ console.log(chalk.cyan("\n Harness Audit Report\n"));
1915
+ for (const check of result.checks) {
1916
+ const icon = check.status === "pass" ? chalk.green("\u2713") : check.status === "warn" ? chalk.yellow("\u26A0") : chalk.red("\u2717");
1917
+ console.log(` ${icon} ${check.name.padEnd(40)} ${check.message}`);
1918
+ }
1919
+ const overall = result.passed ? chalk.green("PASSED") : chalk.red("FAILED");
1920
+ console.log(`
1921
+ Overall: ${overall}
1922
+ `);
1923
+ if (!result.passed) process.exit(1);
1924
+ });
1925
+ program.command("sync").description("Sync .claude/ files with harness_config.json (only changed files are updated)").option("--config <path>", "Config file path", ".claude/harness_config.json").option("--dir <path>", "Claude directory", ".claude").option("--dry-run", "Preview changes without writing files").action((opts) => {
1926
+ const result = syncHarness(opts.config, opts.dir, { dryRun: opts.dryRun });
1927
+ const prefix = opts.dryRun ? chalk.yellow("[DRY RUN] ") : "";
1928
+ console.log(chalk.cyan(`
1929
+ ${prefix}Sync results:
1930
+ `));
1931
+ if (result.updated.length === 0) {
1932
+ console.log(chalk.green(" \u2713 All files are up to date."));
1933
+ } else {
1934
+ for (const f of result.updated) {
1935
+ const icon = opts.dryRun ? chalk.yellow("~") : chalk.green("\u2713");
1936
+ console.log(` ${icon} updated: ${f}`);
1937
+ }
1938
+ }
1939
+ if (result.skipped.length > 0) {
1940
+ console.log(chalk.gray(`
1941
+ (${result.skipped.length} file(s) unchanged)`));
1942
+ }
1943
+ if (result.warnings.length > 0) {
1944
+ result.warnings.forEach((w) => console.log(chalk.yellow(`
1945
+ \u26A0 ${w}`)));
1946
+ }
1947
+ console.log();
1948
+ });
1949
+ program.command("mode <mode>").description(`Switch cost mode: ${COST_MODE_KEYS.join(" | ")}`).action((mode) => {
1950
+ if (!COST_MODE_KEYS.includes(mode.toUpperCase())) {
1951
+ console.error(chalk.red(` Invalid mode: ${mode}. Use: ${COST_MODE_KEYS.join(" | ")}`));
1952
+ process.exit(1);
1953
+ }
1954
+ const result = switchMode(mode.toUpperCase());
1955
+ console.log(chalk.green(` \u2713 Mode switched: ${result.previous} \u2192 ${result.current}`));
1956
+ console.log(chalk.gray(" Harness files regenerated.\n"));
1957
+ });
1958
+ var sessionCmd = program.command("session").description("Session management commands");
1959
+ sessionCmd.command("search <id>").description("Search session file for a specific ID and show its context").option("--file <path>", "Session file path", ".claude/sessions/current_session.md").action((id, opts) => {
1960
+ const result = sessionSearch(id, opts.file);
1961
+ if (!result.found) {
1962
+ console.error(chalk.red(` \u2717 ID not found: ${id} in ${opts.file}`));
1963
+ process.exit(1);
1964
+ }
1965
+ console.log(chalk.cyan(`
1966
+ Session Entry: ${result.id}
1967
+ `));
1968
+ if (result.timestamp) {
1969
+ console.log(chalk.gray(` Timestamp: ${result.timestamp}`));
1970
+ }
1971
+ if (result.context.length > 0) {
1972
+ console.log(chalk.gray("\n --- Prior context ---"));
1973
+ console.log(chalk.gray(result.context.map((l) => ` ${l}`).join("\n")));
1974
+ }
1975
+ console.log(chalk.white("\n --- Content ---"));
1976
+ console.log(result.content.split("\n").map((l) => ` ${l}`).join("\n"));
1977
+ console.log();
1978
+ });
1979
+ program.parse();