Skip to main content

Markdown Generator

Overview​

The Markdown Generator creates and maintains the markdown repository for each work - a GitHub repository containing the README.md and individual item detail pages. It transforms structured item data into human-readable markdown format.

Architecture​

┌─────────────────────────────────────────────────────────────────┐
│ MarkdownGeneratorService │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ initialize() │ │
│ │ │ │
│ │ 1. Clone/create markdown repository │ │
│ │ 2. Switch to PR branch (if PR mode) │ │
│ │ 3. Generate README.md via ReadmeBuilder │ │
│ │ 4. Generate detail pages for each item │ │
│ │ 5. Commit and push │ │
│ │ 6. Create PR (if PR mode) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Uses: MarkdownRepository, ReadmeBuilder │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ GitHub Markdown Repository │
│ │
│ {owner}/{work-slug}/ │
│ ├── README.md # Main work listing │
│ ├── details/ # Individual item pages │
│ │ ├── item-slug-1.md │
│ │ ├── item-slug-2.md │
│ │ └── ... │
│ └── LICENSE # Auto-generated license │
└─────────────────────────────────────────────────────────────────┘

Data Flow​

TriggerGenerationOrchestrator
│
├── DataGeneratorService.initialize()
│ └── Returns: {items, categories, tags, ...}
│
▼
MarkdownGeneratorService.initialize(payload, dataResult)
│
├── Clone/create repository
│
├── Switch to PR branch (if update_with_pull_request)
│
├── ReadmeBuilder.build()
│ ├── Generate header (custom or default)
│ ├── Generate table of contents
│ ├── Generate category sections
│ │ └── For each item: name, description, link, badges
│ ├── Generate footer (custom or default)
│ └── Returns: README.md content
│
├── Write README.md
│
├── For each item:
│ └── Write details/{slug}.md
│
├── Commit & Push
│
└── Create PR (if PR mode)
│
▼
Returns: {success, prUpdate?}

Repository Structure​

README.md​

# My Work

A curated list of the best monitoring tools.

## Table of Contents

