Skip to content

Commit a2e303c

Browse files
authored
Merge pull request #5 from hack-dance/sessions
Sessions
2 parents dba7750 + 451a3a3 commit a2e303c

235 files changed

Lines changed: 35782 additions & 26239 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.

‎.claude/CLAUDE.md‎

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Ultracite Code Standards
2+
3+
This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
4+
5+
## Quick Reference
6+
7+
- **Format code**: `bun x ultracite fix`
8+
- **Check for issues**: `bun x ultracite check`
9+
- **Diagnose setup**: `bun x ultracite doctor`
10+
11+
Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
12+
13+
---
14+
15+
## Core Principles
16+
17+
Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
18+
19+
### Type Safety & Explicitness
20+
21+
- Use explicit types for function parameters and return values when they enhance clarity
22+
- Prefer `unknown` over `any` when the type is genuinely unknown
23+
- Use const assertions (`as const`) for immutable values and literal types
24+
- Leverage TypeScript's type narrowing instead of type assertions
25+
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
26+
27+
### Modern JavaScript/TypeScript
28+
29+
- Use arrow functions for callbacks and short functions
30+
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
31+
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
32+
- Prefer template literals over string concatenation
33+
- Use destructuring for object and array assignments
34+
- Use `const` by default, `let` only when reassignment is needed, never `var`
35+
36+
### Async & Promises
37+
38+
- Always `await` promises in async functions - don't forget to use the return value
39+
- Use `async/await` syntax instead of promise chains for better readability
40+
- Handle errors appropriately in async code with try-catch blocks
41+
- Don't use async functions as Promise executors
42+
43+
### React & JSX
44+
45+
- Use function components over class components
46+
- Call hooks at the top level only, never conditionally
47+
- Specify all dependencies in hook dependency arrays correctly
48+
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
49+
- Nest children between opening and closing tags instead of passing as props
50+
- Don't define components inside other components
51+
- Use semantic HTML and ARIA attributes for accessibility:
52+
- Provide meaningful alt text for images
53+
- Use proper heading hierarchy
54+
- Add labels for form inputs
55+
- Include keyboard event handlers alongside mouse events
56+
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
57+
58+
### Error Handling & Debugging
59+
60+
- Remove `console.log`, `debugger`, and `alert` statements from production code
61+
- Throw `Error` objects with descriptive messages, not strings or other values
62+
- Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
63+
- Prefer early returns over nested conditionals for error cases
64+
65+
### Code Organization
66+
67+
- Keep functions focused and under reasonable cognitive complexity limits
68+
- Extract complex conditions into well-named boolean variables
69+
- Use early returns to reduce nesting
70+
- Prefer simple conditionals over nested ternary operators
71+
- Group related code together and separate concerns
72+
73+
### Security
74+
75+
- Add `rel="noopener"` when using `target="_blank"` on links
76+
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
77+
- Don't use `eval()` or assign directly to `document.cookie`
78+
- Validate and sanitize user input
79+
80+
### Performance
81+
82+
- Avoid spread syntax in accumulators within loops
83+
- Use top-level regex literals instead of creating them in loops
84+
- Prefer specific imports over namespace imports
85+
- Avoid barrel files (index files that re-export everything)
86+
- Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags
87+
88+
### Framework-Specific Guidance
89+
90+
**Next.js:**
91+
- Use Next.js `<Image>` component for images
92+
- Use `next/head` or App Router metadata API for head elements
93+
- Use Server Components for async data fetching instead of async Client Components
94+
95+
**React 19+:**
96+
- Use ref as a prop instead of `React.forwardRef`
97+
98+
**Solid/Svelte/Vue/Qwik:**
99+
- Use `class` and `for` attributes (not `className` or `htmlFor`)
100+
101+
---
102+
103+
## Testing
104+
105+
- Write assertions inside `it()` or `test()` blocks
106+
- Avoid done callbacks in async tests - use async/await instead
107+
- Don't use `.only` or `.skip` in committed code
108+
- Keep test suites reasonably flat - avoid excessive `describe` nesting
109+
110+
## When Biome Can't Help
111+
112+
Biome's linter will catch most issues automatically. Focus your attention on:
113+
114+
1. **Business logic correctness** - Biome can't validate your algorithms
115+
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
116+
3. **Architecture decisions** - Component structure, data flow, and API design
117+
4. **Edge cases** - Handle boundary conditions and error states
118+
5. **User experience** - Accessibility, performance, and usability considerations
119+
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
120+
121+
---
122+
123+
Most formatting and common issues are automatically fixed by Biome. Run `bun x ultracite fix` before committing to ensure compliance.

