Document Mattermost cloud startup flow (#36559)

* Add Cursor Cloud Agent Docker environment

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix Cloud Agent enterprise and Docker access

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix Cloud Agent Go path setup

Co-authored-by: Cursor <cursoragent@cursor.com>

* Use Cursor multi-repo enterprise checkout

Co-authored-by: Cursor <cursoragent@cursor.com>

* Use sibling enterprise checkout layout

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add tmux to Cloud Agent image

Co-authored-by: Cursor <cursoragent@cursor.com>

* Document Mattermost cloud startup flow

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Document Mattermost license behavior in cloud

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Nick MisasiandCursor authored and GitHub committed 2026-05-13 21:45:38 +00:00
1 parent d8612e378f
commit 11b55b77f3
8 files changed
+608 -1

No files matched your search

+166
View File
@@ -0,0 +1,166 @@
FROM ubuntu:24.04
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ARG GO_VERSION=1.25.9
ARG NODE_VERSION=24.11.1
ARG NVM_VERSION=0.40.3
ARG AGENT_BROWSER_VERSION=0.27.0
ARG DOCKER_VERSION=5:28.5.2-1~ubuntu.24.04~noble
ARG CONTAINERD_VERSION=2.2.3-1~ubuntu.24.04~noble
ARG DOCKER_BUILDX_VERSION=0.33.0-1~ubuntu.24.04~noble
ARG DOCKER_COMPOSE_VERSION=5.1.3-1~ubuntu.24.04~noble
ENV DEBIAN_FRONTEND=noninteractive
ENV NVM_DIR=/home/ubuntu/.nvm
ENV GOPATH=/home/ubuntu/go
ENV PATH=/home/ubuntu/.nvm/versions/node/v${NODE_VERSION}/bin:/usr/local/go/bin:/home/ubuntu/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
RUN apt-get update && \
apt-get install -y --no-install-recommends \
apt-transport-https \
acl \
bash \
build-essential \
ca-certificates \
curl \
dnsutils \
file \
fuse-overlayfs \
git \
git-lfs \
gnupg \
iproute2 \
iptables \
jq \
less \
libasound2t64 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libatspi2.0-0 \
libcairo2 \
libcups2 \
libdrm2 \
libgbm1 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libsecret-1-0 \
libx11-xcb1 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
libxshmfence1 \
locales \
lsof \
make \
nano \
netcat-openbsd \
openssh-server \
pgloader \
pkg-config \
procps \
python3 \
python3-pip \
python3-venv \
rsync \
sudo \
tar \
tmux \
unzip \
vim \
xmlsec1 \
xz-utils \
zip && \
locale-gen en_US.UTF-8 && \
git lfs install --system && \
rm -rf /var/lib/apt/lists/*
RUN install -m 0755 -d /etc/apt/keyrings && \
curl --retry 3 --retry-delay 5 -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
chmod a+r /etc/apt/keyrings/docker.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
docker-ce=${DOCKER_VERSION} \
docker-ce-cli=${DOCKER_VERSION} \
containerd.io=${CONTAINERD_VERSION} \
docker-buildx-plugin=${DOCKER_BUILDX_VERSION} \
docker-compose-plugin=${DOCKER_COMPOSE_VERSION} && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /etc/docker && \
printf '%s\n' \
'{' \
' "storage-driver": "fuse-overlayfs",' \
' "features": {' \
' "buildkit": true' \
' }' \
'}' > /etc/docker/daemon.json && \
update-alternatives --set iptables /usr/sbin/iptables-legacy && \
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
RUN install -m 0755 -d /etc/apt/keyrings && \
curl --retry 3 --retry-delay 5 -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg -o /etc/apt/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list && \
apt-get update && \
apt-get install -y --no-install-recommends gh && \
rm -rf /var/lib/apt/lists/*
RUN case "$(dpkg --print-architecture)" in \
amd64) go_arch=amd64 ;; \
arm64) go_arch=arm64 ;; \
*) echo "Unsupported Go architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \
esac && \
curl --retry 3 --retry-delay 5 -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${go_arch}.tar.gz" -o /tmp/go.tgz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf /tmp/go.tgz && \
ln -sfnT /usr/local/go/bin/go /usr/local/bin/go && \
ln -sfnT /usr/local/go/bin/gofmt /usr/local/bin/gofmt && \
rm -f /tmp/go.tgz
RUN case "$(dpkg --print-architecture)" in \
amd64) aws_arch=x86_64 ;; \
arm64) aws_arch=aarch64 ;; \
*) echo "Unsupported AWS CLI architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \
esac && \
curl --retry 3 --retry-delay 5 -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-${aws_arch}.zip" -o /tmp/awscliv2.zip && \
unzip -q /tmp/awscliv2.zip -d /tmp && \
/tmp/aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli && \
rm -rf /tmp/aws /tmp/awscliv2.zip
RUN install -m 0755 -d /var/run/sshd && \
printf '%s\n' 'PasswordAuthentication no' 'ChallengeResponseAuthentication no' 'UsePAM no' > /etc/ssh/sshd_config.d/disable_password_auth.conf && \
if ! id -u ubuntu >/dev/null 2>&1; then useradd -m -s /bin/bash ubuntu; fi && \
groupadd -f docker && \
usermod -aG docker,sudo ubuntu && \
echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ubuntu && \
chmod 0440 /etc/sudoers.d/ubuntu && \
echo "ubuntu:ubuntu" | chpasswd && \
install -d -o ubuntu -g ubuntu "${NVM_DIR}" "${GOPATH}"
RUN git clone --depth 1 --branch "v${NVM_VERSION}" https://github.com/nvm-sh/nvm.git "${NVM_DIR}" && \
chown -R ubuntu:ubuntu "${NVM_DIR}" "${GOPATH}" && \
su ubuntu -c "bash -lc 'set -e; source ${NVM_DIR}/nvm.sh; nvm install ${NODE_VERSION}; nvm alias default ${NODE_VERSION}; nvm use default; npm install -g agent-browser@${AGENT_BROWSER_VERSION}; agent-browser install || true'" && \
ln -sfn "${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/node" /usr/local/bin/node && \
ln -sfn "${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/npm" /usr/local/bin/npm && \
ln -sfn "${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/npx" /usr/local/bin/npx && \
ln -sfn "${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/agent-browser" /usr/local/bin/agent-browser
RUN { \
echo 'export NVM_DIR="$HOME/.nvm"'; \
echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"'; \
echo 'export GOPATH="$HOME/go"'; \
echo 'export PATH="$NVM_DIR/versions/node/v24.11.1/bin:/usr/local/go/bin:$GOPATH/bin:$PATH"'; \
} >> /home/ubuntu/.bashrc && \
chown ubuntu:ubuntu /home/ubuntu/.bashrc
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
WORKDIR /home/ubuntu
USER ubuntu
+36
View File
@@ -0,0 +1,36 @@
# Cursor Cloud Agent Environment
This directory defines the checked-in Cloud Agent environment for this repository. Cursor resolves `.cursor/environment.json` before personal or team saved environments, so this replaces the snapshot-dependent `/onboard` flow for agents started from this repo.
The Docker build context is `.cursor/` only. The Dockerfile intentionally does not copy the repository; Cursor checks out the requested commit at runtime.
## What Is Baked Into The Image
- Ubuntu 24.04.
- Docker CE 28.5.2 with `fuse-overlayfs` and `iptables-legacy`, matching Cursor's Docker-in-Cloud guidance for complex compose setups.
- Go 1.25.9 from `server/.go-version`.
- Node 24.11.1/npm 11 via nvm, matching `.nvmrc` and `webapp/package.json`.
- `agent-browser@0.27.0` and browser dependencies for screenshot workflows.
- AWS CLI v2 for S3 uploads.
- Common Mattermost build/test tools: `make`, `jq`, `xmlsec1`, `pgloader`, Git LFS, GitHub CLI, Python 3, and build essentials.
## Runtime Hooks
- `cloud-agent-install.sh` runs after Cursor checks out the repo. It refreshes nvm, installs agent-browser browsers, verifies Cursor's multi-repo `mattermost/enterprise` checkout, runs `server` Go dependency hydration, installs webapp dependencies, and runs Playwright `npm ci`.
- `cloud-agent-start.sh` materializes `.cursor/cursor.md` as `.cursor/AGENTS.md`, fixes current-session Docker socket access, then starts Docker and waits until `docker info` and `docker compose version` succeed.
The environment declares `github.com/mattermost/enterprise` in `repositoryDependencies` so Cursor can provide it as part of the multi-repo workspace. Cursor currently clones the repositories as siblings, such as `/agent/repos/mattermost` and `/agent/repos/enterprise`, which matches `server/Makefile`'s default `../../enterprise` path. The install hook does not clone, pull, or symlink enterprise.
## Useful Skips
Set these environment variables to `true` to shorten startup for narrow tasks:
- `CLOUD_AGENT_SKIP_ENTERPRISE`
- `CLOUD_AGENT_SKIP_GO_DEPS`
- `CLOUD_AGENT_SKIP_WEBAPP_DEPS`
- `CLOUD_AGENT_SKIP_PLAYWRIGHT_DEPS`
- `CLOUD_AGENT_SKIP_AGENT_BROWSER_INSTALL`
## Expected Secrets
- AWS uploads use the standard AWS CLI environment variables provided to the Cloud Agent: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_S3_BUCKET_NAME`. The image only supplies the `aws` binary.
+106
View File
@@ -0,0 +1,106 @@
# Cursor Cloud Agent Instructions
These instructions apply to Cursor Cloud Agents after `.cursor/scripts/cloud-agent-start.sh` materializes this file as `.cursor/AGENTS.md`.
## Environment
- Docker must be available. If `docker info` fails, inspect `/tmp/docker-service-start.log` and `/tmp/dockerd.log`; do not assume a snapshot will provide Docker.
- The image includes Go, Node/npm, Docker Compose, AWS CLI v2, and `agent-browser`.
- Cursor should provide `mattermost/enterprise` through the multi-repo environment. The expected layout is sibling repositories, such as `/agent/repos/mattermost` and `/agent/repos/enterprise`; this matches `server/Makefile`'s default `../../enterprise` path.
## Running Mattermost
1. Start dependencies:
```bash
cd server
make start-docker
```
2. Start the server:
```bash
cd server
make run-server
```
3. Start the web app in another terminal when UI work needs live verification:
```bash
cd webapp
make run
```
The Mattermost server is expected at `http://localhost:8065`. The webapp dev server commonly uses `http://localhost:9005`.
### Known-good Cloud flow
- In this multi-repo Cloud environment, `mattermost` and `enterprise` are expected to start from `master`, so sibling checkout skew should not need extra handling.
- `server/Makefile`'s `run` target only reaches `run-client` if the server is backgrounded. In Cloud, the reliable combined startup is:
```bash
cd server
ENABLED_DOCKER_SERVICES='postgres redis' RUN_SERVER_IN_BACKGROUND=true make run
```
- If you want split terminals instead, use:
```bash
cd server
ENABLED_DOCKER_SERVICES='postgres redis' make run-server
```
and then:
```bash
cd webapp
make run
```
- When the server starts and `MM_LICENSE` is present in the environment, the server applies that license automatically. If `MM_LICENSE` is not set, starting the server automatically applies an Entry license, which provides nearly all functionality needed for development.
- `ENABLED_DOCKER_SERVICES='postgres redis'` avoids optional local-dev services such as Prometheus, Grafana, Loki, Minio, Azurite, and OpenLDAP. This is useful in Cloud when Docker Hub rate limits block the default `make start-docker` dependency set.
- If the first-user signup UI is flaky but the server is already healthy, seed local state with `mmctl` and then log in through the browser:
```bash
cd server
./bin/mmctl --local user create --email cursor@example.com --username cursoradmin --password Password123! --system-admin --email-verified --disable-welcome-email
./bin/mmctl --local team create --name cursorteam --display-name "Cursor Team" --email cursor@example.com
```
- A healthy server responds at:
```bash
curl http://127.0.0.1:8065/api/v4/system/ping
```
## Tests And Setup
- Backend workspace setup is handled by `cd server && make setup-go-work`; never run `go mod tidy` directly.
- Webapp dependencies are installed with `cd webapp && make node_modules`.
- Playwright dependencies are installed with `cd e2e-tests/playwright && npm ci`.
- For full Playwright compose flows, use the existing `e2e-tests` Makefile and scripts. Docker Compose is available in the Cloud Agent image.
## Browser Screenshots
Use `agent-browser` for browser automation and screenshots. If the CLI is missing or browsers are unavailable, run:
```bash
npm install -g agent-browser@0.27.0
agent-browser install
```
- Chrome is available in the Cloud image, and `agent-browser skills get core --full` is a quick check that the CLI and bundled skills are working.
Prefer verifying UI changes against the running local Mattermost instance before opening or updating a PR.
## AWS And PR Artifacts
AWS CLI v2 is installed for uploading screenshots or reports. Cloud Agents should receive `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_S3_BUCKET_NAME` as environment variables.
Before uploading, verify credentials with:
```bash
aws sts get-caller-identity
```
- If the configured S3 bucket is public, upload with `aws s3 cp` and share the plain object URL `https://$AWS_S3_BUCKET_NAME.s3.amazonaws.com/<key>` instead of generating a presigned URL.
Do not hardcode AWS credentials or bucket secrets in the repository.
+23
View File
@@ -0,0 +1,23 @@
{
"name": "Mattermost Cloud Agent",
"user": "ubuntu",
"build": {
"dockerfile": "Dockerfile",
"context": "."
},
"repositoryDependencies": [
"github.com/mattermost/enterprise"
],
"install": "bash .cursor/scripts/cloud-agent-install.sh",
"start": "bash .cursor/scripts/cloud-agent-start.sh",
"ports": [
{
"name": "Mattermost server",
"port": 8065
},
{
"name": "Webapp dev server",
"port": 9005
}
]
}
+179
View File
@@ -0,0 +1,179 @@
#!/usr/bin/env bash
set -Eeuo pipefail
log() {
printf '[cloud-agent-install] %s\n' "$*" >&2
}
is_true() {
case "${1:-}" in
1 | true | TRUE | yes | YES) return 0 ;;
*) return 1 ;;
esac
}
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
cd "$ROOT"
NODE_VERSION="${CLOUD_AGENT_NODE_VERSION:-24.11.1}"
AGENT_BROWSER_VERSION="${CLOUD_AGENT_BROWSER_VERSION:-0.27.0}"
export GOPATH="${GOPATH:-$HOME/go}"
export PATH="/usr/local/go/bin:$GOPATH/bin:/usr/local/bin:$PATH"
ensure_go() {
if ! command -v go >/dev/null 2>&1; then
log "Go is not available on PATH. PATH=$PATH"
return 1
fi
log "Using $(go version)"
}
source_node() {
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
if [ -s "$NVM_DIR/nvm.sh" ]; then
# shellcheck source=/dev/null
. "$NVM_DIR/nvm.sh"
fi
}
ensure_node() {
source_node
if command -v nvm >/dev/null 2>&1; then
nvm install "$NODE_VERSION" >/dev/null
nvm alias default "$NODE_VERSION" >/dev/null
nvm use "$NODE_VERSION" >/dev/null
fi
if ! command -v node >/dev/null 2>&1 || ! command -v npm >/dev/null 2>&1; then
log "Node.js/npm are not available; check the Cloud Agent Dockerfile build."
return 1
fi
log "Using node $(node --version) and npm $(npm --version)"
if ! command -v agent-browser >/dev/null 2>&1; then
npm install -g "agent-browser@${AGENT_BROWSER_VERSION}"
fi
if ! is_true "${CLOUD_AGENT_SKIP_AGENT_BROWSER_INSTALL:-false}"; then
agent-browser install || log "agent-browser install failed; continuing so code tasks are not blocked."
fi
}
enterprise_build_dir() {
case "$BUILD_ENTERPRISE_DIR" in
/*) realpath -m "$BUILD_ENTERPRISE_DIR" ;;
*) realpath -m "$ROOT/server/$BUILD_ENTERPRISE_DIR" ;;
esac
}
find_enterprise_checkout() {
local candidates=()
if [ -n "${ENTERPRISE_CHECKOUT_DIR:-}" ]; then
candidates+=("$ENTERPRISE_CHECKOUT_DIR")
fi
if [ -n "${ENTERPRISE_DIR:-}" ]; then
candidates+=("$ENTERPRISE_DIR")
fi
candidates+=(
"$ROOT/../enterprise"
"$ROOT/../../enterprise"
"$HOME/enterprise"
)
local candidate
for candidate in "${candidates[@]}"; do
if git -C "$candidate" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
realpath -m "$candidate"
return 0
fi
done
return 1
}
verify_enterprise_checkout() {
if is_true "${CLOUD_AGENT_SKIP_ENTERPRISE:-false}"; then
log "Skipping enterprise verification because CLOUD_AGENT_SKIP_ENTERPRISE is set."
return 0
fi
local target
if ! target="$(find_enterprise_checkout)"; then
log "Enterprise checkout not found. Ensure the Cursor multi-repo environment includes github.com/mattermost/enterprise."
return 1
fi
log "Enterprise checkout ready at $target."
}
hydrate_go_dependencies() {
if is_true "${CLOUD_AGENT_SKIP_GO_DEPS:-false}"; then
log "Skipping Go dependency hydration."
return 0
fi
if [ -d server ]; then
if [ -n "${BUILD_ENTERPRISE_DIR:-}" ]; then
local enterprise_dir
enterprise_dir="$(enterprise_build_dir)"
log "Hydrating Go workspace with BUILD_ENTERPRISE_DIR=$enterprise_dir"
(
cd server
BUILD_ENTERPRISE_DIR="$enterprise_dir" make setup-go-work
go mod download
if [ -f public/go.mod ]; then
(cd public && go mod download)
fi
)
else
log "Hydrating Go workspace with server/Makefile default enterprise path."
(
cd server
make setup-go-work
go mod download
if [ -f public/go.mod ]; then
(cd public && go mod download)
fi
)
fi
fi
}
hydrate_webapp_dependencies() {
if is_true "${CLOUD_AGENT_SKIP_WEBAPP_DEPS:-false}"; then
log "Skipping webapp dependency hydration."
return 0
fi
if [ -f webapp/package.json ]; then
log "Hydrating webapp dependencies."
(cd webapp && make node_modules)
fi
}
hydrate_playwright_dependencies() {
if is_true "${CLOUD_AGENT_SKIP_PLAYWRIGHT_DEPS:-false}"; then
log "Skipping Playwright dependency hydration."
return 0
fi
if [ -f e2e-tests/playwright/package-lock.json ]; then
log "Hydrating Playwright dependencies."
(cd e2e-tests/playwright && npm ci)
fi
}
ensure_go
ensure_node
verify_enterprise_checkout
hydrate_go_dependencies
hydrate_webapp_dependencies
hydrate_playwright_dependencies
log "AWS CLI: $(aws --version 2>&1 || printf 'not available')"
log "Install hook complete."
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
set -Eeuo pipefail
log() {
printf '[cloud-agent-start] %s\n' "$*" >&2
}
materialize_cloud_agent_instructions() {
if [ -f .cursor/cursor.md ]; then
cp .cursor/cursor.md .cursor/AGENTS.md
log "Materialized Cloud Agent instructions at .cursor/AGENTS.md."
fi
}
materialize_cloud_agent_instructions
if ! command -v docker >/dev/null 2>&1; then
log "Docker CLI is missing. The Cloud Agent image did not build from .cursor/Dockerfile."
exit 1
fi
ensure_docker_socket_access() {
if [ ! -S /var/run/docker.sock ]; then
return 0
fi
sudo groupadd -f docker
sudo usermod -aG docker "$(id -un)"
sudo chgrp docker /var/run/docker.sock >/dev/null 2>&1 || true
sudo chmod g+rw /var/run/docker.sock >/dev/null 2>&1 || true
if command -v setfacl >/dev/null 2>&1; then
sudo setfacl -m "u:$(id -un):rw" /var/run/docker.sock >/dev/null 2>&1 || true
fi
}
if [ -f /proc/sys/kernel/apparmor_restrict_unprivileged_userns ]; then
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 >/dev/null 2>&1 || \
log "Could not relax AppArmor user namespace restriction; openldap-based tests may need a larger host profile."
fi
ensure_docker_socket_access
if docker info >/dev/null 2>&1; then
log "Docker is already running."
docker compose version
exit 0
fi
log "Starting Docker daemon."
if command -v service >/dev/null 2>&1; then
sudo sh -c 'service docker start >/tmp/docker-service-start.log 2>&1' || \
log "service docker start failed; falling back to direct dockerd startup."
fi
if ! pgrep -x dockerd >/dev/null 2>&1; then
sudo sh -c 'nohup dockerd --host=unix:///var/run/docker.sock >/tmp/dockerd.log 2>&1 &'
fi
for _ in {1..60}; do
ensure_docker_socket_access
if docker info >/dev/null 2>&1; then
log "Docker is ready."
docker version
docker compose version
exit 0
fi
sleep 1
done
log "Docker did not become ready within 60 seconds."
if [ -f /tmp/docker-service-start.log ]; then
log "docker service output:"
tail -n 80 /tmp/docker-service-start.log >&2 || true
fi
if [ -f /tmp/dockerd.log ]; then
log "dockerd output:"
tail -n 120 /tmp/dockerd.log >&2 || true
fi
exit 1
+9 -1
View File
@@ -166,7 +166,15 @@ docker-compose.override.yaml
**/CLAUDE.md
.claude
.cursorrules
.cursor/
.cursor/*
!.cursor/README.md
!.cursor/cursor.md
!.cursor/Dockerfile
!.cursor/environment.json
!.cursor/scripts/
.cursor/scripts/*
!.cursor/scripts/cloud-agent-install.sh
!.cursor/scripts/cloud-agent-start.sh
server/prev-report.xml
server/prev-gotestsum.json
server/shard-*.txt
+6
View File
@@ -10,3 +10,9 @@ When creating a pull request, follow `.github/PULL_REQUEST_TEMPLATE.md` exactly:
- Remove all `<!-- -->` comments.
- Omit sections that are not applicable (Ticket Link, Screenshots) — do not write N/A, just remove the header.
- The `#### Release Note` header and its "```release-note" fenced code block **must always be present** (WITHOUT escaping the ``` characters). Write `NONE` if the change has no API, schema, UI, or breaking changes.
## Cursor Cloud Agents
This repository has a checked-in Cloud Agent environment under `.cursor/`. Docker is started by `.cursor/scripts/cloud-agent-start.sh`; if Docker is unavailable in Cloud, treat that as an environment failure rather than falling back to snapshot assumptions.
The environment declares `mattermost/enterprise` as a Cursor multi-repo dependency. Cursor clones the repositories as siblings, so `server/Makefile` can use its default `../../enterprise` path; the install hook does not clone or symlink enterprise.