Skip to main content

Overview

This guide shows how to integrate install.md support into AI agents, development tools, and other software that can interpret and execute installation instructions.

For AI agent developers

Basic execution flow

  1. Fetch the install.md file
    import requests
    
    url = "https://example.com/install.md"
    response = requests.get(url)
    install_instructions = response.text
    
  2. Parse the structure
    # Extract key components
    lines = install_instructions.split('\n')
    
    # Find title (first H1)
    title = next(line.strip('#').strip() for line in lines if line.startswith('# '))
    
    # Find description (blockquote after title)
    description = next(line.strip('>').strip() for line in lines if line.startswith('> '))
    
    # Rest is installation instructions
    instructions = '\n'.join(lines[lines.index(f'> {description}') + 1:]).strip()
    
  3. Present to user for confirmation
    print(f"About to install: {title}")
    print(f"Description: {description}")
    print(f"\nInstructions preview:")
    print(instructions[:200] + "..." if len(instructions) > 200 else instructions)
    
    if input("\nProceed with installation? (y/n): ").lower() != 'y':
        return
    
  4. Execute instructions
    • Parse the instructions into actionable steps
    • Execute each step while showing progress
    • Handle errors gracefully
    • Provide clear feedback to the user

Safety considerations

Always require user confirmation

Never execute installation instructions without explicit user approval. Show a summary of what will happen.

Validate sources

Verify the source of the install.md file. Consider maintaining an allowlist of trusted domains.

Sandbox when possible

If your environment supports it, execute installation steps in a sandboxed or containerized environment first.

Provide rollback

Keep track of changes made during installation so they can be reversed if needed.

Error handling

class InstallationError(Exception):
    def __init__(self, step, message):
        self.step = step
        self.message = message
        super().__init__(f"Installation failed at step '{step}': {message}")

def execute_installation(instructions):
    steps = parse_steps(instructions)
    completed_steps = []

    try:
        for step in steps:
            print(f"Executing: {step.description}")
            execute_step(step)
            completed_steps.append(step)
    except Exception as e:
        print(f"Error during installation: {e}")
        print(f"Completed {len(completed_steps)} of {len(steps)} steps")

        if input("Attempt rollback? (y/n): ").lower() == 'y':
            rollback_steps(completed_steps)

        raise InstallationError(step.description, str(e))

Progress reporting

Provide clear feedback during installation:
def execute_with_progress(instructions):
    steps = parse_steps(instructions)

    for i, step in enumerate(steps, 1):
        print(f"\n[{i}/{len(steps)}] {step.description}")

        result = execute_step(step)

        if result.success:
            print(f"✓ {step.description}")
        else:
            print(f"✗ {step.description}: {result.error}")
            break

    print(f"\n{'=' * 50}")
    print(f"Installation {'completed successfully' if all_success else 'failed'}")

For CLI tools

Command structure

Support these patterns:
# Fetch and execute remote install.md
your-agent install https://example.com/install.md

# Execute local install.md file
your-agent install ./install.md

# Pipe from curl
curl -fsSL https://example.com/install.md | your-agent install

# Preview without executing
your-agent install --dry-run https://example.com/install.md

Implementation example

import sys
import argparse

def main():
    parser = argparse.ArgumentParser(description='Execute install.md files')
    parser.add_argument('source', help='URL or path to install.md file, or "-" for stdin')
    parser.add_argument('--dry-run', action='store_true', help='Preview without executing')
    parser.add_argument('--yes', '-y', action='store_true', help='Skip confirmation prompts')

    args = parser.parse_args()

    # Read instructions
    if args.source == '-' or not sys.stdin.isatty():
        instructions = sys.stdin.read()
    elif args.source.startswith('http'):
        instructions = fetch_remote(args.source)
    else:
        instructions = read_file(args.source)

    # Parse and display
    title, description, steps = parse_install_md(instructions)

    print(f"Installing: {title}")
    print(f"{description}\n")

    if args.dry_run:
        print("Steps that would be executed:")
        for i, step in enumerate(steps, 1):
            print(f"  {i}. {step}")
        return

    # Confirm
    if not args.yes:
        if input("Proceed? (y/n): ").lower() != 'y':
            print("Installation cancelled")
            return

    # Execute
    execute_installation(steps)

For IDE extensions

VS Code extension