‎.claude/settings.json‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hooks": {
3+
"PostToolUse": [
4+
{
5+
"matcher": "Write|Edit",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "bun x ultracite fix"
10+
}
11+
]
12+
}
13+
]
14+
}
15+
}

‎.codex/skills/hack-tickets/SKILL.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: hack-tickets
33
description: >
44
Use the hack tickets extension (git-backed JSONL event log) to create/list/show/sync lightweight tickets.
55
Trigger when asked to track work items, decisions, or bugs inside a repo without external issue trackers.
6-
Prefer `hack x tickets ...` commands; store lives on branch `hack/tickets` by default.
6+
Prefer `hack x tickets ...` commands; store lives on hidden ref `refs/hack/tickets` by default.
77
---
88

99
# hack tickets
@@ -53,7 +53,8 @@ Tip: use `--body-stdin` for multi-line markdown.
5353

5454
- Tickets are derived from an append-only event log (JSONL).
5555
- Local state lives in `.hack/tickets/` (gitignored on the main branch).
56-
- Sync writes commits to a dedicated branch (`hack/tickets` by default) and pushes to your remote.
56+
- Sync writes commits to a dedicated ref (`refs/hack/tickets` hidden by default) and pushes to your remote.
57+
- Set `controlPlane.tickets.git.refMode` to `heads` to use a normal branch ref (and protect it if desired).
5758

5859
## Tips
5960

‎.cursor/hooks.json‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"version": 1,
3+
"hooks": {
4+
"afterFileEdit": [
5+
{
6+
"command": "bun x ultracite fix"
7+
}
8+
]
9+
}
10+
}

‎.github/workflows/release.yml‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
name: Release
22

3+
# Disabled: Running releases locally until Mac CI signing is set up
4+
# To re-enable: uncomment the push trigger below
35
on:
4-
push:
5-
tags:
6-
- "v*"
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: 'Release tag (e.g., v0.1.0)'
10+
required: true
11+
# push:
12+
# tags:
13+
# - "v*"
714

815
jobs:
916
create-release:

‎.husky/pre-commit‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
bun test
2+
3+
#!/bin/sh
4+
# Exit on any error
5+
set -e
6+
7+
# Check if there are any staged files
8+
if [ -z "$(git diff --cached --name-only)" ]; then
9+
echo "No staged files to format"
10+
exit 0
11+
fi
12+
13+
# Store the hash of staged changes to detect modifications
14+
STAGED_HASH=$(git diff --cached | sha256sum | cut -d' ' -f1)
15+
16+
# Save list of staged files (handling all file states)
17+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
18+
PARTIALLY_STAGED=$(git diff --name-only)
19+
20+
# Stash unstaged changes to preserve working directory
21+
# --keep-index keeps staged changes in working tree
22+
git stash push --quiet --keep-index --message "pre-commit-stash" || true
23+
STASHED=$?
24+
25+
# Run formatter on the staged files
26+
bun x ultracite fix
27+
FORMAT_EXIT_CODE=$?
28+
29+
# Restore working directory state
30+
if [ $STASHED -eq 0 ]; then
31+
# Re-stage the formatted files
32+
if [ -n "$STAGED_FILES" ]; then
33+
echo "$STAGED_FILES" | while IFS= read -r file; do
34+
if [ -f "$file" ]; then
35+
git add "$file"
36+
fi
37+
done
38+
fi
39+
40+
# Restore unstaged changes
41+
git stash pop --quiet || true
42+
43+
# Restore partial staging if files were partially staged
44+
if [ -n "$PARTIALLY_STAGED" ]; then
45+
for file in $PARTIALLY_STAGED; do
46+
if [ -f "$file" ] && echo "$STAGED_FILES" | grep -q "^$file$"; then
47+
# File was partially staged - need to unstage the unstaged parts
48+
git restore --staged "$file" 2>/dev/null || true
49+
git add -p "$file" < /dev/null 2>/dev/null || git add "$file"
50+
fi
51+
done
52+
fi
53+
else
54+
# No stash was created, just re-add the formatted files
55+
if [ -n "$STAGED_FILES" ]; then
56+
echo "$STAGED_FILES" | while IFS= read -r file; do
57+
if [ -f "$file" ]; then
58+
git add "$file"
59+
fi
60+
done
61+
fi
62+
fi
63+
64+
# Check if staged files actually changed
65+
NEW_STAGED_HASH=$(git diff --cached | sha256sum | cut -d' ' -f1)
66+
if [ "$STAGED_HASH" != "$NEW_STAGED_HASH" ]; then
67+
echo "✨ Files formatted by Ultracite"
68+
fi
69+
70+
exit $FORMAT_EXIT_CODE

