Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Jamulus — Agent Instructions

Jamulus is a real-time networked music jamming application (client and server). Qt/C++, built with qmake. Entry point: `src/main.cpp`; build variants via `CONFIG` flags in `Jamulus.pro`.

This file is the starting point for coding agents. It links to the detailed docs — read the relevant one before starting:

- [CONTRIBUTING.md](CONTRIBUTING.md) — process, code style, licensing, ownership. Its rules apply to agent-assisted work without exception.
- [COMPILING.md](COMPILING.md) — building on every supported platform.
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — source map, threading model, and the invariants that protect live performances.
- [docs/DEPLOY.md](docs/DEPLOY.md) — moving a self-built server binary onto production hosts and verifying it.
- [docs/JAMULUS_PROTOCOL.md](docs/JAMULUS_PROTOCOL.md) — the wire protocol.
- [SECURITY.md](SECURITY.md) — report vulnerabilities to [email protected], never in a public issue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would an agent open an issue automatically?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could, yes. Github has a high degree of automation support for its features.

@mcfnord mcfnord Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(AI has been handling your requests in near-real time, including comments made in my name.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd then appreciate to know what is AI and what is you :-)


## Scope

- One logical change per PR. No drive-by refactors, no reformatting of code you didn't otherwise touch, no bundled extras.
- Features must be agreed in a GitHub issue or Discussion **before** coding — see CONTRIBUTING.md. If no agreement exists, propose; don't implement.
- Stability outranks everything: Jamulus runs live performances. Prefer not adding a feature over adding risk (KISS principles in CONTRIBUTING.md).

## Architecture invariants

Read [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) before changing code. Its invariants, in brief:

1. Never block the real-time audio path (sound callbacks, socket thread, server mix timer).
2. All network input is untrusted — bounds-check everything; drop malformed packets silently.

## DO NOT edit (generated or third-party)

- `moc_*.cpp`, `ui_*.h`, `qrc_*.cpp` are generated at build time (moc/uic/rcc) — never hand-edit.
- `*.qm` files are compiled translations — regenerate from the `.ts` sources in `src/translation/`, never hand-edit.
- `libs/` is third-party (opus, oboe, NSIS). `libs/oboe` is a git submodule — run `git submodule update --init` if it is empty.
- Never run clang-format on any of the above.

## Build / verify

- Linux desktop: `qmake && make` (`qmake-qt5` on Fedora).
- Headless server: `qmake "CONFIG+=headless serveronly" && make`.
- macOS: `qmake QMAKE_APPLE_DEVICE_ARCHS=arm64 QT_ARCH=arm64 -spec macx-xcode Jamulus.pro` (use `x86_64` on Intel Macs; `macx-clang` to build with `make`), then `xcodebuild build` and `macdeployqt ./Release/Jamulus.app`. Full platform details: [COMPILING.md](COMPILING.md).
- There is no automated test suite. To verify a change: build a headless server and run `./Jamulus --server --nogui`, connect a client build to `127.0.0.1`, and exercise the changed behavior. State in the PR what you tested and on which platform. An untested change is an unfinished change.

## Style (C / C++ / Obj-C++)

- Run `make clang_format` before committing (the target exists once `qmake` has generated the Makefile). CI enforces a specific clang-format version — see `clangFormatVersion` in `.github/workflows/coding-style-check.yml`.
- If you add a new source directory or file extension, update `.github/workflows/coding-style-check.yml` and `.clang-format-ignore` as well as `Jamulus.pro` (see the comment above `CLANG_FORMAT_SOURCES`) — otherwise CI and local formatting silently diverge.
- Rules in brief: 4-space indent (no tabs), braces on their own line, space inside `()` and around `if`/`for`/`while` conditions, column limit 150, left pointer alignment (`int* p`).
- New files need an AGPL 3.0 (or later) license header; pre-3.12.1 files carry combined GPL/AGPL blocks — leave existing headers alone. Details in CONTRIBUTING.md.

## Translations

- Use substitution, never concatenation: `tr ( "Hello, %1!" ).arg ( name )` — concatenated fragments cannot be translated.
- Per-language `.ts` files live in `src/translation/`; see [docs/TRANSLATING.md](docs/TRANSLATING.md).

## JSON-RPC

- If you change RPC methods, regenerate `docs/JSON-RPC.md` with `tools/generate_json_rpc_docs.py` — CI (`check-json-rpcs-docs.yml`) fails otherwise.

## Other tooling

