Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
36368be
Build CueGrove site and Early Access workflow
13304930782 Jul 25, 2026
9bde3df
Support Google Workspace SMTP relay
13304930782 Jul 25, 2026
af5a0a4
Fix admin settings and review flow
13304930782 Jul 25, 2026
3e2117b
Allow recovery of missing decision emails
13304930782 Jul 25, 2026
6e5c039
Configure SMTP EHLO identity
13304930782 Jul 25, 2026
ec67dbc
Add admin configuration center
13304930782 Jul 26, 2026
b0ddc63
Lower admin password minimum to eight characters
13304930782 Jul 26, 2026
076de03
Polish public and admin layouts
13304930782 Jul 26, 2026
3b79a43
Add typed hero headline
13304930782 Jul 26, 2026
2224e97
Address site security review
13304930782 Jul 26, 2026
bd31602
Improve frontend responsiveness and resilience
13304930782 Jul 26, 2026
5bf44bc
Improve responsive navigation and viewport layout
13304930782 Jul 26, 2026
298fe04
Add Turnstile verification to early access
13304930782 Jul 26, 2026
2bc5d5b
Add CueGrove privacy promise
13304930782 Jul 27, 2026
a8befab
Add CueGrove security commitment
13304930782 Jul 27, 2026
da86663
Use dedicated security contact
13304930782 Jul 28, 2026
793108a
feat: add administrator multi-factor authentication
13304930782 Jul 28, 2026
5d151b1
feat: follow system language on public pages
13304930782 Jul 28, 2026
c5fa1ef
security: add supply-chain checks
13304930782 Jul 28, 2026
1ab56e0
security: document secret scan test vector
13304930782 Jul 28, 2026
186db91
ci: align dependency review exception
13304930782 Jul 28, 2026
8b8f963
Add spam folder reminder after application submission
13304930782 Jul 29, 2026
838bdb2
Refine CueGrove public pages
13304930782 Jul 31, 2026
d654054
Clarify PromptDock AI privacy boundary
13304930782 Jul 31, 2026
9b4adf9
Split CueGrove frontend by route
13304930782 Jul 31, 2026
b613e92
Add feedback portal and bulk approval resend
13304930782 Aug 1, 2026
2a75fb7
Merge pull request #13 from 13304930782/codex/cuegrove-bulk-feedback
13304930782 Aug 1, 2026
8b53d93
Add threaded tester feedback conversations
13304930782 Aug 1, 2026
42ba5f6
Fix mobile footer wrapping
13304930782 Aug 2, 2026
4fcf838
Add local random dice and form tool
13304930782 Aug 7, 2026
ef34eaa
Refine dice and random matching utility
13304930782 Aug 7, 2026
bffedb0
Roll two six-sided dice
13304930782 Aug 7, 2026
32ed210
Show dice values separately
13304930782 Aug 7, 2026
30860fd
Track random matching rounds
13304930782 Aug 7, 2026
bfe2e66
Link dice rolls to list shuffling
13304930782 Aug 7, 2026
c57fc6d
Separate dice roll from list randomization
13304930782 Aug 7, 2026
8f4d768
Split manual swaps from final matching
13304930782 Aug 7, 2026
5684b28
Shuffle entire list on each manual click
13304930782 Aug 7, 2026
927fb5e
Protect random tools with temporary access keys
13304930782 Aug 7, 2026
320fa74
Allow administrators to bypass tool keys
13304930782 Aug 7, 2026
f80a86d
Localize admin interface
13304930782 Aug 7, 2026
0342999
Add access key deletion controls
13304930782 Aug 7, 2026
fc81ca7
Harden roll access authorization
13304930782 Aug 7, 2026
9fe994e
Match temporary access status styling
13304930782 Aug 7, 2026
bdd15ac
Add admin PromptDock release upload
13304930782 Aug 11, 2026
654b64c
Fix nanoid supply chain advisory
13304930782 Aug 11, 2026
93be2f2
Fix release upload panel layout
13304930782 Aug 11, 2026
2c0c42f
Restrict roll key issuer accounts
13304930782 Aug 11, 2026
e784a30
Harden delegated key issuer permissions
13304930782 Aug 11, 2026
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
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_BASE=/api
VITE_SITE_URL=http://localhost:5173
31 changes: 31 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: 2

updates:
- package-ecosystem: npm
directory: /
target-branch: codex/cuegrove-site
schedule:
interval: weekly
day: monday
time: "04:10"
timezone: Asia/Shanghai
open-pull-requests-limit: 5
groups:
production-dependencies:
dependency-type: production
development-dependencies:
dependency-type: development
commit-message:
prefix: deps

- package-ecosystem: github-actions
directory: /
target-branch: codex/cuegrove-site
schedule:
interval: weekly
day: monday
time: "04:30"
timezone: Asia/Shanghai
open-pull-requests-limit: 5
commit-message:
prefix: ci
79 changes: 79 additions & 0 deletions .github/workflows/supply-chain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Supply chain security

