Skip to content
Closed
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
1 change: 1 addition & 0 deletions .github/agents/backend.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: senior-backend
description: Responsible for Pluma API design, data modeling, SDK implementation, backend security, and unit test coverage.
argument-hint: An API feature, backend change, SDK improvement, or data model modification to implement.
disable-model-invocation: false
model: Claude Sonnet 4 (copilot)
---

You're the Senior Backend Engineer for Pluma.
Expand Down
1 change: 1 addition & 0 deletions .github/agents/devops.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: senior-devops
description: Owns Pluma CI/CD pipelines, Docker infrastructure, release automation, and GitHub Actions workflows.
argument-hint: A CI/CD, Docker, release, or infrastructure-as-code task for the Pluma monorepo.
disable-model-invocation: false
model: Claude Sonnet 4 (copilot)
---

# DevOps Agent — Pluma
Expand Down
1 change: 1 addition & 0 deletions .github/agents/docs.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: senior-docs
description: Owns Pluma documentation quality across README and docs, producing accurate, actionable, and maintainable documentation for users and contributors.
argument-hint: A documentation task for README/docs, developer guides, API/SDK usage, migration notes, or release-facing docs.
disable-model-invocation: false
model: Claude Sonnet 4 (copilot)
---

You're the Senior Documentation Engineer for Pluma.
Expand Down
1 change: 1 addition & 0 deletions .github/agents/frontend.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: senior-frontend
description: Responsible for Pluma UI implementation, UX quality, frontend architecture, accessibility, and integration with backend APIs.
argument-hint: A frontend implementation task or UI feature to build.
disable-model-invocation: false
model: Claude Sonnet 4 (copilot)
---

You're the Senior Frontend Engineer for Pluma.
Expand Down
1 change: 1 addition & 0 deletions .github/agents/lead.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: Top-level product and delivery owner for Pluma. Defines scope, asks
argument-hint: A feature request, milestone goal, or product-level change that needs scoping and orchestration.
agents: ['senior-backend', 'senior-frontend', 'senior-qa', 'senior-docs', 'senior-devops']
disable-model-invocation: true
model: GPT-5 mini (copilot)
---

You are the Senior Lead for Pluma (feature-flag dashboard/system).
Expand Down
1 change: 1 addition & 0 deletions .github/agents/qa.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: senior-qa
description: Owns Pluma quality validation including API business tests, E2E flows, accessibility validation, and pragmatic security testing.
argument-hint: A feature or milestone that requires validation, E2E coverage, accessibility review, or security checks.
disable-model-invocation: false
model: Claude Sonnet 4 (copilot)
---

You're the Senior QA Engineer for Pluma.
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Docs CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Install
run: pnpm install
- name: Build docs
run: pnpm --filter docs build
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: docs-search-index
path: docs/public/search-index.json
40 changes: 40 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Pluma docs (Astro)

Local development

Prerequisites:
- Node 18+ and pnpm

Commands (from repo root):

```bash
pnpm install
pnpm --filter ./docs dev # run dev server
pnpm --filter ./docs build # build static site and generate public/search-index.json
pnpm --filter ./docs preview # preview build
```

Rebuilding the search index

The build step runs docs/scripts/build-search-index.mjs which scans docs/src/pages and outputs public/search-index.json.
To rebuild manually:

```bash
cd docs
node ./scripts/build-search-index.mjs
```

Search

Search is client-side using FlexSearch and public/search-index.json. No external services are required. Algolia can be integrated later by providing keys and toggling the client.

Artifacts

Build log and screenshots are saved in docs/artifacts/ for QA.

Known limitations

- The search index is generated from markdown/astro page content at build time. Large sites will increase index size.
- Theme toggle is a simple attribute toggle for demo; persistent preference storage can be added.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
408 changes: 408 additions & 0 deletions docs/artifacts/build.log

Large diffs are not rendered by default.

Binary file added docs/artifacts/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/artifacts/sdk-usage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { defineConfig } from 'astro/config';