Create a VS Code extension that recognizes install.md files:
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    // Register command to execute install.md
    let disposable = vscode.commands.registerCommand(
        'install-md.execute',
        async (uri: vscode.Uri) => {
            const document = await vscode.workspace.openTextDocument(uri);
            const content = document.getText();

            // Parse install.md
            const { title, description, instructions } = parseInstallMd(content);

            // Show preview
            const panel = vscode.window.createWebviewPanel(
                'installPreview',
                `Install: ${title}`,
                vscode.ViewColumn.One,
                {}
            );

            panel.webview.html = getPreviewHtml(title, description, instructions);

            // Handle execution
            panel.webview.onDidReceiveMessage(
                async message => {
                    if (message.command === 'execute') {
                        await executeInTerminal(instructions);
                    }
                }
            );
        }
    );

    context.subscriptions.push(disposable);
}

async function executeInTerminal(instructions: string) {
    const terminal = vscode.window.createTerminal('install.md');
    terminal.show();

    // Send to Claude Code or other AI agent
    terminal.sendText(`claude execute "${instructions}"`);
}

JetBrains plugin

Similar approach for IntelliJ IDEA, PyCharm, etc:
class InstallMdAction : AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val file = e.getData(CommonDataKeys.VIRTUAL_FILE) ?: return
        val content = String(file.contentsToByteArray())

        val (title, description, instructions) = parseInstallMd(content)

        val proceed = Messages.showYesNoDialog(
            e.project,
            "Install $title?\n\n$description",
            "Confirm Installation",
            Messages.getQuestionIcon()
        ) == Messages.YES

        if (proceed) {
            executeInTerminal(e.project, instructions)
        }
    }
}

For web browsers

Browser extension

Create an extension that detects install.md files and offers to execute them:
// Content script that detects install.md files
if (window.location.pathname.endsWith('.md') ||
    window.location.pathname.endsWith('/install.md')) {

    // Check if this is an install.md file
    fetch(window.location.href)
        .then(response => response.text())
        .then(content => {
            if (isInstallMd(content)) {
                showInstallButton(content);
            }
        });
}

function showInstallButton(content) {
    const button = document.createElement('button');
    button.textContent = 'Install with AI Agent';
    button.onclick = () => {
        chrome.runtime.sendMessage({
            action: 'install',
            content: content
        });
    };

    document.body.insertBefore(button, document.body.firstChild);
}

function isInstallMd(content) {
    // Check if it follows install.md format
    const lines = content.split('\n');
    return lines.some(line => line.match(/^# /)) &&
           lines.some(line => line.match(/^> /));
}

For package managers

NPM package

Create an NPM package for executing install.md files:
{
  "name": "install-md",
  "version": "1.0.0",
  "bin": {
    "install-md": "./bin/install-md.js"
  },
  "dependencies": {
    "marked": "^4.0.0",
    "chalk": "^5.0.0",
    "inquirer": "^9.0.0"
  }
}
#!/usr/bin/env node

const { execSync } = require('child_process');
const chalk = require('chalk');
const inquirer = require('inquirer');

async function main() {
    const url = process.argv[2];

    if (!url) {
        console.error('Usage: install-md <url>');
        process.exit(1);
    }

    const response = await fetch(url);
    const content = await response.text();

    const { title, description, instructions } = parseInstallMd(content);

    console.log(chalk.bold.blue(`\nInstalling: ${title}`));
    console.log(chalk.gray(description));

    const { proceed } = await inquirer.prompt([{
        type: 'confirm',
        name: 'proceed',
        message: 'Proceed with installation?',
        default: false
    }]);

    if (!proceed) {
        console.log('Installation cancelled');
        return;
    }

    // Execute using AI agent
    execSync(`claude execute "${instructions}"`, { stdio: 'inherit' });
}

main();

Testing your integration

Create a test install.md file:
# Test Installation

> A simple test to verify install.md integration.

Echo "Hello from install.md!"

Create a test file at ~/install-md-test.txt with the content "Installation successful".

Verify the file exists and display its contents.
Test that your integration:
  1. ✓ Fetches the file correctly
  2. ✓ Parses title and description
  3. ✓ Displays content to user
  4. ✓ Requires confirmation
  5. ✓ Executes steps in order
  6. ✓ Shows progress
  7. ✓ Handles errors gracefully
  8. ✓ Provides useful feedback

Security checklist

Before releasing your integration:
  • Require explicit user confirmation
  • Validate and sanitize all inputs
  • Display full instructions before execution
  • Implement timeout protection
  • Add rate limiting for remote fetches
  • Log all executed commands
  • Provide dry-run mode
  • Support rollback when possible
  • Handle network failures gracefully
  • Warn users about executing remote code

Contributing

Help improve install.md integration:

Share your integration

Submit your integration to be listed in the documentation.

Next steps