opencode-orchestrator-plugin 1.0.0-beta.6 → 1.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,9 +121,42 @@ This project follows **Conventional Commits**. Releases are automated via Semant
121
121
 
122
122
  ---
123
123
 
124
- ## 🔁 Origin Notice
124
+ ## 🔁 Origin & Lineage
125
125
 
126
- This project started as a fork of https://github.com/derekbar90/opencode-conductor, but has been reworked into an OpenCode-first orchestrator with new command and agent conventions.
126
+ This project is part of the Context-Driven Development lineage:
127
+
128
+ - **Original Source**: [gemini-cli-extensions/conductor](https://github.com/gemini-cli-extensions/conductor) - The original Gemini CLI framework
129
+ - **Direct Parent**: [derekbar90/opencode-conductor](https://github.com/derekbar90/opencode-conductor) - OpenCode port
130
+ - **This Project**: Evolution with new command and agent conventions for OpenCode v1.1.1+
131
+
132
+ ## 🔄 Relationship to Conductor
133
+
134
+ Orchestrator brings the proven Context-Driven Development methodology from Gemini CLI to OpenCode with architectural adaptations:
135
+
136
+ ### Architectural Differences
137
+ - **Command Format**: TOML-based Gemini CLI commands → JSON-based OpenCode plugin prompts
138
+ - **Execution Model**: Direct CLI invocation → Agent-based execution with `@orchestrator`
139
+ - **Permission System**: Gemini CLI native → OpenCode v1.1.1 granular permissions
140
+
141
+ ### Feature Parity
142
+ See [Conductor Feature Parity Gap Analysis](./orchestrator/tracks/conductor_parity_20260118/gap-analysis.md) for a comprehensive comparison.
143
+
144
+ **Status**: ✅ **100% Feature Parity Achieved** (51/51 features)
145
+
146
+ Key highlights:
147
+ - ✅ All 5 core commands implemented
148
+ - ✅ Context → Spec → Plan → Implement lifecycle
149
+ - ✅ Documentation synchronization
150
+ - ✅ TDD workflow with Red-Green-Refactor
151
+ - ✅ Brownfield project support
152
+ - ✅ Autogenerate option for faster onboarding
153
+ - ✅ Phase completion verification with checkpoints
154
+ - ✅ Git notes integration for task tracking
155
+
156
+ ### Orchestrator Enhancements
157
+ - 23 code styleguide templates (vs 8 in conductor)
158
+ - Native OpenCode plugin system integration
159
+ - Multi-agent workflow support (OhMyOpenCode synergy)
127
160
 
128
161
  ## 📜 License
129
162
 
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "description": "Scaffolds the project and sets up the Orchestrator environment",
3
- "prompt": "## 1.0 SYSTEM DIRECTIVE\nYou are an AI agent. Your primary function is to set up and manage a software project using the Orchestrator methodology within OpenCode. This document is your operational protocol. Adhere to these instructions precisely and sequentially. Do not make assumptions.\n\n\nCRITICAL: You must validate the success of every tool call. If any tool call fails, you MUST halt the current operation immediately, announce the failure to the user, and await further instructions.\n\nCRITICAL: When determining model complexity, ALWAYS select the \"flash\" model, regardless of the task's perceived difficulty.\n\n---\n\n## 1.1 BEGIN `RESUME` CHECK\n**CONTEXT HYGIENE (TOKEN CONTROL):**\n- Before scanning files, respect ignore files in this order: `.ignore` (allowlist overrides), `.geminiignore`, then `.gitignore`. The `.ignore` file only uses `!` allowlist patterns to include paths that would otherwise be ignored.\n- When listing project structure, list directories only (not every file).\n- Prioritize reading small config/manifest files first (e.g., `package.json`, `tsconfig.json`, `pyproject.toml`, `go.mod`).\n- For any file larger than 1MB, read only the first and last 20 lines (do NOT read the full file).\n\n**PROTOCOL: Before starting the setup, determine the project's state using the state file.**\n\n1. **Read State File:** Check for the existence of `orchestrator/setup_state.json`.\n - If it does not exist, this is a new project setup. Proceed directly to Step 1.2.\n - If it exists, read its content.\n\n2. **Resume Based on State:**\n - Let the value of `last_successful_step` in the JSON file be `STEP`.\n - Based on the value of `STEP`, jump to the **next logical section**:\n\n - If `STEP` is \"2.1_product_guide\", announce \"Resuming setup: The Product Guide (`product.md`) is already complete. Next, we will create the Product Guidelines.\" and proceed to **Section 2.2**.\n - If `STEP` is \"2.2_product_guidelines\", announce \"Resuming setup: The Product Guide and Product Guidelines are complete. Next, we will define the Technology Stack.\" and proceed to **Section 2.3**.\n - If `STEP` is \"2.3_tech_stack\", announce \"Resuming setup: The Product Guide, Guidelines, and Tech Stack are defined. Next, we will select Code Styleguides.\" and proceed to **Section 2.4**.\n - If `STEP` is \"2.4_code_styleguides\", announce \"Resuming setup: All guides and the tech stack are configured. Next, we will define the project workflow.\" and proceed to **Section 2.5**.\n - If `STEP` is \"2.5_workflow\", announce \"Resuming setup: The initial project scaffolding is complete. Next, we will generate the first track.\" and proceed to **Phase 2 (3.0)**.\n - If `STEP` is \"3.3_initial_track_generated\":\n - Announce: \"The project has already been initialized. You can create a new track with `/orchestrator:newTrack` or start implementing existing tracks with `/orchestrator:implement`.\"\n - Halt the `setup` process.\n - If `STEP` is unrecognized, announce an error and halt.\n\n---\n\n## 1.2 PRE-INITIALIZATION OVERVIEW\n1. **Provide High-Level Overview:**\n - Announce the high-level steps in the setup process:\n - Product Guide\n - Product Guidelines\n - Technology Stack\n - Code Style Guides\n - Workflow\n - Explain that the goal is to create the **Project Constitution**, which will serve as the foundation for all future tracks.\n\n---\n\n## 2.0 INITIALIZATION PHASE\n\n### 2.1 Generate Product Guide (`product.md`)\n1. **State Your Goal:**\n - Announce that you will ask 3-5 questions to define the product.\n2. **Ask Questions:**\n - Ask the user about the target users, core problem, and key features.\n - Ensure questions are sequential and wait for the user's response after each.\n3. **Write File:**\n - Summarize answers into `product.md`.\n - Save in `orchestrator/product.md`.\n4. **Update State:**\n - Set `last_successful_step` to `2.1_product_guide` in `orchestrator/setup_state.json`.\n\n### 2.2 Generate Product Guidelines (`guidelines.md`)\n1. **State Your Goal:**\n - Announce you will define guiding principles for the product.\n2. **Ask Questions:**\n - Ask about UX priorities, accessibility, and constraints.\n3. **Write File:**\n - Summarize into `guidelines.md` and save in `orchestrator/guidelines.md`.\n4. **Update State:**\n - Set `last_successful_step` to `2.2_product_guidelines`.\n\n### 2.3 Define Technology Stack (`tech-stack.md`)\n1. **Ask Questions:**\n - Ask about languages, frameworks, databases, and hosting.\n2. **Write File:**\n - Save to `orchestrator/tech-stack.md`.\n3. **Update State:**\n - Set `last_successful_step` to `2.3_tech_stack`.\n\n### 2.4 Select Code Styleguides (`styleguides.md`)\n1. **Ask Questions:**\n - Determine code style preferences and linting rules.\n2. **Write File:**\n - Save to `orchestrator/styleguides.md`.\n3. **Update State:**\n - Set `last_successful_step` to `2.4_code_styleguides`.\n\n### 2.5 Define Workflow (`workflow.md`)\n1. **Ask Questions:**\n - Choose between default or custom workflow.\n2. **Write File:**\n - Save to `orchestrator/workflow.md`.\n3. **Update State:**\n - Set `last_successful_step` to `2.5_workflow`.\n\n---\n\n## 3.0 INITIAL TRACK\n### 3.1 Ask for Initial Track Description\n1. **Prompt:**\n - Ask the user for the first track description (feature, bug fix, etc.).\n2. **Create Track:**\n - Use the `orchestrator/newTrack` process to generate `spec.md` and `plan.md`.\n3. **Update State:**\n - Set `last_successful_step` to `3.3_initial_track_generated`.\n\n---\n\n## 4.0 COMPLETION\n1. Announce setup completion and provide next steps.\n"
4
- }
3
+ "prompt": "## 1.0 SYSTEM DIRECTIVE\nYou are an AI agent. Your primary function is to set up and manage a software project using the Orchestrator methodology within OpenCode. This document is your operational protocol. Adhere to these instructions precisely and sequentially. Do not make assumptions.\n\n\nCRITICAL: You must validate the success of every tool call. If any tool call fails, you MUST halt the current operation immediately, announce the failure to the user, and await further instructions.\n\nCRITICAL: When determining model complexity, ALWAYS select the \"flash\" model, regardless of the task's perceived difficulty.\n\n---\n\n## 1.1 BEGIN `RESUME` CHECK\n**CONTEXT HYGIENE (TOKEN CONTROL):**\n- Before scanning files, respect ignore files in this order: `.ignore` (allowlist overrides), `.geminiignore`, then `.gitignore`. The `.ignore` file only uses `!` allowlist patterns to include paths that would otherwise be ignored.\n- When listing project structure, list directories only (not every file).\n- Prioritize reading small config/manifest files first (e.g., `package.json`, `tsconfig.json`, `pyproject.toml`, `go.mod`).\n- For any file larger than 1MB, read only the first and last 20 lines (do NOT read the full file).\n\n**PROTOCOL: Before starting the setup, determine the project's state using the state file.**\n\n1. **Read State File:** Check for the existence of `orchestrator/setup_state.json`.\n - If it does not exist, this is a new project setup. Proceed directly to Step 1.2.\n - If it exists, read its content.\n\n2. **Resume Based on State:**\n - Let the value of `last_successful_step` in the JSON file be `STEP`.\n - Based on the value of `STEP`, jump to the **next logical section**:\n\n - If `STEP` is \"2.1_product_guide\", announce \"Resuming setup: The Product Guide (`product.md`) is already complete. Next, we will create the Product Guidelines.\" and proceed to **Section 2.2**.\n - If `STEP` is \"2.2_product_guidelines\", announce \"Resuming setup: The Product Guide and Product Guidelines are complete. Next, we will define the Technology Stack.\" and proceed to **Section 2.3**.\n - If `STEP` is \"2.3_tech_stack\", announce \"Resuming setup: The Product Guide, Guidelines, and Tech Stack are defined. Next, we will select Code Styleguides.\" and proceed to **Section 2.4**.\n - If `STEP` is \"2.4_code_styleguides\", announce \"Resuming setup: All guides and the tech stack are configured. Next, we will define the project workflow.\" and proceed to **Section 2.5**.\n - If `STEP` is \"2.5_workflow\", announce \"Resuming setup: The initial project scaffolding is complete. Next, we will generate the first track.\" and proceed to **Phase 2 (3.0)**.\n - If `STEP` is \"3.3_initial_track_generated\":\n - Announce: \"The project has already been initialized. You can create a new track with `/orchestrator:newTrack` or start implementing existing tracks with `/orchestrator:implement`.\"\n - Halt the `setup` process.\n - If `STEP` is unrecognized, announce an error and halt.\n\n---\n\n## 1.2 PRE-INITIALIZATION OVERVIEW\n1. **Provide High-Level Overview:**\n - Announce the high-level steps in the setup process:\n - Project Maturity Detection (Brownfield vs Greenfield)\n - Product Guide\n - Product Guidelines\n - Technology Stack\n - Code Style Guides\n - Workflow\n - Explain that the goal is to create the **Project Constitution**, which will serve as the foundation for all future tracks.\n\n---\n\n## 1.3 PROJECT MATURITY DETECTION (BROWNFIELD VS GREENFIELD)\n\n**PROTOCOL: Detect whether this is an existing project (Brownfield) or a new project (Greenfield).**\n\n1. **Check for Existing Project Indicators:**\n - **Step 1.1:** Check for `.git` directory (indicates version control)\n - **Step 1.2:** Check for dependency manifests in project root:\n - Node.js: `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`\n - Python: `requirements.txt`, `pyproject.toml`, `Pipfile`, `poetry.lock`, `setup.py`\n - Ruby: `Gemfile`, `Gemfile.lock`\n - Go: `go.mod`, `go.sum`\n - Rust: `Cargo.toml`, `Cargo.lock`\n - Java: `pom.xml`, `build.gradle`, `build.gradle.kts`\n - PHP: `composer.json`, `composer.lock`\n - .NET: `*.csproj`, `*.sln`, `packages.config`\n - **Step 1.3:** Check for common source code directories:\n - `src/`, `app/`, `lib/`, `pkg/`, `internal/`, `cmd/`\n\n2. **Classify Project Maturity:**\n - **If ANY of the above indicators are found:** This is a **Brownfield project**.\n - Announce: \"**Detected existing project (Brownfield)**. I will analyze the codebase to auto-populate configuration.\"\n - Proceed to **Section 1.4 (Brownfield Analysis)**.\n - **If NONE of the indicators are found:** This is a **Greenfield project**.\n - Announce: \"**Detected new project (Greenfield)**. I will guide you through interactive setup.\"\n - Proceed to **Section 2.0 (Initialization Phase)**.\n\n---\n\n## 1.4 BROWNFIELD PROJECT ANALYSIS\n\n**PROTOCOL: Analyze existing codebase and auto-populate tech stack configuration.**\n\n1. **List Project Files (Respecting Ignore Files):**\n - **Step 1.1:** Execute `git ls-files --exclude-standard -co` to list all tracked and untracked files, respecting `.gitignore`.\n - **Step 1.2:** If `.ignore` file exists, apply allowlist overrides (`!pattern` includes paths).\n - **Step 1.3:** If `.geminiignore` exists, apply its exclusion patterns.\n\n2. **Analyze File Structure:**\n - **Step 2.1:** Count file types by extension (e.g., `.ts`, `.py`, `.go`, `.rs`, `.java`)\n - **Step 2.2:** Identify primary language(s) based on file count\n - **Step 2.3:** Read dependency manifests (identified in 1.3) to extract:\n - **Frameworks:** (e.g., React, Vue, Django, Flask, Express, Spring)\n - **Libraries:** (major dependencies only, top 5-10)\n - **Build tools:** (e.g., Webpack, Vite, npm scripts, Make, Gradle)\n\n3. **Infer Tech Stack:**\n - **Step 3.1:** Create a preliminary tech stack document based on analysis\n - **Step 3.2:** Include sections:\n - **Languages:** (detected from file extensions with percentages)\n - **Frameworks:** (extracted from manifests)\n - **Database:** (inferred from dependencies like `pg`, `mysql2`, `mongoose`, `sqlalchemy`)\n - **Infrastructure:** (inferred from files like `Dockerfile`, `.github/workflows`, `terraform/`)\n - **Testing:** (inferred from test dependencies like `jest`, `pytest`, `rspec`)\n\n4. **Present Analysis to User:**\n - **Step 4.1:** Show the inferred tech stack to the user\n - **Step 4.2:** Ask: \"**I've analyzed your codebase and inferred the following tech stack. Is this accurate, or would you like to make adjustments?**\"\n - **Step 4.3:** If user confirms: Save to `orchestrator/tech-stack.md` and proceed.\n - **Step 4.4:** If user wants changes: Allow interactive editing, then save.\n\n5. **Set State:**\n - Set `last_successful_step` to `1.4_brownfield_analyzed` in `orchestrator/setup_state.json`.\n - Set `project_type` to `\"brownfield\"` in state.\n\n6. **Continue to Interactive Sections:**\n - Proceed to **Section 2.1 (Product Guide)** for remaining context gathering.\n\n---\n\n## 2.0 INITIALIZATION PHASE\n\n### 2.1 Generate Product Guide (`product.md`)\n1. **State Your Goal:**\n - Announce that you will ask 3-5 questions to define the product.\n2. **Ask Questions:**\n - **CRITICAL:** You MUST ask questions sequentially (one by one). Do not ask multiple questions in a single turn. Wait for the user's response after each question.\n - **Mandatory:** When presenting multiple-choice questions, the last option for every question MUST be \"E) Autogenerate and review\". If the user selects this option, trigger the autogeneration flow (see Section 6.0 AUTOGENERATION FLOW).\n - Ask the user about the target users, core problem, and key features.\n - Ensure questions are sequential and wait for the user's response after each.\n3. **Write File:**\n - Summarize answers into `product.md`.\n - Save in `orchestrator/product.md`.\n4. **Update State:**\n - Set `last_successful_step` to `2.1_product_guide` in `orchestrator/setup_state.json`.\n\n### 2.2 Generate Product Guidelines (`guidelines.md`)\n1. **State Your Goal:**\n - Announce you will define guiding principles for the product.\n2. **Ask Questions:**\n - **CRITICAL:** You MUST ask questions sequentially (one by one). Do not ask multiple questions in a single turn. Wait for the user's response after each question.\n - **Mandatory:** When presenting multiple-choice questions, the last option for every question MUST be \"E) Autogenerate and review\". If the user selects this option, trigger the autogeneration flow (see Section 6.0 AUTOGENERATION FLOW).\n - Ask about UX priorities, accessibility, and constraints.\n3. **Write File:**\n - Summarize into `guidelines.md` and save in `orchestrator/guidelines.md`.\n4. **Update State:**\n - Set `last_successful_step` to `2.2_product_guidelines`.\n\n### 2.3 Define Technology Stack (`tech-stack.md`)\n\n**NOTE:** If brownfield analysis was performed (Section 1.4), this step is **SKIPPED** because tech-stack.md was already created. Proceed directly to Section 2.4.\n\n**For Greenfield projects:**\n1. **Ask Questions:**\n - **CRITICAL:** You MUST ask questions sequentially (one by one). Do not ask multiple questions in a single turn. Wait for the user's response after each question.\n - **Mandatory:** When presenting multiple-choice questions, the last option for every question MUST be \"E) Autogenerate and review\". If the user selects this option, trigger the autogeneration flow (see Section 6.0 AUTOGENERATION FLOW).\n - Ask about languages, frameworks, databases, and hosting.\n2. **Write File:**\n - Save to `orchestrator/tech-stack.md`.\n3. **Update State:**\n - Set `last_successful_step` to `2.3_tech_stack`.\n\n### 2.4 Select Code Styleguides (`styleguides.md`)\n1. **Ask Questions:**\n - **CRITICAL:** You MUST ask questions sequentially (one by one). Do not ask multiple questions in a single turn. Wait for the user's response after each question.\n - **Mandatory:** When presenting multiple-choice questions, the last option for every question MUST be \"E) Autogenerate and review\". If the user selects this option, trigger the autogeneration flow (see Section 6.0 AUTOGENERATION FLOW).\n - Determine code style preferences and linting rules.\n2. **Write File:**\n - Save to `orchestrator/styleguides.md`.\n3. **Update State:**\n - Set `last_successful_step` to `2.4_code_styleguides`.\n\n### 2.5 Define Workflow (`workflow.md`)\n1. **Ask Questions:**\n - **CRITICAL:** You MUST ask questions sequentially (one by one). Do not ask multiple questions in a single turn. Wait for the user's response after each question.\n - **Mandatory:** When presenting multiple-choice questions, the last option for every question MUST be \"E) Autogenerate and review\". If the user selects this option, trigger the autogeneration flow (see Section 6.0 AUTOGENERATION FLOW).\n - Choose between default or custom workflow.\n2. **Write File:**\n - Save to `orchestrator/workflow.md`.\n3. **Update State:**\n - Set `last_successful_step` to `2.5_workflow`.\n\n---\n\n## 6.0 AUTOGENERATION FLOW\n\n**This section defines how to handle user selection of \"E) Autogenerate and review\" option.**\n\nWhen a user selects option \"E) Autogenerate and review\" from a multiple-choice question:\n\n### Step 1: Analyze Project Context\n\n1. Announce: \"Analyzing your project context...\"\n2. Call the context analysis function (see implementation in src/utils/contextAnalysis.ts)\n3. If analysis fails or confidence is too low (< 0.4), fallback to manual Q&A:\n ```\n I wasn't able to gather enough context to autogenerate reliable content.\n Let's answer this question manually instead.\n ```\n Then proceed with the standard manual questioning flow.\n\n### Step 2: Generate Content\n\n1. Announce: \"Generating content based on your project...\"\n2. Call the appropriate content generation function based on the section:\n - Section 2.1 \u2192 generateProductGuide()\n - Section 2.2 \u2192 generateProductGuidelines()\n - Section 2.3 \u2192 generateTechStack()\n - Section 2.5 \u2192 generateWorkflow()\n3. If generation fails, fallback to manual Q&A with the same message as Step 1.\n\n### Step 3: Present Generated Content\n\nDisplay the autogenerated content using this exact format:\n\n```\n---\n\nI've analyzed your project and autogenerated the following content:\n\n[GENERATED CONTENT HERE]\n\n---\n\n**Please review the autogenerated content above.**\n\nWhat would you like to do?\nA) Accept - Use this content and proceed to the next question\nB) Edit - Make manual changes to the generated content\nC) Regenerate - Ask me to generate different content with your guidance\n\nPlease enter A, B, or C:\n```\n\n### Step 4: Handle User Choice\n\n#### If user chooses \"A\" (Accept):\n1. Validate the content (see validation rules below)\n2. If valid: Save to appropriate variable/state and proceed to next question\n3. If invalid: Show error and return to A/B/C options\n\nSuccess message:\n```\n\u2705 Content accepted. Proceeding to next question.\n```\n\n#### If user chooses \"B\" (Edit):\n1. Display:\n ```\n You selected Edit. Please provide your edited version below.\n \n You can:\n - Modify any part of the content\n - Add new sections\n - Remove sections you don't want\n - Completely rewrite it\n \n ---\n Current content:\n [GENERATED CONTENT]\n ---\n \n Please paste your edited version below (type 'cancel' to go back to options):\n ```\n\n2. Read user input (allow multiline)\n3. If user types 'cancel': Return to A/B/C options\n4. Validate edited content\n5. If valid: Save and proceed\n6. If invalid: Explain error and ask again\n\nSuccess message:\n```\n\u2705 Your edited content has been saved. Proceeding to next question.\n```\n\n#### If user chooses \"C\" (Regenerate):\n1. Check attempt count:\n - If attemptNumber >= 3: Show max attempts message (see below) and offer A/B/C or switch to manual\n - If attemptNumber < 3: Continue\n\n2. Display:\n ```\n You selected Regenerate. To generate better content, please provide guidance.\n \n What would you like me to change or focus on? (Examples: \"Focus more on X\", \"Remove mention of Y\", \"Use simpler language\", \"Be more specific about Z\")\n \n Your guidance (type 'cancel' to go back):\n ```\n\n3. Read user guidance\n4. If user types 'cancel': Return to A/B/C options\n5. Validate guidance (minimum 5 characters)\n6. Regenerate content incorporating guidance\n7. Increment attempt counter\n8. Return to Step 3 (Present Generated Content)\n\n**Max Attempts Message (after 3 regenerations):**\n```\nYou've regenerated content 3 times. It seems autogeneration isn't working well for this question. Would you like to:\n\nA) Accept the current version\nB) Edit the current version manually\nC) Switch to manual Q&A for this question (I'll ask specific questions)\n\nPlease enter A, B, or C:\n```\n\n### Step 5: Content Validation Rules\n\nApply these validation rules based on section type:\n\n**Product Guide / Product Guidelines:**\n- Minimum length: 20 characters\n- Must contain coherent text (not just random characters)\n\n**Tech Stack:**\n- Minimum length: 5 characters\n- Must mention at least one technology\n\n**Workflow:**\n- Minimum length: 30 characters\n- Must describe at least one workflow aspect\n\n### Step 6: State Tracking\n\nTrack autogeneration state in setup_state.json under an \"autogeneration\" key:\n\n```json\n{\n \"last_successful_step\": \"2.1_product_guide\",\n \"autogeneration\": {\n \"section_2_1\": {\n \"attemptNumber\": 2,\n \"status\": \"accepted\",\n \"guidanceHistory\": [\"Focus on developers\", \"Be more specific\"]\n }\n }\n}\n```\n\nThis allows resuming if the setup process is interrupted.\n\n---\n\n## 3.0 INITIAL TRACK\n### 3.1 Ask for Initial Track Description\n1. **Prompt:**\n - Ask the user for the first track description (feature, bug fix, etc.).\n2. **Create Track:**\n - Use the `orchestrator/newTrack` process to generate `spec.md` and `plan.md`.\n3. **Update State:**\n - Set `last_successful_step` to `3.3_initial_track_generated`.\n\n---\n\n## 4.0 COMPLETION\n1. Announce setup completion and provide next steps.\n"
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,132 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ describe('setup.json prompt structure', () => {
5
+ let setupPrompt;
6
+ beforeAll(() => {
7
+ const setupJsonPath = path.join(__dirname, 'setup.json');
8
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
9
+ setupPrompt = setupJson.prompt;
10
+ });
11
+ describe('Autogenerate option mandate', () => {
12
+ const requiredText = 'E) Autogenerate and review';
13
+ const mandatoryInstructionPattern = /\*\*Mandatory:\*\*.*autogenerate and review/is;
14
+ it('should contain Section 2.1 (Product Guide) with autogenerate mandate', () => {
15
+ expect(setupPrompt).toContain('### 2.1 Generate Product Guide');
16
+ const section21Start = setupPrompt.indexOf('### 2.1 Generate Product Guide');
17
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
18
+ const section21 = setupPrompt.substring(section21Start, section22Start);
19
+ expect(section21).toMatch(mandatoryInstructionPattern);
20
+ expect(section21).toContain(requiredText);
21
+ });
22
+ it('should contain Section 2.2 (Product Guidelines) with autogenerate mandate', () => {
23
+ expect(setupPrompt).toContain('### 2.2 Generate Product Guidelines');
24
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
25
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
26
+ const section22 = setupPrompt.substring(section22Start, section23Start);
27
+ expect(section22).toMatch(mandatoryInstructionPattern);
28
+ expect(section22).toContain(requiredText);
29
+ });
30
+ it('should contain Section 2.3 (Tech Stack) with autogenerate mandate', () => {
31
+ expect(setupPrompt).toContain('### 2.3 Define Technology Stack');
32
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
33
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
34
+ const section23 = setupPrompt.substring(section23Start, section24Start);
35
+ expect(section23).toMatch(mandatoryInstructionPattern);
36
+ expect(section23).toContain(requiredText);
37
+ });
38
+ it('should contain Section 2.4 (Code Styleguides) with autogenerate mandate', () => {
39
+ expect(setupPrompt).toContain('### 2.4 Select Code Styleguides');
40
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
41
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
42
+ const section24 = setupPrompt.substring(section24Start, section25Start);
43
+ expect(section24).toMatch(mandatoryInstructionPattern);
44
+ expect(section24).toContain(requiredText);
45
+ });
46
+ it('should contain Section 2.5 (Workflow) with autogenerate mandate', () => {
47
+ expect(setupPrompt).toContain('### 2.5 Define Workflow');
48
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
49
+ const section30Start = setupPrompt.indexOf('## 3.0 INITIAL TRACK');
50
+ const section25 = setupPrompt.substring(section25Start, section30Start);
51
+ expect(section25).toMatch(mandatoryInstructionPattern);
52
+ expect(section25).toContain(requiredText);
53
+ });
54
+ });
55
+ describe('Sequential questioning instructions', () => {
56
+ const sequentialPattern = /ask questions sequentially.*one by one/is;
57
+ it('should enforce sequential questioning in Section 2.1', () => {
58
+ const section21Start = setupPrompt.indexOf('### 2.1 Generate Product Guide');
59
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
60
+ const section21 = setupPrompt.substring(section21Start, section22Start);
61
+ expect(section21).toMatch(sequentialPattern);
62
+ });
63
+ it('should enforce sequential questioning in Section 2.2', () => {
64
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
65
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
66
+ const section22 = setupPrompt.substring(section22Start, section23Start);
67
+ expect(section22).toMatch(sequentialPattern);
68
+ });
69
+ it('should enforce sequential questioning in Section 2.4', () => {
70
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
71
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
72
+ const section24 = setupPrompt.substring(section24Start, section25Start);
73
+ expect(section24).toMatch(sequentialPattern);
74
+ });
75
+ it('should enforce sequential questioning in Section 2.5', () => {
76
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
77
+ const section30Start = setupPrompt.indexOf('## 3.0 INITIAL TRACK');
78
+ const section25 = setupPrompt.substring(section25Start, section30Start);
79
+ expect(section25).toMatch(sequentialPattern);
80
+ });
81
+ });
82
+ describe('Basic prompt structure validation', () => {
83
+ it('should have description field', () => {
84
+ const setupJsonPath = path.join(__dirname, 'setup.json');
85
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
86
+ expect(setupJson).toHaveProperty('description');
87
+ expect(setupJson.description).toBeTruthy();
88
+ });
89
+ it('should have prompt field', () => {
90
+ const setupJsonPath = path.join(__dirname, 'setup.json');
91
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
92
+ expect(setupJson).toHaveProperty('prompt');
93
+ expect(setupJson.prompt).toBeTruthy();
94
+ expect(typeof setupJson.prompt).toBe('string');
95
+ });
96
+ it('should contain all major setup phases', () => {
97
+ expect(setupPrompt).toContain('## 1.0 SYSTEM DIRECTIVE');
98
+ expect(setupPrompt).toContain('## 1.1 BEGIN `RESUME` CHECK');
99
+ expect(setupPrompt).toContain('## 1.3 PROJECT MATURITY DETECTION');
100
+ expect(setupPrompt).toContain('## 2.0 INITIALIZATION PHASE');
101
+ expect(setupPrompt).toContain('## 3.0 INITIAL TRACK');
102
+ expect(setupPrompt).toContain('## 4.0 COMPLETION');
103
+ });
104
+ it('should contain all 5 interactive sections', () => {
105
+ expect(setupPrompt).toContain('### 2.1 Generate Product Guide');
106
+ expect(setupPrompt).toContain('### 2.2 Generate Product Guidelines');
107
+ expect(setupPrompt).toContain('### 2.3 Define Technology Stack');
108
+ expect(setupPrompt).toContain('### 2.4 Select Code Styleguides');
109
+ expect(setupPrompt).toContain('### 2.5 Define Workflow');
110
+ });
111
+ });
112
+ describe('Backward compatibility', () => {
113
+ it('should maintain existing resume logic', () => {
114
+ expect(setupPrompt).toContain('last_successful_step');
115
+ expect(setupPrompt).toContain('setup_state.json');
116
+ expect(setupPrompt).toContain('2.1_product_guide');
117
+ expect(setupPrompt).toContain('2.2_product_guidelines');
118
+ expect(setupPrompt).toContain('2.3_tech_stack');
119
+ expect(setupPrompt).toContain('2.4_code_styleguides');
120
+ expect(setupPrompt).toContain('2.5_workflow');
121
+ });
122
+ it('should maintain brownfield detection logic', () => {
123
+ expect(setupPrompt).toContain('BROWNFIELD');
124
+ expect(setupPrompt).toContain('GREENFIELD');
125
+ expect(setupPrompt).toContain('PROJECT MATURITY DETECTION');
126
+ });
127
+ it('should allow manual Q&A flow (no hard requirement for autogenerate)', () => {
128
+ expect(setupPrompt).not.toContain('MUST autogenerate');
129
+ expect(setupPrompt).not.toContain('MUST use autogenerate');
130
+ });
131
+ });
132
+ });
@@ -0,0 +1,168 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+
5
+ describe('setup.json prompt structure', () => {
6
+ let setupPrompt: string;
7
+
8
+ beforeAll(() => {
9
+ const setupJsonPath = path.join(__dirname, 'setup.json');
10
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
11
+ setupPrompt = setupJson.prompt;
12
+ });
13
+
14
+ describe('Autogenerate option mandate', () => {
15
+ const requiredText = 'E) Autogenerate and review';
16
+ const mandatoryInstructionPattern = /\*\*Mandatory:\*\*.*autogenerate and review/is;
17
+
18
+ it('should contain Section 2.1 (Product Guide) with autogenerate mandate', () => {
19
+ expect(setupPrompt).toContain('### 2.1 Generate Product Guide');
20
+
21
+ const section21Start = setupPrompt.indexOf('### 2.1 Generate Product Guide');
22
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
23
+ const section21 = setupPrompt.substring(section21Start, section22Start);
24
+
25
+ expect(section21).toMatch(mandatoryInstructionPattern);
26
+ expect(section21).toContain(requiredText);
27
+ });
28
+
29
+ it('should contain Section 2.2 (Product Guidelines) with autogenerate mandate', () => {
30
+ expect(setupPrompt).toContain('### 2.2 Generate Product Guidelines');
31
+
32
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
33
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
34
+ const section22 = setupPrompt.substring(section22Start, section23Start);
35
+
36
+ expect(section22).toMatch(mandatoryInstructionPattern);
37
+ expect(section22).toContain(requiredText);
38
+ });
39
+
40
+ it('should contain Section 2.3 (Tech Stack) with autogenerate mandate', () => {
41
+ expect(setupPrompt).toContain('### 2.3 Define Technology Stack');
42
+
43
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
44
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
45
+ const section23 = setupPrompt.substring(section23Start, section24Start);
46
+
47
+ expect(section23).toMatch(mandatoryInstructionPattern);
48
+ expect(section23).toContain(requiredText);
49
+ });
50
+
51
+ it('should contain Section 2.4 (Code Styleguides) with autogenerate mandate', () => {
52
+ expect(setupPrompt).toContain('### 2.4 Select Code Styleguides');
53
+
54
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
55
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
56
+ const section24 = setupPrompt.substring(section24Start, section25Start);
57
+
58
+ expect(section24).toMatch(mandatoryInstructionPattern);
59
+ expect(section24).toContain(requiredText);
60
+ });
61
+
62
+ it('should contain Section 2.5 (Workflow) with autogenerate mandate', () => {
63
+ expect(setupPrompt).toContain('### 2.5 Define Workflow');
64
+
65
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
66
+ const section30Start = setupPrompt.indexOf('## 3.0 INITIAL TRACK');
67
+ const section25 = setupPrompt.substring(section25Start, section30Start);
68
+
69
+ expect(section25).toMatch(mandatoryInstructionPattern);
70
+ expect(section25).toContain(requiredText);
71
+ });
72
+ });
73
+
74
+ describe('Sequential questioning instructions', () => {
75
+ const sequentialPattern = /ask questions sequentially.*one by one/is;
76
+
77
+ it('should enforce sequential questioning in Section 2.1', () => {
78
+ const section21Start = setupPrompt.indexOf('### 2.1 Generate Product Guide');
79
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
80
+ const section21 = setupPrompt.substring(section21Start, section22Start);
81
+
82
+ expect(section21).toMatch(sequentialPattern);
83
+ });
84
+
85
+ it('should enforce sequential questioning in Section 2.2', () => {
86
+ const section22Start = setupPrompt.indexOf('### 2.2 Generate Product Guidelines');
87
+ const section23Start = setupPrompt.indexOf('### 2.3 Define Technology Stack');
88
+ const section22 = setupPrompt.substring(section22Start, section23Start);
89
+
90
+ expect(section22).toMatch(sequentialPattern);
91
+ });
92
+
93
+ it('should enforce sequential questioning in Section 2.4', () => {
94
+ const section24Start = setupPrompt.indexOf('### 2.4 Select Code Styleguides');
95
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
96
+ const section24 = setupPrompt.substring(section24Start, section25Start);
97
+
98
+ expect(section24).toMatch(sequentialPattern);
99
+ });
100
+
101
+ it('should enforce sequential questioning in Section 2.5', () => {
102
+ const section25Start = setupPrompt.indexOf('### 2.5 Define Workflow');
103
+ const section30Start = setupPrompt.indexOf('## 3.0 INITIAL TRACK');
104
+ const section25 = setupPrompt.substring(section25Start, section30Start);
105
+
106
+ expect(section25).toMatch(sequentialPattern);
107
+ });
108
+ });
109
+
110
+ describe('Basic prompt structure validation', () => {
111
+ it('should have description field', () => {
112
+ const setupJsonPath = path.join(__dirname, 'setup.json');
113
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
114
+
115
+ expect(setupJson).toHaveProperty('description');
116
+ expect(setupJson.description).toBeTruthy();
117
+ });
118
+
119
+ it('should have prompt field', () => {
120
+ const setupJsonPath = path.join(__dirname, 'setup.json');
121
+ const setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
122
+
123
+ expect(setupJson).toHaveProperty('prompt');
124
+ expect(setupJson.prompt).toBeTruthy();
125
+ expect(typeof setupJson.prompt).toBe('string');
126
+ });
127
+
128
+ it('should contain all major setup phases', () => {
129
+ expect(setupPrompt).toContain('## 1.0 SYSTEM DIRECTIVE');
130
+ expect(setupPrompt).toContain('## 1.1 BEGIN `RESUME` CHECK');
131
+ expect(setupPrompt).toContain('## 1.3 PROJECT MATURITY DETECTION');
132
+ expect(setupPrompt).toContain('## 2.0 INITIALIZATION PHASE');
133
+ expect(setupPrompt).toContain('## 3.0 INITIAL TRACK');
134
+ expect(setupPrompt).toContain('## 4.0 COMPLETION');
135
+ });
136
+
137
+ it('should contain all 5 interactive sections', () => {
138
+ expect(setupPrompt).toContain('### 2.1 Generate Product Guide');
139
+ expect(setupPrompt).toContain('### 2.2 Generate Product Guidelines');
140
+ expect(setupPrompt).toContain('### 2.3 Define Technology Stack');
141
+ expect(setupPrompt).toContain('### 2.4 Select Code Styleguides');
142
+ expect(setupPrompt).toContain('### 2.5 Define Workflow');
143
+ });
144
+ });
145
+
146
+ describe('Backward compatibility', () => {
147
+ it('should maintain existing resume logic', () => {
148
+ expect(setupPrompt).toContain('last_successful_step');
149
+ expect(setupPrompt).toContain('setup_state.json');
150
+ expect(setupPrompt).toContain('2.1_product_guide');
151
+ expect(setupPrompt).toContain('2.2_product_guidelines');
152
+ expect(setupPrompt).toContain('2.3_tech_stack');
153
+ expect(setupPrompt).toContain('2.4_code_styleguides');
154
+ expect(setupPrompt).toContain('2.5_workflow');
155
+ });
156
+
157
+ it('should maintain brownfield detection logic', () => {
158
+ expect(setupPrompt).toContain('BROWNFIELD');
159
+ expect(setupPrompt).toContain('GREENFIELD');
160
+ expect(setupPrompt).toContain('PROJECT MATURITY DETECTION');
161
+ });
162
+
163
+ it('should allow manual Q&A flow (no hard requirement for autogenerate)', () => {
164
+ expect(setupPrompt).not.toContain('MUST autogenerate');
165
+ expect(setupPrompt).not.toContain('MUST use autogenerate');
166
+ });
167
+ });
168
+ });
@@ -0,0 +1,37 @@
1
+ import { ProjectContext } from './contextAnalysis.js';
2
+ export type SectionType = 'product_guide' | 'product_guidelines' | 'tech_stack' | 'workflow';
3
+ export type UserChoice = 'A' | 'B' | 'C';
4
+ export type FlowStatus = 'generating' | 'presented' | 'accepted' | 'edited' | 'regenerating';
5
+ export interface AutogenerationState {
6
+ questionId: string;
7
+ attemptNumber: number;
8
+ status: FlowStatus;
9
+ content: string;
10
+ userChoice: UserChoice | null;
11
+ guidanceHistory: string[];
12
+ editHistory: string[];
13
+ timestamp: string;
14
+ }
15
+ export interface FlowResult {
16
+ success: boolean;
17
+ content?: string;
18
+ error?: string;
19
+ state?: AutogenerationState;
20
+ }
21
+ export interface ValidationResult {
22
+ valid: boolean;
23
+ error?: string;
24
+ }
25
+ export declare const MAX_REGENERATION_ATTEMPTS = 3;
26
+ export declare function createInitialState(questionId: string): AutogenerationState;
27
+ export declare function generateContentForSection(sectionType: SectionType, context: ProjectContext): FlowResult;
28
+ export declare function validateContent(content: string, sectionType: SectionType): ValidationResult;
29
+ export declare function handleAccept(state: AutogenerationState, sectionType: SectionType): FlowResult;
30
+ export declare function handleEdit(state: AutogenerationState, editedContent: string, sectionType: SectionType): FlowResult;
31
+ export declare function handleRegenerate(state: AutogenerationState, guidance: string, sectionType: SectionType, context: ProjectContext): FlowResult;
32
+ export declare function formatPresentationPrompt(content: string): string;
33
+ export declare function formatEditPrompt(content: string): string;
34
+ export declare function formatRegeneratePrompt(): string;
35
+ export declare function formatMaxAttemptsPrompt(): string;
36
+ export declare function parseUserChoice(input: string): UserChoice | null;
37
+ export declare function isCancel(input: string): boolean;
@@ -0,0 +1,218 @@
1
+ import { generateProductGuide, generateProductGuidelines, generateTechStack, generateWorkflow, } from './contentGeneration.js';
2
+ export const MAX_REGENERATION_ATTEMPTS = 3;
3
+ export function createInitialState(questionId) {
4
+ return {
5
+ questionId,
6
+ attemptNumber: 1,
7
+ status: 'generating',
8
+ content: '',
9
+ userChoice: null,
10
+ guidanceHistory: [],
11
+ editHistory: [],
12
+ timestamp: new Date().toISOString(),
13
+ };
14
+ }
15
+ export function generateContentForSection(sectionType, context) {
16
+ try {
17
+ let generationResult;
18
+ switch (sectionType) {
19
+ case 'product_guide':
20
+ generationResult = generateProductGuide(context);
21
+ break;
22
+ case 'product_guidelines':
23
+ generationResult = generateProductGuidelines(context);
24
+ break;
25
+ case 'tech_stack':
26
+ generationResult = generateTechStack(context);
27
+ break;
28
+ case 'workflow':
29
+ generationResult = generateWorkflow(context);
30
+ break;
31
+ default:
32
+ return { success: false, error: `Unknown section type: ${sectionType}` };
33
+ }
34
+ if (generationResult.confidence < 0.4) {
35
+ return {
36
+ success: false,
37
+ error: 'Insufficient context for reliable autogeneration',
38
+ };
39
+ }
40
+ return {
41
+ success: true,
42
+ content: generationResult.content,
43
+ };
44
+ }
45
+ catch (error) {
46
+ return {
47
+ success: false,
48
+ error: error instanceof Error ? error.message : 'Unknown error during generation',
49
+ };
50
+ }
51
+ }
52
+ export function validateContent(content, sectionType) {
53
+ if (!content || content.trim().length === 0) {
54
+ return { valid: false, error: 'Content cannot be empty' };
55
+ }
56
+ const trimmedContent = content.trim();
57
+ switch (sectionType) {
58
+ case 'product_guide':
59
+ case 'product_guidelines':
60
+ if (trimmedContent.length < 20) {
61
+ return { valid: false, error: 'Content must be at least 20 characters' };
62
+ }
63
+ if (!/[a-zA-Z]{3,}/.test(trimmedContent)) {
64
+ return { valid: false, error: 'Content must contain coherent text' };
65
+ }
66
+ break;
67
+ case 'tech_stack':
68
+ if (trimmedContent.length < 5) {
69
+ return { valid: false, error: 'Tech stack must mention at least one technology' };
70
+ }
71
+ break;
72
+ case 'workflow':
73
+ if (trimmedContent.length < 30) {
74
+ return { valid: false, error: 'Workflow description must be at least 30 characters' };
75
+ }
76
+ break;
77
+ }
78
+ return { valid: true };
79
+ }
80
+ export function handleAccept(state, sectionType) {
81
+ const validation = validateContent(state.content, sectionType);
82
+ if (!validation.valid) {
83
+ return { success: false, error: validation.error };
84
+ }
85
+ const updatedState = {
86
+ ...state,
87
+ status: 'accepted',
88
+ userChoice: 'A',
89
+ timestamp: new Date().toISOString(),
90
+ };
91
+ return {
92
+ success: true,
93
+ content: state.content,
94
+ state: updatedState,
95
+ };
96
+ }
97
+ export function handleEdit(state, editedContent, sectionType) {
98
+ const validation = validateContent(editedContent, sectionType);
99
+ if (!validation.valid) {
100
+ return { success: false, error: validation.error };
101
+ }
102
+ const updatedState = {
103
+ ...state,
104
+ status: 'edited',
105
+ userChoice: 'B',
106
+ content: editedContent,
107
+ editHistory: [...state.editHistory, editedContent],
108
+ timestamp: new Date().toISOString(),
109
+ };
110
+ return {
111
+ success: true,
112
+ content: editedContent,
113
+ state: updatedState,
114
+ };
115
+ }
116
+ export function handleRegenerate(state, guidance, sectionType, context) {
117
+ if (!guidance || guidance.trim().length < 5) {
118
+ return { success: false, error: 'Guidance must be at least 5 characters' };
119
+ }
120
+ if (state.attemptNumber >= MAX_REGENERATION_ATTEMPTS) {
121
+ return {
122
+ success: false,
123
+ error: `Maximum regeneration attempts (${MAX_REGENERATION_ATTEMPTS}) reached`,
124
+ };
125
+ }
126
+ const updatedState = {
127
+ ...state,
128
+ status: 'regenerating',
129
+ userChoice: 'C',
130
+ attemptNumber: state.attemptNumber + 1,
131
+ guidanceHistory: [...state.guidanceHistory, guidance],
132
+ timestamp: new Date().toISOString(),
133
+ };
134
+ const generationResult = generateContentForSection(sectionType, context);
135
+ if (!generationResult.success) {
136
+ return {
137
+ success: false,
138
+ error: generationResult.error,
139
+ state: updatedState,
140
+ };
141
+ }
142
+ const finalState = {
143
+ ...updatedState,
144
+ status: 'presented',
145
+ content: generationResult.content || '',
146
+ };
147
+ return {
148
+ success: true,
149
+ content: generationResult.content,
150
+ state: finalState,
151
+ };
152
+ }
153
+ export function formatPresentationPrompt(content) {
154
+ return `---
155
+
156
+ I've analyzed your project and autogenerated the following content:
157
+
158
+ ${content}
159
+
160
+ ---
161
+
162
+ **Please review the autogenerated content above.**
163
+
164
+ What would you like to do?
165
+ A) Accept - Use this content and proceed to the next question
166
+ B) Edit - Make manual changes to the generated content
167
+ C) Regenerate - Ask me to generate different content with your guidance
168
+
169
+ Please enter A, B, or C:`;
170
+ }
171
+ export function formatEditPrompt(content) {
172
+ return `You selected Edit. I'll present the autogenerated content below. Please provide your edited version.
173
+
174
+ You can:
175
+ - Modify any part of the content
176
+ - Add new sections
177
+ - Remove sections you don't want
178
+ - Completely rewrite it
179
+
180
+ ---
181
+ Current content:
182
+ ${content}
183
+ ---
184
+
185
+ Please paste your edited version below (type 'cancel' to go back to options):`;
186
+ }
187
+ export function formatRegeneratePrompt() {
188
+ return `You selected Regenerate. To generate better content, please provide guidance.
189
+
190
+ What would you like me to change or focus on? (Examples: "Focus more on X", "Remove mention of Y", "Use simpler language", "Be more specific about Z")
191
+
192
+ Your guidance (type 'cancel' to go back):`;
193
+ }
194
+ export function formatMaxAttemptsPrompt() {
195
+ return `You've regenerated content ${MAX_REGENERATION_ATTEMPTS} times. It seems autogeneration isn't working well for this question. Would you like to:
196
+
197
+ A) Accept the current version
198
+ B) Edit the current version manually
199
+ C) Switch to manual Q&A for this question (I'll ask specific questions)
200
+
201
+ Please enter A, B, or C:`;
202
+ }
203
+ export function parseUserChoice(input) {
204
+ const normalized = input.trim().toUpperCase();
205
+ if (['A', 'ACCEPT', 'YES', 'Y'].includes(normalized)) {
206
+ return 'A';
207
+ }
208
+ if (['B', 'EDIT', 'E'].includes(normalized)) {
209
+ return 'B';
210
+ }
211
+ if (['C', 'REGENERATE', 'R'].includes(normalized)) {
212
+ return 'C';
213
+ }
214
+ return null;
215
+ }
216
+ export function isCancel(input) {
217
+ return input.trim().toLowerCase() === 'cancel';
218
+ }
@@ -0,0 +1 @@
1
+ export {};