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
18 changes: 18 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Build

on:
workflow_dispatch:
pull_request:
paths-ignore: ['*.md']
branches: ['main']

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
build:
if: github.event.pull_request.draft == false
uses: Start9Labs/start-technologies/.github/workflows/build.yml@master
secrets:
DEV_KEY: ${{ secrets.DEV_KEY }}
5 changes: 5 additions & 0 deletions .github/workflows/desktop-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ on:
push:
tags:
- "v*"
# StartOS packaging tags carry the packaging revision as `_<n>`
# (v5.7.0_0) and are pushed by tagAndRelease.yml, not by release.sh.
# They are not desktop releases, and the gates job below would reject
# them anyway for not matching package.json's version.
- "!v*_*"
workflow_dispatch:

permissions:
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Release

on:
push:
tags:
# StartOS release tags carry the packaging revision as `_<n>` (v5.7.0_0),
# written by tagAndRelease. The app's own desktop lane tags plain `v5.7.0`,
# which `v*.*` would also match — so this filter names the underscore.
- 'v*_*'

jobs:
release:
uses: Start9Labs/start-technologies/.github/workflows/release.yml@master
with:
RELEASE_REGISTRY: ${{ vars.RELEASE_REGISTRY }}
S3_S9PKS_BASE_URL: ${{ vars.S3_S9PKS_BASE_URL }}
secrets:
DEV_KEY: ${{ secrets.DEV_KEY }}
S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }}
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
permissions:
contents: write
24 changes: 24 additions & 0 deletions .github/workflows/tagAndRelease.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Tag and Release

on:
push:
branches: ['main']
paths-ignore: ['*.md']

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

jobs:
tag:
uses: Start9Labs/start-technologies/.github/workflows/tagAndRelease.yml@master
with:
REFERENCE_REGISTRY: ${{ vars.REFERENCE_REGISTRY }}
RELEASE_REGISTRY: ${{ vars.RELEASE_REGISTRY }}
S3_S9PKS_BASE_URL: ${{ vars.S3_S9PKS_BASE_URL }}
secrets:
DEV_KEY: ${{ secrets.DEV_KEY }}
S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }}
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
permissions:
contents: write
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ chama-pulse-log.md
# (restored 2026-07-13 after the "clean public repository" cleanup removed them;
# PHILOSOPHY/DECISIONS/INVARIANTS/BACKLOG restored 2026-07-25 from 7e4162c).
# Keep on disk for Claude/CC continuity; push only if explicitly needed.
CLAUDE.md
# CLAUDE.md is the exception: as a StartOS package repo this tree ships the
# tracked one-line `@AGENTS.md` import every package carries.
Codex.md
PHILOSOPHY.md
DECISIONS.md
Expand All @@ -77,3 +78,6 @@ design/mockups/