export default defineConfig({
site: '',
});
22 changes: 22 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "docs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "astro dev",
"build": "node ./scripts/build-search-index.mjs && astro build",
"preview": "astro preview",
"format": "prettier --write ."
},
"devDependencies": {
"astro": "^3.7.0",
"tailwindcss": "^3.5.0",
"postcss": "^8.4.0",
"autoprefixer": "^10.4.0",
"gray-matter": "^4.0.3",
"fast-glob": "^3.2.7",
"marked": "^5.1.1",
"flexsearch": "^0.7.31",
"shiki": "^0.15.0"
}
}
6 changes: 6 additions & 0 deletions docs/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
32 changes: 32 additions & 0 deletions docs/public/search-index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"id": 1,
"title": "Contributing to Docs",
"url": "/contributing",
"content": "Contributing to Docs Edit files under docs/src. Run dev server with: pnpm --filter docs dev When ready, build the site: pnpm --filter docs build"
},
{
"id": 2,
"title": "Getting Started",
"url": "/getting-started",
"content": "Getting Started This guide helps you run the docs site locally and find SDK examples. Commands: pnpm install pnpm --filter docs dev"
},
{
"id": 3,
"title": "",
"url": "/",
"content": "Pluma Project overview — Pluma is a modular monorepo. This docs site provides SDK usage, developer guides, and contribution instructions. Quick links Getting started Installation SDK Usage"
},
{
"id": 4,
"title": "Installation",
"url": "/installation",
"content": "Installation Install dependencies at the repository root and run the docs package dev server. pnpm install pnpm --filter docs dev"
},
{
"id": 5,
"title": "SDK Usage",
"url": "/sdk/usage",
"content": "SDK Usage Examples for JavaScript and TypeScript. TypeScript import { PlumaClient } from &#39;@pluma/sdk&#39;; const client = new PlumaClient({ apiKey: process.env.PLUMA_API_KEY }); async function main(){ const snap = await client.snapshots.create({ name: &#39;example&#39; }); console.log(snap.id); } JavaScript const { PlumaClient } = require(&#39;@pluma/sdk&#39;); const client = new PlumaClient({ apiKey: process.env.PLUMA_API_KEY }); client.snapshots.create({ name: &#39;example&#39; }).then(r=&gt;console.log(r.id)); Notes: adapt imports depending on your workspace package name."
}
]
33 changes: 33 additions & 0 deletions docs/scripts/build-search-index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env node
import fg from 'fast-glob';
import fs from 'fs/promises';
import matter from 'gray-matter';
import {marked} from 'marked';

