Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a04d2be
Merge remote-tracking branch 'origin/main' into dev
volfpeter Dec 15, 2025
091ed14
feat: support color selection for the sparks light config
volfpeter Dec 16, 2025
d97fb19
Merge pull request #115 from skybrush-io/feat/color-for-sparks-light-…
volfpeter Dec 16, 2025
7fe8f4e
fix: unified linter setup and tsconfig.json with Viewer and Sidekick
ntamas Dec 22, 2025
630b2b1
chore: updated minor and patch dependencies
ntamas Dec 22, 2025
6bb1185
fix: fix linter warnings
ntamas Dec 24, 2025
52e1c8c
fix: fix linter warnings
ntamas Dec 24, 2025
a700dbf
chore: fixing linter warnings
ntamas Dec 25, 2025
1852e32
chore: fixing linter warnings
ntamas Dec 25, 2025
c586873
first implementation of the rover commands
r0n4n Jan 3, 2026
865e7df
Add a setting to change the vehicle type
r0n4n Jan 4, 2026
2060c9d
Merge remote-tracking branch 'origin/dev' into dev
r0n4n Jan 4, 2026
151d07c
Merge branch 'main' into dev
volfpeter Jan 9, 2026
8571000
fix: remove batch()
volfpeter Jan 9, 2026
4ecbfe1
chore: add AGENTS.md and ignore some more directories
volfpeter Jan 9, 2026
0013a80
Merge pull request #118 from skybrush-io/chore/agents-md-gitignore
ntamas Jan 9, 2026
01d3f70
refactor: using @skybrush/eslint-config for ESLint configuration
ntamas Jan 11, 2026
e35ceb9
chore: apply automatic lint fixes using eslint
isti115 Jan 11, 2026
37253dc
chore: apply automatic formatting using prettier
isti115 Jan 11, 2026
c37635e
chore: temporarily ignore *.mjs files from linting
isti115 Jan 12, 2026
f830230
refactor: declare types for `@collmot/ol-react`
isti115 Jan 13, 2026
a5e47b8
chore: manually fix the remaining lint errors
isti115 Jan 11, 2026
720590d
chore: remove no longer necessary React imports
isti115 Jan 14, 2026
20a937b
ci: create an automated lint workflow
isti115 Jan 11, 2026
5789011
ci: add automated formatting any typing workflows
isti115 Jan 23, 2026
64b0989
ci: enable npm dependency caching in workflows
isti115 Jan 23, 2026
b7899fb
chore: format non-src files using prettier as well
isti115 Jan 23, 2026
a952a70
chore: ignore recent formatting commits in blames
isti115 Jan 23, 2026
586ccc2
fix: prevent missing type definition file error
isti115 Jan 23, 2026
ef73802
Merge branch 'main' into dev
ntamas Jan 26, 2026
5d75108
Merge branch 'main' into dev
ntamas Jan 26, 2026
7c4f934
Merge remote-tracking branch 'origin/dev' into rover_config
r0n4n Feb 1, 2026
202f1f1
Merge branch 'rover_config' of https://github.com/r0n4n/skybrush-live…
r0n4n Feb 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
4f3cd9bedcaeea806c4f1475c5be836cdebfd84c # switched to xo code style
c8e25a17c993738f9a2a45677b5eb87ce0b8f3b8 # formatting changes for Prettier 2.x
9b34927187440c27331a3559f770e73b1fe17fca # reformatted for Prettier 2.x
37253dc98cac8a493d285ad5dcdacc0b1bb6457f # chore: apply automatic formatting using prettier
b7899fb47db860704ed88e7419d5ecf26f60a3b3 # chore: format non-src files using prettier as well
21 changes: 21 additions & 0 deletions .github/workflows/format-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Format check

on:
push:
branches: ['main', 'dev']
pull_request:
branches: ['main', 'dev']

jobs:
prettier:
name: Run formatting checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Caching
uses: actions/setup-node@v6
- name: Install
run: npm install
- name: Check formatting
run: npm run format:check
21 changes: 21 additions & 0 deletions .github/workflows/lint-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Lint check

