diff --git a/.changeset/serious-turtles-live.md b/.changeset/serious-turtles-live.md new file mode 100644 index 00000000..fae9b5cd --- /dev/null +++ b/.changeset/serious-turtles-live.md @@ -0,0 +1,5 @@ +--- +"hai-build-code-generator": minor +--- + +Merged changes from Cline 3.20.3 (see [changelog](https://github.com/cline/cline/blob/main/CHANGELOG.md#3203)). diff --git a/.eslintrc.json b/.eslintrc.json index 7e0c3bcd..cf366abd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,7 +5,7 @@ "ecmaVersion": 6, "sourceType": "module" }, - "plugins": ["@typescript-eslint"], + "plugins": ["@typescript-eslint", "eslint-rules"], "rules": { "@typescript-eslint/naming-convention": [ "warn", @@ -19,7 +19,15 @@ "eqeqeq": "warn", "no-throw-literal": "warn", "semi": "off", - "react-hooks/exhaustive-deps": "off" + "react-hooks/exhaustive-deps": "off", + "eslint-rules/no-direct-vscode-api": "warn", + "no-restricted-syntax": [ + "error", + { + "selector": "VariableDeclarator[id.type=\"ObjectPattern\"][init.object.name=\"process\"][init.property.name=\"env\"]", + "message": "Use process.env.VARIABLE_NAME directly instead of destructuring" + } + ] }, "ignorePatterns": ["out", "dist", "**/*.d.ts"] } diff --git a/.gitattributes b/.gitattributes index 6313b56c..9f1ff5fc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,4 @@ +demo.gif filter=lfs diff=lfs merge=lfs -text +assets/docs/demo.gif filter=lfs diff=lfs merge=lfs -text + * text=auto eol=lf diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ef3ea0c4..539ee9d4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -5,7 +5,7 @@ body: - type: markdown attributes: value: | - **Important:** All bug reports must be reproducible using Claude 3.5 Sonnet. Cline uses complex prompts so less capable models may not work as expected. + **Important:** All bug reports must be reproducible using Claude 4 Sonnet. HAI uses complex prompts so less capable models may not work as expected. - type: textarea id: what-happened attributes: @@ -24,7 +24,7 @@ body: 2. 3. validations: - required: true + required: false - type: textarea id: logs attributes: @@ -36,23 +36,22 @@ body: attributes: label: Provider/Model description: What provider and model were you using when the issue occurred? - placeholder: "e.g., cline:anthropic/claude-3.7-sonnet, gemini:gemini-2.5-pro-exp-03-25" - validations: - required: true - - type: input - id: operating-system - attributes: - label: Operating System - description: What operating system are you using? - placeholder: "e.g., Windows 11, macOS Sonoma, Ubuntu 22.04" + placeholder: "e.g., anthropic/claude-3.7-sonnet, gemini:gemini-2.5-pro-exp-03-25" validations: required: true - type: textarea id: system-info attributes: - label: System Info - description: What system information is relevant to the issue? - placeholder: "e.g., CPU: Intel Core i7-11700K, GPU: NVIDIA GeForce RTX 3070, RAM: 32GB DDR4" + label: System Information + description: What operating system and hardware are you using? + placeholder: | + Operating System: Windows 11, macOS Sonoma, Ubuntu 22.04, etc. + Hardware: CPU, GPU, RAM specifications if relevant + e.g., + OS: Windows 11 + CPU: Intel Core i7-11700K + GPU: NVIDIA GeForce RTX 3070 + RAM: 32GB DDR4 validations: required: true - type: input @@ -63,8 +62,3 @@ body: placeholder: "e.g., 1.2.3" validations: required: true - - type: textarea - id: additional-context - attributes: - label: Additional context - description: Add any other context about the problem here, such as screenshots or related issues. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2b3bac08..425c0548 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -29,4 +29,4 @@ ### Additional Notes - + \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..3bdd573a --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,25 @@ +# This workflow will only label and/or close 30 issues at a time in order to avoid exceeding a rate limit. +# More info: https://docs.github.com/en/actions/use-cases-and-examples/project-management/closing-inactive-issues +name: Close inactive issues +on: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + days-before-issue-stale: 60 + days-before-issue-close: 14 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + exempt-issue-labels: "pinned,security" + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-stale.yml b/.github/workflows/test-stale.yml new file mode 100644 index 00000000..be573785 --- /dev/null +++ b/.github/workflows/test-stale.yml @@ -0,0 +1,32 @@ +name: Test Stale Issues Workflow +on: + workflow_dispatch: + inputs: + days-before-stale: + description: "Days before an issue becomes stale" + required: true + default: "1" + days-before-close: + description: "Days before a stale issue is closed" + required: true + default: "1" + +jobs: + test-stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@28ca103 + with: + days-before-issue-stale: ${{ github.event.inputs.days-before-stale }} + days-before-issue-close: ${{ github.event.inputs.days-before-close }} + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for ${{ github.event.inputs.days-before-stale }} days with no activity." + close-issue-message: "This issue was closed because it has been inactive for ${{ github.event.inputs.days-before-close }} days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + exempt-issue-labels: "pinned,security" + repo-token: ${{ secrets.GITHUB_TOKEN }} + debug-only: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index df170e9c..c4f0af45 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -68,6 +68,16 @@ jobs: if: steps.webview-cache.outputs.cache-hit != 'true' run: cd webview-ui && npm ci + - name: Install xvfb on Linux + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y xvfb + + - name: Install local modules on windows + if: runner.os == 'Windows' && steps.root-cache.outputs.cache-hit == 'true' + run: | + npm install eslint-plugin-eslint-rules + cd webview-ui/ && npm install eslint-plugin-eslint-rules + - name: Set up NPM on Windows if: runner.os == 'Windows' run: | @@ -86,8 +96,9 @@ jobs: - name: Build Tests and Extension run: npm run pretest - - name: Unit Tests - run: npm run test:unit + # Unit Tests disabled due to module system conflicts between backend and webview-ui + # - name: Unit Tests + # run: npm run test:unit # Run extension tests with coverage - name: Extension Tests with Coverage diff --git a/.gitignore b/.gitignore index 244881aa..2db0518c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,17 +7,17 @@ tmp *.vsix .DS_Store +.idea pnpm-lock.yaml -.hai/ -.haiignore .clineignore - -.env .venv .actrc +webview-ui/src/**/*.js +webview-ui/src/**/*.js.map + # Ignore coverage directories and files coverage # But don't ignore the coverage scripts in .github/scripts/ @@ -25,11 +25,15 @@ coverage *evals.env -# Generated proto files -src/shared/proto/*.ts -src/core/controller/*/methods.ts -src/core/controller/*/index.ts -src/core/controller/grpc-service-config.ts +## Generated files ## +src/generated/ +src/shared/proto/ webview-ui/src/services/grpc-client.ts -src/standalone/server-setup.ts + +# E2E Tests +test-results + +# TAG:HAI +.hai/ .hai.config +.haiignore diff --git a/.hairules/hai-overview.md b/.hairules/hai-overview.md index 809a753e..cf50bb61 100644 --- a/.hairules/hai-overview.md +++ b/.hairules/hai-overview.md @@ -164,6 +164,7 @@ Key providers include: - **OpenRouter**: Meta-provider supporting multiple model providers - **AWS Bedrock**: Integration with Amazon's AI services - **Gemini**: Google's AI models +- **Cerebras**: High-performance inference with Llama, Qwen, and DeepSeek models - **Ollama**: Local model hosting - **LM Studio**: Local model hosting - **VSCode LM**: VSCode's built-in language models @@ -220,7 +221,7 @@ class Task { await pWaitFor(() => this.userMessageContentReady) // 4. Continue loop with tool result - const recDidEndLoop = await this.recursivelyMakeHAIRequests( + const recDidEndLoop = await this.recursivelyMakeClineRequests( this.userMessageContent ) } @@ -430,7 +431,7 @@ The Task class provides robust task state management and resumption capabilities class Task { async resumeTaskFromHistory() { // 1. Load saved state - this.clineMessages = await getSavedHAIMessages(this.getContext(), this.taskId) + this.clineMessages = await getSavedClineMessages(this.getContext(), this.taskId) this.apiConversationHistory = await getSavedApiConversationHistory(this.getContext(), this.taskId) // 2. Handle interrupted tool executions @@ -462,7 +463,7 @@ class Task { private async saveTaskState() { // Save conversation history await saveApiConversationHistory(this.getContext(), this.taskId, this.apiConversationHistory) - await saveHAIMessages(this.getContext(), this.taskId, this.clineMessages) + await saveClineMessages(this.getContext(), this.taskId, this.clineMessages) // Create checkpoint const commitHash = await this.checkpointTracker?.commit() @@ -715,7 +716,7 @@ The Controller class manages MCP servers through the McpHub service: class Controller { mcpHub?: McpHub - constructor(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel, webviewProvider: WebviewProvider) { + constructor(context: vscode.ExtensionContext, webviewProvider: WebviewProvider) { this.mcpHub = new McpHub(this) } @@ -734,7 +735,7 @@ class Controller { const task = `Set up the MCP server from ${mcpDetails.githubUrl}...` // Initialize task and show chat view - await this.initHAIWithTask(task) + await this.initClineWithTask(task) } } ``` diff --git a/.hairules/protobuf-development.md b/.hairules/protobuf-development.md new file mode 100644 index 00000000..c8c13aaa --- /dev/null +++ b/.hairules/protobuf-development.md @@ -0,0 +1,89 @@ +# HAI Protobuf Development Guide + +This guide outlines how to add new gRPC endpoints for communication between the webview (frontend) and the extension host (backend). + +## Overview + +HAI uses [Protobuf](https://protobuf.dev/) to define a strongly-typed API, ensuring efficient and type-safe communication. All definitions are in the `/proto` directory. The compiler and plugins are included as project dependencies, so no manual installation is needed. + +## Key Concepts & Best Practices + +- **File Structure**: Each feature domain should have its own `.proto` file (e.g., `account.proto`, `task.proto`). +- **Message Design**: + - For simple, single-value data, use the shared types in `proto/common.proto` (e.g., `StringRequest`, `Empty`, `Int64Request`). This promotes consistency. + - For complex data structures, define custom messages within the feature's `.proto` file (see `task.proto` for examples like `NewTaskRequest`). +- **Naming Conventions**: + - Services: `PascalCaseService` (e.g., `AccountService`). + - RPCs: `camelCase` (e.g., `accountEmailIdentified`). + - Messages: `PascalCase` (e.g., `StringRequest`). +- **Streaming**: For server-to-client streaming, use the `stream` keyword on the response type. See `subscribeToAuthCallback` in `account.proto` for an example. + +--- + +## 4-Step Development Workflow + +Here’s how to add a new RPC, using `scrollToSettings` as an example. + +### 1. Define the RPC in a `.proto` File + +Add your service method to the appropriate file in the `proto/` directory. + +**File: `proto/ui.proto`** +```proto +service UiService { + // ... other RPCs + // Scrolls to a specific settings section in the settings view + rpc scrollToSettings(StringRequest) returns (KeyValuePair); +} +``` +Here, we use the common `StringRequest` and `KeyValuePair` types. + +### 2. Compile Definitions + +After editing a `.proto` file, regenerate the TypeScript code. From the project root, run: +```bash +npm run protos +``` +This command compiles all `.proto` files and outputs the generated code to `src/generated/` and `src/shared/`. Do not edit these generated files manually. + +### 3. Implement the Backend Handler + +Create the RPC implementation in the backend. Handlers are located in `src/core/controller/[service-name]/`. + +**File: `src/core/controller/ui/scrollToSettings.ts`** +```typescript +import { Controller } from ".." +import { StringRequest, KeyValuePair } from "../../../shared/proto/common" + +/** + * Executes a scroll to settings action + * @param controller The controller instance + * @param request The request containing the ID of the settings section to scroll to + * @returns KeyValuePair with action and value fields for the UI to process + */ +export async function scrollToSettings(controller: Controller, request: StringRequest): Promise { + return KeyValuePair.create({ + key: "scrollToSettings", + value: request.value || "", + }) +} +``` + +### 4. Call the RPC from the Webview + +Call the new RPC from a React component in `webview-ui/`. The generated client makes this simple. + +**File: `webview-ui/src/components/browser/BrowserSettingsMenu.tsx`** (Example) +```tsx +import { UiServiceClient } from "../../../services/grpc" +import { StringRequest } from "../../../../shared/proto/common" + +// ... inside a React component +const handleMenuClick = async () => { + try { + await UiServiceClient.scrollToSettings(StringRequest.create({ value: "browser" })) + } catch (error) { + console.error("Error scrolling to browser settings:", error) + } +} +``` diff --git a/.hairules/workflows/git-branch-analysis.md b/.hairules/workflows/git-branch-analysis.md new file mode 100644 index 00000000..006ac362 --- /dev/null +++ b/.hairules/workflows/git-branch-analysis.md @@ -0,0 +1,75 @@ +# Git Diff Analysis Workflow + +## Objective +Analyze the current branch's changes against main to provide informed insights and context for development decisions. + +## Step 1: Gather Git Information +Do not return any text or conversation other than what is necessary to run these commands + +**First, check the expected output size:** + ```shell + (git branch --show-current && echo "=== STATUS ===" && git status --porcelain | cat && echo "=== COMMIT MESSAGES ===" && git log main..HEAD --oneline | cat && echo "=== CHANGED FILES ===" && git diff main --name-only | cat && echo "=== FULL DIFF ===" && git diff main | cat) | wc -l + ``` + +**If the expected line count is greater than 500 lines, use the file-based approach:** + ```shell + git branch --show-current > hai-git-analysis.temp && echo "=== STATUS ===" >> hai-git-analysis.temp && git status --porcelain >> hai-git-analysis.temp && echo "=== COMMIT MESSAGES ===" >> hai-git-analysis.temp && git log main..HEAD --oneline >> hai-git-analysis.temp && echo "=== CHANGED FILES ===" >> hai-git-analysis.temp && git diff main --name-only >> hai-git-analysis.temp && echo "=== FULL DIFF ===" >> hai-git-analysis.temp && git diff main >> hai-git-analysis.temp + ``` + + Then, read the file using the read_file tool. After you have read the file but before you proceed with subsequent steps, delete it: + ```shell + rm hai-git-analysis.temp + ``` + +**If the expected line count is 500 lines or fewer, use the direct approach:** + ```shell + git branch --show-current && echo "=== STATUS ===" && git status --porcelain | cat && echo "=== COMMIT MESSAGES ===" && git log main..HEAD --oneline | cat && echo "=== CHANGED FILES ===" && git diff main --name-only | cat && echo "=== FULL DIFF ===" && git diff main | cat + ``` + +If using the direct approach, pipe outputs through `cat` to avoid interactive terminals. If the user's shell is not bash/zsh, adjust the command and chaining + syntax accordingly. + +## Step 2: Silent, Structured Analysis Phase +- Analyze all git output without providing commentary or narration +- Read the full diff to understand the scope and nature of changes +- Identify patterns, architectural modifications, or potential impacts +- Use `read_file` to examine any related files providing additional context on the changes you have observed + +## Step 3: Context Gathering +- Analyze related code without providing commentary or narration +- Read relevant related source files if needed for complete understanding +- Check dependencies, imports, or cross-references spanning the changes +- Understand the broader codebase context around modifications +- This additional context gathering should include related backend code, as well as related ui/frontend code +- You will typically need to analyze at least several files, potentially many, in order to fully complete this step +- You should not continue reading additional context if you have exhausted more than 60% of your available context window +- If you have exhausted less than 40% of your context window, you should continue reviewing additional context + +## Step 4: Ready for User Interaction +**Only after completing the full analysis:** +- Engage with the user based on comprehensive understanding +- Provide insights about specific modifications and their impacts +- If you are certain they exist, note potential breaking changes or compatibility issues +- Answer questions with informed context from the complete change set and context gathering +- If the user has not provided a question, or the question is insufficient to provide a quality response, ask brief (one sentence) clarifying questions. +- Only offer recommendations if they are applicable to the user's request and relevant to the changes that you have observed + +## Key Rules +- **No prose or conversation during git research phase** +- **No prose or conversation during context gathering phase** +- **Complete all analysis before any user interaction** +- **Use gathered information for all subsequent questions and insights** +- **Focus on understanding the complete picture before discussing** + +## Optional: Additional Analysis Commands +For deeper investigation when needed: + +```shell +# Detailed commit history with author info +git log main..HEAD --format="%h %s (%an)" | cat + +# Change statistics +git diff main --stat | cat + +# Specific file type changes +git diff main --name-only | grep -E '\.(ts|js|tsx|jsx|py|md)$' | cat diff --git a/.hairules/workflows/pr-review.md b/.hairules/workflows/pr-review.md index 4dd63bbd..4bcb29e7 100644 --- a/.hairules/workflows/pr-review.md +++ b/.hairules/workflows/pr-review.md @@ -1,4 +1,4 @@ -You have access to the `gh` terminal command. I already authenticated it for you. Please review it to use the PR that I asked you to review. You're already in the `cline-based-code-generator` repo. +You have access to the `gh` terminal command. I already authenticated it for you. Please review it to use the PR that I asked you to review. You're already in the `hai` repo. # GitHub PR Review Process - Detailed Sequence of Steps @@ -328,7 +328,7 @@ Hey, the PR looks good overall but I'm concerned about removing those timeouts. Could you add back the timeouts after focusing the sidebar? Something like: ```typescript -await vscode.commands.executeCommand("hai.SidebarProvider.focus") +await vscode.commands.executeCommand("claude-dev.SidebarProvider.focus") await setTimeoutPromise(100) // Give UI time to update visibleWebview = WebviewProvider.getSidebarInstance() ``` diff --git a/.hairules/workflows/writing-documentation.md b/.hairules/workflows/writing-documentation.md new file mode 100644 index 00000000..76e38edd --- /dev/null +++ b/.hairules/workflows/writing-documentation.md @@ -0,0 +1,392 @@ +# General writing guide + +# How I want you to write + +I'm gonna write something technical. + +It's often less about the nitty-gritty details of the tech stuff and more about learning something new or getting a solution handed to me on a silver platter. + +Look, when I read, I want something out of it. So when I write, I gotta remember that my readers want something too. This whole piece? It's about cluing in anyone who writes for me, or wants me to write for them, on how I see this whole writing product thing. + +I'm gonna lay out a checklist of stuff I'd like to have. It'll make the whole writing gig a bit smoother, you know? + +## Crafting Compelling Titles + +I often come across titles like "How to do X with Y,Z technology." These don't excite me because X or Y are usually unfamiliar unless they're already well-known. Its rarely the dream to use X unless X is the dream. + +My dream isn’t to use instructor, its to do something valueble with the data it extracts + +An effective title should: + +- Evoke an emotional response +- Highlight someone's goal +- Offer a dream or aspiration +- Challenge or comment on a belief +- Address someone's problems + +I believe it's more impactful to write about specific problems. If this approach works, you can replicate it across various scenarios rather than staying too general. + +- Time management for everyone can be a 15$ ebook +- Time management for executives is a 2000$ workshop + +Aim for titles that answer questions you think everyone is asking, or address thoughts people have but can't quite articulate. + +Instead of "How I do something" or "How to do something," frame it from the reader's perspective with "How you can do something." This makes the title more engaging. Just make sure the difference is advisory if the content is subjective. “How I made a million dollars” might be more reasonable than “How to make a million dollars” since you are the subject and the goal might be to share your story in hopes of helping others. + +This approach ultimately trains the reader to have a stronger emotional connection to your content. + +- "How I do X" +- "How You Can do X" + +Between these two titles, it's obvious which one resonates more emotionally. + +You can take it further by adding specific conditions. For instance, you could target a particular audience or set a timeframe: + +- How to set up Braintrust +- How to set up Braintrust in 5 minutes + +## NO adjectiives + +I want you to almost always avoid adjectives and try to use evidence instead. Instead of saying "production ready," you can write something like "scaling this to 100 servers or 1 million documents per second." Numbers like that will tell you exactly what the specificity of your product is. If you have to use adjectives rather than evidence, you are probably making something up. + +There's no reason to say something like "blazingly fast" unless those things are already known phrases. + +Instead, say "200 times faster" or "30% faster." A 30% improvement in recommendation system speed is insane. + +There's a 200 times performance improvement because we went from one programming language to another. It's just something that's a little bit more expected and understandable. + +Another test that I really like using recently is tracking whether or not the statements you make can be: + +- Visualized +- Proven false +- Said only by you + +If you can nail all three, the claim you make will be more likely to resonate with an audience because only you can say it. + +Earlier this year, I had an example where I embedded all of Wikipedia in 17 minutes with 20 bucks, and it got half a million views. All we posted was a video of me kicking off the job, and then you can see all the log lines go through. You see the number of containers go from 1 out of 50 to 50 out of 50. + +It was easy to visualize and could have been proven false by being unreproducible. Lastly, Modal is the only company that could do that in such an effortless way, which made it unique. + +## Keep It Digestible + - Aim for 5-minute reads + - Write at a Grade 10 reading level + - Break up long paragraphs + - Use headers and bullet points + +## Make It Scannable + - Bold key points + - Use subheadings every 3-4 paragraphs + - Include plenty of white space + - Add relevant examples + +This structure works whether you're writing a tweet thread or a full blog post. The key is making complex ideas accessible. + +# Guide to Writing HAI Documentation + +## Some general principles for explaining features + +If you're talking about a feature, it's helpful to start with a human-readable explanations that cover what the feature is in simple terms. Skip jargon and explain it like you're talking to someone who's never seen it before. This sets the foundation for everything that follows. + +Combine location and usage into one flowing section. Tell users exactly where to find the feature and how to use it, but weave the instructions into natural prose with a good balance of bullet points, numbered lists, code examples (if applicable), mintlify components, and headers/subheaders. Users shouldn't have to jump between separate "where is it" and "how do I use it" sections. + +Show the feature in action with real examples like actual files, workflows, or code. Users need to see concrete implementations, not just abstract descriptions. This is where understanding turns into practical knowledge. + +When talking about a feature, include an inspiration section that sparks imagination. This section pushes people from understanding to action by showing them what becomes possible when they use this feature creatively. It's what separates good documentation from great documentation. + +## Writing Principles That Actually Work + +### Write for Action, Not Just Understanding + +Documentation should motivate users to try things. Instead of just explaining how something works, focus on what users can accomplish with it. The inspiration section is crucial - it's what transforms passive readers into active users. + +### Create a Natural Story Flow + +It should feel like a conversation that naturally progresses from "what is this?" to "how do I use it?" to "here's a real example" to "imagine what you could do with this." + +### Show Real Examples, Not Toy Demos + +Provide actual workflow files, real code snippets, and concrete implementations that users can copy and adapt. Abstract examples don't help anyone - users want to see exactly what they'll be working with. + +### Keep It Scannable But Not Fragmented + +Write in prose that flows naturally when read completely, but structure it so users can quickly find specific information when they're troubleshooting. Avoid dense walls of text, but also avoid over-formatting with excessive bullet points and bold headers. There should be a nice visual heirarchy of balance between all elements, so you can quickly scan the page and find what you're looking for. + +## Language and Tone Guidelines + +Write clearly without dumbing things down. Use simple language when possible, but don't avoid technical terms that users need to know. Explain concepts in terms of what users can achieve rather than how the software works internally. + +Make your writing conversational and encouraging. Phrases like "you can also try" or "when that works" feel more natural than rigid instructional language. Help users feel confident about trying new things. + +Keep content concise and purposeful. Every sentence should either help users understand something or help them do something. If it doesn't serve one of those purposes, cut it. + +Build in context and reasoning. Users want to understand why they're doing something, not just what to do. This builds confidence and helps them troubleshoot when things don't work exactly as expected. + +## Practical Implementation + +Structure each feature page consistently with the four-section approach, but let the content flow naturally within that structure. Use visual assets like videos and screenshots to complement the written content - they often communicate more effectively than paragraphs of description. + +Link generously to related resources, examples, and deeper documentation. Users should never feel stuck or wonder where to go next. Maintain a repository of real examples that users can reference and adapt to their own needs. + +The goal is documentation that feels more like helpful guidance from an experienced colleague than a technical manual. Users should finish reading feeling excited about what they can accomplish, not just informed about what the feature does. + +## Balance Structure with Flexibility + +While they discuss having consistent documentation structure, there's also mention of making content feel less rigid and more natural. The writing should follow guidelines while still feeling conversational and engaging. + +## Bad examples + +I personally hate this pattern of bullet point **Bold Text** colon and then more text: + +#### macOS + +1. **Switch to bash**: Go to HAI Settings → Terminal → Default Terminal Profile → Select "bash" +2. **Disable Oh-My-Zsh temporarily**: If using zsh, try `mv ~/.zshrc ~/.zshrc.backup` and restart VSCode +3. **Set environment**: Add to your shell config: `export TERM=xterm-256color` + +#### Windows + +1. **Use PowerShell 7**: Install from Microsoft Store, then select it in HAI settings +2. **Disable Windows ConPTY**: VSCode Settings → Terminal › Integrated: Windows Enable Conpty → Uncheck +3. **Try Command Prompt**: Sometimes simpler is better - switch to cmd.exe + +#### Linux + +1. **Use bash**: Most reliable option - select in HAI settings +2. **Check permissions**: Ensure VSCode has terminal access permissions +3. **Disable custom prompts**: Comment out prompt customizations in `.bashrc` + + + +We should instead strive to write beautiful docs that read well. We can use bullet points and numbered lists but it should read naturally and be delightful to look at hierachally when scanning through the doc. There should be a good balance between blocks of text, code snippets, paragraphs, numbered lists, and bullet points. When scanning the documentation visually, you should feel like you're adminiring a tasteful art piece. + + +#### macOS + +The most common fix is switching to bash. Navigate to HAI Settings → Terminal → Default Terminal Profile and select "bash" from the dropdown. + +If you're still having issues, Oh-My-Zsh might be interfering with terminal integration. Try temporarily disabling it: +- Run `mv ~/.zshrc ~/.zshrc.backup` +- Restart VSCode + +You can also add `export TERM=xterm-256color` to your shell configuration file to improve compatibility. + +#### Windows + +PowerShell 7 provides the most reliable experience. Install it from the Microsoft Store, then select it in your HAI settings. + +Still seeing problems? Try these solutions: +- Disable Windows ConPTY: VSCode Settings → Terminal › Integrated: Windows Enable Conpty → uncheck +- Switch to Command Prompt (cmd.exe) - sometimes simpler shells work better + +#### Linux + +Bash is your most dependable option. Select it in HAI settings if you haven't already. + +Check these common issues: +- Ensure VSCode has terminal access permissions +- Temporarily comment out custom prompt configurations in your `.bashrc` + + +This is much more natural to read. Writing this way creates a conversational flow, and bullet points are used idiomatically. + +# Using Mintlify Components Idiomatically + +Mintlify's custom components can transform basic documentation into engaging, scannable content that users actually want to read. Here's how to use them effectively. + +## Visual Content with Frames + +Videos and images should be wrapped in `` components rather than using raw HTML or markdown. This creates consistent styling and proper responsive behavior. + +For videos, embed them directly rather than linking externally. Users are much more likely to watch a 30-second demonstration than click through to another platform: + +```jsx + +