Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
d6f5e8a
feat(android): floating frosted-glass pill bottom bar
Oct 10, 2026
a5a20d2
feat(android): debug builds install next to the release app
Oct 10, 2026
27adf47
fix(android): use Haze 1.6.10 for the frosted pill bar
Oct 10, 2026
f20ce06
fix(android): resolve Haze 1.6.10 API issues in the pill bar
Oct 10, 2026
e3ca5e6
fix(android): clip the pill bar before the haze blur, not after
Oct 10, 2026
c02ca42
feat(android): sign CI debug builds with a committed debug key
Oct 10, 2026
665f7d8
Merge pull request #1 from Ichiro786/m3e/frosted-pill-nav
Ichiro786 Oct 10, 2026
86562db
style(android): menus go pure black like the drawer
Oct 11, 2026
272c8af
feat(android): restyle the chats drawer in Muse's visual language
Oct 11, 2026
43583d9
revert(android): exclude menu and drawer polish from chat-polishing b…
Oct 11, 2026
ef6513e
Merge branch 'main' of nano-muse/nanoMuse into upstream/menu-polish
lgy0404 Oct 11, 2026
979d65a
revert(android): keep the debug application id and the local debug key
lgy0404 Oct 11, 2026
44242e2
docs(changelog): the pill bar lands under Unreleased, with the notice…
lgy0404 Oct 11, 2026
2799ca8
Merge pull request #329 from Ichiro786/upstream/menu-polish
lgy0404 Oct 11, 2026
247aae7
Merge branch 'main' of nano-muse/nanoMuse into upstream/drawer-polish
lgy0404 Oct 11, 2026
a2e9076
fix(android): the drawer lands on its own, the content keeps its inse…
lgy0404 Oct 11, 2026
c6c4f8f
feat(ios): the tab bar is a floating frosted-glass pill
lgy0404 Oct 11, 2026
2c91e37
feat(web): the phone layout's tab bar is a floating frosted-glass pill
lgy0404 Oct 11, 2026
94b38f1
Merge pull request #330 from Ichiro786/upstream/drawer-polish
lgy0404 Oct 11, 2026
c0c8b3b
docs(ios): one stray run of spaces out of ios.md
lgy0404 Oct 11, 2026
3adf665
docs(web): the Chinese pages call the pill 胶囊, as every-device.md does
lgy0404 Oct 11, 2026
196b813
Merge branch 'main' into feat/web-pill-bar
lgy0404 Oct 11, 2026
ec049cf
docs(every-device): the computer column says where the pill bar shows
lgy0404 Oct 11, 2026
e5a4e28
Merge pull request #342 from nano-muse/feat/web-pill-bar
lgy0404 Oct 11, 2026
bfa9572
fix(android): read the Claude Code OAuth identifier on the OAuth path…
lgy0404 Oct 11, 2026
8f7656d
fix(android): fold a carriage return as a column overwrite in tool ou…
lgy0404 Oct 11, 2026
4fe059a
docs(changelog): Android API-key and carriage-return fixes
lgy0404 Oct 11, 2026
704fca8
test(android): follow the per-session shell model in the coordinator …
lgy0404 Oct 11, 2026
f1495e1
test(android): feed OpenAIProviderTest the SSE streams sendMessage ex…
lgy0404 Oct 11, 2026
5f538fe
docs: changelog entry for the Android test-source fixes
lgy0404 Oct 11, 2026
c79889c
test(runtime): resolve .example hosts offline in the web tool tests
lgy0404 Oct 11, 2026
104cf16
fix(android): name the icon-only controls for a screen reader
lgy0404 Oct 11, 2026
2c7aeac
fix(android): cancel the relay and proxy requests with their coroutine
lgy0404 Oct 11, 2026
d3ca95c
fix(desktop): read the cached update check against the running version
lgy0404 Oct 11, 2026
d19d128
fix(android): keep a cancelled avatar run out of its replacement's tiles
lgy0404 Oct 11, 2026
5bed715
fix(android): Stop during the first send leaves the welcome alone
lgy0404 Oct 11, 2026
273bd9c
ci: every pull request gets its platform and kind labels
lgy0404 Oct 11, 2026
3d440b9
Merge pull request #344 from nano-muse/fix/android-anthropic-key-and-cr
lgy0404 Oct 11, 2026
87817d5
Merge pull request #345 from nano-muse/test/example-hosts-resolve-off…
lgy0404 Oct 11, 2026
9f450b0
Merge pull request #346 from nano-muse/test/android-upstream-test-drift
lgy0404 Oct 11, 2026
52c188d
Merge pull request #349 from nano-muse/fix/desktop-update-cache
lgy0404 Oct 11, 2026
989f106
Merge branch 'main' into ci/pr-labels
lgy0404 Oct 11, 2026
5fd2f60
Merge branch 'main' into fix/android-accessible-names
lgy0404 Oct 11, 2026
d92c49b
fix(android): a Stop before the first row is on screen gives the comp…
lgy0404 Oct 11, 2026
ee68b05
Merge branch 'main' into fix/android-cancel-paths
lgy0404 Oct 11, 2026
525a0c1
ci(android): run the upstream provider and sandbox tests beside ours
lgy0404 Oct 11, 2026
a0b3e58
Merge pull request #350 from nano-muse/ci/pr-labels
lgy0404 Oct 11, 2026
3842580
Merge pull request #351 from nano-muse/fix/android-cancel-paths
lgy0404 Oct 11, 2026
00e3cff
fix(android): the debug request log masks credential headers and keep…
lgy0404 Oct 11, 2026
eedbc5d
Merge branch 'main' into fix/android-accessible-names
lgy0404 Oct 11, 2026
62500d0
Merge pull request #352 from nano-muse/fix/android-debug-log-headers
lgy0404 Oct 11, 2026
80e505e
Merge pull request #353 from nano-muse/ci/android-upstream-tests
lgy0404 Oct 11, 2026
f0e1008
Merge branch 'main' into fix/android-accessible-names
lgy0404 Oct 11, 2026
baba4b3
fix(android): restore the chat-polish commits missing from the pushed…
Oct 11, 2026
bc1eae7
Merge pull request #348 from nano-muse/fix/android-accessible-names
lgy0404 Oct 11, 2026
0c21e53
Merge branch main into m3e/chat-polishing
lgy0404 Oct 11, 2026
44e25b4
fix(android): finish the chat polish on the Muse canvas
lgy0404 Oct 11, 2026
fbf9ecf
docs(android): the chat palette in rebrand.py, brand.md and design.md
lgy0404 Oct 11, 2026
db7b166
fix(ios): the pill bar takes the composer's width
lgy0404 Oct 11, 2026
52ecfad
Merge branch 'main' into feat/ios-pill-bar
lgy0404 Oct 11, 2026
3d74506
fix(android): the pill bar takes the composer's width
lgy0404 Oct 11, 2026
0e4270f
fix(web): the pill bar takes the composer's width
lgy0404 Oct 11, 2026
0af896f
Merge pull request #331 from Ichiro786/m3e/chat-polishing
lgy0404 Oct 11, 2026
835387e
Merge branch 'main' into feat/ios-pill-bar
lgy0404 Oct 11, 2026
577151f
feat(web): monochrome chat pills, ink send button and a fading header
lgy0404 Oct 11, 2026
4c17b7a
feat(ios): the chat is monochrome, as on Android
lgy0404 Oct 11, 2026
3557f48
Merge branch 'main' into feat/web-mono-chat
lgy0404 Oct 11, 2026
b780824
feat(android): a clip of your own as the face
lgy0404 Oct 11, 2026
f98f381
Merge branch 'main' into feat/android-own-clip
lgy0404 Oct 11, 2026
ebc328f
docs: issues stay open until a maintainer closes them, copy fixes
lgy0404 Oct 11, 2026
eccc510
Merge branch 'main' into docs/issue-policy-and-copy
lgy0404 Oct 11, 2026
5238fb4
fix: locale-safe time strings, runtime healthcheck, stable classifier…
lgy0404 Oct 11, 2026
a902fb1
Merge branch 'main' into fix/small-code-items
lgy0404 Oct 11, 2026
fbba915
Merge pull request #343 from nano-muse/feat/ios-pill-bar
lgy0404 Oct 11, 2026
0aebe0f
Merge branch 'main' into fix/web-pill-width
lgy0404 Oct 11, 2026
dca5625
fix(cloud): the relay image runs as an unprivileged user
lgy0404 Oct 11, 2026
d39633e
Merge branch 'main' into fix/relay-image-non-root
lgy0404 Oct 11, 2026
9d752c5
feat(desktop): monochrome chat pills, ink send button and a fading he…
lgy0404 Oct 11, 2026
89811cf
Merge branch 'main' into feat/desktop-mono-chat
lgy0404 Oct 11, 2026
93281f9
Merge branch 'main' into feat/ios-mono-chat
lgy0404 Oct 11, 2026
23f038f
docs(design): the iOS chat shares the Android chat palette
lgy0404 Oct 11, 2026
89cee96
feat(ios): a clip of your own as the face
lgy0404 Oct 11, 2026
ed59bfb
Merge branch 'main' into feat/ios-own-clip
lgy0404 Oct 11, 2026
0d03b24
Merge pull request #365 from nano-muse/fix/web-pill-width
lgy0404 Oct 11, 2026
7dd0a58
Merge pull request #363 from nano-muse/docs/issue-policy-and-copy
lgy0404 Oct 11, 2026
3963b22
docs(cloud): the admin CLI help names NANOMUSE_CLOUD_BASE
lgy0404 Oct 11, 2026
10ae973
Merge branch 'main' into fix/small-code-items
lgy0404 Oct 11, 2026
cf322b7
Merge pull request #367 from nano-muse/feat/desktop-mono-chat
lgy0404 Oct 11, 2026
961485e
Merge branch 'main' into feat/web-mono-chat
lgy0404 Oct 11, 2026
b8f10ce
Merge pull request #366 from nano-muse/fix/relay-image-non-root
lgy0404 Oct 11, 2026
a6f0f42
feat(ios): the pill bar's indicator is the chat's ink
lgy0404 Oct 11, 2026
aba0aeb
feat(web): the pill bar's indicator is the chat's ink
lgy0404 Oct 11, 2026
9612d2c
feat(runtime): a list of custom OpenAI-compatible endpoints behind th…
lgy0404 Oct 11, 2026
7e8d2d2
feat(web): several custom endpoints on the Connections screen
lgy0404 Oct 11, 2026
154f641
feat(desktop): one row per custom endpoint, each with its own key
lgy0404 Oct 11, 2026
771f10a
feat(desktop): a clip of your own as the face
lgy0404 Oct 11, 2026
3210a85
Merge branch 'main' into feat/desktop-own-clip
lgy0404 Oct 11, 2026
b791f6c
Merge branch 'main' into feat/multi-openai-endpoints
lgy0404 Oct 11, 2026
fe66d8e
Merge pull request #361 from nano-muse/feat/web-mono-chat
lgy0404 Oct 11, 2026
cf75d97
Merge branch 'main' into fix/small-code-items
lgy0404 Oct 11, 2026
45136cc
docs(changelog): one copy of the web pill bullet
lgy0404 Oct 11, 2026
777f35f
Merge pull request #368 from nano-muse/feat/ios-mono-chat
lgy0404 Oct 11, 2026
37859dd
Merge pull request #370 from nano-muse/feat/desktop-own-clip
lgy0404 Oct 11, 2026
8aa105c
Merge pull request #362 from nano-muse/feat/android-own-clip
lgy0404 Oct 11, 2026
a9a2de8
Merge branch 'main' into feat/ios-own-clip
lgy0404 Oct 11, 2026
ab64584
Merge pull request #369 from nano-muse/feat/ios-own-clip
lgy0404 Oct 11, 2026
27a2184
Merge branch 'main' into fix/small-code-items
lgy0404 Oct 11, 2026
48b9caa
Merge pull request #364 from nano-muse/fix/small-code-items
lgy0404 Oct 11, 2026
3319104
Merge branch 'main' into feat/multi-openai-endpoints
lgy0404 Oct 11, 2026
d74f74a
Merge pull request #371 from nano-muse/feat/multi-openai-endpoints
lgy0404 Oct 11, 2026
8d4b0f0
build(release): 1.0.3 Helm
lgy0404 Oct 11, 2026
85fb376
test(desktop): the update-cache test reads the package version
lgy0404 Oct 11, 2026
34a950c
Merge pull request #374 from nano-muse/release/1.0.3
lgy0404 Oct 11, 2026
92cefcf
test(desktop): read the stylesheet with LF endings in the styles test
lgy0404 Oct 11, 2026
9988f85
Merge pull request #376 from nano-muse/fix/desktop-styles-test-crlf
lgy0404 Oct 11, 2026
724bb03
docs(ios): build 22 is 1.0.3, submitted to the beta review
lgy0404 Oct 11, 2026
4f2a15b
Merge pull request #377 from nano-muse/docs/ios-build-22
lgy0404 Oct 11, 2026
fb7e54a
docs(readme): the visitors badge runs on hits.sh, with the count carr…
lgy0404 Oct 11, 2026
a8b4260
style(cloud): run ruff format over the relay
lgy0404 Oct 11, 2026
7798278
Merge pull request #378 from nano-muse/docs/visitors-badge-hits
lgy0404 Oct 11, 2026
495fa7f
ci: run ruff format --check in the relay job
lgy0404 Oct 11, 2026
179ca14
Merge branch 'main' into audit4/cloud-format
lgy0404 Oct 11, 2026
ba4f637
ci: label web pull requests right, test the desktop on Windows, trim …
lgy0404 Oct 11, 2026
b4927c1
fix(showcase): fixed phone address, DeepSeek Flash vision, log rotati…
lgy0404 Oct 11, 2026
60f9052
Merge branch 'main' into audit4/ci-hygiene
lgy0404 Oct 11, 2026
6ba3408
docs(showcase): fixed a dangling trace note, the 微信 sentence and a st…
lgy0404 Oct 11, 2026
eb962fd
fix(web): offer the Sentinel's three risk levels for an MCP server, n…
lgy0404 Oct 11, 2026
7e93e3f
Merge branch 'main' into audit4/showcase-fixes
lgy0404 Oct 11, 2026
acb1112
fix(desktop): run the shell's tests in CI, make them CRLF-safe, cover…
lgy0404 Oct 11, 2026
27cbea6
Merge branch 'main' into audit4/web-polish
lgy0404 Oct 11, 2026
2a80277
fix(cloud): one hub device per console tab, consistent backups, a mai…
lgy0404 Oct 11, 2026
262f318
Merge branch 'main' into audit4/desktop-fixes
lgy0404 Oct 11, 2026
cda83c9
docs(changelog): name the pull request behind the web console bullet
lgy0404 Oct 11, 2026
6e5eb32
docs(changelog): the desktop fixes of #383 under Unreleased
lgy0404 Oct 11, 2026
e63af0a
chore(release): release-docs.py writes the roadmap rows; release-apk.…
lgy0404 Oct 11, 2026
7d2592c
fix(android): bounded clip import, hub answers on a dropped socket, q…
lgy0404 Oct 11, 2026
ce98e7d
ci: the phones' catalogue and Ideas copies keep LF too
lgy0404 Oct 11, 2026
eebd2ec
Merge branch 'main' into audit4/android-fixes
lgy0404 Oct 11, 2026
fbe1148
fix(runtime): honest risk for standing work, a wider SSRF guard, no s…
lgy0404 Oct 11, 2026
ba49887
docs(own-key): the Hands model row is a picker of the endpoint's mode…
lgy0404 Oct 11, 2026
2ffe313
ci: a change to config/ runs the Python checks
lgy0404 Oct 11, 2026
3a1c188
Merge branch 'main' into audit4/runtime-fixes
lgy0404 Oct 11, 2026
5f38c69
docs(changelog): the audit bullets carry their pull request number
lgy0404 Oct 11, 2026
af3b864
docs(app): the account, hub, hands and bridge routes in the API table
lgy0404 Oct 11, 2026
bf7259f
fix(cloud): close a device's hub socket when its key is signed out
lgy0404 Oct 11, 2026
6bcb282
fix(ios): password refusals, the Cloud row's allowance line, the rela…
lgy0404 Oct 11, 2026
9501fab
Merge branch 'main' into audit4/ios-audit
lgy0404 Oct 11, 2026
1831667
docs(zh): the showcase page's 轨迹 labels render as bold
lgy0404 Oct 11, 2026
a24a6ff
docs: bring the docs up to the code after the docs audit
lgy0404 Oct 11, 2026
414cc61
Merge pull request #381 from nano-muse/audit4/showcase-fixes
lgy0404 Oct 11, 2026
725ee2a
Merge branch 'main' into audit4/docs-1
lgy0404 Oct 11, 2026
dfa56e9
Merge pull request #379 from nano-muse/audit4/cloud-format
lgy0404 Oct 11, 2026
3b7c469
Merge remote-tracking branch 'origin/main' into audit4/cloud-fixes
lgy0404 Oct 11, 2026
cddd69d
Merge branch 'main' into audit4/docs-1
lgy0404 Oct 11, 2026
0ffc189
docs(hub): the 4001 note names the release after 0.24.2
lgy0404 Oct 11, 2026
4bfdf45
Merge pull request #387 from nano-muse/audit4/runtime-fixes
lgy0404 Oct 11, 2026
723b4b0
Merge pull request #388 from nano-muse/audit4/runtime-docs
lgy0404 Oct 11, 2026
e49726a
Merge pull request #383 from nano-muse/audit4/desktop-fixes
lgy0404 Oct 11, 2026
c5af27d
Merge pull request #386 from nano-muse/audit4/android-fixes
lgy0404 Oct 11, 2026
8262a0e
Merge pull request #382 from nano-muse/audit4/web-polish
lgy0404 Oct 11, 2026
022a0e9
Merge pull request #384 from nano-muse/audit4/cloud-fixes
lgy0404 Oct 11, 2026
5e47ba4
ci(harness): the desktop shell's tests run on Windows too
lgy0404 Oct 11, 2026
81c7c09
Merge remote-tracking branch 'origin/main' into audit4/ci-hygiene
lgy0404 Oct 11, 2026
04db9be
Merge remote-tracking branch 'origin/main' into audit4/ci-release-scr…
lgy0404 Oct 11, 2026
eb0d49b
fix(ios): password_wrong and password_weak keep their own sentences
lgy0404 Oct 11, 2026
61e8f6c
docs(zh): punctuation outside emphasis runs on four pages; a test ren…
lgy0404 Oct 11, 2026
72ef517
Merge pull request #389 from nano-muse/audit4/ios-audit
lgy0404 Oct 11, 2026
aa944d4
test(desktop): two Mac path assertions read the same on Windows
lgy0404 Oct 11, 2026
8aa6682
Merge remote-tracking branch 'origin/main' into audit4/docs-1
lgy0404 Oct 11, 2026
028a83f
Merge remote-tracking branch 'origin/main' into audit4/ci-hygiene
lgy0404 Oct 11, 2026
342bc4f
Merge remote-tracking branch 'origin/main' into audit4/ci-release-scr…
lgy0404 Oct 11, 2026
2e3ff71
Merge pull request #390 from nano-muse/audit4/docs-1
lgy0404 Oct 11, 2026
e86da0f
Merge remote-tracking branch 'origin/main' into audit4/ci-hygiene
lgy0404 Oct 11, 2026
e498912
chore(release): release-docs.py works out the roadmap rows before it …
lgy0404 Oct 11, 2026
e5a42eb
Merge remote-tracking branch 'origin/main' into audit4/ci-release-scr…
lgy0404 Oct 11, 2026
af1c0e3
Merge pull request #380 from nano-muse/audit4/ci-hygiene
lgy0404 Oct 11, 2026
9886ece
Merge remote-tracking branch 'origin/main' into audit4/ci-release-scr…
lgy0404 Oct 11, 2026
166e35a
Merge pull request #385 from nano-muse/audit4/ci-release-scripts
lgy0404 Oct 11, 2026
ecb2800
feat(relay): show who invited whom on the admin page
lgy0404 Oct 12, 2026
1896212
Merge pull request #391 from nano-muse/feat/admin-invites
lgy0404 Oct 12, 2026
c7bd659
chore(sync): merge sanitized upstream through v1.0.3 (Helm)
zeeshanhaque21 Oct 12, 2026
df23dbb
build(web): regenerate committed static from the merged source (Node 22)
zeeshanhaque21 Oct 12, 2026
f38a067
test(sync): keep the fork's expectations on two tests upstream 1.0.3 …
zeeshanhaque21 Oct 12, 2026
e7f645a
docs(evidence): add the 2026-10-11 sync PR body
zeeshanhaque21 Oct 12, 2026
204633f
style(sync): apply ruff format to the three files an earlier sanitiza…
zeeshanhaque21 Oct 12, 2026
cc4b552
fix(docs): restore the sentence period the mirror-clause removal ate,…
zeeshanhaque21 Oct 12, 2026
33161f5
docs(evidence): correct the PR body's counts, tested head, and preser…
zeeshanhaque21 Oct 12, 2026
80ce858
docs(evidence): restate the runtime counts and the commit list from f…
zeeshanhaque21 Oct 12, 2026
b1cec00
docs(evidence): enumerate only the stable content commits in the PR body
zeeshanhaque21 Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
39 changes: 32 additions & 7 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
# What never enters a build context rooted here: the runtime image (Dockerfile) copies
# pyproject.toml, README.md, LICENSE, nanomuse/ and config/config.example.toml; the showcase's
# Caddy image (demo/showcase/caddy/Dockerfile, built from this root too) copies demo/mobilegym/
# and demo/showcase/site/. A pattern without `**/` matches at the root only (Go's
# filepath.Match, not gitignore), so the caches are listed with it.
.git
.github
.venv
.env
__pycache__
*.pyc
.pytest_cache
.ruff_cache
.env.*
**/__pycache__
**/*.pyc
**/.pytest_cache
**/.ruff_cache
**/.mypy_cache
**/*.egg-info
**/node_modules
workspace/
config/config.toml
config/*.local.toml
tests/
docs/
dist/
build/
*.egg-info
web/node_modules/
web/dist/
# the other trees: the Android and iPhone apps with their native builds, the desktop, the
# relay, the web console's sources (its build is committed under nanomuse/server/static/),
# the docs site, the project page
android/
harness/
cloud/
web/
website/
site/
assets/
scripts/
CHANGELOG.md
# the showcase's run-time directories (demo/showcase/.gitignore): the dataset, other sites
demo/showcase/data/
demo/showcase/site/dist/
demo/showcase/sites.d/
demo/showcase/www/
demo/showcase/mobilegym/
16 changes: 16 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,19 @@
# normalised: android/ is an upstream subtree and carries a few vendored files as they came.
*.sh text eol=lf
gradlew text eol=lf

# The desktop (harness/) is built and tested on Windows runners, whose checkout turns LF into
# CRLF under core.autocrlf; its tests read their own sources and look for `\n` in them (the
# v1.0.3 tag's Windows installer build failed on exactly that), so the tree's text files keep
# LF on every platform. Git tells text from binary itself; the clips and pictures are named
# so that the detection can never touch them.
harness/** text=auto eol=lf
harness/**/*.mp4 binary
harness/**/*.png binary
harness/**/*.webp binary
harness/**/*.icns binary
harness/**/*.ico binary
# The phones' copies of the desktop's catalogues and Ideas lists: the desktop's tests compare
# them with its own byte for byte (tests/fences.test.mjs), so they keep LF the same way.
android/src/android/app/src/main/assets/nanomuse/*.json text eol=lf
android/src/ios/NanoMuse/Resources/*.json text eol=lf
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/app_bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ body:
id: version
attributes:
label: nanoMuse version
description: Settings → About, e.g. 1.0.2 (45)
description: Settings → About, e.g. 1.0.3 (46)
validations:
required: true
- type: input
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ body:
id: os
attributes:
label: OS and runtime
description: e.g. macOS 15 / Python 3.12, Ubuntu 24.04 / Docker, Windows 11 / desktop 1.0.2, iOS 18 / iPhone 15
description: e.g. macOS 15 / Python 3.12, Ubuntu 24.04 / Docker, Windows 11 / desktop 1.0.3, iOS 18 / iPhone 15
- type: textarea
id: logs
attributes:
Expand Down
4 changes: 2 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## What

<!-- One or two sentences. Link the issue if there is one: Fixes #123 -->
<!-- One or two sentences. Link the issue if there is one: For #123 (not Fixes or Closes; an issue stays open until the fix has shipped) -->

## Why

Expand All @@ -12,7 +12,7 @@

<!-- Tick what applies; the commands are in AGENTS.md, one block per part of the tree. -->

- [ ] The checks for the part I changed pass (runtime: `ruff check nanomuse tests scripts && ruff format --check nanomuse tests scripts && mypy && python -m pytest -q -m "not live"`; relay: `cd cloud && ruff check . && pytest`; web: `cd web && npm run check && npm run build`; desktop: `cd harness/dsh-nanomuse && pnpm build && pnpm typecheck && pnpm test`)
- [ ] The checks for the part I changed pass (runtime: `ruff check nanomuse tests scripts && ruff format --check nanomuse tests scripts && mypy && python -m pytest -q -m "not live"`; relay: `cd cloud && ruff check . && ruff format --check . && pytest`; web: `cd web && npm run check && npm run build`; desktop: `cd harness/dsh-nanomuse && pnpm build && pnpm typecheck && pnpm test`)
- [ ] New behaviour has a test; tests use `MockLLM`, no network
- [ ] If a person sees or does something differently: a line under `## [Unreleased]` in `CHANGELOG.md` (past tense, concrete, in the right section) and the page under `docs/` with its `docs/zh/` twin
- [ ] If a user-visible string was added or changed: every locale of that file (English first, then 简体中文, then the rest; same placeholders)
Expand Down
52 changes: 52 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Platform labels for pull requests, from the files a pull request touches (actions/labeler).
# The kind label (bug, enhancement, documentation, ci, release, maintenance) comes from the title;
# see .github/workflows/labels.yml and CONTRIBUTING.md, "Issues and pull requests (maintainers)".

android:
- changed-files:
- any-glob-to-any-file:
- "android/src/android/**"
- "android/deps/**"
- "android/scripts/**"
- "scripts/android/**"
- "scripts/release-apk.sh"

ios:
- changed-files:
- any-glob-to-any-file:
- "android/src/ios/**"
- "scripts/gen-ios-icons.py"
- ".github/workflows/ios-*.yml"

desktop:
- changed-files:
- any-glob-to-any-file:
- "harness/**"
- ".github/workflows/desktop-app.yml"
- ".github/workflows/harness.yml"

web:
- changed-files:
- any-glob-to-any-file:
- "web/**"
- "nanomuse/server/static/**"
- "demo/**"

runtime:
- changed-files:
- any-glob-to-any-file:
# nanomuse/ without nanomuse/server/static/, the committed web build (that is `web`,
# above): the four globs together cover every other file under nanomuse/
- "nanomuse/*"
- "nanomuse/!(server)/**"
- "nanomuse/server/*"
- "nanomuse/server/!(static)/**"
- "tests/**"
- "pyproject.toml"
- "Dockerfile"
- "docker-compose.yml"

cloud:
- changed-files:
- any-glob-to-any-file:
- "cloud/**"
16 changes: 14 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,24 @@ jobs:
./gradlew :app:assembleDebug --console=plain --no-daemon

# Our unit tests (io.github.nanomuse.*: the guards, the hub client, the sandbox paths, the
# strings' parity). Same Gradle invocation as AGENTS.md; the compiled classes are warm.
# strings' parity), plus the upstream provider and sandbox tests, the two OpenMinis packages
# our edits touch (#333, #334, #335). Same Gradle invocation as AGENTS.md; the compiled
# classes are warm.
- name: Unit tests
working-directory: android/src/android
run: |
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$NDK_VERSION"
./gradlew :app:testDebugUnitTest --tests 'io.github.nanomuse.*' --console=plain --no-daemon
./gradlew :app:testDebugUnitTest --tests 'io.github.nanomuse.*' \
--tests 'com.openminis.app.provider.*' --tests 'com.openminis.app.sandbox.*' \
--console=plain --no-daemon

# The on-device tests cannot run here (no emulator), but the source set must keep
# compiling or io.github.nanomuse.reach.ReachHubInstrumentedTest never runs anywhere (#332).
- name: androidTest compiles
working-directory: android/src/android
run: |
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$NDK_VERSION"
./gradlew :app:compileDebugAndroidTestKotlin --console=plain --no-daemon

- name: Badging
run: |
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
- "nanomuse/**"
- "tests/**"
- "scripts/**"
- "config/**" # config.example.toml: the tests read it, the image carries it
- "pyproject.toml"
- "Dockerfile"
- ".dockerignore"
Expand Down Expand Up @@ -172,6 +173,10 @@ jobs:
if: env.RUN == 'true'
run: uv run ruff check .

- name: Ruff format
if: env.RUN == 'true'
run: uv run ruff format --check .

- name: Tests
if: env.RUN == 'true'
run: uv run python -m pytest -q
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/desktop-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
# Each platform builds the bundle (harness/dsh-nanomuse: pnpm build, test, pack), stages dsh
# next to it with npm (scripts/prepare-dsh.mjs, the platform's own native prebuilds), builds
# the runtime (scripts/desktop-app/build-runtime.py --target harness/desktop/runtime, a
# PyInstaller build), wraps it all with electron-builder, and
# then boots the unpacked app's harness once in Node mode (scripts/smoke.mjs) to see the Host
# PyInstaller build), runs the shell's own tests (harness/desktop: npm test), wraps it all
# with electron-builder, and then boots the unpacked app's harness once in Node mode (scripts/smoke.mjs) to see the Host
# come up with the bundle's rows. On macOS the Swift helper that holds the hands' permissions
# (harness/desktop/mac/computer-use/build.sh → "nanoMuse Computer Use.app") is built first and
# electron-builder lays out the .app with it inside;
Expand Down Expand Up @@ -40,7 +40,10 @@ permissions:
contents: read

# One run per branch; a newer push to the same branch cancels the older build,
# but a tag or a manual run is never cancelled.
# but a tag or a manual run is never cancelled. A manual run shares the group of the branch it
# runs on: "Run workflow" on main while a push to main is building waits for that build to end
# rather than running beside it, which is slower but never leaves two runs attaching the
# same installers.
concurrency:
group: desktop-app-${{ github.ref }}
cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' && !startsWith(github.ref, 'refs/tags/') }}
Expand Down Expand Up @@ -144,6 +147,7 @@ jobs:
run: |
npm ci
npm run typecheck
npm test
npm run dist
- name: The helper that holds the hands' permissions (macOS, nanoMuse Computer Use.app, Swift)
if: runner.os == 'macOS'
Expand All @@ -167,6 +171,7 @@ jobs:
run: |
npm ci
npm run typecheck
npm test
npm run dist:dir
../../scripts/desktop-app/package-mac.sh "${{ matrix.label == 'macos-arm64' && 'arm64' || 'x64' }}"
- name: Boot the packaged harness once
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Docker image
# Publishes ghcr.io/nano-muse/nanomuse for linux/amd64 and linux/arm64:
# main -> :edge
# tag vX.Y.Z -> :X.Y.Z, :X.Y, :latest
# tag vX.Y.Z-rc1 -> :X.Y.Z-rc1 only (a pre-release moves neither :X.Y nor :latest)
# Pull requests build the amd64 image without pushing (the CI workflow smoke-tests it).

on:
Expand Down Expand Up @@ -47,7 +48,8 @@ jobs:
type=edge,branch=main
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-fork.') }}
# fork tags (v1.0.3-fork.1) contain '-' and never move latest; neither do prereleases
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-') }}
labels: |
org.opencontainers.image.title=nanoMuse
org.opencontainers.image.description=Open-source version of Meta's Muse personal agent: phone app, Sentinel gatekeeper, credential vault, memory and goals. Bring your own model.
Expand Down Expand Up @@ -80,7 +82,8 @@ jobs:
type=edge,branch=main
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-fork.') }}
# fork tags (v1.0.3-fork.1) contain '-' and never move latest; neither do prereleases
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-') }}
labels: |
org.opencontainers.image.title=nanoMuse (with browser)
org.opencontainers.image.description=nanoMuse with Chromium bundled for the browser tool.
Expand Down
59 changes: 55 additions & 4 deletions .github/workflows/harness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
# (docs/harness.md, harness/README.md); nanoMuse Desktop
# itself carries the same bundle (desktop-app.yml)
#
# A push or pull request that touches harness/ builds, typechecks and tests the bundle; a
# release tag `v*` also packs it and attaches the tarball and its checksum to the release of
# A push or pull request that touches harness/ builds, typechecks and tests the bundle and the
# Electron shell (harness/desktop: typecheck and its node tests, no installer), on Linux and on
# Windows, where the tests see a checkout made with core.autocrlf and Windows paths; a
# release tag `v*` also packs the bundle and attaches the tarball and its checksum to the release of
# the same name (the one scripts/release-apk.sh creates with the APK), retrying until it
# exists. "Run workflow" with a release tag does the same for a release that already exists.
# The bundle's version must be the tag's: the release recipe bumps harness/dsh-nanomuse/package.json.
# The paths include the phones' copies of the catalogues and of the Ideas list: the tests
# check that they match the desktop's (tests/fences.test.mjs, connectors-json.mjs --check).
name: harness bundle

on:
push:
branches: ["**"]
paths: ["harness/**", "scripts/connectors-json.mjs", "scripts/providers-json.mjs", "nanomuse/llm/providers.json", "android/src/android/app/src/main/assets/nanomuse/connectors.json", "android/src/android/app/src/main/assets/nanomuse/providers.json", "android/src/ios/NanoMuse/Resources/connectors.json", "android/src/ios/NanoMuse/Resources/providers.json", ".github/workflows/harness.yml"]
paths: ["harness/**", "scripts/connectors-json.mjs", "scripts/providers-json.mjs", "nanomuse/llm/providers.json", "android/src/android/app/src/main/assets/nanomuse/connectors.json", "android/src/android/app/src/main/assets/nanomuse/providers.json", "android/src/android/app/src/main/assets/nanomuse/ideas.*.json", "android/src/ios/NanoMuse/Resources/connectors.json", "android/src/ios/NanoMuse/Resources/providers.json", ".github/workflows/harness.yml"]
tags: ["v*"]
pull_request:
paths: ["harness/**", "scripts/connectors-json.mjs", "scripts/providers-json.mjs", "nanomuse/llm/providers.json", "android/src/android/app/src/main/assets/nanomuse/connectors.json", "android/src/android/app/src/main/assets/nanomuse/providers.json", "android/src/ios/NanoMuse/Resources/connectors.json", "android/src/ios/NanoMuse/Resources/providers.json", ".github/workflows/harness.yml"]
paths: ["harness/**", "scripts/connectors-json.mjs", "scripts/providers-json.mjs", "nanomuse/llm/providers.json", "android/src/android/app/src/main/assets/nanomuse/connectors.json", "android/src/android/app/src/main/assets/nanomuse/providers.json", "android/src/android/app/src/main/assets/nanomuse/ideas.*.json", "android/src/ios/NanoMuse/Resources/connectors.json", "android/src/ios/NanoMuse/Resources/providers.json", ".github/workflows/harness.yml"]
workflow_dispatch:
inputs:
release_tag:
Expand All @@ -40,6 +44,7 @@ jobs:
bundle:
name: build · test · pack
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
Expand All @@ -59,6 +64,16 @@ jobs:
pnpm build
pnpm typecheck
pnpm test
# The Electron shell's own checks (AGENTS.md). Its tests stand in a fake `electron`
# module, so the Electron binary is not downloaded; desktop-app.yml builds the real thing.
- name: The desktop shell typechecks and its tests pass
working-directory: harness/desktop
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
run: |
npm ci
npm run typecheck
npm test
- name: The phones' copies of the connectors catalogue are current
run: node scripts/connectors-json.mjs --check
- name: The clients' copies of the provider catalogue are current
Expand Down Expand Up @@ -99,6 +114,42 @@ jobs:
path: packages/*
if-no-files-found: error

# The same build, typecheck and tests on Windows, on every pull request: the v1.0.3 tag's
# Windows installer build failed on a test that first met a CRLF checkout there, which
# desktop-app.yml only runs on a tag or by hand. No pack, no dsh install, no installer.
windows:
name: build · test (Windows)
runs-on: windows-latest
# a test that leaves a handle open hangs the process; the limit turns that into a failure
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
with:
version: 11
- uses: actions/setup-node@v7
with:
node-version: 22
cache: pnpm
cache-dependency-path: harness/dsh-nanomuse/pnpm-lock.yaml
- name: The bundle
working-directory: harness/dsh-nanomuse
shell: bash
run: |
pnpm install --frozen-lockfile
pnpm build
pnpm typecheck
pnpm test
- name: The desktop shell
working-directory: harness/desktop
shell: bash
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
run: |
npm ci
npm run typecheck
npm test

release:
if: (startsWith(github.ref, 'refs/tags/v') || inputs.release_tag != '') && !contains(inputs.release_tag || github.ref_name, '-fork.')
needs: bundle
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ios-testflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ name: iOS · TestFlight
# IOS_DIST_P12_BASE64, IOS_DIST_P12_PASSWORD
# Signing is manual: the team's Apple Distribution certificate from the secrets, the App Store
# profiles fetched from the account with the key. Nothing that signs is in the repository.
# The build number (CFBundleVersion) is this workflow's run number, so every upload counts up
# on its own and the release notes can name it; the marketing version is the project's.

on:
workflow_dispatch:
Expand Down
Loading
Loading