on:
push:
branches: ['main', 'dev']
pull_request:
branches: ['main', 'dev']

jobs:
eslint:
name: Run lint checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Caching
uses: actions/setup-node@v6
- name: Install
run: npm install
- name: Lint
run: npm run lint:check
21 changes: 21 additions & 0 deletions .github/workflows/type-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Type check

on:
push:
branches: ['main', 'dev']
pull_request:
branches: ['main', 'dev']

jobs:
tsc:
name: Run type checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Caching
uses: actions/setup-node@v6
- name: Install
run: npm install
- name: Typecheck
run: npm run type:check
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Git worktree directories
.wt
.worktree

# VSCode settings
.vscode

Expand Down Expand Up @@ -58,3 +62,7 @@ assets/shows/

# Development stuff
etc/dev/

# AI
.plan
.prompt
150 changes: 150 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# AGENTS.md

This file provides guidelines for agentic coding assistants working on the Skybrush Live codebase.

## Build, Lint, and Test Commands

### Essential Commands

- `npm run lint` - Run ESLint to check code quality
- `npm test` - Run all Jest tests
- `npm test -- path/to/test.test.ts` - Run a single test file
- `npm test -- -t "test name"` - Run tests matching a pattern
- `npm start` - Start development web server (http://localhost:8080)
- `npm run start:electron` - Start Electron desktop app
- `npm run bundle` - Build for production
- `npm run lint && npm test` - Run linting and tests together (run this before committing)

But you shouldn't try to build the project unless explicitly asked to do so!

### Testing Notes

- Jest is configured with TypeScript support
- Test files use `.test.ts` or `.test.tsx` extension
- Coverage is collected automatically in `coverage/` directory
- Use `test.skip()` to skip long-running tests (see test/nearestNeighbors.test.ts:82)

Never run tests unless explicitly asked!

## Code Style Guidelines

### File Format (.editorconfig)

- Encoding: UTF-8
- Indentation: 2 spaces (no tabs) for JS/JSX/TS/TSX/CSS/LESS
- Line endings: LF (Unix-style)
- Final newline: Required at end of files

### TypeScript Rules

- Strict mode enabled
- Use `type` instead of `interface` for type definitions (ESLint enforced)
- Use `T[]` for simple array types, `Array<T>` for complex types
- Use type-only imports: `import type { Foo } from 'bar'` (ESLint enforced)
- Path alias: `~/*` maps to `./src/*` (e.g., `~/utils/arrays`)
- Allow `any` type as pragmatic escape hatch for third-party libraries
- Allow non-null assertions (`!`) when appropriate
- Unused variables with leading underscore (`_unused`) are allowed
- Never cast types using patterns like this: `const x = y as unknown as SomeType`.
- If a named alias exists for a type, use the named alias, that makes the code easier to understand.

### Import Ordering

Import groups:

1. External libraries (e.g., `react`, `lodash-es/has`)
2. `@skybrush` libraries (e.g. `@skybrush/mui-components`)
3. Internal modules with `~/` alias (e.g., `~/utils/arrays`)
4. Relative imports (e.g., `./types`)

Type-only imports are grouped with regular imports, using `type` keyword.

### Naming Conventions

- **Variables/Functions**: camelCase
- **Components**: PascalCase
- **Types/Interfaces**: PascalCase (e.g., `type Coordinate2D`)
- **Constants**: UPPER_SNAKE_CASE (e.g., `NEW_ITEM_ID`, `EMPTY_ARRAY`)
- **Files**: camelCase for utilities, PascalCase for components

### Export rules

- Use named exports for utilities and non-React components.
- Use default export for React components.

### Error Handling

- Use custom Error classes when needed (e.g., `class ItemExistsError extends Error`)
- Include helpful error messages
- Use try/catch for expected errors; allow errors to bubble up for unexpected ones

### Code Organization

- **Utilities**: Pure functions in `src/utils/` (e.g., arrays, collections, math)
- **Components**: Organized by feature in `src/components/` and `src/features/`
- **Hooks**: Custom React hooks in `src/hooks/`
- **Types**: Shared types in `src/types/` or co-located with usage
- **Selectors**: Redux selectors in `src/selectors/`
- **Sagas**: Redux sagas in `src/sagas/`

### React Patterns

- Use function components (declared with `const Comp = () => {}` pattern) with hooks
- Export default for components, named exports for utilities
- Use React hooks as needed
- Prop types defined as TypeScript types
- If component is connected to the Redux store, create the base non-connected implementation with the desired component name.
Then create a connected component with the same name and the "Connected" prefix. Finally default export the connected component.

### Documentation

- Use JSDoc comments for exported functions and complex types
- Include parameter descriptions with `@param` tags
- Include return type descriptions with `@returns` tags
- Add inline comments for non-obvious logic

### Redux/State Management

- Use Redux Toolkit patterns
- Selectors memoized with reselect (`createSelector`)

### Testing Patterns

- Use `describe` to group related tests
- Use `test` for individual test cases
- Arrange-Act-Assert pattern preferred
- Mock external dependencies
- Use `expect().toBe()`, `expect().toEqual()`, `expect().toThrow()` appropriately
- Skip long-running tests with `test.skip()`

### Performance Considerations

- Use `rejectNullish()` for filtering arrays (see src/utils/arrays.ts)
- Use `EMPTY_ARRAY` and `EMPTY_OBJECT` constants instead of `[]`/`{}`
- Memoize expensive computations with `memoize-one` or similar
- Use proper keys in lists (prefer stable IDs over array indices)

### Library Usage

- Use `lodash-es` for utility functions (tree-shakeable ES modules)
- Use `neverthrow` for Result/Either patterns
- Use `i18next` for internationalization (translation function: `tt`)
- Use `react-final-form` for forms with `mui-rff`
- Use Material-UI (@mui/material) for UI components

## Important Files and Directories

- `src/` - Main source code
- `test/` - Test files
- `webpack/` - Webpack configuration
- `eslint.config.mjs` - ESLint rules (flat config format)
- `tsconfig.json` - TypeScript configuration
- `jest.config.ts` - Jest test configuration
- `babel.config.json` - Babel transpilation config

## General Rules

- Be succint unless explicitly asked to be verbose.
- If something is unclear, ask for input before you continue.
- Don't output things or explanations that were not requested.
- Clearly modularize code, create the correct abstractions. Explore related parts of the codebase and use that as the guideline.
1 change: 0 additions & 1 deletion DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ https://github.com/sindresorhus/p-timeout/commit/234f6428dabd228116a31a146c725eb

We should stick to 6.1.4 until this is sorted out, _or_ maybe refactor our code
to use an `AbortSignal` instead where possible.

14 changes: 8 additions & 6 deletions assets/css/dseg.css
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
@font-face {
font-family: 'DSEG14-Classic';
src: url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.woff2') format('woff2'),
url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.woff') format('woff'),
url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.ttf') format('truetype');
src:
url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.woff2') format('woff2'),
url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.woff') format('woff'),
url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}

@font-face {
font-family: 'DSEG7-Classic';
src: url('../fonts/DSEG7-Classic/DSEG7Classic-Regular.woff2') format('woff2'),
url('../fonts/DSEG7-Classic/DSEG7Classic-Regular.woff') format('woff'),
url('../fonts/DSEG7-Classic/DSEG7Classic-Regular.ttf') format('truetype');
src:
url('../fonts/DSEG7-Classic/DSEG7Classic-Regular.woff2') format('woff2'),
url('../fonts/DSEG7-Classic/DSEG7Classic-Regular.woff') format('woff'),
url('../fonts/DSEG7-Classic/DSEG7Classic-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
23 changes: 16 additions & 7 deletions assets/css/kbd.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ kbd {
user-select: none;
}

kbd:hover, kbd:hover * {
kbd:hover,
kbd:hover * {
color: black;
/* box-shadow: 1px 1px 1px #333; */
}
kbd:active, kbd:active * {
kbd:active,
kbd:active * {
color: black;
box-shadow: 1px 1px 0px #ddd inset;
}
Expand All @@ -71,27 +73,34 @@ kbd:active kbd {
}

/* Deep blue */
kbd.deep-blue, .deep-blue kbd {
kbd.deep-blue,
.deep-blue kbd {
background: steelblue;
color: #eee;
}

kbd.deep-blue:hover, kbd.deep-blue:hover *, .deep-blue kbd:hover {
kbd.deep-blue:hover,
kbd.deep-blue:hover *,
.deep-blue kbd:hover {
color: white;
}

/* Dark apple */
kbd.dark-apple, .dark-apple kbd {
kbd.dark-apple,
.dark-apple kbd {
background: black;
color: #ddd;
}

kbd.dark-apple:hover, kbd.dark-apple:hover *, .dark-apple kbd:hover {
kbd.dark-apple:hover,
kbd.dark-apple:hover *,
.dark-apple kbd:hover {
color: white;
}

/* Type writer */
kbd.type-writer, .type-writer kbd {
kbd.type-writer,
.type-writer kbd {
border-radius: 10px;
background: #333;
color: white;
Expand Down
7 changes: 4 additions & 3 deletions assets/css/proggy-vector.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@font-face {
font-family: 'Proggy Vector';
src: url('../fonts/ProggyVector/ProggyVector-Regular.woff2') format('woff2'),
url('../fonts/ProggyVector/ProggyVector-Regular.woff') format('woff'),
url('../fonts/ProggyVector/ProggyVector-Regular.ttf') format('truetype');
src:
url('../fonts/ProggyVector/ProggyVector-Regular.woff2') format('woff2'),
url('../fonts/ProggyVector/ProggyVector-Regular.woff') format('woff'),
url('../fonts/ProggyVector/ProggyVector-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
21 changes: 15 additions & 6 deletions assets/css/workbench.less
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,12 @@ body .lm_header {

/* Perspective switching in header */
.wb-perspective-bar {
background: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.25) 80%, rgba(0, 0, 0, 0.4) 100%);
background: linear-gradient(
to right,
transparent 0%,
rgba(0, 0, 0, 0.25) 80%,
rgba(0, 0, 0, 0.4) 100%
);
flex: 1;
justify-content: left;
border-right: 1px solid #424242;
Expand All @@ -93,20 +98,24 @@ body .lm_header {
display: none;
border-bottom: 3px solid transparent;
border-radius: 0;
font-size: 14px !important; /* consistent with sidebar */
font-size: 14px !important; /* consistent with sidebar */
height: 100%;
background: unset;
box-shadow: unset;
padding: 7px 8px 4px 8px; /* padding higher at the top to compensate for border at bottom */
padding: 7px 8px 4px 8px; /* padding higher at the top to compensate for border at bottom */
}
.wb-perspective-bar .wb-perspective-selected button {
background: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.25) 100%);
border-bottom: 3px solid #03a9f4; /* Material UI lightBlue[500] */
background: linear-gradient(
to bottom,
transparent 0%,
rgba(0, 0, 0, 0.25) 100%
);
border-bottom: 3px solid #03a9f4; /* Material UI lightBlue[500] */
}
.wb-perspective-bar button:hover {
/* styling same as for GenericHeaderButton */
background: linear-gradient(to bottom, #06c 0%, #25a 100%);
border-bottom: 3px solid #03a9f4; /* Material UI lightBlue[500] */
border-bottom: 3px solid #03a9f4; /* Material UI lightBlue[500] */
}

/* Disable draggable splitters for fixed layouts */
Expand Down
1 change: 0 additions & 1 deletion assets/icons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ for Windows:
https://icoconvert.com/

Favicon was generated with https://favicon.io

1 change: 0 additions & 1 deletion config/webapp-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* @file Application configuration at startup, suitable for the web app demo deployment.
*/

import * as React from 'react';
import demoShowUrl from '~/../assets/shows/demo.skyc';

import { type ConfigOverrides } from 'config-overrides';
Expand Down
Loading