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
73 changes: 73 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Deploy Docs

on:
pull_request:
branches:
- main
paths:
- ".github/workflows/deploy-docs.yml"
- "docs/**"
- "package.json"
- "pnpm-lock.yaml"
push:
branches:
- main
paths:
- ".github/workflows/deploy-docs.yml"
- "docs/**"
- "package.json"
- "pnpm-lock.yaml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: github-pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.12.4

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build docs
run: pnpm docs:build

- name: Upload Pages artifact
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist

deploy:
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ coverage
.DS_Store
.pnpm-store
*.tsbuildinfo
docs/.vitepress/cache
docs/.vitepress/dist
160 changes: 34 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,62 @@
# Project Standards

`project-standards` is a pnpm monorepo for managing repository standards in one place.
`project-standards` is a pnpm monorepo for rolling out shared repository standards with a small, reviewable diff.

It keeps the real configuration sources and the applying CLI together so that new and existing repositories can adopt the same baseline with a small, reviewable diff.
It combines shared config packages, repository templates, and a CLI so teams can adopt a common baseline without copying large configuration blocks into every repository.

## Documentation

Product documentation lives in `docs/` and is published as a VitePress site in English and Japanese.

- overview: `docs/index.md`
- concepts and safety model: `docs/concepts.md`
- CLI usage: `docs/cli.md`
- base preset details: `docs/templates/base.md`
- Japanese pages: `docs/ja/`

To run the docs locally:

```sh
pnpm docs:dev
```

## What This Repository Does

This repository is designed around three responsibilities:
This repository combines three responsibilities:

- shared configuration packages for tools that should be referenced instead of copied
- repository templates for files that must exist inside each target repository
- a Node.js CLI that can plan, diff, and apply those files safely
- a Node.js CLI that can `init`, `diff`, and `apply` those files safely

The current MVP focuses on a small base preset with:
## Current Base Preset

The first `base` preset includes:

- Renovate baseline config
- shared ESLint flat config with Stylistic rules
- Oxlint and Oxfmt starter files
- `AGENTS.md`, `CLAUDE.md`, Cursor rules, and Cursor commands

## Design Goals

- support both new repositories and existing repositories
- stay idempotent wherever possible
- make `diff` and `--dry-run` the default review path
- avoid clobbering repository-specific files by default
- keep preset and template expansion easy for future stacks
## Typical Workflow

## MVP Strategy
For an existing repository:

The initial implementation uses two file strategies:
1. Run `diff` to preview the proposed changes.
2. Review the plan and the generated diff.
3. Run `apply --dry-run` if you want an extra safety check.
4. Run `apply` once the diff looks correct.

- `create_if_missing`: create a file only when it does not already exist
- `replace_if_managed`: replace a file only when it contains the managed marker
For a new repository:

This keeps existing repositories safe while still allowing standards-managed files to be upgraded later.
1. Run `init` against an empty or intentionally prepared directory.
2. Review the created baseline files.
3. Add repository-specific setup on top of the generated scaffold.

## Workspace Layout

```text
.
├── docs
├── packages
│ ├── cli
│ ├── core
Expand All @@ -52,112 +69,3 @@ This keeps existing repositories safe while still allowing standards-managed fil
├── tsconfig.base.json
└── tsconfig.json
```

## Packages

### `packages/core`

Shared planner primitives:

- preset manifest loading
- file strategy evaluation
- diff rendering
- dry-run friendly apply flow

### `packages/cli`

The first CLI entrypoint. Current commands:

- `init`
- `apply`
- `diff`
- `doctor` (stub)
- `upgrade` (stub)

### `packages/eslint-config`

Shared ESLint flat config package for repositories that want a common lint baseline.

### `packages/renovate-config`

Shared Renovate config source for the base preset.

## Templates

`templates/base` is the first preset manifest plus concrete files to apply into target repositories.

Current managed targets include:

- `renovate.json`
- `eslint.config.mjs`
- `.oxlintrc.json`
- `.oxfmtrc.json`
- `AGENTS.md`
- `CLAUDE.md`
- `.cursor/rules/repository-standards.mdc`
- `.cursor/commands/quality-check.md`