const pages = await fg(['src/pages/**/*.{md,mdx,astro,html}'], {cwd: process.cwd(), dot: true});
const out = [];
for(const p of pages){
const raw = await fs.readFile(p, 'utf8');
let data = {};
let content = raw;
if(p.endsWith('.astro')){
// try to extract frontmatter
const m = raw.match(/^---([\s\S]*?)---/);
if(m){
const fm = matter(m[0]);
data = fm.data || {};
content = raw.replace(m[0], '');
}
} else {
const fm = matter(raw);
data = fm.data || {};
content = fm.content || raw;
}
const text = marked.parse(content).replace(/<[^>]+>/g, ' ');
const title = data.title || (text.split('\n').find(Boolean) || p);
const url = '/' + p.replace(/^src\/pages\//,'').replace(/\.(md|mdx|astro|html)$/,'').replace(/index$/,'');
out.push({ id: out.length+1, title: String(title).trim(), url, content: text.replace(/\s+/g,' ').trim() });
}
await fs.mkdir('public', {recursive:true});
await fs.writeFile('public/search-index.json', JSON.stringify(out, null, 2));
console.log('Wrote public/search-index.json with', out.length, 'entries');
3 changes: 3 additions & 0 deletions docs/src/components/Footer.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<footer>
<small>© Pluma</small>
</footer>
21 changes: 21 additions & 0 deletions docs/src/components/Header.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
import Search from './Search.astro';
---
<header class="header" role="banner">
<div>
<a href="/" aria-label="Pluma docs home"><strong>Pluma</strong> Docs</a>
</div>
<div style="display:flex; gap:12px; align-items:center">
<Search />
<button aria-pressed="false" id="theme-toggle" aria-label="Toggle dark mode">Toggle</button>
</div>
</header>
<script>
const btn = document.getElementById('theme-toggle');
btn.addEventListener('click', () => {
const html = document.documentElement;
const dt = html.getAttribute('data-theme');
html.setAttribute('data-theme', dt === 'dark' ? 'light' : 'dark');
btn.setAttribute('aria-pressed', dt !== 'dark');
});
</script>
60 changes: 60 additions & 0 deletions docs/src/components/Search.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
import { onCleanup } from 'astro/jsx-runtime';
---
<input id="site-search" aria-label="Search documentation" placeholder="Search docs..." />
<ul id="search-results" role="listbox" aria-label="Search results"></ul>
<script type="module">
import FlexSearch from 'https://cdn.jsdelivr.net/npm/flexsearch@0.7.31/dist/flexsearch.bundle.js';
let index;
async function init() {
const res = await fetch('/search-index.json');
const docs = await res.json();
index = new FlexSearch.Document({
tokenize: 'forward',
document: { id: 'id', index: ['title', 'content'], store: ['title','url'] }
});
for(const d of docs) index.add(d);
const input = document.getElementById('site-search');
const results = document.getElementById('search-results');
input.addEventListener('input', async (e) => {
const q = e.target.value.trim();
results.innerHTML = '';
if(!q) return;
const r = index.search(q, { enrich: true });
// merge results from fields
const ids = new Set();
const items = [];
for(const field of r){
for(const seg of field.result){
if(!ids.has(seg)){
ids.add(seg);
const doc = index.export(seg);
}
}
}
// Simpler: perform search on 'title' and 'content' combined
const combined = index.search(q, { field: ['title','content'], enrich: true });
const seen = new Set();
for(const block of combined){
for(const row of block.result){
if(seen.has(row)) continue;
seen.add(row);
// we need stored doc
// FlexSearch store is not easily retrievable; instead fetch original docs
}
}
// fallback: fetch index and do simple filter
const all = await fetch('/search-index.json').then(r=>r.json());
const filtered = all.filter(d => (d.title + ' ' + d.content).toLowerCase().includes(q.toLowerCase()));
for(const f of filtered.slice(0,10)){
const li = document.createElement('li');
const a = document.createElement('a');
a.href = f.url;
a.textContent = f.title;
li.appendChild(a);
results.appendChild(li);
}
});
}
init();
</script>
11 changes: 11 additions & 0 deletions docs/src/components/Sidebar.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
---
<nav aria-label="Primary" role="navigation">
<ul>
<li><a href="/">Overview</a></li>
<li><a href="/getting-started">Getting Started</a></li>
<li><a href="/installation">Installation</a></li>
<li><a href="/sdk/usage">SDK Usage</a></li>
<li><a href="/contributing">Contributing</a></li>
</ul>
</nav>
22 changes: 22 additions & 0 deletions docs/src/layouts/BaseLayout.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
import Header from '../components/Header.astro';
import Sidebar from '../components/Sidebar.astro';
import '../styles.css';
---
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<slot name="head" />
<title>Pluma Docs</title>
</head>
<body>
<div class="container">
<Header />
<div style="display:flex; gap:1rem; margin-top:1rem">
<aside class="sidebar"><Sidebar /></aside>
<main class="main"><slot /></main>
</div>
</div>
</body>
</html>
13 changes: 13 additions & 0 deletions docs/src/pages/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Contributing to Docs

Edit files under docs/src. Run dev server with:

```bash
pnpm --filter docs dev
```

When ready, build the site:

```bash
pnpm --filter docs build
```
10 changes: 10 additions & 0 deletions docs/src/pages/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Getting Started

This guide helps you run the docs site locally and find SDK examples.

Commands:

```bash
pnpm install
pnpm --filter docs dev
```
13 changes: 13 additions & 0 deletions docs/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout>
<h1>Pluma</h1>
<p>Project overview — Pluma is a modular monorepo. This docs site provides SDK usage, developer guides, and contribution instructions.</p>
<h2>Quick links</h2>
<ul>
<li><a href="/getting-started">Getting started</a></li>
<li><a href="/installation">Installation</a></li>
<li><a href="/sdk/usage">SDK Usage</a></li>
</ul>
</BaseLayout>
8 changes: 8 additions & 0 deletions docs/src/pages/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Installation

Install dependencies at the repository root and run the docs package dev server.

```bash
pnpm install
pnpm --filter docs dev
```
Loading
Loading