- [Monitoring](#monitoring)
- [Logging](#logging)
- [Alerting](#alerting)

## Monitoring

| Name | Description |
| ----------------------------------- | ----------------------------- |
| [Prometheus](details/prometheus.md) | Open-source monitoring system |
| [Grafana](details/grafana.md) | Visualization and analytics |

## Logging

| Name | Description |
| ----------------------------------------- | ------------------------- |
| [Elasticsearch](details/elasticsearch.md) | Distributed search engine |

---

## Contributing

[Contributing guidelines]

## License

[License text]

details/{slug}.md​

# Prometheus

Open-source systems monitoring and alerting toolkit.

## Overview

Prometheus is an open-source monitoring system with a dimensional data model...

## Features

- Multi-dimensional data model
- Flexible query language (PromQL)
- Pull-based metrics collection
- Service discovery

## Links

- [Official Website](https://prometheus.io)
- [GitHub Repository](https://github.com/prometheus/prometheus)
- [Documentation](https://prometheus.io/docs)

## Tags

`open-source` `monitoring` `cloud-native`

---

_Last updated: 2024-01-16_

Key Components​

MarkdownGeneratorService​

Main orchestrator for markdown generation.

class MarkdownGeneratorService {
async initialize(payload: WorkGenerationPayload, dataResult: DataGeneratorResult): Promise<MarkdownGeneratorResult>;
}

MarkdownRepository​

Handles file operations for the markdown repository.

class MarkdownRepository {
// README operations
writeReadme(content: string): Promise<void>;
readReadme(): Promise<string | null>;

// Detail page operations
writeDetails(slug: string, content: string): Promise<void>;
readDetails(slug: string): Promise<string | null>;
removeDetails(slug: string): Promise<void>;
listDetails(): Promise<string[]>;

// Cleanup
resetFiles(): Promise<void>; // Clear generated files, keep .git

// Git operations
clone(): Promise<void>;
commit(message: string): Promise<void>;
push(): Promise<void>;
createBranch(name: string): Promise<void>;
createPullRequest(title: string, body: string): Promise<PR>;
}

ReadmeBuilder​

Generates README.md content from structured data.

class ReadmeBuilder {
build(options: ReadmeBuildOptions): string;
}

interface ReadmeBuildOptions {
work: Work;
items: ItemData[];
categories: Category[];
tags: Tag[];
readmeConfig?: ReadmeConfig;
}

interface ReadmeConfig {
header?: string;
overwriteDefaultHeader?: boolean;
footer?: string;
overwriteDefaultFooter?: boolean;
}

README Generation​

Header Section​

Default Header:

# {Work Name}

{Work Description}

Custom Header (if readmeConfig.header provided):

  • If overwriteDefaultHeader: true: Uses only custom header
  • If overwriteDefaultHeader: false: Prepends custom header to default

Table of Contents​

Generated from categories with priority ordering:

## Table of Contents

- [Priority Category 1](#priority-category-1)
- [Priority Category 2](#priority-category-2)
- [Other Category](#other-category)

Category Sections​

Each category gets a section with a table:

## Monitoring

| Name | Description |
| --------------------------- | -------------- |
| [Tool 1](details/tool-1.md) | Description... |
| [Tool 2](details/tool-2.md) | Description... |

Featured Items: Marked with star or badge

Item Ordering:

  1. Featured items first
  2. By order field (if set)
  3. Alphabetically by name

Default Footer:

---

## Contributing

Contributions welcome! Please read our contributing guidelines.

## License

This list is licensed under [LICENSE].

---

_Generated with [Ever Works](https://ever.works)_

Custom Footer: Same logic as header

Detail Page Generation​

Each item gets a detail page at details/{slug}.md:

function generateDetailPage(item: ItemData): string {
return `
# ${item.name}

${item.description}

## Overview

${item.markdown || 'No detailed description available.'}

## Links

- [Official Website](${item.source_url})

## Tags

${item.tags.map((t) => `\`${t}\``).join(' ')}

---

*Last updated: ${new Date().toISOString().split('T')[0]}*
`.trim();
}

Interfaces​

MarkdownGeneratorResult​

interface MarkdownGeneratorResult {
success: boolean;
prUpdate?: {
branch: string;
title: string;
body: string;
number: number;
url: string;
};
error?: string;
}

ReadmeConfig​

interface ReadmeConfig {
header?: string; // Custom header content
overwriteDefaultHeader?: boolean; // Replace vs prepend
footer?: string; // Custom footer content
overwriteDefaultFooter?: boolean; // Replace vs append
}

PR Mode​

When update_with_pull_request: true:

  1. Create branch: ever-update-{timestamp}
  2. Make all changes on branch
  3. Create PR with summary:
## README Update

This PR updates the work README with the latest items.

### Changes

- Added 5 new items
- Updated 3 existing items
- Removed 1 outdated item

### Categories

- Monitoring: 12 items
- Logging: 8 items
- Alerting: 5 items

---

_Generated by Ever Works_

Repository Initialization​

For new works, the service:

  1. Creates GitHub repository
  2. Initializes with basic structure
  3. Adds LICENSE file
  4. Commits initial README
async initializeRepository(): Promise<void> {
await this.githubService.createRepository(repoName, {
description: work.description,
private: false,
auto_init: true,
});

await this.markdownRepository.writeReadme(initialReadme);
await this.markdownRepository.commit('Initial commit');
await this.markdownRepository.push();
}

Error Handling​

ErrorHandling
Repository doesn't existCreate it
Clone failsRetry with backoff
Write failsLog error, continue with other files
Push failsCheck permissions, retry
PR creation failsFall back to direct commit

File Locations​

/packages/agent/src/markdown-generator/
├── markdown-generator.service.ts # Main service
├── markdown-repository.ts # File operations
├── readme-builder.ts # README generation
└── templates/ # Optional templates

Configuration​

Configuration comes from:

  1. CreateItemsGeneratorDto.update_with_pull_request
  2. Work.readmeConfig (header/footer customization)

Integration Points​

  • Input: Items, categories, tags from DataGenerator
  • Output: GitHub markdown repository
  • Dependencies: GitService for GitHub operations

See Also​