// tools/init-project/rules-generator.ts — Write .claude/rules/planu-workflow.md
// SPEC-263: Autonomous CLAUDE.md that makes Planu mandatory
import { writeFile, mkdir, access } from 'node:fs/promises';
import { join } from 'node:path';
import { assertEnglishOnlyArtifactText } from '../../engine/spec-language/english-only.js';
const PLANU_WORKFLOW_RULES_PATH = '.claude/rules/planu-workflow.md';
const PLANU_WORKFLOW_RULES_CONTENT = `# Planu SDD Workflow (MANDATORY)

Auto-generated by \`init_project\`. Do not edit manually.

## Spec Lifecycle

| State | Meaning |
|-------|---------|
| draft | created, not reviewed |
| review | ready for approval |
| approved | safe to implement |
| implementing | work in progress |
| done | implemented + validated |

Flow: \`facilitate → create_spec → challenge_spec → check_readiness → approve → implement → validate → done\`

## When to use \`facilitate\`

Any new feature, bug fix, refactor, integration, or task > 5 min.

## Session Start

1. \`planu_status\` — check active specs
2. Resume any \`implementing\` spec before starting new work

## Session End

- \`session_checkpoint\` — persist context for the next session
- \`update_status(done)\` — if work is complete

## Quick Reference

| Goal | Tool |
|------|------|
| New feature | \`facilitate("what to build")\` |
| Project status | \`planu_status\` |
| Find related specs | \`semantic_search("keywords")\` |
| List approved work | \`list_specs\` with \`status: approved\` |
| Mark done | \`update_status\` → \`done\` |
| Verify | \`validate\` |
| Save session | \`session_checkpoint\` |

## Rules

- NEVER write code before spec is \`approved\`
- NEVER skip \`validate\` after implementation
- NEVER create design docs outside \`planu/specs/\`

## Model Selection (MANDATORY)

Use the cheapest/fastest model that can handle the task:

| Task type | Capability needed |
|-----------|-------------------|
| Search, explore, read, grep, summarize | smallest / fastest model |
| Implement, fix, refactor, tests, UI | mid-tier model |
| Architecture, complex debug, multi-system planning | most capable model |

**Claude Code users**: haiku (read-only) · sonnet (implement) · opus (architecture).
Set \`CLAUDE_CODE_SUBAGENT_MODEL=haiku\` in \`.env\` for automatic haiku on all read-only subagents (4–18x cheaper).

**Cursor / Windsurf / other**: use the equivalent lightweight model for search/read subagents.

## Token Optimization

- Lead with action/result — not reasoning. One sentence beats three.
- Never repeat what the user said or file contents back to them.
- Delegate to subagents: file searches, multi-file reads, independent tasks
- Stop early: task done → stop. No trailing "let me know if..." summaries.

## Output Quality

- Summarize tool results in plain language — never dump raw JSON to the user
- Keep output < 500 tokens for read operations, < 200 tokens for write confirmations
- After every tool call: explain what happened in simple terms
`;
const AGENT_TEAMS_RULES_PATH = '.claude/rules/agent-teams.md';
export function generateAgentTeamsRulesContent() {
    return `# Agent Teams (MANDATORY when 3+ specs in parallel)

This rule file is auto-generated by Planu \`init_project\`. Do not edit manually — re-run \`init_project\` to update.

## When to Use Agent Teams

Use Agent Teams when ALL of the following apply:
- 3+ independent specs are ready to implement simultaneously
- Estimated total effort > 8h
- Specs touch different modules/packages (clear file ownership boundaries)
- Monorepo or multi-layer architecture with well-defined interfaces

## File Ownership (MANDATORY)

**Two teammates MUST NEVER modify the same file.** This is non-negotiable.

- \`plan_team_distribution\` auto-assigns exclusive file ownership per agent
- Review the distribution before spawning — resolve any conflicts first
- If two specs require the same shared file, implement them sequentially, not in parallel

## Workflow

\`\`\`
1. plan_team_distribution   # input: spec IDs → output: file ownership map
2. generate_teammate_prompt # input: teammate assignment → output: isolated prompt
3. spawn N agents           # claude -p "<prompt>" for each teammate (run in parallel)
4. validate_team_results    # input: projectPath → verifies merged code integrity
\`\`\`

## Available Team Patterns

- **implement-and-test** — one agent implements, another writes tests (zero shared files)
- **full-stack** — frontend and backend agents with a contract-first API boundary
- **research-then-build** — researcher gathers context first, builder implements after
- **parallel-specs** — N agents implement N fully independent specs simultaneously

## Quick Reference

| Goal | Tool |
|------|------|
| Plan team distribution | \`plan_team_distribution\` with spec IDs array |
| Get teammate context | \`generate_teammate_prompt\` with assignment object |
| Validate merged result | \`validate_team_results\` after all agents complete |

## Prohibited Patterns

- NEVER spawn teammates without running \`plan_team_distribution\` first
- NEVER assign the same file to two different teammates
- NEVER skip \`validate_team_results\` after parallel implementation
- NEVER use Agent Teams for 1-2 specs — sequential is faster and safer
`;
}
/**
 * Write .claude/rules/agent-teams.md to the target project.
 * Always overwrites to keep the content up to date.
 */
