Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
- name: Setup Node and pnpm
uses: ./.github/actions/setup-node

- name: Check Apps Table
run: pnpm check-table

- name: Lint
run: pnpm lint

Expand Down
78 changes: 49 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
# Shelby Protocol Examples
<p align="center">
<a href="https://shelby.xyz">
<img src="https://avatars.githubusercontent.com/u/219037914?s=96&v=4" alt="Shelby Logo" width="96" height="96">
<h3 align="center">Shelby Examples</h3>
</a>
</p>

<p align="center">
<span>🌐 Website: <a href="https://shelby.xyz">shelby.xyz</a></span>
&nbsp;|&nbsp;
<span>📚 Documentation: <a href="https://docs.shelby.xyz">docs.shelby.xyz</a></span>
&nbsp;|&nbsp;
<span>🐙 GitHub: <a href="https://github.com/shelby">github.com/shelby</a></span>
&nbsp;|&nbsp;
<span>🐦 Twitter: <a href="https://x.com/shelbyserves">@shelbyserves</a></span>
</p>

A collection of examples demonstrating various features and capabilities of the Shelby ecosystem. This repository is modeled after [Vercel's examples repository](https://github.com/vercel/examples) and serves as a comprehensive resource for developers building with Shelby.

<div align="center">
<img src="https://avatars.githubusercontent.com/u/219037914?s=96&v=4" alt="Shelby Protocol Logo" width="96" height="96">
</div>

A collection of examples demonstrating various features and capabilities of the Shelby Protocol ecosystem. This repository is modeled after [Vercel's examples repository](https://github.com/vercel/examples) and serves as a comprehensive resource for developers building with Shelby Protocol.

## About Shelby Protocol
## What's Inside

Shelby Protocol is a decentralized infrastructure platform designed to simplify the development and deployment of distributed applications. Learn more about us:
This Turborepo includes the following example applications:

- 🌐 **Website**: [shelby.xyz](https://shelby.xyz/)
- 📚 **Documentation**: [docs.shelby.xyz](https://docs.shelby.xyz/)
- 🐙 **GitHub**: [github.com/shelby](https://github.com/shelby)
- 🐦 **Twitter**: [@shelbyserves](https://x.com/shelbyserves)
<!-- APPS_TABLE_START -->
<!-- This table is auto-generated by @shelby-protocol/table-generator -->

## What's Inside
### Applications

This Turborepo includes the following packages and applications:
| Name | Description | Path & Links |
| --- | --- | --- |
| `@shelby-protocol/web` | A Next.js application showcasing Shelby integrations | [`apps/web`](./apps/web) |

### Apps and Packages
<!-- APPS_TABLE_END -->

- `@shelby-protocol/web`: A [Next.js](https://nextjs.org/) application showcasing Shelby Protocol integrations
- `@shelby-protocol/ui`: A React component library shared across applications

Each package/app is 100% [TypeScript](https://www.typescriptlang.org/) and follows Shelby Protocol's development standards.
Each application is 100% [TypeScript](https://www.typescriptlang.org/) and follows Shelby's development standards.

### Development Tools

Expand Down Expand Up @@ -57,13 +65,13 @@ pnpm install

### Development

To develop all apps and packages:
To develop all applications:

```bash
pnpm dev
```

To develop a specific package:
To develop a specific application:

```bash
# Develop the web application
Expand All @@ -72,13 +80,13 @@ pnpm dev --filter=@shelby-protocol/web

### Building

To build all apps and packages:
To build all applications:

```bash
pnpm build
```

To build a specific package:
To build a specific application:

```bash
# Build the web application
Expand All @@ -102,14 +110,26 @@ Run tests:
pnpm test:once
```

## Contributing
### Table Maintenance

The applications table above is automatically maintained by the `@shelby-protocol/table-generator` package:

We welcome contributions to the Shelby Protocol examples repository! Please read our contributing guidelines and feel free to submit issues and pull requests.
Update the table:
```bash
pnpm update-table
```

## License
Check if table is up to date:
```bash
pnpm check-table
```

The table generator scans all applications in the `apps/` directory and automatically updates the README with current information including names, descriptions, and links. This ensures the documentation stays synchronized with the actual codebase.

## Contributing

This repository is open source and available under the [MIT License](LICENSE).
We welcome contributions to the Shelby examples repository! Please read our contributing guidelines and feel free to submit issues and pull requests.

---

Built with ❤️ by the [Shelby Protocol team](https://github.com/shelby)
Built with ❤️ by the [Shelby team](https://github.com/shelby)
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "@shelby-protocol/web",
"version": "0.1.0",
"description": "A Next.js application showcasing Shelby integrations",
"type": "module",
"private": true,
"scripts": {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"fmt": "turbo run fmt",
"build": "turbo run build",
"test:once": "turbo run test:once",
"generate": "turbo run generate"
"generate": "turbo run generate",
"update-table": "pnpm --filter @shelby-protocol/table-generator update-table",
"check-table": "pnpm --filter @shelby-protocol/table-generator check-table"
},
"devDependencies": {
"@biomejs/biome": "2.0.6",
Expand Down
40 changes: 40 additions & 0 deletions packages/table-generator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@shelby-protocol/table-generator",
"version": "0.0.1",
"private": true,
"description": "Automatically generates and maintains the applications table in README.md",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"bin": {
"update-apps-table": "./dist/cli.js"
},
"scripts": {
"build": "tsc",
"dev": "tsx src/cli.ts",
"lint": "biome check .",
"fmt": "biome check . --write",
"test:once": "echo 'No tests configured'",
"update-table": "tsx src/cli.ts",
"check-table": "tsx src/cli.ts --check"
},
"dependencies": {
"tsx": "^4.19.2"
},
"devDependencies": {
"@types/node": "^22.15.3",
"typescript": "5.8.2"
},
"keywords": [
"monorepo",
"documentation",
"automation",
"table-generation"
]
}
96 changes: 96 additions & 0 deletions packages/table-generator/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env tsx

import { resolve } from "node:path";
import { updateAppsTable } from "./index.js";

/**
* Parse command line arguments
*/
function parseArgs() {
const args = process.argv.slice(2);
return {
check: args.includes("--check"),
verbose: args.includes("--verbose") || args.includes("-v"),
help: args.includes("--help") || args.includes("-h"),
};
}

/**
* Show help message
*/
function showHelp() {
console.log(`
@shelby-protocol/table-generator

Automatically generates and maintains the apps table in README.md

USAGE:
tsx src/cli.ts [options]
pnpm update-table [options]
pnpm check-table

OPTIONS:
--check Check if table is up to date (exits with code 1 if not)
--verbose, -v Show verbose output
--help, -h Show this help message

EXAMPLES:
tsx src/cli.ts # Update the table
tsx src/cli.ts --check # Check if table is up to date
tsx src/cli.ts --verbose # Update with verbose output
pnpm update-table # Update using npm script
pnpm check-table # Check using npm script
`);
}

/**
* Main CLI function
*/
function main() {
const { check, help } = parseArgs();

if (help) {
showHelp();
return;
}

try {
// Find the monorepo root (2 levels up from this package)
const rootDir = resolve(import.meta.dirname, "../../../");

const wasUpdated = updateAppsTable({
rootDir,
checkOnly: check,
verbose: true, // Always verbose in CLI
});

if (check) {
console.log("✅ README.md table is up to date");
process.exit(0);
} else if (wasUpdated) {
console.log("📝 README.md has been updated");
process.exit(0);
} else {
console.log("✅ No changes needed");
process.exit(0);
}
} catch (error) {
console.error("❌ Error:", (error as Error).message);

if (check && (error as Error).message.includes("out of sync")) {
console.error("\n💡 Run 'pnpm update-table' to fix this");
}

process.exit(1);
}
}

// Run if this script is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
try {
main();
} catch (error) {
console.error("Unexpected error:", error);
process.exit(1);
}
}
39 changes: 39 additions & 0 deletions packages/table-generator/src/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { MonorepoItem } from "./types.js";

/**
* Generate markdown table for apps and packages
*/
export function generateTable(items: MonorepoItem[], title: string): string {
if (items.length === 0) {
return `### ${title}\n\nNo ${title.toLowerCase()} found.\n`;
}

const headers = ["Name", "Description", "Path & Links"];
const separator = headers.map(() => "---").join(" | ");

let table = `### ${title}\n\n| ${headers.join(" | ")} |\n| ${separator} |\n`;

for (const item of items) {
const links: string[] = [];

// Add source link with path
links.push(`[\`${item.path}\`](./${item.path})`);

// Add homepage link if available
if (item.homepage) {
links.push(`[Live Demo](${item.homepage})`);
}

// Add repository link if different from homepage
if (item.repository && item.repository !== item.homepage) {
links.push(`[Repository](${item.repository})`);
}

const pathAndLinks = links.join(" • ");
const escapedDescription = item.description.replace(/\|/g, "\\|");

table += `| \`${item.name}\` | ${escapedDescription} | ${pathAndLinks} |\n`;
}

return `${table}\n`;
}
63 changes: 63 additions & 0 deletions packages/table-generator/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { resolve } from "node:path";
import { generateTable } from "./generator.js";
import { updateReadme } from "./readme-updater.js";
import { getMonorepoApps } from "./scanner.js";
import type { TableGeneratorOptions } from "./types.js";

/**
* Main function to update the apps table in README.md
*/
export function updateAppsTable(options: TableGeneratorOptions = {}) {
const {
rootDir = process.cwd(),
readmePath = resolve(rootDir, "README.md"),
checkOnly = false,
verbose = false,
} = options;

if (verbose) {
console.log("🔍 Scanning monorepo for apps...");
}

// Scan for apps only
const { apps } = getMonorepoApps(rootDir);

if (verbose) {
console.log(`Found ${apps.length} apps`);
}

// Generate apps table only
const appsTable = generateTable(apps, "Applications");

// Update README
const result = updateReadme(readmePath, appsTable, "");

if (result.error) {
throw new Error(result.error);
}

if (checkOnly) {
if (result.wasUpdated) {
throw new Error("README.md table is out of sync");
}
if (verbose) console.log("✅ README.md table is up to date");
return false;
}

if (result.wasUpdated) {
if (verbose) console.log("✅ Updated README.md with latest apps table");
return true;
}
if (verbose) console.log("✅ Table is already up to date");
return false;
}

export { generateTable } from "./generator.js";
export { updateReadme } from "./readme-updater.js";
export { getMonorepoApps } from "./scanner.js";
// Re-export types and functions for library usage
export type {
MonorepoApps,
MonorepoItem,
TableGeneratorOptions,
} from "./types.js";
Loading