on:
pull_request:
push:
branches:
- main
- codex/cuegrove-site
schedule:
- cron: '23 19 * * 1'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: supply-chain-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
dependency-review:
name: Review dependency changes
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Block newly introduced high-risk dependencies
uses: actions/dependency-review-action@v5
with:
fail-on-severity: high
# RSC/server actions are not present in this static client-only site.
# Time-limited exception: SUPPLY_CHAIN_SECURITY.md (review 2026-08-29).
allow-ghsas: GHSA-qwww-vcr4-c8h2

production-audit:
name: Audit production dependencies
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 11.9.0

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm

- name: Install exactly locked dependencies
run: pnpm install --frozen-lockfile

- name: Block high and critical production vulnerabilities
run: pnpm audit --prod --audit-level high

secret-scan:
name: Scan repository history for secrets
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out full repository history
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Detect hard-coded credentials and tokens
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ build/
*.xccovreport
*.profraw

# CueGrove website
node_modules/
.pnpm-store/
dist/
server/node_modules/
server/.env
server/uploads/
.env
npm-debug.log*

# Local Xcode user state
xcuserdata/
*.xcuserstate
Expand Down
1 change: 1 addition & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
793108af90a321fe6c7a69b66de2def74189c02a:server/test/mfa.test.js:generic-api-key:20
30 changes: 30 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Project agent instructions

## Git workflow

- Never merge a working branch into `main` unless the user explicitly authorizes that specific merge.
- After completing and verifying a requested modification, stage only the files belonging to that task, commit them on the current working branch, and push that branch by default without waiting for a separate push request.
- Never include unrelated or pre-existing user changes in a commit. If the task changes cannot be isolated safely, stop and explain the conflict instead of switching branches or merging.

## Deployment handoff

- After completing changes that can be deployed, always include copyable deployment commands in the final response.
- The CueGrove production application is managed as the `cuegrove-api` Node project in the BaoTa panel.
- Never run, recommend, or include PM2 lifecycle or persistence commands for this project, including `pm2 start`, `pm2 stop`, `pm2 restart`, `pm2 reload`, `pm2 startOrReload`, `pm2 delete`, and `pm2 save`.
- Deployment commands should cover only the applicable code update, dependency installation, database migration, tests, frontend build, and health checks.
- After the server-side build is complete, explicitly tell the user: `请在宝塔面板中手动重启 Node 项目 cuegrove-api。`
- Run or suggest public API health checks only after the user has restarted the project in BaoTa. The health endpoint is `https://cuegroveapp.com/api/health`.
- Only include Nginx validation or reload commands when Nginx configuration changed as part of the task.

The standard CueGrove server update commands are:

```bash
cd /www/wwwroot/cuegrove
git pull --ff-only origin codex/cuegrove-site
pnpm install --frozen-lockfile
pnpm --dir server migrate
pnpm test
pnpm build
```

Then tell the user to restart `cuegrove-api` manually in BaoTa. Do not append PM2 commands.
Binary file added Brand/CueGrove/CueGrove-google-workspace-120.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Brand/CueGrove/CueGrove-icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Brand/CueGrove/CueGrove-icon-master.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
143 changes: 143 additions & 0 deletions CUEGROVE_DEPLOY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# CueGrove website deployment

The CueGrove website is isolated from the PromptDock app and from Mooncci. It uses a Vite static frontend, a PM2-managed Express API, MySQL, and SMTP.

## 1. Prepare isolated services

Create a new MySQL database and user for CueGrove. Do not reuse Mooncci tables or credentials.

```sql
CREATE DATABASE cuegrove CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'cuegrove'@'127.0.0.1' IDENTIFIED BY 'replace-with-a-strong-password';
GRANT ALL PRIVILEGES ON cuegrove.* TO 'cuegrove'@'127.0.0.1';
FLUSH PRIVILEGES;
```

Copy `server/.env.example` to `server/.env` and configure:

- the production `SITE_URL` and `ALLOWED_ORIGINS`;
- the isolated database credentials;
- a random `JWT_SECRET` of at least 32 characters;
- the existing Cloudflare Turnstile widget secret as `TURNSTILE_SECRET`;
- a unique secure cookie name and `COOKIE_SECURE=true`;
- optional initial SMTP host and credentials. After the first owner signs in,
SMTP can be moved into the encrypted database-backed settings page.

Never commit `server/.env`.

The Turnstile site key is public and embedded in the Early Access form. Its
secret must exist only in `server/.env` as `TURNSTILE_SECRET`. Submissions fail
closed if the secret is missing or Cloudflare cannot verify the browser token.
The application sends the requesting IP to Cloudflare `siteverify` for abuse
verification but does not store the IP in CueGrove's database.

`DB_PASSWORD`, `JWT_SECRET`, cookie security, and the API port are boot-level
settings and intentionally remain in `server/.env`. The website never returns
these values to a browser. The SMTP password saved in the administrator UI is
encrypted with a key derived from `JWT_SECRET`; if `JWT_SECRET` is rotated,
re-enter the SMTP password in the UI.

### Google Workspace SMTP relay

