Skip to content

Commit 361be7c

Browse files
committed
feat: migrate homelab and scout-for-lol to monorepo
Homelab (Phase 4b): - 4 sub-packages: cdk8s, ha, deps-email, helm-types - Renamed @homelab/* to @shepherdjerred/homelab-* - Fixed tsconfig extends paths for new directory depth - helm-types uses standalone tsconfig (composite/noEmit conflict) - ha typecheck skipped (requires Home Assistant generated types) - Added @types/bun to sub-packages (workspace hoisting limitation) Scout (Phase 4c): - 6 sub-packages: backend, data, report, frontend, desktop, ui - Renamed @scout-for-lol/* to @shepherdjerred/scout-* - Updated 1164+ import references across all source files - Fixed tsconfig extends paths and type include paths - Moved satori patch to monorepo root - Removed node from ui tsconfig types - Prisma-dependent packages need prisma generate before typecheck CI infrastructure: - Dagger: installWorkspaceDeps mounts for all sub-packages - Dagger: compliance exemptions for homelab and scout - Dagger: helm-types added to PACKAGES for npm publishing - Dagger: quality ratchet now counts scout Rust allows - Pre-commit: typecheck blocks for all sub-packages - Pre-commit: scout Tauri Rust clippy/fmt checks - lint-staged: patterns for nested workspace packages - knip: entries for all sub-packages - release-please: helm-types publishing config - Quality baseline updated (eslint-disable: 129, ts: 64, rust: 7, prettier: 5) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 78a4800 commit 361be7c

3,038 files changed

Lines changed: 3899449 additions & 184 deletions

File tree

Some content is hidden

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

.dagger/src/index.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from "./birmel.js";
1010
import { reviewPr, handleInteractive } from "./code-review.js";
1111

12-
const PACKAGES = ["eslint-config", "dagger-utils", "bun-decompile", "webring", "astro-opengraph-images"] as const;
12+
const PACKAGES = ["eslint-config", "dagger-utils", "bun-decompile", "webring", "astro-opengraph-images", "homelab/helm-types"] as const;
1313
const REPO_URL = "shepherdjerred/monorepo";
1414

1515
const BUN_VERSION = "1.3.6";
@@ -95,6 +95,22 @@ function installWorkspaceDeps(source: Directory): Container {
9595
.withMountedFile("/workspace/packages/dpp/common/package.json", source.file("packages/dpp/common/package.json"))
9696
.withMountedFile("/workspace/packages/dpp/backend/package.json", source.file("packages/dpp/backend/package.json"))
9797
.withMountedFile("/workspace/packages/dpp/frontend/package.json", source.file("packages/dpp/frontend/package.json"))
98+
// Homelab sub-packages
99+
.withExec(["mkdir", "-p", "/workspace/packages/homelab"])
100+
.withMountedFile("/workspace/packages/homelab/package.json", source.file("packages/homelab/package.json"))
101+
.withMountedFile("/workspace/packages/homelab/cdk8s/package.json", source.file("packages/homelab/cdk8s/package.json"))
102+
.withMountedFile("/workspace/packages/homelab/ha/package.json", source.file("packages/homelab/ha/package.json"))
103+
.withMountedFile("/workspace/packages/homelab/deps-email/package.json", source.file("packages/homelab/deps-email/package.json"))
104+
.withMountedFile("/workspace/packages/homelab/helm-types/package.json", source.file("packages/homelab/helm-types/package.json"))
105+
// Scout sub-packages
106+
.withExec(["mkdir", "-p", "/workspace/packages/scout"])
107+
.withMountedFile("/workspace/packages/scout/package.json", source.file("packages/scout/package.json"))
108+
.withMountedFile("/workspace/packages/scout/backend/package.json", source.file("packages/scout/backend/package.json"))
109+
.withMountedFile("/workspace/packages/scout/data/package.json", source.file("packages/scout/data/package.json"))
110+
.withMountedFile("/workspace/packages/scout/report/package.json", source.file("packages/scout/report/package.json"))
111+
.withMountedFile("/workspace/packages/scout/frontend/package.json", source.file("packages/scout/frontend/package.json"))
112+
.withMountedFile("/workspace/packages/scout/desktop/package.json", source.file("packages/scout/desktop/package.json"))
113+
.withMountedFile("/workspace/packages/scout/ui/package.json", source.file("packages/scout/ui/package.json"))
98114
// Clauderon web packages (nested workspace with own lockfile)
99115
.withMountedFile("/workspace/packages/clauderon/web/package.json", source.file("packages/clauderon/web/package.json"))
100116
.withMountedFile("/workspace/packages/clauderon/web/bun.lock", source.file("packages/clauderon/web/bun.lock"))
@@ -125,6 +141,25 @@ function installWorkspaceDeps(source: Directory): Container {
125141
.withMountedDirectory("/workspace/packages/dpp/common", source.directory("packages/dpp/common"))
126142
.withMountedDirectory("/workspace/packages/dpp/backend", source.directory("packages/dpp/backend"))
127143
.withMountedDirectory("/workspace/packages/dpp/frontend", source.directory("packages/dpp/frontend"))
144+
// Homelab sub-packages
145+
.withMountedDirectory("/workspace/packages/homelab/cdk8s", source.directory("packages/homelab/cdk8s"))
146+
.withMountedDirectory("/workspace/packages/homelab/ha", source.directory("packages/homelab/ha"))
147+
.withMountedDirectory("/workspace/packages/homelab/deps-email", source.directory("packages/homelab/deps-email"))
148+
.withMountedDirectory("/workspace/packages/homelab/helm-types", source.directory("packages/homelab/helm-types"))
149+
.withMountedFile("/workspace/packages/homelab/tsconfig.base.json", source.file("packages/homelab/tsconfig.base.json"))
150+
.withMountedFile("/workspace/packages/homelab/eslint.config.ts", source.file("packages/homelab/eslint.config.ts"))
151+
.withMountedDirectory("/workspace/packages/homelab/eslint-rules", source.directory("packages/homelab/eslint-rules"))
152+
// Scout sub-packages
153+
.withMountedDirectory("/workspace/packages/scout/backend", source.directory("packages/scout/backend"))
154+
.withMountedDirectory("/workspace/packages/scout/data", source.directory("packages/scout/data"))
155+
.withMountedDirectory("/workspace/packages/scout/report", source.directory("packages/scout/report"))
156+
.withMountedDirectory("/workspace/packages/scout/frontend", source.directory("packages/scout/frontend"))
157+
.withMountedDirectory("/workspace/packages/scout/desktop", source.directory("packages/scout/desktop"))
158+
.withMountedDirectory("/workspace/packages/scout/ui", source.directory("packages/scout/ui"))
159+
.withMountedFile("/workspace/packages/scout/tsconfig.base.json", source.file("packages/scout/tsconfig.base.json"))
160+
.withMountedFile("/workspace/packages/scout/eslint.config.ts", source.file("packages/scout/eslint.config.ts"))
161+
.withMountedDirectory("/workspace/packages/scout/eslint-rules", source.directory("packages/scout/eslint-rules"))
162+
.withMountedDirectory("/workspace/packages/scout/types", source.directory("packages/scout/types"))
128163
// Clauderon web packages
129164
.withMountedDirectory("/workspace/packages/clauderon/web/shared", source.directory("packages/clauderon/web/shared"))
130165
.withMountedDirectory("/workspace/packages/clauderon/web/client", source.directory("packages/clauderon/web/client"))
@@ -408,7 +443,7 @@ for dir in /workspace/packages/*/; do
408443
PKG=$(basename "$dir")
409444
# Skip exempt packages
410445
case "$PKG" in
411-
resume|eslint-config|clauderon|claude-plugin|a2ui-poc|discord-claude|fonts|anki|castle-casters|macos-cross-compiler|dpp) continue ;;
446+
resume|eslint-config|clauderon|claude-plugin|a2ui-poc|discord-claude|fonts|anki|castle-casters|macos-cross-compiler|dpp|homelab|scout) continue ;;
412447
esac
413448
414449
echo "Checking $PKG..."
@@ -469,10 +504,10 @@ BASELINE_RUST=$(grep -o '"rust-allow": [0-9]*' /workspace/.quality-baseline.json
469504
BASELINE_PRETTIER=$(grep -o '"prettier-ignore": [0-9]*' /workspace/.quality-baseline.json | grep -o '[0-9]*')
470505
471506
# Count current suppressions (excluding node_modules, dist, archive)
472-
CURRENT_ESLINT=$(grep -r "eslint-disable" /workspace/packages/ /workspace/.dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | wc -l | tr -d ' ')
473-
CURRENT_TS=$(grep -r "@ts-expect-error\\|@ts-ignore\\|@ts-nocheck" /workspace/packages/ /workspace/.dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | wc -l | tr -d ' ')
474-
CURRENT_RUST=$(grep -r '#\\[allow(' /workspace/packages/clauderon/src/ --include="*.rs" 2>/dev/null | wc -l | tr -d ' ')
475-
CURRENT_PRETTIER=$(grep -r "prettier-ignore" /workspace/packages/ /workspace/.dagger/ --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.css" --include="*.json" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | wc -l | tr -d ' ')
507+
CURRENT_ESLINT=$(grep -r "eslint-disable" /workspace/packages/ /workspace/.dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | grep -v generated | wc -l | tr -d ' ')
508+
CURRENT_TS=$(grep -r "@ts-expect-error\\|@ts-ignore\\|@ts-nocheck" /workspace/packages/ /workspace/.dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | grep -v generated | wc -l | tr -d ' ')
509+
CURRENT_RUST=$(grep -r '#\\[allow(' /workspace/packages/clauderon/src/ /workspace/packages/scout/desktop/src-tauri/src/ --include="*.rs" 2>/dev/null | wc -l | tr -d ' ')
510+
CURRENT_PRETTIER=$(grep -r "prettier-ignore" /workspace/packages/ /workspace/.dagger/ --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.css" --include="*.json" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | grep -v generated | wc -l | tr -d ' ')
476511
477512
echo "Suppression counts (current / baseline):"
478513
echo " eslint-disable: $CURRENT_ESLINT / $BASELINE_ESLINT"

.husky/pre-commit

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ run_check() {
3838
}
3939

4040
# --- Rust checks (when .rs files or Cargo files change) ---
41-
if has_changes '\.rs$|Cargo\.(toml|lock)$'; then
41+
if has_changes '^packages/clauderon/.*\.(rs)$|^packages/clauderon/.*Cargo\.(toml|lock)$'; then
4242
# cargo clippy
4343
run_check "cargo clippy" sh -c 'cd packages/clauderon && cargo clippy --all-targets --all-features -- -D warnings'
4444

@@ -51,6 +51,11 @@ if has_changes '\.rs$|Cargo\.(toml|lock)$'; then
5151
fi
5252
fi
5353

54+
if has_changes '^packages/scout/desktop/src-tauri/.*\.(rs)$|^packages/scout/desktop/src-tauri/.*Cargo\.(toml|lock)$'; then
55+
run_check "scout cargo clippy" sh -c 'cd packages/scout/desktop/src-tauri && cargo clippy --all-targets --all-features -- -D warnings'
56+
run_check "scout cargo fmt" sh -c 'cd packages/scout/desktop/src-tauri && cargo fmt -- --check'
57+
fi
58+
5459
# --- Per-package TypeScript typecheck ---
5560
if has_changes '^packages/birmel/.*\.(ts|tsx)$'; then
5661
run_check "birmel typecheck" sh -c 'cd packages/birmel && bun run typecheck'
@@ -97,6 +102,14 @@ if has_changes '^packages/dpp/.*\.(ts|tsx)$'; then
97102
run_check "dpp typecheck" sh -c 'for pkg in common backend frontend; do bun run --filter="./packages/dpp/$pkg" typecheck; done'
98103
fi
99104

105+
if has_changes '^packages/homelab/.*\.(ts|tsx)$'; then
106+
run_check "homelab typecheck" sh -c 'for pkg in cdk8s ha deps-email helm-types; do bun run --filter="./packages/homelab/$pkg" typecheck; done'
107+
fi
108+
109+
if has_changes '^packages/scout/.*\.(ts|tsx)$'; then
110+
run_check "scout typecheck" sh -c 'for pkg in backend data report frontend desktop ui; do bun run --filter="./packages/scout/$pkg" typecheck; done'
111+
fi
112+
100113
# --- Clauderon web packages ---
101114
if has_changes '^packages/clauderon/web/shared/.*\.(ts|tsx)$'; then
102115
run_check "web/shared typecheck" sh -c 'cd packages/clauderon/web/shared && bun run typecheck'
@@ -141,7 +154,7 @@ if has_changes '^packages/.*/package\.json$|^packages/.*/eslint\.config\.|^packa
141154
for dir in packages/*/; do
142155
PKG=$(basename "$dir")
143156
case "$PKG" in
144-
resume|eslint-config|clauderon|claude-plugin|a2ui-poc|discord-claude|fonts|anki|castle-casters|macos-cross-compiler|dpp) continue ;;
157+
resume|eslint-config|clauderon|claude-plugin|a2ui-poc|discord-claude|fonts|anki|castle-casters|macos-cross-compiler|dpp|homelab|scout) continue ;;
145158
esac
146159
147160
# Check for eslint config
@@ -185,10 +198,10 @@ if has_changes '\.(ts|tsx|rs)$'; then
185198
BASELINE_RUST=$(grep -o "\"rust-allow\": [0-9]*" .quality-baseline.json | grep -o "[0-9]*")
186199
BASELINE_PRETTIER=$(grep -o "\"prettier-ignore\": [0-9]*" .quality-baseline.json | grep -o "[0-9]*")
187200
188-
CURRENT_ESLINT=$(grep -r "eslint-disable" packages/ .dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | wc -l | tr -d " ")
189-
CURRENT_TS=$(grep -r "@ts-expect-error\|@ts-ignore\|@ts-nocheck" packages/ .dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | wc -l | tr -d " ")
201+
CURRENT_ESLINT=$(grep -r "eslint-disable" packages/ .dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | grep -v generated | wc -l | tr -d " ")
202+
CURRENT_TS=$(grep -r "@ts-expect-error\|@ts-ignore\|@ts-nocheck" packages/ .dagger/ --include="*.ts" --include="*.tsx" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | grep -v generated | wc -l | tr -d " ")
190203
CURRENT_RUST=$(grep -r "#\[allow(" packages/clauderon/src/ --include="*.rs" 2>/dev/null | wc -l | tr -d " ")
191-
CURRENT_PRETTIER=$(grep -r "prettier-ignore" packages/ .dagger/ --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.css" --include="*.json" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | wc -l | tr -d " ")
204+
CURRENT_PRETTIER=$(grep -r "prettier-ignore" packages/ .dagger/ --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.css" --include="*.json" 2>/dev/null | grep -v node_modules | grep -v dist | grep -v archive | grep -v generated | wc -l | tr -d " ")
192205
193206
echo "Suppression counts (current / baseline):"
194207
echo " eslint-disable: $CURRENT_ESLINT / $BASELINE_ESLINT"

.lintstagedrc.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,54 @@ export default {
9393

9494
return commands;
9595
},
96+
// Homelab sub-packages
97+
"packages/homelab/*/src/**/*.{ts,tsx,js,jsx}": (filenames) => {
98+
const packageMap = new Map();
99+
100+
for (const filename of filenames) {
101+
const match = filename.match(/^packages\/homelab\/([^/]+)\//);
102+
if (match) {
103+
const packageName = match[1];
104+
if (!packageMap.has(packageName)) {
105+
packageMap.set(packageName, []);
106+
}
107+
packageMap.get(packageName).push(filename);
108+
}
109+
}
110+
111+
const commands = [];
112+
for (const [packageName, files] of packageMap) {
113+
const packageDir = `packages/homelab/${packageName}`;
114+
const relativeFiles = files.map(f => path.relative(packageDir, f)).join(" ");
115+
commands.push(`cd ${packageDir} && bunx eslint --fix ${relativeFiles}`);
116+
}
117+
118+
return commands;
119+
},
120+
// Scout sub-packages
121+
"packages/scout/*/src/**/*.{ts,tsx,js,jsx}": (filenames) => {
122+
const packageMap = new Map();
123+
124+
for (const filename of filenames) {
125+
const match = filename.match(/^packages\/scout\/([^/]+)\//);
126+
if (match) {
127+
const packageName = match[1];
128+
if (!packageMap.has(packageName)) {
129+
packageMap.set(packageName, []);
130+
}
131+
packageMap.get(packageName).push(filename);
132+
}
133+
}
134+
135+
const commands = [];
136+
for (const [packageName, files] of packageMap) {
137+
const packageDir = `packages/scout/${packageName}`;
138+
const relativeFiles = files.map(f => path.relative(packageDir, f)).join(" ");
139+
commands.push(`cd ${packageDir} && bunx eslint --fix ${relativeFiles}`);
140+
}
141+
142+
return commands;
143+
},
96144
// .dagger CI pipeline
97145
".dagger/src/**/*.ts": (filenames) => {
98146
const daggerDir = ".dagger";

.quality-baseline.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"eslint-disable": 33,
3-
"ts-suppressions": 49,
4-
"rust-allow": 52,
5-
"prettier-ignore": 3,
2+
"eslint-disable": 129,
3+
"ts-suppressions": 64,
4+
"rust-allow": 7,
5+
"prettier-ignore": 5,
66
"updated": "2026-02-10"
77
}

.release-please-manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
"packages/eslint-config": "0.2.0",
55
"packages/clauderon": "0.1.0",
66
"packages/webring": "1.5.0",
7-
"packages/astro-opengraph-images": "1.14.2"
7+
"packages/astro-opengraph-images": "1.14.2",
8+
"packages/homelab/helm-types": "1.1.0"
89
}

0 commit comments

Comments
 (0)