Skip to content
Merged
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
34 changes: 34 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
permissions:
contents: read
id-token: write
outputs:
tag: ${{ steps.release.outputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
Expand Down Expand Up @@ -232,3 +234,35 @@ jobs:
fi

npm publish --provenance --access public --tag "${DIST_TAG}"

installers:
# Unsigned double-click installers (macOS .command, Windows .cmd, Linux .sh),
# built from the same verified release commit once npm publication succeeded,
# with stable names so releases/latest/download/<name> links keep working.
needs: publish
if: github.repository == 'Gentleman-Programming/gentle-shell'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
persist-credentials: false
ref: ${{ github.sha }}

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: "24"
package-manager-cache: false

- name: Build double-click installers
run: node scripts/build-installer-bundles.mjs --out "${RUNNER_TEMP}/installers"

- name: Attach installers to the release
env:
GH_TOKEN: ${{ github.token }}
# The tag the publish job verified against protected main, not the raw input.
RELEASE_TAG: ${{ needs.publish.outputs.tag }}
run: gh release upload "${RELEASE_TAG}" "${RUNNER_TEMP}"/installers/* --repo "${GITHUB_REPOSITORY}" --clobber
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ The [v3.5.1 release](https://github.com/Gentleman-Programming/gentle-shell/relea

> **Naming transition:** The product is called `gentle-shell`; the current npm package and repository remain `gentle-pi` until migration.

### Easiest: download and double-click (no terminal needed)

Download the installer for your computer, double-click it, and follow the steps in your browser. It installs everything Gentle Shell needs (Node.js, pnpm, Pi and Gentle Shell), or updates what you already have, and installs nothing until you confirm the plan it shows you. (To show that plan it may first download Node.js and pnpm into a temporary folder, which it removes afterwards.)

| Your computer | Download | Then |
| --- | --- | --- |
| **macOS** | [gentle-shell-installer-macos.zip](https://github.com/Gentleman-Programming/gentle-shell/releases/latest/download/gentle-shell-installer-macos.zip) | Open the zip, then double-click **Install Gentle Shell.command** inside the *Gentle Shell Installer* folder. |
| **Windows** | [gentle-shell-installer-windows.zip](https://github.com/Gentleman-Programming/gentle-shell/releases/latest/download/gentle-shell-installer-windows.zip) | Right-click the zip → **Extract All**. Open the extracted folder, then the *Gentle Shell Installer* folder inside it, and double-click **Install Gentle Shell.cmd**. It does not run from inside the zip. |
| **Linux** | [gentle-shell-installer-linux.tar.gz](https://github.com/Gentleman-Programming/gentle-shell/releases/latest/download/gentle-shell-installer-linux.tar.gz) | Extract it, then double-click **install-gentle-shell.sh**. If your file manager does not run scripts, run `sh install-gentle-shell.sh` in that folder. |

A small window opens, then the installer appears in your browser. Use the tab it opens, and keep the small window open until the installer says it is done. If a download link does not open, the newest release does not include the installers yet: use [Path C](#path-c-browser-installer-from-a-checkout) meanwhile.

> **Your computer will warn you the first time.** These installers are not signed with an Apple or Microsoft developer certificate yet, so the system cannot verify who made them. That warning is expected; here is how to continue:
>
> - **macOS:** you see *"Install Gentle Shell.command" Not Opened* (or *cannot be opened because Apple cannot check it*). Click **Done**, open **System Settings → Privacy & Security**, scroll down to the message about *Install Gentle Shell.command*, click **Open Anyway**, and confirm with your password. On older macOS versions you can instead right-click the file, choose **Open**, then **Open** again. You only do this once.
> - **Windows:** you see *Windows protected your PC*: click **More info**, then **Run anyway**. If you see *Open File – Security Warning* instead, click **Run**.
> - **Linux:** if double-click opens the file in an editor, run `sh install-gentle-shell.sh` in that folder instead.
>
> Only download from this repository's [Releases](https://github.com/Gentleman-Programming/gentle-shell/releases) page. To check a download, compare its SHA-256 with [gentle-shell-installers-SHA256SUMS.txt](https://github.com/Gentleman-Programming/gentle-shell/releases/latest/download/gentle-shell-installers-SHA256SUMS.txt).

The installer is a preview: it is tested on Linux and in CI, while clean-machine runs on macOS and Windows are still being verified. How it works and what it changes: **[installation wizard](docs/install-wizard.md)**.

### Path A: standalone `gentle-shell` (recommended, no pi changes)

`gentle-shell` opens Pi with the Gentle Shell package loaded, without installing it into your pi agent or editing its `settings.json`.
Expand Down Expand Up @@ -289,9 +311,9 @@ See the [v3.5.1 release notes](https://github.com/Gentleman-Programming/gentle-s

**Builtin codemode warning.** gentle-pi replaces Pi's builtin `codemode` with its compact renderer, so Pi warns at startup that the builtin was not loaded. In your own Pi home (`pi` with this package, or `gentle-shell --link`), gentle-pi asks once in the interactive TUI whether to add `"-builtin:codemode"` to `extensions` in the agent `settings.json` (usually `~/.pi/agent/settings.json`); it writes only if you accept, and the warning disappears from the next launch. A declined prompt is not repeated. To silence it by hand, add the entry yourself, for example `"extensions": ["-builtin:codemode"]`. Isolated `gentle-shell` homes already carry it.

### Path C: browser installer (preview)
### Path C: browser installer from a checkout

The browser installer sets up Gentle Shell on a new computer or one that already has some of it: it installs what is missing (Node.js, pnpm, Pi, Gentle Shell) and updates an existing Gentle Shell. It checks the machine, shows exactly what it will change, and changes nothing until you confirm.
The same installer as the [download above](#easiest-download-and-double-click-no-terminal-needed), started from a clone instead of a download:

```bash
git clone https://github.com/Gentleman-Programming/gentle-shell.git
Expand All @@ -304,7 +326,7 @@ sh scripts/bootstrap.sh
scripts\bootstrap.cmd
```

The bootstrap gets Node.js and pnpm into a temporary folder if they are missing, then opens the wizard in your browser at a private `127.0.0.1` address. Use the tab it opens: the link works once and expires after 2 minutes. On the review screen, choose what to install:
It installs what is missing (Node.js, pnpm, Pi, Gentle Shell) and updates an existing Gentle Shell; nothing changes until you confirm. The bootstrap gets Node.js and pnpm into a temporary folder if they are missing, then opens the wizard in your browser at a private `127.0.0.1` address. Use the tab it opens: the link works once and expires after 2 minutes. On the review screen, choose what to install:

- **Latest release** (recommended): the published Gentle Shell with its pinned Gentle AI binary.
- **Latest main**: development builds of Gentle Shell and Gentle AI from the latest commit of `main`, built on your computer. Needs Go.
Expand Down
40 changes: 35 additions & 5 deletions docs/install-wizard.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,41 @@ foundation, the standard installation runner module (including runtime
persistence), the secure local wizard host with its packaged entry and the
interactive browser wizard UI are implemented. Windows native validation
remains unavailable locally.
**Preview:** run it from a checkout with `sh scripts/bootstrap.sh` (macOS,
Linux) or `scripts\bootstrap.cmd` (Windows), as the [README](../README.md#path-c-browser-installer-preview)
shows. There are no published bootstrap artifacts yet, and native macOS/Windows
clean-machine runs are still unverified (T7); one Linux clean-container run
passed (see [Clean-machine acceptance](#clean-machine-acceptance-t7)).
**Preview:** download the unsigned double-click installer for your system
from a release, or run it from a checkout with `sh scripts/bootstrap.sh`
(macOS, Linux) or `scripts\bootstrap.cmd` (Windows), as the
[README](../README.md#easiest-download-and-double-click-no-terminal-needed)
shows. Native macOS/Windows clean-machine runs are still unverified (T7); one
Linux clean-container run passed (see
[Clean-machine acceptance](#clean-machine-acceptance-t7)).

### Double-click downloads

[`scripts/build-installer-bundles.mjs`](../scripts/build-installer-bundles.mjs)
builds three archives with stable names, attached to every release by the
`installers` job of `publish.yml` after the verified npm publication (same
commit, `contents: write` only in that job), with
`gentle-shell-installers-SHA256SUMS.txt`:

| Asset | Launcher |
| --- | --- |
| `gentle-shell-installer-macos.zip` | `Gentle Shell Installer/Install Gentle Shell.command` |
| `gentle-shell-installer-windows.zip` | `Gentle Shell Installer/Install Gentle Shell.cmd` (CRLF, ends with `pause`) |
| `gentle-shell-installer-linux.tar.gz` | `gentle-shell-installer/install-gentle-shell.sh` |

Each launcher runs `installer/scripts/bootstrap.sh` (or `bootstrap.cmd`) next to
it; `installer/` holds `package.json`, every `installerPaths` file and every
module they import (only `node:` built-ins otherwise), as real files because the
bootstrap refuses symlinked bundle files. The downloads are **unsigned**:
macOS Gatekeeper and Windows SmartScreen warn on first run, and the README
explains how to continue. Signing and notarization are not done yet.

The `installers` job uploads to the release with the tag the `publish` job
verified (`needs.publish.outputs.tag`). It runs after npm publication, so its
failure never affects npm, but it marks the run failed: recover with
`gh run rerun <run id> --failed`, not a new `publish.yml` dispatch (that version
is already on npm). Each launcher reports whether the bootstrap succeeded before
it lets the window close.

## What is available

Expand Down
30 changes: 30 additions & 0 deletions odd/tasks/double-click-installers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Double-click installers (unsigned)

Objective: a person who does not use a terminal downloads one file, double-clicks it, and the installation wizard opens and runs.
Branch: `feat/double-click-installers` (from `main` be2869b7b). Delivery: single PR. Test runner: `node --experimental-strip-types --test <files>`; suite `pnpm test`.

## Specs

- S1. "como un ejecutor clásico de computadora para una persona que no sabe. Bien, entonces vos entrás, le das un doble clic, se abre el instalador y hace los pasos": one downloadable file per system whose double-click starts the existing bootstrap and wizard, with no git, clone or typed command — macOS (`.command`), Windows (`.cmd`), Linux (`.sh`).
- S2. "sin firma": the downloads are unsigned; no code-signing or notarization.
- S3. "indicando esto que me dices en el readme": the README explains the download and the operating-system warnings an unsigned file triggers and how to continue past them (macOS Gatekeeper "Open Anyway", Windows SmartScreen "More info → Run anyway", extracting the zip first).
- S4 (assumption, needed by S1): every release gets the installers attached with stable names, so a "latest" download link always points at the newest release, plus SHA-256 checksums.

## Tasks

| ID | Specs | Route | Status | Evidence |
|----|-------|-------|--------|----------|
| T1 | S1, S2, S4 (bundle builder: wizard files + launchers per OS, archives, checksums) | inline | done e81b84140 | RED (module missing) → GREEN installer-bundles 6/0; downloads ~100 KB; ditto keeps the .command executable |
| T2 | S4 (publish.yml: attach the installers to the release after the verified publication) | inline | done 3e04bcb8a | RED→GREEN package-manifest workflow test; actionlint unavailable |
| T3 | S3 (README download section with unsigned warnings; install-wizard doc) | inline | done 98cb92c69 | structural readback; anchors checked by the verifier |

Route evidence: no Writer trigger (sequential, shared bundle layout). Risk: item 5 (release workflow) → independent verifier unless the native assessment says otherwise.

## Log

- L1 (2026-10-09, user): "Cuéntame ahora cómo aparece en el readme todo el tema de la instalación fácil con el web. Bien, porque de vuelta, esto necesito que sea como un ejecutor clásico de computadora para una persona que no sabe. Bien, entonces vos entrás, le das un doble clic, se abre el instalador y hace los pasos. Esa es la idea."
- L2 (2026-10-09, user decision): "sin firma, indicando esto que me dices en el readme"
- L3 (evidence): README Path C requires `git clone` and a terminal command. `publish.yml` only publishes npm; the GitHub release is created before it runs (gentle-pi-release skill). The wizard imports only `node:` modules, so a bundle needs no dependencies.
- L4 (verification): native assess be2869b7b..98cb92c69 = high (shell_source in publish.yml). Independent verifier: PASS S1–S4, no blockers. Native review lineage review-6d42a119a798ceaa approved by risk, readability and reliability lenses; authority burned. Full `pnpm test`: only the three failures already on main.
- L5 (follow-up from verifier and review advisories): launchers report a failed bootstrap; the scanner also follows `new URL("./file", import.meta.url)`; the installers job uploads with the publish job's verified tag and `package-manager-cache: false`; named assets; README Windows folders, temporary-tools wording and a fallback when links are not live yet; recovery note in docs. Not verified: real double-click on clean macOS/Windows/Linux, Gatekeeper/SmartScreen screens, the job on a real runner.

Loading
Loading