Skip to content

Commit d7261a4

Browse files
authored
Merge pull request #2 from block/dx-setup
Add DX tooling — biome, lefthook, CI, and task runner
2 parents 7745b40 + bf96ebb commit d7261a4

49 files changed

Lines changed: 4298 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(git -C /Users/nahiyan/Development/ghost log --oneline)",
5+
"Bash(git:*)",
6+
"Bash(pnpm install:*)",
7+
"Bash(pnpm build:*)",
8+
"Bash(pnpm test:*)",
9+
"Bash(node:*)",
10+
"Bash(npx tsc:*)",
11+
"Bash(npx vitest:*)",
12+
"Bash(npx biome:*)",
13+
"Bash(just check:*)",
14+
"Bash(just build:*)",
15+
"Bash(npx lefthook:*)",
16+
"Bash(mv commit-msg.pre-entire commit-msg)",
17+
"Bash(mv post-commit.pre-entire post-commit)",
18+
"Bash(mv pre-push.pre-entire pre-push)",
19+
"Bash(mv prepare-commit-msg.pre-entire prepare-commit-msg)",
20+
"Bash(pnpm:*)"
21+
]
22+
}
23+
}

.github/workflows/ci.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint:
15+
name: Lint & Format
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 10
18+
steps:
19+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
20+
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
21+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
22+
with:
23+
node-version: 22
24+
cache: pnpm
25+
- run: pnpm install --frozen-lockfile
26+
- run: pnpm check
27+
28+
test:
29+
name: Unit Tests
30+
runs-on: ubuntu-latest
31+
timeout-minutes: 15
32+
steps:
33+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
34+
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
35+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
36+
with:
37+
node-version: 22
38+
cache: pnpm
39+
- run: pnpm install --frozen-lockfile
40+
- run: pnpm test

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
*.tsbuildinfo
4+
.DS_Store

.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
shamefully-hoist=false
2+
strict-peer-dependencies=true

biome.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.4.10/schema.json",
3+
"vcs": {
4+
"enabled": true,
5+
"clientKind": "git",
6+
"useIgnoreFile": true
7+
},
8+
"files": {
9+
"includes": ["**", "!**/test/fixtures"]
10+
},
11+
"formatter": {
12+
"enabled": true,
13+
"indentStyle": "space"
14+
},
15+
"linter": {
16+
"enabled": true,
17+
"rules": {
18+
"recommended": true,
19+
"suspicious": {
20+
"noExplicitAny": "warn",
21+
"noAssignInExpressions": "warn"
22+
}
23+
}
24+
},
25+
"javascript": {
26+
"formatter": {
27+
"quoteStyle": "double"
28+
}
29+
}
30+
}

justfile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Default recipe
2+
default:
3+
@just --list
4+
5+
# ── Dev Environment ──────────────────────────────────────────
6+
7+
# Install dependencies
8+
setup:
9+
pnpm install
10+
11+
# ── Build & Check ────────────────────────────────────────────
12+
13+
# Run all checks (lint, format, typecheck, file sizes)
14+
check:
15+
pnpm check
16+
17+
# Format code
18+
fmt:
19+
pnpm fmt
20+
21+
# Check formatting without modifying
22+
fmt-check:
23+
pnpm exec biome format .
24+
25+
# Build all packages
26+
build:
27+
pnpm build
28+
29+
# Full CI gate
30+
ci: check test build
31+
32+
# ── Test ─────────────────────────────────────────────────────
33+
34+
# Run unit tests
35+
test:
36+
pnpm test
37+
38+
# Run tests in watch mode
39+
test-watch:
40+
pnpm test:watch
41+
42+
# ── Utilities ────────────────────────────────────────────────
43+
44+
# Clean build artifacts
45+
clean:
46+
pnpm clean
47+
rm -rf node_modules packages/*/node_modules

lefthook.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pre-commit:
2+
commands:
3+
format:
4+
run: npx biome format --write . && npx biome check --fix . && git add -u
5+
check:
6+
run: just check
7+
8+
pre-push:
9+
parallel: true
10+
commands:
11+
check:
12+
run: just check
13+
test:
14+
run: just test
15+
build:
16+
run: just build

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "ghost",
3+
"private": true,
4+
"description": "Design drift detection system",
5+
"license": "Apache-2.0",
6+
"packageManager": "pnpm@10.12.4",
7+
"engines": {
8+
"node": ">=18.0.0"
9+
},
10+
"scripts": {
11+
"build": "tsc --build",
12+
"clean": "tsc --build --clean",
13+
"test": "vitest run",
14+
"test:watch": "vitest",
15+
"typecheck": "tsc --build",
16+
"check": "biome check . && pnpm typecheck && pnpm check:file-sizes",
17+
"check:file-sizes": "node scripts/check-file-sizes.mjs",
18+
"fmt": "biome format --write .",
19+
"lint": "biome lint ."
20+
},
21+
"devDependencies": {
22+
"@biomejs/biome": "^2.4.0",
23+
"@types/node": "^22.0.0",
24+
"lefthook": "^2.1.0",
25+
"typescript": "^5.7.0",
26+
"vitest": "^3.0.0"
27+
}
28+
}

packages/ghost-cli/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "ghost-cli",
3+
"version": "0.1.0",
4+
"description": "CLI for ghost design drift detection",
5+
"license": "Apache-2.0",
6+
"type": "module",
7+
"bin": {
8+
"ghost": "./dist/bin.js"
9+
},
10+
"files": [
11+
"dist"
12+
],
13+
"scripts": {
14+
"build": "tsc --build"
15+
},
16+
"dependencies": {
17+
"@ghost/core": "workspace:*",
18+
"citty": "^0.1.6"
19+
}
20+
}

packages/ghost-cli/src/bin.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env node
2+
3+
import {
4+
formatCLIReport,
5+
formatJSONReport,
6+
loadConfig,
7+
scan,
8+
} from "@ghost/core";
9+
import { defineCommand, runMain } from "citty";
10+
11+
const scanCommand = defineCommand({
12+
meta: {
13+
name: "scan",
14+
description: "Scan for design drift",
15+
},
16+
args: {
17+
config: {
18+
type: "string",
19+
description: "Path to ghost config file",
20+
alias: "c",
21+
},
22+
format: {
23+
type: "string",
24+
description: "Output format: cli or json",
25+
default: "cli",
26+
},
27+
"no-color": {
28+
type: "boolean",
29+
description: "Disable colored output",
30+
default: false,
31+
},
32+
},
33+
async run({ args }) {
34+
try {
35+
const config = await loadConfig(args.config);
36+
const report = await scan(config);
37+
38+
const output =
39+
args.format === "json"
40+
? formatJSONReport(report)
41+
: formatCLIReport(report);
42+
43+
process.stdout.write(output);
44+
process.exit(report.summary.errors > 0 ? 1 : 0);
45+
} catch (err) {
46+
console.error(
47+
`Error: ${err instanceof Error ? err.message : String(err)}`,
48+
);
49+
process.exit(2);
50+
}
51+
},
52+
});
53+
54+
const main = defineCommand({
55+
meta: {
56+
name: "ghost",
57+
version: "0.1.0",
58+
description: "Design drift detection",
59+
},
60+
subCommands: {
61+
scan: scanCommand,
62+
},
63+
});
64+
65+
runMain(main);

0 commit comments

Comments
 (0)