export async function generateAgentTeamsRules(projectPath) {
    const rulesPath = join(projectPath, AGENT_TEAMS_RULES_PATH);
    const rulesDir = join(projectPath, '.claude/rules');
    await mkdir(rulesDir, { recursive: true });
    const content = generateAgentTeamsRulesContent();
    assertEnglishOnlyArtifactText(content, 'rule');
    await writeFile(rulesPath, content, 'utf-8');
}
/**
 * Write .claude/rules/agent-teams.md only if it does not exist yet.
 * @returns true if the file was created, false if it already existed.
 */
export async function generateAgentTeamsRulesIfMissing(projectPath) {
    const rulesPath = join(projectPath, AGENT_TEAMS_RULES_PATH);
    try {
        await access(rulesPath);
        return false; // already exists
    }
    catch {
        await generateAgentTeamsRules(projectPath);
        return true;
    }
}
/**
 * Write .claude/rules/planu-workflow.md to the target project.
 * Always overwrites to keep the content up to date.
 */
export async function generateWorkflowRules(projectPath) {
    const rulesPath = join(projectPath, PLANU_WORKFLOW_RULES_PATH);
    const rulesDir = join(projectPath, '.claude/rules');
    await mkdir(rulesDir, { recursive: true });
    assertEnglishOnlyArtifactText(PLANU_WORKFLOW_RULES_CONTENT, 'rule');
    await writeFile(rulesPath, PLANU_WORKFLOW_RULES_CONTENT, 'utf-8');
}
/**
 * Write .claude/rules/planu-workflow.md only if it does not exist yet.
 * @returns true if the file was created, false if it already existed.
 */
export async function generateWorkflowRulesIfMissing(projectPath) {
    const rulesPath = join(projectPath, PLANU_WORKFLOW_RULES_PATH);
    try {
        await access(rulesPath);
        return false; // already exists
    }
    catch {
        await generateWorkflowRules(projectPath);
        return true;
    }
}
/**
 * Exposed for testing — returns the rules file path relative to project root.
 */
export function getWorkflowRulesRelativePath() {
    return PLANU_WORKFLOW_RULES_PATH;
}
// SPEC-494: Claude Code mode hints per spec phase
const PLANU_MODES_RULES_PATH = '.claude/rules/planu-modes.md';
const PLANU_MODES_RULES_CONTENT = `# Claude Code Mode Hints (MANDATORY — Planu SDD)

Auto-generated by \`init_project\`. Do not edit manually.

## Mode per Spec Phase

When the user moves a spec to a new status, suggest the matching Claude Code permission mode.
Never suggest bypassPermissions — it disables all safety checks.

| Spec Status | Suggested Mode | When to use |
|-------------|---------------|-------------|
| \`draft\` | \`default\` | Spec not yet approved — always ask before changes |
| \`review\` | \`default\` | Under review — user must confirm before edits |
| \`approved\` | \`plan\` | Spec is the contract — use plan mode to review before coding |
| \`implementing\` | \`acceptEdits\` | Spec is the contract — auto-accept file edits, bash still asks |
| \`done\` | \`default\` | Implementation complete — back to safe default |

## How to apply

- After \`update_status\` returns \`suggestedClaudeMode\`, relay it to the user: "I recommend switching to \`/mode <mode>\`"
- NEVER switch modes automatically — always tell the user and let them decide
- Critical bash actions (git push, npm publish, rm -rf) require approval regardless of mode
`;
/**
 * Write .claude/rules/planu-modes.md only if it does not exist yet.
 * @returns true if the file was created, false if it already existed.
 */
export async function generateModeRulesIfMissing(projectPath) {
    const rulesPath = join(projectPath, PLANU_MODES_RULES_PATH);
    try {
        await access(rulesPath);
        return false; // already exists
    }
    catch {
        const rulesDir = join(projectPath, '.claude/rules');
        await mkdir(rulesDir, { recursive: true });
        assertEnglishOnlyArtifactText(PLANU_MODES_RULES_CONTENT, 'rule');
        await writeFile(rulesPath, PLANU_MODES_RULES_CONTENT, 'utf-8');
        return true;
    }
}
// SPEC-517: Response style rules for token optimization
const RESPONSE_STYLE_RULES_PATH = '.claude/rules/planu-response-style.md';
const RESPONSE_STYLE_RULES_CONTENT = `# Response Style (Planu Optimized)
- Lead with action/result — never restate the question
- No trailing summaries ("I've done X" — user can see the diff)
- Use bullet points over prose paragraphs
- File references: \`path/file.ts:42\` not full paths in text
- Code blocks only for actual code — not for file lists
- When done: one line max. Stop.
`;
/**
 * Write .claude/rules/planu-response-style.md only if it does not exist yet.
 * @returns true if the file was created, false if it already existed.
 */
export async function generateResponseStyleRulesIfMissing(projectPath) {
    const rulesPath = join(projectPath, RESPONSE_STYLE_RULES_PATH);
    try {
        await access(rulesPath);
        return false; // already exists
    }
    catch {
        const rulesDir = join(projectPath, '.claude/rules');
        await mkdir(rulesDir, { recursive: true });
        assertEnglishOnlyArtifactText(RESPONSE_STYLE_RULES_CONTENT, 'rule');
        await writeFile(rulesPath, RESPONSE_STYLE_RULES_CONTENT, 'utf-8');
        return true;
    }
}
//# sourceMappingURL=rules-generator.js.map