# Local StartOS package artifacts (rebuild; do not commit)
*.s9pk
startos/*.js
docker-images
ncc-cache
68 changes: 68 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# AGENTS.md

This repository is **both** the Chama application source and a StartOS service-package
repository — it builds a `.s9pk` for StartOS out of the very source it ships. Everything
under `startos/` plus `Dockerfile`, `Makefile`, `icon.png`, `LICENSE`, `instructions.md`
and `.github/workflows/{build,release,tagAndRelease}.yml` is the packaging layer;
everything else is the application.

Develop the packaging layer inside a StartOS packaging workspace created by
`start-cli s9pk init-workspace`, which provides the packaging guide and agent context one
level up. If you're reading this in a bare clone with no workspace, the full guide is at
<https://docs.start9.com/packaging>.

**Start every packaging task at the recipe index** —
`../start-technologies/projects/start-sdk/docs/src/recipes.md` (or
<https://docs.start9.com/packaging/recipes.html>). It maps an intent to the constructs,
the reference pages, and a named production package to copy. Find the recipe before you
read a neighbouring package: one you reach by grepping may be non-conformant, and the
recipe outranks it.

Work `TODO.md` from top to bottom. Keep `README.md` (architecture, for developers and
LLMs) and `instructions.md` (end-user docs) in sync with your changes.

## This repo

- **Package id is `chama`.** One image built from this repo's own `Dockerfile`, one `main`
volume, no dependencies, no actions. The image serves three independent Chama web
origins (ports 8080/8081/8082), each proxying `/bridge/` to its own
`chama-fedimint-bridge` process on loopback (8787/8788/8789) with its own wallet
directory under `/data/client-<n>`.
- **`packageRepo` is this fork** (`Start9-Community/chama`); `upstreamRepo` is the
application's home (`jesuspirate/chama`). Packaging changes land here.

## Packaging gotchas specific to this repo

- **Use the `startos:*` npm scripts, never `check` / `build`.** `npm run build` is the
Vite web build the `Dockerfile` calls; `npm run typecheck` is the app's. The StartOS
bundle is `startos:check` → `startos:lint` → `startos:build`. `Makefile` overrides
`s9pk.mk`'s stock `javascript/index.js` recipe for exactly this reason — make prints a
"overriding recipe" warning on every run, which is expected.
- **The StartOS tsconfig is `startos/tsconfig.json`, not the root one.** The root
`tsconfig.json` belongs to the React app and includes only `src`. Keeping the packaging
tsconfig inside `startos/` is also what lets the SDK's ESLint runner (`projectService`)
resolve a project for `startos/**/*.ts`.
- **`javascript/index.js` is emitted as ESM, not CJS.** `ncc` follows the root
`package.json`'s `"type": "module"`, and writes a matching `javascript/package.json`.
StartOS's container runtime `require()`s the bundle, which works because Node ≥ 20.19
supports `require(esm)`. Do not "fix" this by dropping `"type": "module"` — the app
needs it — and do not add a `startos/package.json` to force CJS: webpack then emits an
empty export table and the package loads with no `manifest`/`main`/`init`.
- **`icon.png` is a 512×512 downscale of `src-tauri/icons/icon.png`.** The 1024×1024
original is ~713 KB, and a package icon is embedded as a base64 data URL in every
registry index. Regenerate with:
`convert src-tauri/icons/icon.png -filter Lanczos -resize 512x512 -strip -quality 95 icon.png`
- **Two release lanes share this repo's tags.** `scripts/release.sh` tags `vX.Y.Z` for the
desktop/Zapstore lane; StartOS's `tagAndRelease.yml` tags `vX.Y.Z_<revision>`. The tag
filters in `release.yml` and `desktop-release.yml` keep them apart — keep them in sync
if either changes.
- **The Docker build context is the whole repo**, filtered by `.dockerignore`. Anything
the web build or the Rust bridge needs must stay out of that ignore list.

## Inspecting a running install

To run a command inside the service's container (check a bridge, read nginx logs), use
`start-cli package attach chama -n chama-sub -- <cmd>`. Select the subcontainer by **name**
with `-n` (the name passed to `SubContainer.of` in `startos/main.ts` — here `chama-sub`) or
by image with `-i`. Note: `-s/--subcontainer` matches the internal **Guid**, not the name,
so passing a name to `-s` fails with "no matching subcontainers".
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
33 changes: 7 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
ARCHES := x86 arm
# overrides to s9pk.mk must precede the include statement
include node_modules/@start9labs/start-sdk/s9pk.mk

# Published npm builds of the SDK (e.g. 1.5.3) do not always include s9pk.mk.
# Prefer the package-local file; else a common Start9 SDK checkout; else fail loud.
# Override anytime:
# make START_SDK_MK=/path/to/start-sdk/s9pk.mk x86
START_SDK_MK ?= node_modules/@start9labs/start-sdk/s9pk.mk
ifeq ($(wildcard $(START_SDK_MK)),)
ifneq ($(wildcard $(HOME)/start9-workspace/start-technologies/projects/start-sdk/s9pk.mk),)
START_SDK_MK := $(HOME)/start9-workspace/start-technologies/projects/start-sdk/s9pk.mk
endif
endif
ifeq ($(wildcard $(START_SDK_MK)),)
$(error s9pk.mk missing at $(START_SDK_MK). Use an SDK that ships s9pk.mk (≥2.0.6), or: make START_SDK_MK=/path/to/start-sdk/s9pk.mk x86)
endif
include $(START_SDK_MK)

# StartOS packages discover their catalog artwork from a root-level `icon.*`.
# Always derive it from the same high-resolution canonical mark shipped by
# Tauri so package builds cannot drift to a placeholder or approximation.
icon.png: src-tauri/icons/icon.png
cp $< $@

ingredients: icon.png

# Chama's existing `build` script builds the web application. Override the SDK's
# conventional package target so the StartOS runtime bundle uses its own scripts.
javascript/index.js: $(shell find startos -type f) tsconfig.startos.json node_modules
# The SDK's stock recipe runs `npm run check` / `npm run build`; in this repo
# those script names belong to the Chama web app, so the StartOS bundle is
# driven by the `startos:*` scripts. A recipe override must follow the include.
javascript/index.js: $(shell find startos -type f) node_modules
npm run startos:check
npm run startos:lint
npm run startos:build
Loading