Current template notes for the MVP:

- `eslint.config.mjs` assumes the target repository also installs `@jabelic/eslint-config`
- `AGENTS.md` and `CLAUDE.md` are managed base stubs; stack-specific composition is reserved for later

## CLI Usage

Install dependencies and build the workspace:

```sh
pnpm install
pnpm build
```

Show help:

```sh
node packages/cli/dist/index.js --help
```

Preview a repository diff:

```sh
node packages/cli/dist/index.js diff ../target-repository
```

Apply only quality-related files:

```sh
node packages/cli/dist/index.js apply ../target-repository --include quality --dry-run
```

Initialize a new repository directory:

```sh
node packages/cli/dist/index.js init ../new-repository --yes
```

## Current Scope

Implemented now:

- pnpm workspace and TypeScript project references
- base preset manifest and template files
- diffable plan/apply engine
- minimal shared config packages
- safe CLI for `init`, `apply`, and `diff`

Reserved for later:

- stack composition beyond the base preset
- package manager and dependency mutation inside target repositories
- richer merge strategies for partially managed files
- `doctor` checks for stack-specific quality tools
- `upgrade` flows for refreshing managed files and preset versions

## Future Extensions

This monorepo is intentionally shaped so more standards can be added incrementally:

- additional presets such as `react`, `vue`, or `library`
- doctor integrations for `react-doctor`, `vue-doctor`, `knip`, `secretlint`, `markdownlint`, `publint`, and `tsc --noEmit`
- more shared config packages and stack plugins
- generated PR-friendly change plans per repository
88 changes: 88 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { defineConfig } from "vitepress";

const repositoryName = process.env.GITHUB_REPOSITORY?.split("/")[1];
const base =
process.env.GITHUB_ACTIONS && repositoryName ? `/${repositoryName}/` : "/";

const englishNav = [
{ text: "Overview", link: "/" },
{ text: "Concepts", link: "/concepts" },
{ text: "CLI", link: "/cli" },
{ text: "Base Template", link: "/templates/base" },
];

const englishSidebar = [
{
text: "Guide",
items: [
{ text: "Overview", link: "/" },
{ text: "Concepts", link: "/concepts" },
{ text: "CLI", link: "/cli" },
{ text: "Base Template", link: "/templates/base" },
],
},
];

const japaneseNav = [
{ text: "概要", link: "/ja/" },
{ text: "基本概念", link: "/ja/concepts" },
{ text: "CLI", link: "/ja/cli" },
{ text: "Base Template", link: "/ja/templates/base" },
];

const japaneseSidebar = [
{
text: "ガイド",
items: [
{ text: "概要", link: "/ja/" },
{ text: "基本概念", link: "/ja/concepts" },
{ text: "CLI", link: "/ja/cli" },
{ text: "Base Template", link: "/ja/templates/base" },
],
},
];

export default defineConfig({
title: "Project Standards",
description: "Shared repository standards, templates, and CLI workflows.",
base,
lastUpdated: true,
themeConfig: {
socialLinks: [
{
icon: "github",
link: "https://github.com/Jabelic-Works/project-standards",
},
],
},
locales: {
root: {
label: "English",
lang: "en-US",
title: "Project Standards",
description: "Shared repository standards, templates, and CLI workflows.",
themeConfig: {
nav: englishNav,
sidebar: englishSidebar,
langMenuLabel: "Languages",
lastUpdatedText: "Last updated",
outlineTitle: "On this page",
returnToTopLabel: "Return to top",
},
},
ja: {
label: "日本語",
lang: "ja-JP",
title: "Project Standards",
description: "共有リポジトリ標準、テンプレート、CLI ワークフロー。",
themeConfig: {
nav: japaneseNav,
sidebar: japaneseSidebar,
langMenuLabel: "言語",
lastUpdatedText: "最終更新",
outlineTitle: "このページについて",
returnToTopLabel: "ページ上部へ戻る",
},
},
},
});
Loading
Loading