‎.releaserc.json‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,26 @@
33
"tagFormat": "v${version}",
44
"plugins": [
55
["@semantic-release/commit-analyzer", { "preset": "conventionalcommits" }],
6-
["@semantic-release/release-notes-generator", { "preset": "conventionalcommits" }],
6+
[
7+
"@semantic-release/release-notes-generator",
8+
{ "preset": "conventionalcommits" }
9+
],
710
["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }],
811
[
912
"@semantic-release/exec",
10-
{ "prepareCmd": "bun run scripts/prepare-release.ts --version=${nextRelease.version}" }
13+
{
14+
"prepareCmd": "bun run scripts/prepare-release.ts --version=${nextRelease.version}"
15+
}
1116
],
1217
[
1318
"@semantic-release/git",
1419
{
15-
"assets": ["CHANGELOG.md", "package.json", "bun.lock", "apps/macos/Config/Base.xcconfig"],
20+
"assets": [
21+
"CHANGELOG.md",
22+
"package.json",
23+
"bun.lock",
24+
"apps/macos/Config/Base.xcconfig"
25+
],
1626
"message": "chore(release): ${nextRelease.version}\n\n${nextRelease.notes}"
1727
}
1828
]

‎.vscode/settings.json‎

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,54 @@
11
{
2-
"sweetpad.build.xcodeWorkspacePath": "apps/macos/HackDesktop.xcodeproj/project.xcworkspace"
3-
}
2+
"sweetpad.build.xcodeWorkspacePath": "apps/macos/HackDesktop.xcodeproj/project.xcworkspace",
3+
"editor.defaultFormatter": "esbenp.prettier-vscode",
4+
"typescript.tsdk": "node_modules/typescript/lib",
5+
"editor.formatOnSave": true,
6+
"editor.formatOnPaste": true,
7+
"emmet.showExpandedAbbreviation": "never",
8+
"[javascript]": {
9+
"editor.defaultFormatter": "biomejs.biome"
10+
},
11+
"[typescript]": {
12+
"editor.defaultFormatter": "biomejs.biome"
13+
},
14+
"[javascriptreact]": {
15+
"editor.defaultFormatter": "biomejs.biome"
16+
},
17+
"[typescriptreact]": {
18+
"editor.defaultFormatter": "biomejs.biome"
19+
},
20+
"[json]": {
21+
"editor.defaultFormatter": "biomejs.biome"
22+
},
23+
"[jsonc]": {
24+
"editor.defaultFormatter": "biomejs.biome"
25+
},
26+
"[html]": {
27+
"editor.defaultFormatter": "biomejs.biome"
28+
},
29+
"[vue]": {
30+
"editor.defaultFormatter": "biomejs.biome"
31+
},
32+
"[svelte]": {
33+
"editor.defaultFormatter": "biomejs.biome"
34+
},
35+
"[css]": {
36+
"editor.defaultFormatter": "biomejs.biome"
37+
},
38+
"[yaml]": {
39+
"editor.defaultFormatter": "biomejs.biome"
40+
},
41+
"[graphql]": {
42+
"editor.defaultFormatter": "biomejs.biome"
43+
},
44+
"[markdown]": {
45+
"editor.defaultFormatter": "biomejs.biome"
46+
},
47+
"[mdx]": {
48+
"editor.defaultFormatter": "biomejs.biome"
49+
},
50+
"editor.codeActionsOnSave": {
51+
"source.fixAll.biome": "explicit",
52+
"source.organizeImports.biome": "explicit"
53+
}
54+
}

0 commit comments

Comments
 (0)