- `.sh` files: lint with `shellcheck --shell=bash` and `shfmt -d`.
- Python (under `tools/`): max line length 99, run `pylint` (< 3.0) with the repo's `.pylintrc`.
- ChangeLog: put `CHANGELOG: <one sentence>` in the PR description (`CHANGELOG: SKIP` for changes users won't notice). Do **not** edit the `ChangeLog` file — it causes conflicts.

## Version / portability constraints

- Minimum Qt is **5.12.2**. Guard newer APIs with `#if QT_VERSION >= QT_VERSION_CHECK(...)`.
- Maintain C++11 compatibility and keep Windows, macOS, Linux, Android and iOS building.

## PR expectations

- Naming your branch `autobuild/<name>` triggers CI builds of all targets on your fork — use it before opening the PR.
- Include the `CHANGELOG:` line, and for new dependencies or build changes add `AUTOBUILD: Please build all targets` to the PR description.
14 changes: 13 additions & 1 deletion COMPILING.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,19 @@ make
sudo make install # optional
```

To control the server with systemd, runtime options and similar, refer to the [Server manual](https://jamulus.io/wiki/Server-Linux).
To control the server with systemd, runtime options and similar, refer to the [Server manual](https://jamulus.io/wiki/Server-Linux). If you plan to copy the binary onto other machines, read [docs/DEPLOY.md](docs/DEPLOY.md) first — architecture and library mismatches between build and target hosts are the most common cause of broken deployments.

### Troubleshooting: moc errors with GCC 13+

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should fix this then.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I can reproduce the failure on Ubuntu 24.04 (GCC 13.3 / Qt 5.15.13) and will open a separate PR that fixes it in the build itself. Once that merges, this section can shrink to a sentence or disappear.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: I tried to reproduce this on clean main before writing a fix — Ubuntu 24.04, GCC 13.3, Qt 5.15.13, both CONFIG+=headless serveronly and CONFIG+=headless — and both build cleanly. The failure I had seen involves my fork's additions, not upstream code. So there is nothing to fix here, no build-fix PR is coming, and this troubleshooting section was rightly dropped from the PR.


On distributions shipping GCC 13 or later (e.g. Ubuntu 24.04), Qt 5's `moc` can fail to parse the system headers because of the `_GLIBCXX_VISIBILITY` macro. Workaround — after `qmake`, generate `moc_predefs.h` and neutralize the macro, then build:

```shell
make moc_predefs.h
printf "\n#undef _GLIBCXX_VISIBILITY\n#define _GLIBCXX_VISIBILITY(V)\n" >> moc_predefs.h
make
```

(If your Makefile builds into `release/`, the file is `release/moc_predefs.h` and is produced by `make -f Makefile.Release release/moc_predefs.h`.)

---

Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ We’d really appreciate your support! Please ensure that you understand the fol
- Otherwise, please [post on the GitHub Discussions](https://github.com/jamulussoftware/jamulus/discussions) and say that you are planning to do some coding and explain why. Then we can discuss the specification.
- Please begin coding only after we have agreed on a specification to avoid putting a lot of effort into something that may not be accepted later.

If you work with an AI coding agent, [AGENTS.md](AGENTS.md) is its entry point into this repository. Everything in this document applies to agent-assisted contributions without exception — you remain the author, and you are expected to understand and stand behind every line you submit.


## Jamulus project/source code general principles

Expand Down Expand Up @@ -39,7 +41,7 @@ Please see the [.clang_format file](https://github.com/jamulussoftware/jamulus/b

- Insert a space before and after `(` and `)`. There should be no space between `)` and `;` or before an empty `()`.
- Enclose all bodies of `if`, `else`, `while`, `for`, etc. in braces `{` and `}` on separate lines.
- Do not use concatinations in strings with parameters. Instead use substitutions. **Do:** `QString ( tr ( "Hello, %1. Have a nice day!" ) ).arg( getName() )` **Don't:** `tr ( "Hello " ) + getName() + tr ( ". Have a nice day!" )` ...to make translation easier.
- Do not use concatenations in strings with parameters. Instead use substitutions. **Do:** `QString ( tr ( "Hello, %1. Have a nice day!" ) ).arg( getName() )` **Don't:** `tr ( "Hello " ) + getName() + tr ( ". Have a nice day!" )` ...to make translation easier.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open a separate PR which only contains this typo fix. This will be a trivial merge

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — #3792.


#### Python
Please install and use [pylint](https://pylint.org/) to scan any Python code.
Expand Down
Loading