Skip to content

Commit 29d63dc

Browse files
CopilotRichDom2185
andcommitted
Create comprehensive .github/copilot-instructions.md with validated commands and timing
Co-authored-by: RichDom2185 <[email protected]>
1 parent b0697a6 commit 29d63dc

File tree

3 files changed

+424
-6
lines changed

3 files changed

+424
-6
lines changed

.github/copilot-instructions.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Source Academy Frontend
2+
3+
The Source Academy Frontend is a React.js TypeScript web application for an immersive online programming education platform. It features a coding playground, SICP JS textbook integration, assessment system, grading tools, collaborative sessions, and game elements. The application is built with React 18, Redux, TypeScript, and modern tooling.
4+
5+
**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**
6+
7+
## Working Effectively
8+
9+
### Environment Setup
10+
- Node.js version: 20.9.0+ (as specified in `.node-version`)
11+
- Package manager: Yarn 4.6.0 (managed via corepack)
12+
- Enable corepack: `corepack enable`
13+
14+
### Bootstrap and Build Process
15+
1. **Install dependencies** (25 seconds):
16+
```bash
17+
corepack enable
18+
yarn install
19+
```
20+
**NOTE**: Installation may fail due to network restrictions accessing `cdn.sheetjs.com` for the xlsx package. If this occurs, temporarily modify `package.json` to use `"xlsx": "^0.18.5"` instead of the CDN URL, run `yarn install --mode update-lockfile`, then `yarn install`.
21+
22+
2. **TypeScript compilation** (20 seconds):
23+
```bash
24+
yarn run tsc --noEmit
25+
```
26+
27+
3. **Linting** (7 seconds):
28+
```bash
29+
yarn run eslint
30+
```
31+
32+
4. **Format checks** (10 seconds):
33+
```bash
34+
yarn run format:ci
35+
```
36+
37+
5. **Production build** (40 seconds, **NEVER CANCEL**):
38+
```bash
39+
yarn run build
40+
```
41+
**CRITICAL**: Set timeout to 60+ minutes. Build completes in ~40 seconds but may take longer on slower systems.
42+
43+
6. **Test suite** (1 minute 45 seconds, **NEVER CANCEL**):
44+
```bash
45+
yarn run test
46+
```
47+
**CRITICAL**: Set timeout to 30+ minutes. One test may fail due to network restrictions accessing `sicp.sourceacademy.org`.
48+
49+
### Development Server
50+
- **Start development server** (16 seconds build + server startup):
51+
```bash
52+
yarn run start
53+
```
54+
- **Access**: http://localhost:8000
55+
- **Hot reload**: Enabled with live updates
56+
57+
## Validation
58+
59+
### Manual Testing Requirements
60+
**ALWAYS run through at least one complete end-to-end scenario after making changes:**
61+
62+
1. **Basic Playground Functionality**:
63+
- Navigate to http://localhost:8000 (redirects to /playground)
64+
- Verify the editor loads with syntax highlighting
65+
- Write test code: `function factorial(n) { return n <= 1 ? 1 : n * factorial(n - 1); } factorial(5);`
66+
- Click "Run" button
67+
- Verify output "120" appears in the result panel
68+
- Test REPL by typing expressions in the bottom panel
69+
70+
2. **Navigation and UI**:
71+
- Verify navigation bar with "Playground" and "SICP JS" links
72+
- Test language selector (Source §1 through §4)
73+
- Verify all toolbar buttons are functional (Run, Share, Session, Folder, Google Drive, GitHub)
74+
- Check welcome message and documentation links work
75+
76+
3. **Build Validation**:
77+
- **ALWAYS** run `yarn run format` and `yarn run eslint` before committing
78+
- The CI workflow (`.github/workflows/ci.yml`) runs: `tsc`, `format:ci`, `eslint`, `build`, `test --bail=1`, `test-coveralls`
79+
80+
## Network Limitations
81+
82+
**Important**: Several external services are not accessible in sandboxed environments:
83+
- `cdn.sheetjs.com` - xlsx package installation fails
84+
- `sicp.sourceacademy.org` - SICP JS content fails to load
85+
- `fonts.googleapis.com`, `apis.google.com` - Google services blocked
86+
- These failures are expected and should be documented as "fails due to network limitations"
87+
88+
## Common Tasks
89+
90+
### Repository Structure
91+
```
92+
/home/runner/work/frontend/frontend/
93+
├── .github/workflows/ # CI/CD pipelines
94+
├── .node-version # Node.js 20.9.0
95+
├── package.json # Dependencies and scripts
96+
├── tsconfig.json # TypeScript configuration
97+
├── rsbuild.config.ts # Build configuration (replaces webpack)
98+
├── vitest.config.ts # Test configuration
99+
├── src/
100+
│ ├── assets/ # Static assets
101+
│ ├── commons/ # Shared components and utilities
102+
│ ├── features/ # Redux features (actions, reducers, sagas)
103+
│ ├── pages/ # Page components matching routes
104+
│ └── styles/ # SCSS stylesheets
105+
├── public/ # Public static files
106+
└── scripts/ # Utility scripts
107+
```
108+
109+
### Key npm Scripts
110+
- `yarn start` - Development server (http://localhost:8000)
111+
- `yarn build` - Production build (40s, outputs to `build/`)
112+
- `yarn test` - Test suite (1m45s, may have 1 network-related failure)
113+
- `yarn format` - Auto-fix code formatting (ESLint + Prettier)
114+
- `yarn format:ci` - Check formatting without changes
115+
- `yarn eslint` - Lint TypeScript/JavaScript code
116+
- `yarn tsc` - TypeScript compilation check
117+
118+
### Environment Configuration
119+
Copy `.env.example` to `.env` and configure:
120+
- `REACT_APP_BACKEND_URL` - Backend API endpoint
121+
- `REACT_APP_USE_BACKEND` - Enable/disable backend integration
122+
- `REACT_APP_PLAYGROUND_ONLY` - Playground-only mode for GitHub Pages
123+
- Authentication providers, Google Drive, GitHub integration settings
124+
125+
### Memory Requirements
126+
The build process requires significant memory:
127+
- Set `NODE_OPTIONS=--max_old_space_size=8192` for CI/CD
128+
- Local development typically works with default Node.js memory limits
129+
130+
### Technology Stack
131+
- **Frontend**: React 18.3.1 with TypeScript 5.8.2
132+
- **State Management**: Redux Toolkit with Redux Saga
133+
- **Build Tool**: rsbuild (modern webpack replacement)
134+
- **Testing**: Vitest with jsdom environment
135+
- **Styling**: SCSS with Blueprint UI components
136+
- **Linting**: ESLint 9 with TypeScript rules
137+
- **Code Editor**: ACE editor with Source language support
138+
139+
### Debugging Tips
140+
- Check browser console for React DevTools and HMR connection messages
141+
- Build warnings about missing Node.js modules (perf_hooks) are expected in browser builds
142+
- ESLint warnings about React hooks dependencies are common and generally safe
143+
- Use `yarn run test:watch` for interactive test development
144+
- Use `yarn run test:ui` for browser-based test UI
145+
146+
**Remember**: Always validate functionality manually by running the application and testing user scenarios. The playground must be able to execute code and display results correctly.

package.json.backup

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
{
2+
"private": true,
3+
"type": "module",
4+
"name": "frontend",
5+
"packageManager": "[email protected]",
6+
"version": "1.4.3",
7+
"scripts-info": {
8+
"analyze": "Analyze bundle size breakdown",
9+
"format": "Format source code",
10+
"start": "Start the Webpack development server",
11+
"build": "Build production bundle",
12+
"test": "Run unit tests",
13+
"update-ui-snapshots": "Update UI test snapshots"
14+
},
15+
"scripts": {
16+
"analyze": "yarn build --stats; webpack-bundle-analyzer build/bundle-stats.json",
17+
"build": "tsc -b && rsbuild build",
18+
"coverage": "./scripts/coverage-fix.sh do && yarn test --coverage && ./scripts/coverage-fix.sh undo",
19+
"format": "eslint --fix src && prettier --write \"src/**/*.{js,jsx,ts,tsx}\" && prettier --write --parser scss \"src/**/*.scss\"",
20+
"format:tsx": "prettier --list-different \"src/**/*.{js,jsx,ts,tsx}\"",
21+
"format:scss": "prettier --list-different --parser scss \"src/**/*.scss\"",
22+
"format:ci": "yarn run format:tsx && yarn run format:scss",
23+
"start": "rsbuild dev",
24+
"test": "cross-env TZ=Asia/Singapore vitest run",
25+
"test:watch": "cross-env TZ=Asia/Singapore vitest",
26+
"test:ui": "cross-env TZ=Asia/Singapore vitest --ui --no-open",
27+
"test-coveralls": "./scripts/test-coveralls.sh",
28+
"update-ui-snapshots": "vitest run --update",
29+
"eslint": "eslint src",
30+
"prepare": "husky",
31+
"preview": "rsbuild preview"
32+
},
33+
"dependencies": {
34+
"@blueprintjs/core": "^5.10.1",
35+
"@blueprintjs/datetime2": "^2.3.3",
36+
"@blueprintjs/icons": "^6.0.0",
37+
"@blueprintjs/select": "^5.1.3",
38+
"@convergencelabs/ace-collab-ext": "^0.6.0",
39+
"@mantine/hooks": "^7.11.2",
40+
"@octokit/rest": "^22.0.0",
41+
"@reduxjs/toolkit": "^1.9.7",
42+
"@sentry/browser": "^8.33.0",
43+
"@sourceacademy/c-slang": "^1.0.21",
44+
"@sourceacademy/sharedb-ace": "^2.1.1",
45+
"@sourceacademy/sling-client": "^0.1.0",
46+
"@szhsin/react-menu": "^4.0.0",
47+
"@tanstack/react-table": "^8.9.3",
48+
"@tremor/react": "^1.8.2",
49+
"ace-builds": "^1.42.1",
50+
"acorn": "^8.9.0",
51+
"ag-grid-community": "^32.3.1",
52+
"ag-grid-react": "^32.3.1",
53+
"array-move": "^4.0.0",
54+
"browserfs": "^1.4.3",
55+
"classnames": "^2.3.2",
56+
"conductor": "https://github.com/source-academy/conductor.git#0.2.1",
57+
"dayjs": "^1.11.13",
58+
"dompurify": "^3.2.4",
59+
"flexboxgrid": "^6.3.1",
60+
"flexboxgrid-helpers": "^1.1.3",
61+
"hastscript": "^9.0.0",
62+
"i18next": "^25.0.0",
63+
"i18next-browser-languagedetector": "^8.0.0",
64+
"immer": "^9.0.21",
65+
"java-slang": "^1.0.13",
66+
"js-cookie": "^3.0.5",
67+
"js-slang": "^1.0.84",
68+
"js-yaml": "^4.1.0",
69+
"konva": "^9.2.0",
70+
"language-directory": "https://github.com/source-academy/language-directory.git",
71+
"lodash": "^4.17.21",
72+
"lz-string": "^1.4.4",
73+
"mdast-util-from-markdown": "^2.0.0",
74+
"mdast-util-to-hast": "^13.0.0",
75+
"normalize.css": "^8.0.1",
76+
"phaser": "~3.90.0",
77+
"query-string": "^9.0.0",
78+
"re-resizable": "^6.9.9",
79+
"react": "^18.3.1",
80+
"react-ace": "^14.0.0",
81+
"react-copy-to-clipboard": "^5.1.0",
82+
"react-debounce-render": "^8.0.2",
83+
"react-dom": "^18.3.1",
84+
"react-drag-drop-files": "^3.0.0",
85+
"react-draggable": "^4.4.5",
86+
"react-dropzone": "^14.2.3",
87+
"react-i18next": "^15.0.0",
88+
"react-konva": "^18.2.10",
89+
"react-latex-next": "^3.0.0",
90+
"react-mde": "^11.5.0",
91+
"react-papaparse": "^4.0.2",
92+
"react-qr-reader": "^3.0.0-beta-1",
93+
"react-redux": "^8.1.1",
94+
"react-router": "^7.6.2",
95+
"react-select": "^5.7.3",
96+
"react-simple-keyboard": "^3.6.27",
97+
"react-sortable-hoc": "^2.0.0",
98+
"react-syntax-highlighter": "^15.5.0",
99+
"react-textarea-autosize": "^8.5.2",
100+
"redux-mock-store": "^1.5.4",
101+
"redux-saga": "^1.2.3",
102+
"rehype-react": "^8.0.0",
103+
"showdown": "^2.1.0",
104+
"sourceror": "^0.8.5",
105+
"unified": "^11.0.0",
106+
"uuid": "^11.0.2",
107+
"workbox-core": "^7.3.0",
108+
"workbox-precaching": "^7.3.0",
109+
"workbox-routing": "^7.3.0",
110+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
111+
"xml2js": "^0.6.0",
112+
"yareco": "^0.1.5"
113+
},
114+
"devDependencies": {
115+
"@aaroon/workbox-rspack-plugin": "^0.3.2",
116+
"@babel/core": "^7.24.5",
117+
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
118+
"@babel/preset-typescript": "^7.24.1",
119+
"@babel/runtime": "^7.24.5",
120+
"@rsbuild/core": "^1.3.12",
121+
"@rsbuild/plugin-eslint": "^1.1.1",
122+
"@rsbuild/plugin-node-polyfill": "^1.3.0",
123+
"@rsbuild/plugin-react": "^1.3.0",
124+
"@rsbuild/plugin-sass": "^1.3.1",
125+
"@rsbuild/plugin-svgr": "^1.2.0",
126+
"@svgr/webpack": "^8.0.0",
127+
"@swc/core": "^1.11.22",
128+
"@testing-library/dom": "^10.4.0",
129+
"@testing-library/jest-dom": "^6.0.0",
130+
"@testing-library/react": "^16.0.0",
131+
"@testing-library/user-event": "^14.6.0",
132+
"@types/estree": "^1.0.5",
133+
"@types/gapi": "^0.0.47",
134+
"@types/gapi.auth2": "^0.0.61",
135+
"@types/gapi.client": "^1.0.5",
136+
"@types/gapi.client.drive-v3": "^0.0.5",
137+
"@types/google.picker": "^0.0.51",
138+
"@types/identity-obj-proxy": "^3",
139+
"@types/js-cookie": "^3.0.6",
140+
"@types/js-yaml": "^4.0.5",
141+
"@types/lodash": "^4.14.195",
142+
"@types/react": "^18.3.3",
143+
"@types/react-copy-to-clipboard": "^5.0.4",
144+
"@types/react-dom": "^18.3.0",
145+
"@types/react-redux": "^7.1.24",
146+
"@types/react-syntax-highlighter": "^15.5.7",
147+
"@types/react-test-renderer": "^18.0.0",
148+
"@types/redux-mock-store": "^1.0.3",
149+
"@types/showdown": "^2.0.1",
150+
"@types/xml2js": "^0.4.11",
151+
"@vitejs/plugin-react-swc": "^3.11.0",
152+
"@vitest/coverage-v8": "3.2.4",
153+
"@vitest/ui": "^3.2.4",
154+
"buffer": "^6.0.3",
155+
"canvas": "^3.1.0",
156+
"constants-browserify": "^1.0.0",
157+
"coveralls": "^3.1.1",
158+
"cross-env": "^10.0.0",
159+
"eslint": "^9.9.0",
160+
"eslint-plugin-react": "^7.35.0",
161+
"eslint-plugin-react-hooks": "^5.2.0",
162+
"eslint-plugin-react-refresh": "^0.4.9",
163+
"eslint-plugin-simple-import-sort": "^12.1.1",
164+
"https-browserify": "^1.0.0",
165+
"husky": "^9.0.0",
166+
"identity-obj-proxy": "^3.0.0",
167+
"jsdom": "^26.0.0",
168+
"npm-run-all2": "^8.0.0",
169+
"os-browserify": "^0.3.0",
170+
"path": "^0.12.7",
171+
"path-browserify": "^1.0.1",
172+
"phaser3spectorjs": "^0.0.8",
173+
"prettier": "^3.3.3",
174+
"process": "^0.11.10",
175+
"react-error-overlay": "^6.0.11",
176+
"react-test-renderer": "^18.2.0",
177+
"redux-saga-test-plan": "^4.0.6",
178+
"resize-observer-polyfill": "^1.5.1",
179+
"sass": "^1.63.6",
180+
"stream-browserify": "^3.0.0",
181+
"stream-http": "^3.2.0",
182+
"timers-browserify": "^2.0.12",
183+
"typescript": "^5.8.2",
184+
"typescript-eslint": "^8.1.0",
185+
"url": "^0.11.1",
186+
"vitest": "^3.2.4",
187+
"webpack-bundle-analyzer": "^4.9.0"
188+
},
189+
"browserslist": {
190+
"production": [
191+
"Firefox ESR",
192+
"last 2 chrome versions",
193+
"last 2 safari versions"
194+
],
195+
"development": [
196+
"last 1 chrome version",
197+
"last 1 firefox version",
198+
"last 1 safari version"
199+
]
200+
}
201+
}

0 commit comments

Comments
 (0)