For a server with a fixed public IP, Google Workspace can authenticate SMTP relay
traffic by IP without storing a Google account password. Add the server IP in
Google Admin Console under **Apps > Google Workspace > Gmail > Routing > SMTP
relay service**, restrict senders to your domain, and require TLS. Then use:

```dotenv
MAIL_ENABLED=true
SMTP_HOST=smtp-relay.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_AUTH_REQUIRED=false
SMTP_TIMEOUT_MS=20000
SMTP_HELO_NAME=mail.cuegroveapp.com
SMTP_USER=
SMTP_PASS=
SMTP_FROM=CueGrove <mooncci@cuegroveapp.com>
SMTP_REPLY_TO=mooncci@cuegroveapp.com
```

Keep `SMTP_AUTH_REQUIRED=true` for providers that authenticate with a username
and password.

For reliable Google relay delivery, create a DNS-only `A` record for the EHLO
hostname that points to the server public IP, and configure the server
provider's reverse DNS/PTR for that IP to the same hostname. Google can
temporarily reject connections whose EHLO name is not a fully qualified domain
name or whose forward and reverse DNS do not match.

## 2. Install, migrate, and create the owner

```bash
pnpm install
pnpm --dir server migrate
read -s CUEGROVE_ADMIN_PASSWORD
export CUEGROVE_ADMIN_PASSWORD
pnpm --dir server create-admin -- --name "CueGrove Owner" --email owner@example.com --role owner
unset CUEGROVE_ADMIN_PASSWORD
pnpm build
```

The owner bootstrap command hashes the password with bcrypt and never writes it to a file.

## 3. Run behind Nginx

Copy `dist/` to the site root, start the API with:

```bash
pm2 start server/ecosystem.config.cjs
pm2 save
```

Adapt `server/nginx.cuegrove.conf.example`, enable HTTPS, then reload Nginx. The frontend and `/api` must share one origin for the administrator cookie and origin checks.
If the live site already has a Content Security Policy, allow
`https://challenges.cloudflare.com` in `script-src`, `connect-src`, and
`frame-src` so the Turnstile widget can load and complete verification.

## 4. Finish setup in the administrator UI

Sign in at `/admin/login`, open Settings, and configure:

1. the current cohort;
2. the real PromptDock download URL;
3. the feedback URL;
4. the administrator notification email;
5. whether new applications should trigger notification email;
6. SMTP host, port, connection security, mailbox credentials, sender, and
reply-to address.

Approvals remain disabled until the download URL is present. Use **Send test email** before reviewing applicants.

Owners can open **Administrators** to create or disable administrator accounts,
change `owner/admin` roles, clear login locks, and set a new password. At least
one active owner is always required. Public registration is intentionally not
available: visitors submit Early Access applications without creating an
account.

Environment SMTP values are used only as a fallback until an owner saves the
SMTP form. Passwords are encrypted at rest and are never displayed again.

## Updating an existing BaoTa deployment

From the project directory, update the same branch and apply all new migrations:

```bash
cd /www/wwwroot/cuegrove
git pull origin codex/cuegrove-site
pnpm install --frozen-lockfile
pnpm --dir server migrate
pnpm build
```

Then restart the `cuegrove-api` Node/PM2 project in BaoTa. Nginx should continue
serving `/www/wwwroot/cuegrove/dist` and proxying `/api/` to
`http://127.0.0.1:3001`. No new public registration route is required.

## Backup and recovery

- Back up the CueGrove MySQL database daily and retain at least 14 daily copies.
- Back up `server/.env` separately in an encrypted secrets manager.
- The static frontend can be recreated with `pnpm build`; do not treat `dist/` as the primary backup.
- Test a database restore before opening applications, and again after schema migrations.
- A failed result email does not undo a review decision. Open the application in the admin dashboard and use **Retry decision email**.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,15 @@ The backup format and SwiftData schema both remain at version 1. Future model ch
A free Personal Team supports local development and widget testing. A DMG can be created without a paid account, but public Developer ID signing, notarization, and Mac App Store distribution require the Apple Developer Program. An unsigned or unnotarized DMG may trigger Gatekeeper warnings on other Macs.

PromptDock is available under the [MIT License](LICENSE).

## CueGrove website

This repository also contains the independent CueGrove brand website and PromptDock Early Access workflow:

- `src/` contains the bilingual React/Vite public site and protected administrator UI.
- `server/` contains the isolated Express, MySQL, authentication, review, and SMTP service.
- `Brand/CueGrove/` contains the CueGrove source brand assets.

Use `pnpm dev` for the frontend, `pnpm server:dev` for the API, `pnpm build` for the production frontend, and `pnpm test` for backend validation and branded-email tests. Production setup and recovery instructions are in [CUEGROVE_DEPLOY.md](CUEGROVE_DEPLOY.md).

The PromptDock DMG endpoint is intentionally an unlisted direct download for approved Early Access recipients. Possession of that URL is not strict authorization: recipients can share it, and the server does not require an administrator session to download the current build. Use authenticated, expiring links if future releases require enforced per-user access.
Loading
Loading