diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml index 7436460..4465b91 100644 --- a/.github/workflows/release-assets.yml +++ b/.github/workflows/release-assets.yml @@ -7,7 +7,7 @@ on: tag: description: Existing draft release tag required: true - default: v0.1.0-demo.20 + default: v0.1.0-demo.21 type: string include_macos: description: Include macOS (requires Developer ID signing and Apple notarization secrets) @@ -168,7 +168,7 @@ jobs: if [[ "$INCLUDE_MACOS" = "true" ]]; then bun run release:build else - bun run release:build --platforms=windows-x64,linux-x64 + bun run release:build --platforms=macos-source,windows-x64,linux-x64 fi - name: Verify built bundles @@ -178,6 +178,7 @@ jobs: run: | set -euo pipefail files=( + "release/PacePaper-${VERSION}-macos-source.zip" "release/PacePaper-${VERSION}-windows-x64.zip" "release/PacePaper-${VERSION}-linux-x64.tar.gz" "release/PacePaper-${VERSION}-User-Guide.html" @@ -197,6 +198,11 @@ jobs: (cd release && shasum -a 256 -c SHA256SUMS.txt) unzip -tq "release/PacePaper-${VERSION}-windows-x64.zip" tar -tzf "release/PacePaper-${VERSION}-linux-x64.tar.gz" >/dev/null + unzip -tq "release/PacePaper-${VERSION}-macos-source.zip" + source_package="PacePaper-${VERSION}-macos-source" + unzip -p "release/PacePaper-${VERSION}-macos-source.zip" "${source_package}/Start PacePaper.command" > "$RUNNER_TEMP/Start PacePaper.command" + bash -n "$RUNNER_TEMP/Start PacePaper.command" + unzip -p "release/PacePaper-${VERSION}-macos-source.zip" "${source_package}/package.json" | cmp package.json - if [[ "$INCLUDE_MACOS" = "true" ]]; then unzip -tq "release/PacePaper-${VERSION}-macos-universal.zip" extracted_mac="$RUNNER_TEMP/digitaldp-mac-verification" @@ -231,6 +237,7 @@ jobs: release/PacePaper-${{ steps.meta.outputs.version }}-macos-universal.zip release/PacePaper-${{ steps.meta.outputs.version }}-windows-x64.zip release/PacePaper-${{ steps.meta.outputs.version }}-linux-x64.tar.gz + release/PacePaper-${{ steps.meta.outputs.version }}-macos-source.zip release/PacePaper-${{ steps.meta.outputs.version }}-User-Guide.html release/PacePaper-${{ steps.meta.outputs.version }}-User-Guide.txt release/PacePaper-${{ steps.meta.outputs.version }}-Release-Notes.txt @@ -243,6 +250,7 @@ jobs: run: | set -euo pipefail files=( + "release/PacePaper-${VERSION}-macos-source.zip" "release/PacePaper-${VERSION}-windows-x64.zip" "release/PacePaper-${VERSION}-linux-x64.tar.gz" "release/PacePaper-${VERSION}-User-Guide.html" @@ -286,6 +294,7 @@ jobs: `PacePaper-${version}-User-Guide.txt`, `PacePaper-${version}-Release-Notes.txt`, "SHA256SUMS.txt", + `PacePaper-${version}-macos-source.zip`, ]; if (process.env.INCLUDE_MACOS === "true") expected.push(`PacePaper-${version}-macos-universal.zip`); diff --git a/LICENSE b/LICENSE index a222cd1..0221605 100644 --- a/LICENSE +++ b/LICENSE @@ -19,9 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- - -Project-name notice: the name "PacePaper" and the project's icon artwork are -not granted by this license. You may use them to refer to this project and its -derivatives, but not as the name or icon of an unrelated product. diff --git a/README.md b/README.md index 3ec7f90..90bbdbb 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,27 @@ PacePaper is a local-network workspace for supervised examination practice and c PacePaper is an independent school-practice tool. It is not an official examination-delivery system, is not affiliated with or endorsed by the International Baccalaureate, Cambridge University Press & Assessment, Pearson, College Board, ACT, or any other awarding body, and should not be used to deliver live high-stakes examinations. +![WeChat contact QR code for PacePaper](docs/wechat-qr.png) + +## Download and run + +| Your computer | What to do | +| --- | --- | +| **Windows 10/11 (x64)** | Download `PacePaper-0.1.0-demo.21-windows-x64.zip`, extract it, and run `PacePaper.exe`. Nothing to install; works offline. | +| **Linux (x64)** | Download `PacePaper-0.1.0-demo.21-linux-x64.tar.gz`, extract it, and run `PacePaper`. Nothing to install; works offline. | +| **macOS (Apple silicon or Intel)** | Download `PacePaper-0.1.0-demo.21-macos-source.zip`, extract it, and double-click `Start PacePaper.command`. The launcher offers to install Bun and installs dependencies; first launch needs internet. | + +**These downloads are unsigned, so your computer may warn you the first time.** + +- **Windows:** SmartScreen may show “Windows protected your PC”. Choose **More info → Run anyway**. +- **macOS:** If the launcher cannot be opened, right-click it and choose **Open**, or run once in Terminal: + `xattr -d com.apple.quarantine "$HOME/Downloads/PacePaper-0.1.0-demo.21-macos-source/Start PacePaper.command"` + +PacePaper needs no account or licence key. The bundled sample and ordinary classroom use work offline apart from local-network sharing; optional YouTube or externally hosted HTTPS video needs internet unless hosted on the school network. + ## Try PacePaper in two minutes -**Download the latest demo** for Windows or Linux from the [releases page](https://github.com/GowangInc/PacePaper/releases). Extract the archive, open `PacePaper.exe` (Windows) or `PacePaper` (Linux), and your browser opens the teacher dashboard automatically. There is nothing to install — no Bun, no server setup, no internet connection required. Mac users can run the current source with `Start PacePaper.command` after installing [Bun](https://bun.sh/). +Use the **Download and run** table above to choose the Windows, Linux, or macOS download. On first launch you sign in with the default teacher login **`admin` / `admin`** (change it any time from the **Settings** section), and the Paper library already contains one preloaded **Sample paper** with no subject or IB branding. Open it, start a session, and you can try the whole workflow immediately — classes, timed phases, the candidate view, autosave, focus alerts, and printing — without creating anything first. @@ -142,13 +160,13 @@ The development server listens on `127.0.0.1:9148` by default. `public/index.htm ## For developers — build the desktop releases -The release builder produces shareable, self-contained macOS, Windows, and Linux bundles. They use the normal browser for the existing teacher dashboard and printing workflow; Bun, Node.js, the source checkout, and `public/` folder are not required on the recipient computer. +The release builder creates self-contained Windows and Linux bundles plus a macOS source archive. With Apple signing and notarization credentials, it can also create a signed universal macOS application. Packaged applications use the normal browser for the teacher dashboard and printing; the source archive contains the project files needed by its launcher. -The Mac bundle must be signed with a Developer ID Application certificate and notarized by Apple. The release builder deliberately refuses to create an ad-hoc-signed Mac download, because Gatekeeper can report that download as damaged without offering **Open Anyway**. +The compiled Mac application bundle must be signed with a Developer ID Application certificate and notarized by Apple. The release builder refuses to create an ad-hoc-signed app because Gatekeeper can report it as damaged without offering **Open Anyway**. The source archive does not require Apple signing. -**Version 0.1.0-demo.20 is prepared for Windows x64 and Linux x64.** Student sign-in is intentionally low-friction for a trusted school network: students choose their class and name from the active roster, with no PINs or direct links. Candidate saves use revision checks, and safe exam ending waits for each active candidate's latest save unless the teacher records an override reason. Startup database checks and verified pre-migration snapshots protect existing work. The release retains teacher-only marking controls and is not an official examination-delivery system. +**Version 0.1.0-demo.21 ships Windows x64 and Linux x64 applications plus a macOS source archive for Apple-silicon and Intel Macs.** Student sign-in is intentionally low-friction for a trusted school network: students choose their class and name from the active roster, with no PINs or direct links. Candidate saves use revision checks, and safe exam ending waits for each active candidate's latest save unless the teacher records an override reason. Startup database checks and verified pre-migration snapshots protect existing work. The release retains teacher-only marking controls and is not an official examination-delivery system. -Once the signing and notarization credentials described below are available, run `bun run release:build`. The generated archives, standalone user guides, and checksums are placed in `release/`. On macOS, use the notarized `macos-universal` archive for both Apple-silicon and Intel Macs; extract the correct platform archive and start its PacePaper app or executable. The macOS bundle and Windows executable carry the PacePaper icon; the Linux archive includes the matching PNG for desktop integration. A packaged release automatically opens the teacher dashboard on the first available local port from `9148` through `9158`, so the address may be different from `9148` when another local instance is running. The initial release is intentionally offline: it makes no licence, activation, telemetry, or other network call. See the illustrated teacher-facing [`USER_GUIDE.html`](USER_GUIDE.html), its editable [`USER_GUIDE.md`](USER_GUIDE.md) source, and [`release/README.md`](release/README.md) for concise install, storage, signing, and classroom-sharing notes. +Run `bun run release:build` to generate selected archives, standalone user guides, release notes, and checksums in `release/`. Without Apple release credentials, build the unsigned macOS source archive and the Windows/Linux applications with `bun run release:build --platforms=macos-source,windows-x64,linux-x64`; the source ZIP is built from the committed tree. With Developer ID and notarization credentials, the default build also produces a signed universal macOS app. Packaged applications open the teacher dashboard on the first available local port from `9148` through `9158`. See the illustrated [`USER_GUIDE.html`](USER_GUIDE.html), its editable [`USER_GUIDE.md`](USER_GUIDE.md) source, and [`release/README.md`](release/README.md) for install, storage, signing, and classroom-sharing details. ### macOS release credentials @@ -164,13 +182,13 @@ Set `DIGITALDP_MAC_NOTARY_KEYCHAIN` as well when the notary profile is stored in The GitHub release workflow performs the same process using these repository secrets: `APPLE_DEVELOPER_ID_P12_BASE64`, `APPLE_DEVELOPER_ID_P12_PASSWORD`, `APPLE_NOTARY_KEY_BASE64`, `APPLE_NOTARY_KEY_ID`, and `APPLE_NOTARY_ISSUER_ID`. Do not put certificate passwords or private keys in this repository. -To build only Windows and Linux without Apple credentials, explicitly select them: +To build the Windows/Linux applications and macOS source archive without Apple credentials: ```sh -bun run release:build --platforms=windows-x64,linux-x64 +bun run release:build --platforms=macos-source,windows-x64,linux-x64 ``` -For the GitHub workflow, set `include_macos` to `false` for that same platform set. The default still includes macOS and requires successful signing and notarization. Keep the release as a draft until the build and native Windows/Linux startup checks pass; publish only the files listed in that build's `SHA256SUMS.txt` plus the checksum file itself. +The source ZIP is built from the committed Git tree. The GitHub workflow builds this platform set when `include_macos` is `false`; its default also builds the signed and notarized `macos-universal` app. Keep the release as a draft until the build and native Windows/Linux startup checks pass; publish only the files listed in `SHA256SUMS.txt` plus the checksum file itself. The current release builder keeps data outside the replaceable executable, in the per-user application-data location for the platform. It does not package a live database, teacher paper, student response, or protected reference material. A fresh release seeds one generic **Sample paper** with no subject, level, or IB branding, so new users can try the exam workflow immediately; teacher-created and imported papers remain in the local library. Previously downloaded apps retain the code and examples from their own release; source edits do not update those downloads. The teacher login remains `admin` / `admin` and is reset on every app launch; it is not suitable for real student data. @@ -203,7 +221,7 @@ Open the room clock from the specific session for a projector or second screen. Linked clocks follow authoritative timing across windows, independently of decorative titles and names. Timing saves reject stale edits from another window. For a simple paper, reading and writing minutes can be corrected from the clock while the exam is ready or live: a live save moves candidate phase boundaries and deadlines immediately, which is the fastest recovery when a sitting must be extended. Ended exams and fixed timed sections remain read-only. Mounted student views refresh their server timeline without replacing editors. Check the student view before a classroom trial. -Each published build is summarized in its release notes. See the [current release notes](release/RELEASE_NOTES-0.1.0-demo.20.md) for what ships and the verification limits. +Each published build is summarized in its release notes. See the [current release notes](release/RELEASE_NOTES-0.1.0-demo.21.md) for what ships and the verification limits. Teacher-facing **Remove** actions archive records instead of permanently deleting them. Removed students cannot sign in, removed classes are unavailable for new sittings, and removed sittings disappear from the active exam list; all remain available under the corresponding **Removed** disclosure for restoration. Existing submissions stay retained and printable. Live sittings cannot be removed, classes with a live sitting must be ended first, and a student with unfinished live work cannot be removed until that response is submitted or the sitting ends. @@ -255,4 +273,4 @@ Before a classroom pilot, also test the complete teacher and student journey on ## License and support -PacePaper is open source under the [MIT License](LICENSE). The PacePaper name and icon artwork are not part of the MIT grant (see the notice in the LICENSE file). This is an independent project with no affiliation to any awarding body; it is provided for school practice and familiarisation. +PacePaper is open source under the [MIT License](LICENSE). The PacePaper name and icon artwork are not part of the MIT grant (see [TRADEMARK.md](TRADEMARK.md)). This is an independent project with no affiliation to any awarding body; it is provided for school practice and familiarisation. diff --git a/Start PacePaper.command b/Start PacePaper.command index 9fee1c7..62b0b33 100755 --- a/Start PacePaper.command +++ b/Start PacePaper.command @@ -1,20 +1,82 @@ -#!/bin/zsh +#!/bin/bash +# PacePaper — macOS double-click launcher (runs from source). +# +# Double-click this file in Finder. It checks for Bun, offers to install it if missing, +# installs npm dependencies on first run, then starts PacePaper and opens your browser. +# Keep the Terminal window open while PacePaper is in use; Control-C stops it. +# +# This file needs the project folder beside it (package.json, server.ts, src/, public/). set -u +cd "$(dirname "$0")" || exit 1 +export PATH="$HOME/.bun/bin:/opt/homebrew/bin:/usr/local/bin:$PATH" -cd -- "${0:A:h}" || exit 1 -export PATH="${HOME}/.bun/bin:/opt/homebrew/bin:/usr/local/bin:${PATH}" +pause_then_exit() { + [ -t 0 ] && { echo; read -r -p "Press Return to close this window. " _; } + exit "${1:-1}" +} +say() { printf '%s\n' "$1"; } + +# --- 1. Bun ----------------------------------------------------------------- if ! command -v bun >/dev/null 2>&1; then - echo "PacePaper needs Bun to run from source. Install Bun, then open this file again." - echo "https://bun.sh/" - echo - read -r "?Press Return to close this window." - exit 1 + say "" + say "PacePaper runs from source with Bun (https://bun.sh), which isn't installed yet." + say "" + say "Install it, then double-click this file again:" + say " curl -fsSL https://bun.sh/install | bash" + if [ -t 0 ]; then + echo + read -r -p "Install Bun now? [y/N] " answer + case "$answer" in + [yY]*) + say "" + say "Installing Bun..." + if ! curl -fsSL https://bun.sh/install | bash; then + say "" + say "Bun's installer failed. Check your internet connection, then try again." + pause_then_exit 1 + fi + export PATH="$HOME/.bun/bin:$PATH" + if ! command -v bun >/dev/null 2>&1; then + say "" + say "Bun was installed but isn't on the PATH yet. Close this window, open it again, and retry." + pause_then_exit 1 + fi + ;; + *) + say "" + say "Nothing was installed. PacePaper needs Bun to start." + pause_then_exit 1 + ;; + esac + else + pause_then_exit 1 + fi +fi + +# --- 2. Gatekeeper quarantine ---------------------------------------------- +if command -v xattr >/dev/null 2>&1 && xattr -p com.apple.quarantine "$0" >/dev/null 2>&1; then + say "" + say "Note: macOS quarantined this download. If double-clicking does nothing, run this once in Terminal:" + say " xattr -d com.apple.quarantine \"$0\"" +fi + +# --- 3. Dependencies (first run, or after package.json changes) ------------- +if [ ! -d node_modules ] || [ package.json -nt node_modules ]; then + say "" + say "Installing dependencies (this happens once)..." + if ! bun install; then + say "" + say "Dependency install failed. PacePaper needs an internet connection for this first step." + pause_then_exit 1 + fi fi -echo "Starting PacePaper from source. Keep this window open while the app is in use." -echo "Press Control-C here when you want to stop PacePaper." -echo +# --- 4. Start --------------------------------------------------------------- +say "" +say "Starting PacePaper. Keep this window open while the app is in use." +say "Press Control-C here when you want to stop PacePaper." +say "" exec bun run start:app diff --git a/TRADEMARK.md b/TRADEMARK.md new file mode 100644 index 0000000..ec05d54 --- /dev/null +++ b/TRADEMARK.md @@ -0,0 +1,5 @@ +# Trademark Notice + +Project-name notice: the name "PacePaper" and the project's icon artwork are +not granted by this license. You may use them to refer to this project and its +derivatives, but not as the name or icon of an unrelated product. diff --git a/USER_GUIDE.html b/USER_GUIDE.html index c3aaaab..e5f5146 100644 --- a/USER_GUIDE.html +++ b/USER_GUIDE.html @@ -251,7 +251,7 @@

PacePaper teacher guide

This step-by-step guide covers the current PacePaper classroom demo. PacePaper runs on one teacher computer. Students use a browser to connect to that computer through the school network. Start with the guide supplied with your app download; an older download may not include features described in a newer guide.

-

This guide matches PacePaper 0.1.0-demo.19.

+

This guide matches PacePaper 0.1.0-demo.21.

PacePaper is for practice and candidate familiarisation only. It does not deliver an official examination. A fresh installation starts with one preloaded Sample paper that has no subject, level, or IB branding, so you can try the whole exam workflow before building your own. An older app download does not update itself; use the guide supplied with your version.

The four parts of the teacher dashboard

Use the left-hand menu to move between these areas:

@@ -287,18 +287,18 @@

Quick classroom checklist

The detailed instructions below follow the same order.

Step 1 — Start PacePaper

-

PacePaper is a portable app, not an installer. Extract the complete download before opening it.

+

The Windows and Linux downloads are portable apps, not installers. The Mac download is a source archive, not a native app. Extract the complete download before starting it.

- - - + + +
ComputerDownloadOpen
Apple-silicon or Intel MacUse the source option belowStart PacePaper.command
Windows x64windows-x64.zipPacePaper.exe
Linux x64linux-x64.tar.gzPacePaper
Apple-silicon or Intel MacPacePaper-0.1.0-demo.21-macos-source.zipStart PacePaper.command
Windows 10/11 x64PacePaper-0.1.0-demo.21-windows-x64.zipPacePaper.exe
Linux x64PacePaper-0.1.0-demo.21-linux-x64.tar.gzPacePaper
-

Download the latest release bundle for Windows or Linux from the project's releases page. There is no Mac app bundle; on a Mac, install Bun and follow Run from a source checkout below, with IT help for the one-time setup.

+

The Mac download is a source archive, not a compiled app. Extract the complete archive and double-click the launcher. If Bun is missing, it offers to install Bun and installs the dependencies; the first launch needs internet. Windows and Linux downloads are self-contained and work offline with bundled content. YouTube and externally hosted HTTPS videos need internet unless hosted on the school network.

  1. Open PacePaper once on the teacher computer.
  2. Leave the application running for the whole lesson.
  3. @@ -640,7 +640,7 @@

    Student quick instructions

    These independently implemented tools are for practice and are not validated replacements for approved physical calculators. The calculator does not provide CAS, proprietary firmware or document formats, saved programs, general spreadsheets, geometry, 3D graphing or model certification. Expressions are capped at 1000 characters, lists/sequences at 1000 entries, matrices at 20×20 and polynomial roots at degree 6. Quartiles use linear interpolation, which can differ from a physical calculator. Open Supported functions and keyboard controls inside the calculator for commands and conventions.

    Troubleshooting

      -
    • The Mac app says it is damaged: Do not bypass Gatekeeper. Confirm that the release is notarized. If you are working from a source checkout, use Start PacePaper.command from the project folder.
    • +
    • The Mac launcher is blocked: Right-click Start PacePaper.command and choose Open, or remove its quarantine attribute once in Terminal as shown in the root README. The Mac download is a source archive, not a notarized app bundle.
    • The app does not open: Extract the complete download, use the correct platform file, and close any second copy of PacePaper.
    • Students cannot connect: Confirm that classroom sharing is on, use the displayed private-network address, and test it on a real student device. Do not give students localhost or 127.0.0.1.
    • A student cannot sign in: Check that the teacher selected the correct class and that the student name is in the active roster.
    • diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 9c3091a..dd57f19 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -2,7 +2,7 @@ This step-by-step guide covers the current PacePaper classroom demo. PacePaper runs on one teacher computer. Students use a browser to connect to that computer through the school network. Start with the guide supplied with your app download; an older download may not include features described in a newer guide. -This guide matches PacePaper **0.1.0-demo.19**. +This guide matches PacePaper **0.1.0-demo.21**. PacePaper is for **practice and candidate familiarisation only**. It does not deliver an official examination. A fresh installation starts with one preloaded **Sample paper** that has no subject, level, or IB branding, so you can try the whole exam workflow before building your own. An older app download does not update itself; use the guide supplied with your version. @@ -44,15 +44,15 @@ The detailed instructions below follow the same order. ## Step 1 — Start PacePaper -PacePaper is a portable app, not an installer. Extract the complete download before opening it. +The Windows and Linux downloads are portable apps, not installers. The Mac download is a source archive, not a native app. Extract the complete download before starting it. | Computer | Download | Open | | --- | --- | --- | -| Apple-silicon or Intel Mac | Use the source option below | `Start PacePaper.command` | -| Windows x64 | `windows-x64.zip` | `PacePaper.exe` | -| Linux x64 | `linux-x64.tar.gz` | `PacePaper` | +| Apple-silicon or Intel Mac | `PacePaper-0.1.0-demo.21-macos-source.zip` | `Start PacePaper.command` | +| Windows 10/11 x64 | `PacePaper-0.1.0-demo.21-windows-x64.zip` | `PacePaper.exe` | +| Linux x64 | `PacePaper-0.1.0-demo.21-linux-x64.tar.gz` | `PacePaper` | -Download the latest release bundle for Windows or Linux from the project's releases page. There is no Mac app bundle; on a Mac, install Bun and follow **Run from a source checkout** below, with IT help for the one-time setup. +The Mac download is a source archive, not a compiled app. Extract the complete archive and double-click the launcher. If Bun is missing, it offers to install Bun and installs the dependencies; the first launch needs internet. Windows and Linux downloads are self-contained and work offline with bundled content. YouTube and externally hosted HTTPS videos need internet unless hosted on the school network. 1. Open PacePaper once on the teacher computer. 2. Leave the application running for the whole lesson. @@ -454,7 +454,7 @@ These independently implemented tools are for practice and are not validated rep ## Troubleshooting -- **The Mac app says it is damaged:** Do not bypass Gatekeeper. Confirm that the release is notarized. If you are working from a source checkout, use `Start PacePaper.command` from the project folder. +- **The Mac launcher is blocked:** Right-click `Start PacePaper.command` and choose **Open**, or remove its quarantine attribute once in Terminal as shown in the root README. The Mac download is a source archive, not a notarized app bundle. - **The app does not open:** Extract the complete download, use the correct platform file, and close any second copy of PacePaper. - **Students cannot connect:** Confirm that classroom sharing is on, use the displayed private-network address, and test it on a real student device. Do not give students `localhost` or `127.0.0.1`. - **A student cannot sign in:** Check that the teacher selected the correct class and that the student name is in the active roster. diff --git a/docs/wechat-qr.png b/docs/wechat-qr.png new file mode 100644 index 0000000..ac0eb67 Binary files /dev/null and b/docs/wechat-qr.png differ diff --git a/package.json b/package.json index e1d84b8..349e08f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pacepaper", - "version": "0.1.0-demo.20", + "version": "0.1.0-demo.21", "private": true, "type": "module", "scripts": { diff --git a/release/README.md b/release/README.md index 89a3353..ca08cb7 100644 --- a/release/README.md +++ b/release/README.md @@ -2,9 +2,9 @@ This folder receives the shareable PacePaper bundles made by `bun run release:build`. -Bundles built from the current source are self-contained: they include the PacePaper executable and all browser interface files. Teachers do not need Bun, Node.js, or source code. Students need only a browser and a connection to the teacher's computer; an Internet connection is not needed during use. The current builder excludes existing databases, teacher papers, submissions, and protected reference resources. A fresh release installs one generic **Sample paper** with no subject, level, or IB branding, so new users can try the exam workflow immediately. +The Windows and Linux bundles are self-contained: each includes the PacePaper executable and browser interface. The macOS download is a source archive with the project files and launcher; it needs Bun and dependencies, which the launcher offers to install on first run with an internet connection. Students need only a browser and a connection to the teacher's computer. Bundled content works offline; optional YouTube or externally hosted HTTPS video needs internet unless hosted on the school network. The builder excludes existing databases, teacher papers, submissions, and protected reference resources. A fresh release installs one generic **Sample paper** with no subject, level, or IB branding. -Version **0.1.0-demo.20** targets Windows x64 and Linux x64, under the PacePaper name. There is no Mac application in this release because Apple signing and notarization credentials are not configured. Mac users can run the source as described below. A previously downloaded app retains its own code and examples. Check the release notes supplied with that download. +Version **0.1.0-demo.21** includes self-contained Windows x64 and Linux x64 applications and a macOS source archive for Apple-silicon and Intel Macs. The source archive is not a compiled macOS app; its launcher offers to install Bun and installs the project dependencies. The first Mac launch needs an internet connection. A previously downloaded app retains its own code and examples. Check the release notes supplied with that download. Student sign-in is deliberately low-friction for a trusted school network: students choose their class and name from the active roster. No candidate PIN or direct link is created or required. @@ -12,13 +12,13 @@ PacePaper now checks the SQLite database at startup. Before a schema upgrade, it Candidate responses now use revision checks to reject stale saves from another tab or device. Ending an exam waits for each active candidate's latest confirmed save; the teacher can keep the exam running or enter a reason to end it despite unresolved candidates. -Start with `USER-GUIDE.html`, included beside the app or executable in each bundle. It covers the complete teacher and student workflow. A plain-text `USER-GUIDE.txt` is included as an accessible fallback. Both guides are also provided as separate release downloads. +For the Windows and Linux apps, start with `USER-GUIDE.html` included beside the executable; `USER-GUIDE.txt` is the accessible fallback. The macOS source archive contains the editable project guide files. Both standalone guide formats are also provided as release downloads. ## Choose the correct download -- macOS — run the source for now; no Mac archive is included in demo.20 -- `PacePaper-*-windows-x64.zip` — most Windows PCs -- `PacePaper-*-linux-x64.tar.gz` — 64-bit Linux PCs using glibc +- `PacePaper-0.1.0-demo.21-macos-source.zip` — macOS source archive (Apple silicon or Intel) +- `PacePaper-0.1.0-demo.21-windows-x64.zip` — Windows 10/11 x64 +- `PacePaper-0.1.0-demo.21-linux-x64.tar.gz` — Linux x64 using glibc - `PacePaper-*-User-Guide.html` — illustrated, browser-friendly guide - `PacePaper-*-User-Guide.txt` — the same full guide included inside each platform archive - `PacePaper-*-Release-Notes.txt` — review focus, important limitations, and verification evidence @@ -27,21 +27,21 @@ The Windows executable uses the PacePaper application icon. The Linux archive in Extract the entire archive before starting it. Do not run an executable from inside the archive. -On Windows, double-click `PacePaper.exe`. On Linux, make `PacePaper` executable if required and run it. The app opens the teacher dashboard in the normal browser on the first free local port from `9148` through `9158`; use the address that opens automatically. If every port in that range is occupied, close the conflicting local app or have an advanced launcher set `PORT` before starting PacePaper. A future macOS download must be notarized before use. +On macOS, extract the complete source archive and double-click `Start PacePaper.command`; if Bun is missing, the launcher offers to install it and installs dependencies. On Windows, double-click `PacePaper.exe`. On Linux, make `PacePaper` executable if required and run it. The packaged apps open the teacher dashboard in the normal browser on the first free local port from `9148` through `9158`; use the address that opens automatically. If every port in that range is occupied, close the conflicting local app or have an advanced launcher set `PORT` before starting PacePaper. -The current source is labelled `0.1.0-demo.20`, and a fresh release installs the generic **Sample paper** described above. See `RELEASE_NOTES-0.1.0-demo.20.md` for the dated review record. Later source edits require a new build and verification. Existing downloads are unchanged. +The current source is labelled `0.1.0-demo.21`, and a fresh release installs the generic **Sample paper** described above. See `RELEASE_NOTES-0.1.0-demo.21.md` for the release record. Later source edits require a new build and verification. Existing downloads are unchanged. -The release builder will not create a Mac archive without Developer ID signing and successful Apple notarization. Windows may still show a SmartScreen warning while the demo lacks an established publisher reputation. +This release does not include a compiled macOS app because Developer ID signing and Apple notarization credentials are not configured; it includes the macOS source archive instead. The Windows and Linux builds are unsigned, so Windows may show a SmartScreen warning. macOS may report that the launcher cannot be opened; right-click it and choose **Open**, or remove the quarantine attribute once as described in the root README. ## Run from a source checkout -Source use requires Bun and a one-time `bun install` in the project folder. On a Mac, open that folder and double-click `Start PacePaper.command`. On Windows or Linux, open a terminal in the folder and run `bun run start:app`. Keep the terminal open while using PacePaper and press Control-C there to stop it. This source launcher uses the same app data, example papers, automatic browser opening, and classroom-sharing controls as a build made from that source. +Source use requires Bun and project dependencies. On a Mac, double-click `Start PacePaper.command`; it offers to install Bun and runs `bun install` when dependencies are missing, so the first launch needs internet. On Windows or Linux, open a terminal in the project folder and run `bun run start:app` after installing Bun and dependencies. Keep the terminal open while using PacePaper and press Control-C there to stop it. The source launcher uses the same app data, example papers, automatic browser opening, and classroom-sharing controls as a build made from that source. For source development, `bun run samples:build` regenerates manifests, ignored portable papers, and teacher marking guides. `bun run samples:seed` adds or safely upgrades the library, preserving teacher edits and earlier session versions. The app launcher performs the library upgrade automatically; unchanged input does not create duplicates. ## Demo boundaries -- It is fully offline: no telemetry, account registration, activation, or licence call is made. +- The apps make no telemetry, account-registration, activation, or licence calls. Windows and Linux work offline with bundled content; optional hosted video and first-time Mac source setup need internet. - A fresh installation starts with teacher login `admin` / `admin`. Change the password in **Settings**. - Student sign-in uses the active class roster and student name. It does not require candidate PINs, direct links, accounts, or internet access. - It is for familiarisation only. Do not use it with real student data, high-stakes assessment, or copyrighted papers without school approval. diff --git a/release/RELEASE_NOTES-0.1.0-demo.21.md b/release/RELEASE_NOTES-0.1.0-demo.21.md new file mode 100644 index 0000000..cfdb314 --- /dev/null +++ b/release/RELEASE_NOTES-0.1.0-demo.21.md @@ -0,0 +1,24 @@ +# PacePaper 0.1.0-demo.21 release notes + +Release date: 17 October 2026. + +## What is new + +- **macOS source download.** The release includes a source archive for Apple-silicon and Intel Macs. Its double-click launcher offers to install Bun, installs project dependencies when needed, and prints the Gatekeeper recovery command. The first setup needs internet; bundled content works offline. Optional YouTube or externally hosted HTTPS video needs internet unless hosted on the school network. +- **Clear platform coverage.** Windows 10/11 x64 and Linux x64 receive self-contained apps that work offline with bundled content. macOS receives the source archive, not a compiled or notarized application. +- **Canonical MIT licence.** The repository now has an unmodified MIT licence text; the PacePaper name and icon notice is in `TRADEMARK.md`. + +## Downloads + +- `PacePaper-0.1.0-demo.21-windows-x64.zip` — Windows 10/11, x64. +- `PacePaper-0.1.0-demo.21-linux-x64.tar.gz` — Linux x64 using glibc. +- `PacePaper-0.1.0-demo.21-macos-source.zip` — macOS source archive for Apple silicon and Intel. +- `PacePaper-0.1.0-demo.21-User-Guide.html` and `.txt` — illustrated and plain-text user guides. + +The Windows/Linux applications are unsigned; Windows SmartScreen may warn. The macOS source launcher is not notarized and may be blocked by Gatekeeper. See the root README for the one-time open/quarantine instructions. + +## Build and verification scope + +Release verification results are recorded in `VERIFICATION-0.1.0-demo.21.md` after the local build and GitHub checks complete. The macOS source archive is syntax-checked, but this release does not include a native macOS application smoke test. Windows and Linux packaged applications are checked on their native GitHub runners. + +PacePaper remains a supervised practice and familiarisation tool, not an official examination-delivery system. Classroom sharing uses ordinary HTTP on a trusted local network; use only approved practice materials and fake candidates. diff --git a/scripts/build-release.ts b/scripts/build-release.ts index af8279a..7327b94 100644 --- a/scripts/build-release.ts +++ b/scripts/build-release.ts @@ -190,6 +190,14 @@ function archiveNotarizedMacPackage(packageDirectory: string, stagingRoot: strin return { archiveName, archivePath }; } +function buildMacSource(stagingRoot: string): Archive { + const packageName = `PacePaper-${version}-macos-source`; + const archiveName = releaseArchiveName(version, "macos-source"); + const archivePath = join(stagingRoot, archiveName); + run(["git", "archive", "--format=zip", `--prefix=${packageName}/`, "--output", archivePath, "HEAD"], root); + return { archiveName, archivePath }; +} + function prepareMacApp(packageDirectory: string): MacAppPaths { const appDirectory = join(packageDirectory, "PacePaper.app"); const contentsDirectory = join(appDirectory, "Contents"); @@ -288,6 +296,11 @@ try { console.log(`Building ${macUniversalTarget.id}…`); archives.push(await buildMacUniversal(stagingRoot)); } + if (selectedPlatforms.includes("macos-source")) { + console.log("Building macos-source…"); + archives.push(buildMacSource(stagingRoot)); + } + for (const target of targets.filter(({ id }) => selectedPlatforms.includes(id))) { console.log(`Building ${target.id}…`); archives.push(await buildTarget(target, stagingRoot)); @@ -296,7 +309,7 @@ try { const omittedArchiveNames = RELEASE_PLATFORMS .filter((platform) => !selectedPlatforms.includes(platform)) .map((platform) => releaseArchiveName(version, platform)); - // Never leave a previous current-version Mac archive beside a non-Mac build. + // Remove stale outputs for platforms omitted from this build. for (const archiveName of [...retiredArchiveNames, ...omittedArchiveNames]) { rmSync(join(releaseDirectory, archiveName), { force: true }); } @@ -314,7 +327,7 @@ try { .map((assetName) => `${sha256(join(releaseDirectory, assetName))} ${assetName}`) .join("\n"); writeFileSync(join(releaseDirectory, "SHA256SUMS.txt"), `${checksums}\n`); - console.log(`Created ${archives.length} standalone bundles in ${releaseDirectory}`); + console.log(`Created ${archives.length} release archives in ${releaseDirectory}`); } finally { rmSync(stagingRoot, { recursive: true, force: true }); } diff --git a/scripts/release-platforms.test.ts b/scripts/release-platforms.test.ts index 2756c59..7588377 100644 --- a/scripts/release-platforms.test.ts +++ b/scripts/release-platforms.test.ts @@ -6,8 +6,9 @@ describe("explicit release platforms", () => { expect(releasePlatforms([])).toEqual(RELEASE_PLATFORMS); }); - test("allows an intentional Windows/Linux-only build in canonical order", () => { + test("allows an intentional Windows/Linux-only build and unsigned Mac source archive", () => { expect(releasePlatforms(["--platforms=linux-x64,windows-x64"])).toEqual(["windows-x64", "linux-x64"]); + expect(releasePlatforms(["--platforms=macos-source,linux-x64,windows-x64"])).toEqual(["macos-source", "windows-x64", "linux-x64"]); expect(releasePlatforms(["--platforms=macos-universal"])).toEqual(["macos-universal"]); }); @@ -19,9 +20,10 @@ describe("explicit release platforms", () => { ]) expect(() => releasePlatforms(args)).toThrow(); }); - test("names only the supported archive formats", () => { + test("names the supported archive formats", () => { expect(RELEASE_PLATFORMS.map((platform) => releaseArchiveName("0.1.0-demo.5", platform))).toEqual([ "PacePaper-0.1.0-demo.5-macos-universal.zip", + "PacePaper-0.1.0-demo.5-macos-source.zip", "PacePaper-0.1.0-demo.5-windows-x64.zip", "PacePaper-0.1.0-demo.5-linux-x64.tar.gz", ]); diff --git a/scripts/release-platforms.ts b/scripts/release-platforms.ts index 2d9572c..bce7ea6 100644 --- a/scripts/release-platforms.ts +++ b/scripts/release-platforms.ts @@ -1,11 +1,11 @@ -export const RELEASE_PLATFORMS = ["macos-universal", "windows-x64", "linux-x64"] as const; +export const RELEASE_PLATFORMS = ["macos-universal", "macos-source", "windows-x64", "linux-x64"] as const; export type ReleasePlatform = typeof RELEASE_PLATFORMS[number]; /** A partial release must be explicit; omitting the flag keeps macOS signing mandatory. */ export function releasePlatforms(arguments_: readonly string[]): readonly ReleasePlatform[] { if (arguments_.length === 0) return RELEASE_PLATFORMS; if (arguments_.length !== 1 || !arguments_[0]?.startsWith("--platforms=")) { - throw new Error("Usage: bun run release:build [--platforms=macos-universal,windows-x64,linux-x64]"); + throw new Error("Usage: bun run release:build [--platforms=macos-universal,macos-source,windows-x64,linux-x64]"); } const requested = arguments_[0].slice("--platforms=".length).split(","); if (new Set(requested).size !== requested.length