@outfitter/tooling 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.markdownlint-cli2.jsonc +55 -55
- package/README.md +7 -3
- package/biome.json +79 -72
- package/dist/cli/check.js +1 -1
- package/dist/cli/fix.js +1 -1
- package/dist/cli/index.js +232 -38
- package/dist/cli/init.js +1 -1
- package/dist/cli/pre-push.d.ts +34 -1
- package/dist/cli/pre-push.js +14 -2
- package/dist/cli/upgrade-bun.js +1 -1
- package/dist/registry/build.d.ts +6 -0
- package/dist/registry/build.js +31 -13
- package/dist/shared/@outfitter/{tooling-xx1146e3.js → tooling-0x5q15ec.js} +2 -1
- package/dist/shared/@outfitter/tooling-8sd32ts6.js +277 -0
- package/dist/shared/@outfitter/{tooling-s4eqq91d.js → tooling-9errkcvk.js} +2 -1
- package/dist/shared/@outfitter/{tooling-75j500dv.js → tooling-9yzd08v1.js} +10 -6
- package/dist/shared/@outfitter/{tooling-xaxdr9da.js → tooling-mxwc1n8w.js} +13 -3
- package/lefthook.yml +5 -7
- package/package.json +121 -114
- package/registry/registry.json +78 -76
- package/tsconfig.preset.bun.json +5 -5
- package/tsconfig.preset.json +33 -33
- package/dist/shared/@outfitter/tooling-qm7jeg0d.js +0 -99
package/registry/registry.json
CHANGED
|
@@ -1,78 +1,80 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"blocks": {
|
|
4
|
+
"claude": {
|
|
5
|
+
"name": "claude",
|
|
6
|
+
"description": "Claude Code settings and hooks for automated formatting",
|
|
7
|
+
"files": [
|
|
8
|
+
{
|
|
9
|
+
"path": ".claude/settings.json",
|
|
10
|
+
"content": "{\n \"hooks\": {\n \"SessionStart\": [\n {\n \"matcher\": \"*\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"bash \\\"$CLAUDE_PROJECT_DIR/scripts/bootstrap.sh\\\"\",\n \"timeout\": 120\n }\n ]\n }\n ],\n \"Stop\": [\n {\n \"matcher\": \"*\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"bash \\\"$CLAUDE_PROJECT_DIR/.claude/hooks/format-code-on-stop.sh\\\"\",\n \"timeout\": 60\n }\n ]\n }\n ]\n },\n \"enabledPlugins\": {\n \"outfitter@outfitter\": true,\n \"team@outfitter\": true,\n \"kit@outfitter\": true\n },\n \"extraKnownMarketplaces\": {\n \"outfitter\": {\n \"source\": {\n \"source\": \"github\",\n \"repo\": \"outfitter/outfitter\"\n }\n }\n }\n}\n"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"path": ".claude/hooks/format-code-on-stop.sh",
|
|
14
|
+
"content": "#!/usr/bin/env bash\n# format-code-on-stop.sh\n# Formats code and markdown files changed during the session.\n# Designed for Claude Code Stop hook - runs after agent completes work.\n\nset -euo pipefail\n\n# -----------------------------------------------------------------------------\n# Configuration\n# -----------------------------------------------------------------------------\n\n# File patterns for each formatter\nCODE_PATTERNS=\"*.js *.jsx *.ts *.tsx *.json *.jsonc *.css\"\nMARKDOWN_PATTERNS=\"*.md\"\n\n# -----------------------------------------------------------------------------\n# Helpers\n# -----------------------------------------------------------------------------\n\nlog() {\n echo \"[format] $*\"\n}\n\nwarn() {\n echo \"[format] WARNING: $*\" >&2\n}\n\nhint() {\n echo \"[format] HINT: $*\" >&2\n}\n\n# Check if a command exists\nhas_cmd() {\n command -v \"$1\" &>/dev/null\n}\n\n# Get changed files (staged + unstaged, excluding deleted)\nget_changed_files() {\n local patterns=(\"$@\")\n local files=()\n\n # Get both staged and unstaged changes, excluding deleted files\n for pattern in \"${patterns[@]}\"; do\n while IFS= read -r file; do\n [[ -n \"$file\" && -f \"$file\" ]] && files+=(\"$file\")\n done < <(git diff --name-only --diff-filter=d HEAD -- \"$pattern\" 2>/dev/null || true)\n\n # Also check untracked files matching pattern\n while IFS= read -r file; do\n [[ -n \"$file\" && -f \"$file\" ]] && files+=(\"$file\")\n done < <(git ls-files --others --exclude-standard -- \"$pattern\" 2>/dev/null || true)\n done\n\n # Deduplicate\n printf '%s\\n' \"${files[@]}\" | sort -u\n}\n\n# -----------------------------------------------------------------------------\n# Formatters\n# -----------------------------------------------------------------------------\n\nformat_code() {\n local files=()\n\n # Collect changed code files\n while IFS= read -r file; do\n [[ -n \"$file\" ]] && files+=(\"$file\")\n done < <(get_changed_files $CODE_PATTERNS)\n\n if [[ ${#files[@]} -eq 0 ]]; then\n log \"No code files to format\"\n return 0\n fi\n\n log \"Formatting ${#files[@]} code file(s)...\"\n\n # Check for bun\n if ! has_cmd bun; then\n warn \"bun not found - skipping code formatting\"\n hint \"Install bun: curl -fsSL https://bun.sh/install | bash\"\n return 0\n fi\n\n # Check for ultracite (via bun x)\n if ! bun x ultracite --version &>/dev/null; then\n warn \"ultracite not available - skipping code formatting\"\n hint \"Install ultracite: bun add -d ultracite\"\n return 0\n fi\n\n # Run ultracite fix on changed files\n if bun x ultracite fix \"${files[@]}\" 2>/dev/null; then\n log \"Code formatting complete\"\n else\n warn \"ultracite encountered errors (non-fatal)\"\n fi\n}\n\nformat_markdown() {\n local files=()\n\n # Collect changed markdown files\n while IFS= read -r file; do\n [[ -n \"$file\" ]] && files+=(\"$file\")\n done < <(get_changed_files $MARKDOWN_PATTERNS)\n\n if [[ ${#files[@]} -eq 0 ]]; then\n log \"No markdown files to format\"\n return 0\n fi\n\n log \"Formatting ${#files[@]} markdown file(s)...\"\n\n # Check for markdownlint-cli2\n if has_cmd markdownlint-cli2; then\n if markdownlint-cli2 --fix \"${files[@]}\" 2>/dev/null; then\n log \"Markdown formatting complete\"\n else\n warn \"markdownlint-cli2 encountered errors (non-fatal)\"\n fi\n return 0\n fi\n\n # Try via bunx/npx\n if has_cmd bun && bun x markdownlint-cli2 --help &>/dev/null; then\n if bun x markdownlint-cli2 --fix \"${files[@]}\" 2>/dev/null; then\n log \"Markdown formatting complete\"\n else\n warn \"markdownlint-cli2 encountered errors (non-fatal)\"\n fi\n return 0\n fi\n\n if has_cmd npx && npx markdownlint-cli2 --help &>/dev/null; then\n if npx markdownlint-cli2 --fix \"${files[@]}\" 2>/dev/null; then\n log \"Markdown formatting complete\"\n else\n warn \"markdownlint-cli2 encountered errors (non-fatal)\"\n fi\n return 0\n fi\n\n warn \"markdownlint-cli2 not found - skipping markdown formatting\"\n hint \"Install: bun add -g markdownlint-cli2 OR npm install -g markdownlint-cli2\"\n}\n\n# -----------------------------------------------------------------------------\n# Main\n# -----------------------------------------------------------------------------\n\nmain() {\n # Ensure we're in a git repo\n if ! git rev-parse --is-inside-work-tree &>/dev/null; then\n warn \"Not in a git repository - skipping formatting\"\n exit 0\n fi\n\n # Change to repo root\n cd \"$(git rev-parse --show-toplevel)\"\n\n log \"Checking for files to format...\"\n\n format_code\n format_markdown\n\n log \"Done\"\n}\n\nmain \"$@\"\n",
|
|
15
|
+
"executable": true
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"biome": {
|
|
20
|
+
"name": "biome",
|
|
21
|
+
"description": "Biome linter/formatter configuration via Ultracite",
|
|
22
|
+
"files": [
|
|
23
|
+
{
|
|
24
|
+
"path": "biome.json",
|
|
25
|
+
"content": "{\n\t\"$schema\": \"https://biomejs.dev/schemas/2.3.12/schema.json\",\n\t\"root\": false,\n\t\"javascript\": {\n\t\t\"globals\": [\"Bun\"]\n\t},\n\t\"linter\": {\n\t\t\"rules\": {\n\t\t\t\"complexity\": {\n\t\t\t\t\"useLiteralKeys\": \"off\",\n\t\t\t\t\"noVoid\": \"off\",\n\t\t\t\t\"noExcessiveCognitiveComplexity\": \"off\"\n\t\t\t},\n\t\t\t\"performance\": {\n\t\t\t\t\"useTopLevelRegex\": \"off\"\n\t\t\t},\n\t\t\t\"style\": {\n\t\t\t\t\"useBlockStatements\": \"off\"\n\t\t\t},\n\t\t\t\"suspicious\": {\n\t\t\t\t\"noConsole\": \"error\"\n\t\t\t}\n\t\t}\n\t},\n\t\"vcs\": {\n\t\t\"enabled\": true,\n\t\t\"clientKind\": \"git\",\n\t\t\"useIgnoreFile\": true\n\t},\n\t\"files\": {\n\t\t\"ignoreUnknown\": true,\n\t\t\"includes\": [\n\t\t\t\"**\",\n\t\t\t\"!**/node_modules\",\n\t\t\t\"!**/dist\",\n\t\t\t\"!**/.turbo\",\n\t\t\t\"!**/*.gen.ts\",\n\t\t\t\"!registry/registry.json\"\n\t\t]\n\t},\n\t\"overrides\": [\n\t\t{\n\t\t\t\"includes\": [\n\t\t\t\t\"packages/*/src/index.ts\",\n\t\t\t\t\"apps/*/src/index.ts\",\n\t\t\t\t\"**/index.ts\"\n\t\t\t],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"performance\": {\n\t\t\t\t\t\t\"noBarrelFile\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"includes\": [\"**/*.test.ts\", \"**/__tests__/**/*\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"suspicious\": {\n\t\t\t\t\t\t\"useAwait\": \"off\",\n\t\t\t\t\t\t\"noConsole\": \"off\"\n\t\t\t\t\t},\n\t\t\t\t\t\"performance\": {\n\t\t\t\t\t\t\"noDelete\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"includes\": [\"apps/**/*.ts\", \"scripts/**/*.ts\", \"**/scripts/**/*.ts\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"suspicious\": {\n\t\t\t\t\t\t\"noConsole\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"ultracite": "^7.1.1"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"lefthook": {
|
|
33
|
+
"name": "lefthook",
|
|
34
|
+
"description": "Git hooks via Lefthook for pre-commit and pre-push",
|
|
35
|
+
"files": [
|
|
36
|
+
{
|
|
37
|
+
"path": ".lefthook.yml",
|
|
38
|
+
"content": "# Lefthook configuration preset for Outfitter projects\n# https://github.com/evilmartians/lefthook\n#\n# Usage: In your project's .lefthook.yml, add:\n# extends:\n# - node_modules/@outfitter/tooling/lefthook.yml\n\npre-commit:\n parallel: true\n commands:\n ultracite:\n glob: \"*.{js,jsx,ts,tsx,json,jsonc,css}\"\n run: bun x ultracite fix {staged_files}\n stage_fixed: true\n\n typecheck:\n glob: \"*.{ts,tsx}\"\n run: bun run typecheck\n\npre-push:\n parallel: false\n commands:\n verify:\n # TDD-aware: skips strict verification on explicit RED phase branches\n # (*-tests, */tests, *_tests). Otherwise runs verify:ci (or a strict\n # fallback: typecheck/check-or-lint/build/test).\n # Requires: @outfitter/tooling as a dev dependency.\n run: bunx @outfitter/tooling pre-push\n"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@outfitter/tooling": "^0.2.1",
|
|
43
|
+
"lefthook": "^2.0.16",
|
|
44
|
+
"ultracite": "^7.1.1"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"markdownlint": {
|
|
48
|
+
"name": "markdownlint",
|
|
49
|
+
"description": "Markdown linting configuration via markdownlint-cli2",
|
|
50
|
+
"files": [
|
|
51
|
+
{
|
|
52
|
+
"path": ".markdownlint-cli2.jsonc",
|
|
53
|
+
"content": "{\n\t// Outfitter markdownlint preset\n\t// https://github.com/DavidAnson/markdownlint\n\n\t\"config\": {\n\t\t// Headings\n\t\t\"MD003\": { \"style\": \"atx\" }, // ATX-style headings (# Heading)\n\t\t\"MD022\": { \"lines_above\": 1, \"lines_below\": 1 }, // Blank lines around headings\n\t\t\"MD024\": { \"siblings_only\": true }, // Allow duplicate headings in different sections\n\t\t\"MD041\": false, // First line doesn't need to be h1 (frontmatter, etc.)\n\n\t\t// Line length - disabled for prose flexibility\n\t\t\"MD013\": false,\n\n\t\t// Lists\n\t\t\"MD004\": { \"style\": \"dash\" }, // Unordered list style: dash (-)\n\t\t\"MD007\": { \"indent\": 2 }, // List indentation: 2 spaces\n\t\t\"MD032\": true, // Blank lines around lists\n\n\t\t// Code blocks\n\t\t\"MD040\": true, // Fenced code blocks should have a language\n\t\t\"MD046\": { \"style\": \"fenced\" }, // Code block style: fenced (```)\n\t\t\"MD048\": { \"style\": \"backtick\" }, // Code fence style: backticks\n\n\t\t// Links\n\t\t\"MD034\": true, // No bare URLs (use <url> or [text](url))\n\n\t\t// Whitespace\n\t\t\"MD009\": { \"br_spaces\": 2 }, // Allow 2 trailing spaces for <br>\n\t\t\"MD010\": { \"spaces_per_tab\": 2 }, // Tabs to spaces\n\t\t\"MD012\": { \"maximum\": 1 }, // Max 1 consecutive blank line\n\t\t\"MD047\": true, // Files should end with newline\n\n\t\t// HTML - allow for GitHub-specific elements\n\t\t\"MD033\": {\n\t\t\t\"allowed_elements\": [\n\t\t\t\t\"details\",\n\t\t\t\t\"summary\",\n\t\t\t\t\"kbd\",\n\t\t\t\t\"br\",\n\t\t\t\t\"sup\",\n\t\t\t\t\"sub\",\n\t\t\t\t\"img\",\n\t\t\t\t\"picture\",\n\t\t\t\t\"source\",\n\t\t\t\t\"a\"\n\t\t\t]\n\t\t},\n\n\t\t// Emphasis\n\t\t\"MD049\": { \"style\": \"asterisk\" }, // Emphasis style: *italic*\n\t\t\"MD050\": { \"style\": \"asterisk\" } // Strong style: **bold**\n\t},\n\n\t// Ignore patterns\n\t\"ignores\": [\n\t\t\"node_modules/**\",\n\t\t\"**/node_modules/**\",\n\t\t\"dist/**\",\n\t\t\"**/dist/**\",\n\t\t\".turbo/**\",\n\t\t\"**/.turbo/**\",\n\t\t\"CHANGELOG.md\",\n\t\t\"**/CHANGELOG.md\"\n\t]\n}\n"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"bootstrap": {
|
|
58
|
+
"name": "bootstrap",
|
|
59
|
+
"description": "Project bootstrap script for installing tools and dependencies",
|
|
60
|
+
"files": [
|
|
61
|
+
{
|
|
62
|
+
"path": "scripts/bootstrap.sh",
|
|
63
|
+
"content": "#!/usr/bin/env bash\n#\n# bootstrap.sh — Get this repo from clone to runnable\n#\n# Usage: ./scripts/bootstrap.sh [--force]\n#\n# By default, exits immediately if all tools and deps are present.\n# Use --force to run full bootstrap regardless.\n#\n\nset -euo pipefail\n\n# -----------------------------------------------------------------------------\n# Fast path — exit immediately if all tools and deps are present\n# -----------------------------------------------------------------------------\nif [[ \"${1:-}\" != \"--force\" ]]; then\n all_present=true\n command -v bun &>/dev/null || all_present=false\n command -v gh &>/dev/null || all_present=false\n command -v gt &>/dev/null || all_present=false\n command -v markdownlint-cli2 &>/dev/null || all_present=false\n [[ -d \"node_modules\" ]] || all_present=false\n\n if $all_present; then\n exit 0 # All good, nothing to do\n fi\nfi\n\n# Strip --force if present\n[[ \"${1:-}\" == \"--force\" ]] && shift\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[0;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m' # No Color\n\ninfo() { echo -e \"${BLUE}▸${NC} $1\"; }\nsuccess() { echo -e \"${GREEN}✓${NC} $1\"; }\nwarn() { echo -e \"${YELLOW}!${NC} $1\"; }\nerror() { echo -e \"${RED}✗${NC} $1\" >&2; }\n\n# Check if command exists\nhas() { command -v \"$1\" &>/dev/null; }\n\n# Detect OS\nOS=\"$(uname -s)\"\ncase \"$OS\" in\n Darwin) IS_MACOS=true ;;\n Linux) IS_MACOS=false ;;\n *) error \"Unsupported OS: $OS\"; exit 1 ;;\nesac\n\n# -----------------------------------------------------------------------------\n# Homebrew (macOS only)\n# -----------------------------------------------------------------------------\ninstall_homebrew() {\n if $IS_MACOS && ! has brew; then\n info \"Installing Homebrew...\"\n /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n success \"Homebrew installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Bun\n# -----------------------------------------------------------------------------\ninstall_bun() {\n if has bun; then\n success \"Bun already installed ($(bun --version))\"\n else\n info \"Installing Bun...\"\n curl -fsSL https://bun.sh/install | bash\n # Source the updated profile\n export BUN_INSTALL=\"$HOME/.bun\"\n export PATH=\"$BUN_INSTALL/bin:$PATH\"\n success \"Bun installed ($(bun --version))\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# GitHub CLI (gh)\n# -----------------------------------------------------------------------------\ninstall_gh() {\n if has gh; then\n success \"GitHub CLI already installed ($(gh --version | head -1))\"\n else\n info \"Installing GitHub CLI...\"\n if $IS_MACOS; then\n brew install gh\n else\n # Linux: use official apt repo\n curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg\n echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null\n sudo apt update && sudo apt install gh -y\n fi\n success \"GitHub CLI installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Graphite CLI (gt)\n# -----------------------------------------------------------------------------\ninstall_graphite() {\n if has gt; then\n success \"Graphite CLI already installed ($(gt --version 2>/dev/null || echo 'unknown'))\"\n else\n info \"Installing Graphite CLI...\"\n if $IS_MACOS && has brew; then\n brew install withgraphite/tap/graphite\n else\n bun install -g @withgraphite/graphite-cli\n fi\n success \"Graphite CLI installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# markdownlint-cli2\n# -----------------------------------------------------------------------------\ninstall_markdownlint() {\n if has markdownlint-cli2; then\n success \"markdownlint-cli2 already installed\"\n else\n info \"Installing markdownlint-cli2...\"\n bun install -g markdownlint-cli2\n success \"markdownlint-cli2 installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Auth checks\n# -----------------------------------------------------------------------------\ncheck_auth() {\n echo \"\"\n info \"Checking authentication...\"\n\n # GitHub CLI\n if [[ -n \"${GH_TOKEN:-}\" ]] || [[ -n \"${GITHUB_TOKEN:-}\" ]]; then\n success \"GitHub CLI token found in environment\"\n elif gh auth status &>/dev/null; then\n success \"GitHub CLI already authenticated\"\n else\n echo \" GitHub CLI not authenticated. Run 'gh auth login' or set GH_TOKEN\"\n fi\n\n # Graphite CLI\n if [[ -n \"${GT_AUTH_TOKEN:-}\" ]]; then\n info \"Authenticating Graphite CLI...\"\n gt auth --token \"$GT_AUTH_TOKEN\"\n success \"Graphite CLI authenticated\"\n elif gt auth status &>/dev/null 2>&1; then\n success \"Graphite CLI already authenticated\"\n else\n echo \" Graphite CLI not authenticated. Run 'gt auth' or set GT_AUTH_TOKEN\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Project dependencies\n# -----------------------------------------------------------------------------\ninstall_deps() {\n info \"Installing project dependencies...\"\n bun install\n success \"Dependencies installed\"\n}\n\n# -----------------------------------------------------------------------------\n# Main\n# -----------------------------------------------------------------------------\nmain() {\n echo \"\"\n echo -e \"${BLUE}Outfitter Kit Bootstrap${NC}\"\n echo \"────────────────────────\"\n echo \"\"\n\n # Prerequisites\n if $IS_MACOS; then\n install_homebrew\n fi\n\n # Core tools\n install_bun\n install_gh\n install_graphite\n install_markdownlint\n\n # Auth status\n check_auth\n\n echo \"\"\n\n # Project setup\n install_deps\n\n echo \"\"\n echo -e \"${GREEN}Bootstrap complete!${NC}\"\n echo \"\"\n echo \"Next steps:\"\n echo \" bun run build # Build all packages\"\n echo \" bun run test # Run tests\"\n echo \"\"\n}\n\nmain \"$@\"\n",
|
|
64
|
+
"executable": true
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"scaffolding": {
|
|
69
|
+
"name": "scaffolding",
|
|
70
|
+
"description": "Full starter kit: Claude settings, Biome, Lefthook, markdownlint, and bootstrap script",
|
|
71
|
+
"extends": [
|
|
72
|
+
"claude",
|
|
73
|
+
"biome",
|
|
74
|
+
"lefthook",
|
|
75
|
+
"markdownlint",
|
|
76
|
+
"bootstrap"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
78
80
|
}
|
package/tsconfig.preset.bun.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "./tsconfig.preset.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"types": ["@types/bun"]
|
|
6
|
+
}
|
|
7
7
|
}
|
package/tsconfig.preset.json
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"lib": ["ESNext"],
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitAny": true,
|
|
11
|
+
"strictNullChecks": true,
|
|
12
|
+
"strictFunctionTypes": true,
|
|
13
|
+
"strictBindCallApply": true,
|
|
14
|
+
"strictPropertyInitialization": true,
|
|
15
|
+
"noImplicitThis": true,
|
|
16
|
+
"useUnknownInCatchVariables": true,
|
|
17
|
+
"alwaysStrict": true,
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
"noUncheckedIndexedAccess": true,
|
|
20
|
+
"noImplicitReturns": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUnusedLocals": true,
|
|
23
|
+
"noUnusedParameters": true,
|
|
24
|
+
"exactOptionalPropertyTypes": true,
|
|
25
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
"declaration": true,
|
|
28
|
+
"declarationMap": true,
|
|
29
|
+
"sourceMap": true,
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
"esModuleInterop": true,
|
|
32
|
+
"forceConsistentCasingInFileNames": true,
|
|
33
|
+
"isolatedModules": true,
|
|
34
|
+
"verbatimModuleSyntax": true,
|
|
35
|
+
"skipLibCheck": true,
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
"resolveJsonModule": true,
|
|
38
|
+
"allowSyntheticDefaultImports": true
|
|
39
|
+
}
|
|
40
40
|
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/cli/pre-push.ts
|
|
3
|
-
var COLORS = {
|
|
4
|
-
reset: "\x1B[0m",
|
|
5
|
-
red: "\x1B[31m",
|
|
6
|
-
green: "\x1B[32m",
|
|
7
|
-
yellow: "\x1B[33m",
|
|
8
|
-
blue: "\x1B[34m"
|
|
9
|
-
};
|
|
10
|
-
function log(msg) {
|
|
11
|
-
console.log(msg);
|
|
12
|
-
}
|
|
13
|
-
function getCurrentBranch() {
|
|
14
|
-
const result = Bun.spawnSync(["git", "rev-parse", "--abbrev-ref", "HEAD"]);
|
|
15
|
-
return result.stdout.toString().trim();
|
|
16
|
-
}
|
|
17
|
-
function isRedPhaseBranch(branch) {
|
|
18
|
-
return branch.endsWith("-tests") || branch.endsWith("/tests") || branch.endsWith("_tests");
|
|
19
|
-
}
|
|
20
|
-
function isScaffoldBranch(branch) {
|
|
21
|
-
return branch.endsWith("-scaffold") || branch.endsWith("/scaffold") || branch.endsWith("_scaffold");
|
|
22
|
-
}
|
|
23
|
-
function hasRedPhaseBranchInContext(currentBranch) {
|
|
24
|
-
let branches = [];
|
|
25
|
-
try {
|
|
26
|
-
const gtResult = Bun.spawnSync(["gt", "ls"], { stderr: "pipe" });
|
|
27
|
-
if (gtResult.exitCode === 0) {
|
|
28
|
-
branches = gtResult.stdout.toString().split(`
|
|
29
|
-
`).map((line) => line.replace(/^[\u2502\u251C\u2514\u2500\u25C9\u25EF ]*/g, "").replace(/ \(.*/, "")).filter(Boolean);
|
|
30
|
-
}
|
|
31
|
-
} catch {}
|
|
32
|
-
if (branches.length === 0) {
|
|
33
|
-
const gitResult = Bun.spawnSync([
|
|
34
|
-
"git",
|
|
35
|
-
"branch",
|
|
36
|
-
"--list",
|
|
37
|
-
"cli/*",
|
|
38
|
-
"types/*",
|
|
39
|
-
"contracts/*"
|
|
40
|
-
]);
|
|
41
|
-
branches = gitResult.stdout.toString().split(`
|
|
42
|
-
`).map((line) => line.replace(/^[* ]+/, "")).filter(Boolean);
|
|
43
|
-
}
|
|
44
|
-
for (const branch of branches) {
|
|
45
|
-
if (branch === currentBranch)
|
|
46
|
-
continue;
|
|
47
|
-
if (isRedPhaseBranch(branch))
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
function runTests() {
|
|
53
|
-
log("");
|
|
54
|
-
const result = Bun.spawnSync(["bun", "run", "test"], {
|
|
55
|
-
stdio: ["inherit", "inherit", "inherit"]
|
|
56
|
-
});
|
|
57
|
-
return result.exitCode === 0;
|
|
58
|
-
}
|
|
59
|
-
async function runPrePush(options = {}) {
|
|
60
|
-
log(`${COLORS.blue}Pre-push test${COLORS.reset} (TDD-aware)`);
|
|
61
|
-
log("");
|
|
62
|
-
const branch = getCurrentBranch();
|
|
63
|
-
if (isRedPhaseBranch(branch)) {
|
|
64
|
-
log(`${COLORS.yellow}TDD RED phase${COLORS.reset} detected: ${COLORS.blue}${branch}${COLORS.reset}`);
|
|
65
|
-
log(`${COLORS.yellow}Skipping test execution${COLORS.reset} - tests are expected to fail in RED phase`);
|
|
66
|
-
log("");
|
|
67
|
-
log("Remember: GREEN phase (implementation) must make these tests pass!");
|
|
68
|
-
process.exit(0);
|
|
69
|
-
}
|
|
70
|
-
if (isScaffoldBranch(branch)) {
|
|
71
|
-
if (hasRedPhaseBranchInContext(branch)) {
|
|
72
|
-
log(`${COLORS.yellow}Scaffold branch${COLORS.reset} with RED phase branch in context: ${COLORS.blue}${branch}${COLORS.reset}`);
|
|
73
|
-
log(`${COLORS.yellow}Skipping test execution${COLORS.reset} - RED phase tests expected to fail`);
|
|
74
|
-
log("");
|
|
75
|
-
process.exit(0);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (options.force) {
|
|
79
|
-
log(`${COLORS.yellow}Force flag set${COLORS.reset} - skipping tests`);
|
|
80
|
-
process.exit(0);
|
|
81
|
-
}
|
|
82
|
-
log(`Running tests for branch: ${COLORS.blue}${branch}${COLORS.reset}`);
|
|
83
|
-
if (runTests()) {
|
|
84
|
-
log("");
|
|
85
|
-
log(`${COLORS.green}All tests passed${COLORS.reset}`);
|
|
86
|
-
process.exit(0);
|
|
87
|
-
} else {
|
|
88
|
-
log("");
|
|
89
|
-
log(`${COLORS.red}Tests failed${COLORS.reset}`);
|
|
90
|
-
log("");
|
|
91
|
-
log("If this is intentional TDD RED phase work, name your branch:");
|
|
92
|
-
log(" - feature-tests");
|
|
93
|
-
log(" - feature/tests");
|
|
94
|
-
log(" - feature_tests");
|
|
95
|
-
process.exit(1);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export { runPrePush };
|