Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
077e208
Initial implementation of openadapt-tray package
abrichr Jan 17, 2026
467393a
fix: add README badges for license and Python version (#1)
abrichr Jan 17, 2026
30eeb04
Implement native notifications with desktop-notifier (#2)
abrichr Jan 17, 2026
c9b96d3
ci: add PyPI publish and auto-release workflows
abrichr Jan 29, 2026
44503c5
ci: switch to python-semantic-release for automated versioning
abrichr Jan 29, 2026
54063f6
fix(ci): remove build_command from semantic-release config
abrichr Jan 29, 2026
ef99843
chore: release 0.0.1
Jan 29, 2026
cb494e7
fix(ci): use v9 branch config for python-semantic-release (#4)
abrichr Feb 18, 2026
e7b2c24
feat: align tray with the hosted workflow lifecycle
abrichr Jul 15, 2026
9da5304
chore: release 0.1.0
Jul 15, 2026
3f70a44
fix: recover tray 0.1.1 PyPI release
abrichr Jul 15, 2026
807a00f
chore: release 0.1.1
Jul 15, 2026
8de5c99
docs: refresh README release boundary to the shipped 0.1.1 reality (#6)
abrichr Jul 17, 2026
d31d3d9
docs: use canonical 'retained evidence' wording in README (#8)
abrichr Jul 19, 2026
f423ad5
chore: add security CI (CodeQL, gitleaks, dependency-review, Dependab…
abrichr Jul 20, 2026
179c5b6
feat: use OpenAdapt mark, tinted per state, for the tray icon (#16)
abrichr Jul 20, 2026
026bc6c
chore: release 0.2.0
Jul 20, 2026
37122fe
chore(deps): bump actions/dependency-review-action from 4.9.0 to 5.0.…
dependabot[bot] Jul 21, 2026
11a03e2
chore(deps): bump python-semantic-release/publish-action (#11)
dependabot[bot] Jul 21, 2026
c009853
chore(deps): bump actions/checkout from 7.0.0 to 7.0.1 (#12)
dependabot[bot] Jul 21, 2026
fa17cd1
chore(deps): bump actions/setup-python from 6.3.0 to 7.0.0 (#13)
dependabot[bot] Jul 21, 2026
99f8d43
chore(deps): bump python-semantic-release/python-semantic-release (#14)
dependabot[bot] Jul 21, 2026
ba65868
docs: refresh README for the tray companion and reconciled desktop co…
abrichr Jul 21, 2026
8850e58
chore(deps-dev): bump uv from 0.11.26 to 0.11.29 (#15)
dependabot[bot] Jul 21, 2026
c623942
fix(deps): raise vulnerable tray dependency floors (#19)
abrichr Jul 21, 2026
2e21eb2
chore: release 0.2.1
Jul 21, 2026
560e672
chore: clean up repository root (#20)
abrichr Jul 25, 2026
cdbf507
chore(deps): bump github/codeql-action init+analyze to v4.37.3 togeth…
abrichr Jul 27, 2026
6b752c8
chore(deps): bump astral-sh/setup-uv from 8.3.2 to 9.0.0 (#24)
dependabot[bot] Jul 27, 2026
5acbda5
chore(deps): bump pypa/gh-action-pypi-publish from 1.14.0 to 1.14.1 (…
dependabot[bot] Jul 27, 2026
b75c430
chore(deps): bump uv from 0.11.29 to 0.11.32 across every release inp…
abrichr Jul 27, 2026
a955627
chore: gitignore .private/ (#28)
abrichr Jul 28, 2026
48360ec
fix: report keychain, toast and IPC failures honestly; pin ruff to 0.…
abrichr Jul 28, 2026
65eb1b1
chore: release 0.2.2
Jul 28, 2026
ad84c96
fix: make unknown outcomes representable instead of success-shaped (#30)
abrichr Jul 28, 2026
0f72555
chore: release 0.2.3
Jul 28, 2026
55269e0
fix: keep tray command failures visible (#31)
abrichr Jul 28, 2026
83471e4
chore: release 0.2.4
Jul 28, 2026
00e534f
feat: warn before hosted credentials expire (#32)
abrichr Jul 28, 2026
9d89a55
chore: release 0.3.0
Jul 28, 2026
8bb7659
chore(release): enforce the source-policy boundary (#33)
abrichr Jul 28, 2026
6afc0a4
chore: release 0.3.1
Jul 28, 2026
ed5e4d5
chore: confirm tray notification delivery
abrichr Jul 28, 2026
163a97d
chore(deps): bump the codeql-action group with 2 updates (#36)
dependabot[bot] Aug 18, 2026
4e13635
chore(deps): bump pypa/gh-action-pypi-publish from 1.14.1 to 1.14.2 (…
dependabot[bot] Aug 18, 2026
0ff9a9c
chore(deps): bump astral-sh/setup-uv from 9.0.0 to 10.0.1 (#40)
dependabot[bot] Aug 18, 2026
ddea451
chore(deps-dev): bump uv from 0.11.32 to 0.12.4 (#39)
dependabot[bot] Aug 18, 2026
d9df567
chore: release 0.3.2
Aug 18, 2026
670d56e
chore(deps): refresh CodeQL and uv toolchain (#41)
abrichr Aug 18, 2026
996dc67
docs: use canonical launcher quickstart (#42)
abrichr Aug 18, 2026
cc5d8cb
ci: correct the stale version comment on the pypi-publish pin (#43)
abrichr Aug 20, 2026
baa2c8a
chore: ignore every .env variant, not one at a time (#45)
abrichr Aug 26, 2026
da200d0
chore(deps): bump the codeql-action group with 2 updates (#44)
dependabot[bot] Aug 27, 2026
a6a49db
chore(policy): sync generated source boundary (#47)
abrichr Aug 27, 2026
4e4fc4a
fix: lock the semantic release runtime (#46)
abrichr Aug 27, 2026
0195c30
chore: release 0.3.3
Aug 27, 2026
fd44df6
docs: rewrite the README around what the tray actually is (#48)
abrichr Aug 28, 2026
084e232
fix: align Tray with the native Desktop protocol (#49)
abrichr Aug 28, 2026
7a7043f
chore: release 0.3.4
Aug 28, 2026
3d62ab7
chore(deps): bump the codeql-action group with 2 updates (#53)
dependabot[bot] Sep 2, 2026
b6a048b
chore(deps): update the GitHub release publishing action (#55)
dependabot[bot] Sep 10, 2026
d8d6da8
chore: isolate and update the locked release tools (#54)
dependabot[bot] Sep 10, 2026
690ca73
chore(deps): update the reviewed GitPython release dependency (#50)
dependabot[bot] Sep 10, 2026
0501727
chore(deps): align the reviewed UV release tool pins (#51)
dependabot[bot] Sep 10, 2026
7b93465
chore(deps): validate the Hatchling 1.32 release contract (#52)
dependabot[bot] Sep 10, 2026
04f17be
chore: align compatible release tools and bound Click updates (#58)
dependabot[bot] Sep 10, 2026
18d231c
chore: update CodeQL action to 4.38.0
dependabot[bot] Sep 14, 2026
af9038f
chore: update setup-uv action to 10.1.0
dependabot[bot] Sep 14, 2026
e193d5b
chore: synchronize uv 0.12.13 release tools
dependabot[bot] Sep 14, 2026
61413f7
fix: show the recording hotkey in the platform's form in the menu (#69)
abrichr Oct 14, 2026
99b7314
chore: release 0.3.5
Oct 14, 2026
0d6ebfe
chore: sync the published source policy (#72)
abrichr Oct 14, 2026
d4682e3
Plain README, macOS startup crash fix, and working menu actions (#73)
abrichr Oct 14, 2026
d260bfc
chore: release 0.3.6
Oct 14, 2026
67f0648
test: check every label in the default tray menu (#74)
abrichr Oct 14, 2026
b213fe8
fix(deps): patch Dependabot security alerts (#75)
abrichr Oct 14, 2026
a1ee7e5
chore: release 0.3.7
Oct 14, 2026
553dddf
chore: bump the codeql-action group with 2 updates (#65)
dependabot[bot] Oct 17, 2026
e263c22
chore: bump python-semantic-release/publish-action from 10.6.2 to 10.…
dependabot[bot] Oct 17, 2026
0dacb5f
chore: bump astral-sh/setup-uv from 10.1.0 to 10.3.0 (#70)
dependabot[bot] Oct 17, 2026
61972aa
chore: bump hatchling from 1.32.0 to 1.32.4 (#66)
dependabot[bot] Oct 17, 2026
24ef62d
chore: update ruff requirement from <0.17,>=0.16 to >=0.16,<0.18 (#71)
dependabot[bot] Oct 17, 2026
abcd416
build(monorepo): import openadapt-tray into packages/tray
abrichr Oct 19, 2026
27f58f3
build(tray): release openadapt-tray from the monorepo
abrichr Oct 19, 2026
63a2d7c
ci(tray): path-filtered tray jobs and an in-tree desktop IPC test
abrichr Oct 19, 2026
09d2ae0
docs(monorepo): name the tray import PR
abrichr Oct 19, 2026
89d42f7
Merge remote-tracking branch 'origin/main' into monorepo/tray
abrichr Oct 19, 2026
7aff28e
test(desktop): check the in-tree tray peer instead of a pinned checkout
abrichr Oct 19, 2026
1fa6354
Merge remote-tracking branch 'origin/main' into HEAD
abrichr Oct 19, 2026
1ebb417
Merge remote-tracking branch 'origin/main' into monorepo/tray
abrichr Oct 20, 2026
9e96b92
Merge remote-tracking branch 'origin/monorepo/tray' into monorepo/tray
abrichr Oct 20, 2026
8fbb08d
Merge branch 'main' into monorepo/tray
abrichr Oct 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ updates:
open-pull-requests-limit: 5
labels:
- "dependencies"
# packages/tray keeps its own uv.lock, like packages/capture.
- package-ecosystem: "uv"
directory: "/packages/tray"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
labels:
- "dependencies"
# packages/desktop: its uv.lock, the frontend's package-lock.json and the
# Tauri shell's Cargo.lock. Minor and patch bumps are grouped, as they were
# in openadapt-desktop.
Expand Down
13 changes: 4 additions & 9 deletions .github/workflows/desktop-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,12 @@ jobs:
- name: Install Desktop and the exact bundled Flow runtime
run: uv sync --locked --extra dev --extra build

- name: Checkout the exact Tray protocol peer
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: OpenAdaptAI/openadapt-tray
ref: 3d6ffbeda50af2fc4769ae0f1ce55e3d5d49435c
path: packages/desktop/.integration/openadapt-tray
persist-credentials: false

# The Tray client is in this tree (packages/tray), so the test runs
# against the client from the same commit. packages.yml runs this test
# too when only the tray changes.
- name: Exercise the Desktop and Tray IPC contract
env:
OPENADAPT_TRAY_SOURCE: .integration/openadapt-tray/src
OPENADAPT_TRAY_SOURCE: ../tray/src
run: uv run pytest tests/test_tray_integration.py -v

- name: Exercise qualification safety contracts
Expand Down
100 changes: 99 additions & 1 deletion .github/workflows/packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@
# on main, and the bundled-Flow qualification contract) and desktop-build.yml
# (frontend, Python distribution, frozen sidecar, and Tauri installers). Their
# jobs are in packages-gate like every other package's.
#
# openadapt-tray (packages/tray) keeps its own uv.lock and runs `uv sync
# --locked` against it: its suite on Linux with Python 3.10 and 3.12 for a PR,
# plus 3.11, macOS and Windows on main; ruff, the version and changelog
# contract, `uv build` and the archive boundary; and Desktop's socket test
# against this tray client, so a tray change cannot break the protocol
# without the desktop suite running. A desktop change runs that same test in
# desktop-test.yml.
name: Packages

on:
Expand Down Expand Up @@ -74,6 +82,7 @@ jobs:
capture: ${{ steps.classify.outputs.capture }}
privacy: ${{ steps.classify.outputs.privacy }}
desktop: ${{ steps.classify.outputs.desktop }}
tray: ${{ steps.classify.outputs.tray }}
program_graph: ${{ steps.classify.outputs.program_graph }}
weight: ${{ steps.classify.outputs.weight }}
steps:
Expand All @@ -89,7 +98,7 @@ jobs:
run: |
set -euo pipefail
all() {
for pkg in flow types agent capture privacy desktop program_graph weight; do echo "$pkg=true" >> "$GITHUB_OUTPUT"; done
for pkg in flow types agent capture privacy desktop tray program_graph weight; do echo "$pkg=true" >> "$GITHUB_OUTPUT"; done
exit 0
}
case "$EVENT_NAME" in
Expand Down Expand Up @@ -119,6 +128,7 @@ jobs:
capture="$(hit "^packages/capture/|$wf")"
privacy="$(hit "^packages/privacy/|$wf")"
desktop="$(hit "^packages/desktop/|^\.github/workflows/desktop-[a-z-]+\.yml$|$wf")"
tray="$(hit "^packages/tray/|$wf")"
# The program map checks its schema against Flow's copy.
program_graph="$(hit "^packages/program-graph/|^packages/flow/schemas/program-graph-v2\.json$|^\.github/workflows/release-program-graph\.yml$|$wf")"
# Any package's metadata, or the launcher's, can change what an
Expand All @@ -131,6 +141,7 @@ jobs:
echo "capture=$capture"
echo "privacy=$privacy"
echo "desktop=$desktop"
echo "tray=$tray"
echo "program_graph=$program_graph"
echo "weight=$weight"
} | tee -a "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -681,6 +692,90 @@ jobs:
if: needs.scope.outputs.desktop == 'true'
uses: ./.github/workflows/desktop-build.yml

tray:
name: tray (${{ matrix.os }}, py${{ matrix.python-version }})
needs: scope
if: needs.scope.outputs.tray == 'true'
strategy:
fail-fast: false
matrix:
# A pull request runs Linux on the oldest and newest Python; main adds
# 3.11, macOS and Windows, where the tray's platform handlers differ.
include: ${{ fromJSON(github.event_name == 'pull_request' && '[{"os":"ubuntu-latest","python-version":"3.10"},{"os":"ubuntu-latest","python-version":"3.12"}]' || '[{"os":"ubuntu-latest","python-version":"3.10"},{"os":"ubuntu-latest","python-version":"3.11"},{"os":"ubuntu-latest","python-version":"3.12"},{"os":"macos-latest","python-version":"3.12"},{"os":"windows-latest","python-version":"3.12"}]') }}
runs-on: ${{ matrix.os }}
timeout-minutes: 20
defaults:
run:
working-directory: packages/tray
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
- name: Set up Python
run: uv python install ${{ matrix.python-version }}
- name: Install
run: uv sync --locked --python ${{ matrix.python-version }} --extra dev
- name: Test
env:
# No display or input device on the Linux runners.
PYNPUT_BACKEND: ${{ runner.os == 'Linux' && 'dummy' || '' }}
PYSTRAY_BACKEND: ${{ runner.os == 'Linux' && 'dummy' || '' }}
run: uv run --no-sync pytest tests -q

tray-contract:
name: tray lint and release contract
needs: scope
if: needs.scope.outputs.tray == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: packages/tray
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
- name: Set up Python
run: uv python install 3.12
- name: Install
run: uv sync --locked --python 3.12 --extra dev
# The whole package, including examples/ and the root helper scripts.
- name: Ruff
run: uv run --no-sync ruff check .
- name: Build wheel and source distribution
run: uv build
- name: Versions agree and both distributions exist
run: uv run --no-sync python scripts/check_release_consistency.py --require-dist
- name: Verify release archive boundaries
run: uv run --no-sync python scripts/check_source_boundary.py --require-dist

tray-desktop-ipc:
# Desktop's socket server against this tray's IPC client, both from this
# commit. desktop-test.yml runs the same test when Desktop changes.
name: tray and desktop IPC contract
needs: scope
if: needs.scope.outputs.tray == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
defaults:
run:
working-directory: packages/desktop
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
- name: Set up Python
run: uv python install 3.12
- name: Install Desktop
run: uv sync --locked --python 3.12 --extra dev
- name: Exercise the Desktop and Tray IPC contract
env:
OPENADAPT_TRAY_SOURCE: ../tray/src
run: uv run --no-sync pytest tests/test_tray_integration.py -v

program-graph:
name: program-graph (test, build, vendor)
needs: scope
Expand Down Expand Up @@ -806,6 +901,9 @@ jobs:
- privacy-contract
- desktop-test
- desktop-build
- tray
- tray-contract
- tray-desktop-ipc
- program-graph
- install-weight
- capture-core-record
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/release-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# agent openadapt-agent pypi-agent
# capture openadapt-capture pypi-capture
# privacy openadapt-privacy pypi-privacy
# tray openadapt-tray pypi-tray
#
# Manual dispatch only: there is no tag or push trigger, so nothing here runs
# unless someone starts it. openadapt-desktop is not here: desktop-release.yml
Expand All @@ -36,7 +37,7 @@ on:
description: "Package directory under packages/"
required: true
type: choice
options: [flow, types, agent, capture, privacy]
options: [flow, types, agent, capture, privacy, tray]
version:
description: "Version to publish; must equal packages/<package>/pyproject.toml"
required: true
Expand Down Expand Up @@ -96,6 +97,7 @@ jobs:
"agent": "openadapt-agent",
"capture": "openadapt-capture",
"privacy": "openadapt-privacy",
"tray": "openadapt-tray",
}[pkg]
if project["name"] != expected:
sys.exit(f"packages/{pkg} is {project['name']!r}, expected {expected!r}")
Expand Down
3 changes: 2 additions & 1 deletion CAPABILITIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ shipping in the next release.
| Binds each approval to the exact screenshot and form state, and re-reads the form before saving. | [APPROVAL_MODES.md](packages/flow/docs/APPROVAL_MODES.md) |
| Has a written threat model for prompt injection against the agent that teaches or repairs a program, with tests. | [THREAT_MODEL.md](packages/flow/docs/THREAT_MODEL.md) |
| Fills inputs from a referral PDF, fax image or email, and holds back anything unclear for a person. | `intake`, [INTAKE.md](packages/flow/docs/INTAKE.md) |
| Ships as one monorepo with separately installable packages (flow, agent, types, capture, privacy and desktop), each released from the monorepo. | [README](README.md) |
| Ships as one monorepo with separately installable packages (flow, agent, types, capture, privacy, desktop and tray), each released from the monorepo. | [README](README.md) |
| Makes no model calls on healthy runs. Model training (openadapt-ml) is separate research. | [README](README.md) |

## The full map
Expand Down Expand Up @@ -245,6 +245,7 @@ improvising or retrying when something is off.
| Record mouse, keyboard, screen video and accessibility trees on one clock (Windows, macOS, Linux X11) | Released (capture 1.3.0) | Real OS | [packages/capture](packages/capture/README.md); Wayland is not supported |
| Find and redact personal and health data in text, screenshots and structure | Released (privacy 1.1.3) | Unit tests | [packages/privacy](packages/privacy/README.md), [PRIVACY.md](packages/flow/docs/PRIVACY.md) |
| Scrub by default before anything leaves the machine | On main ([#1262](https://github.com/OpenAdaptAI/OpenAdapt/pull/1262)) | Unit tests | `openadapt-privacy` |
| Start and stop Desktop recordings from the menu bar or system tray, and see Desktop's state and how many cloud runs need a person | Released (tray 0.3.7) | Unit tests; CI runs the tray client against Desktop's socket server. The two haven't been run together from packaged installs | [packages/tray](packages/tray/README.md) |
| Each package installs on its own within a size budget, checked in CI (privacy without desktop, capture without plotting) | On main ([#1270](https://github.com/OpenAdaptAI/OpenAdapt/pull/1270), [#1271](https://github.com/OpenAdaptAI/OpenAdapt/pull/1271), [#1279](https://github.com/OpenAdaptAI/OpenAdapt/pull/1279)) | CI | `.github/workflows/packages.yml` |
| See a compiled program as a map (every step, exact edge, loop and stop rule, with each step's checks) and play a recorded run over it; one React package that Desktop, app.openadapt.ai and openadapt.ai share | On main ([packages/program-graph](packages/program-graph/README.md)) | Real compiled OpenEMR referral program and a recorded scoreboard run, both on synthetic data | `@openadapt/program-graph`; `openadapt-flow visualize --format json` |
| Encrypt PHI at rest: every bundle file that can hold patient data under one sealed index (unknown files refused), web recordings from the first frame, and the run directories of sealed bundles; compile, induce, scaffold-verifier, qualify, admit, run, resume and undo read them in memory and refuse without the key | On main | Synthetic (no-plaintext audit-hook test over record, compile and a VERIFIED run; per-frame cost measured) | `openadapt-flow seal`, `record`; [phi_at_rest.md](packages/flow/docs/phi_at_rest.md) |
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ retrieval, and general computer-use agents are separate research surfaces.

- `openadapt/`: launcher package and unified CLI
- `packages/`: the product packages, each folded in with its history
(`flow`, `agent`, `types`, `capture`, `privacy`, `desktop`; see
(`flow`, `agent`, `types`, `capture`, `privacy`, `desktop`, `tray`; see
`docs/monorepo/`), and `program-graph`, the program map Desktop, Cloud and
the website share
- `tests/`: launcher, integration-seam, and release-artifact tests
Expand Down
14 changes: 9 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ Participation in this project is governed by the
`OpenAdaptAI/OpenAdapt` is a monorepo. The root holds the `openadapt`
launcher, and `packages/` holds the engine (`packages/flow`), the MCP server
(`packages/agent`), the shared contracts (`packages/types`), the recorder
(`packages/capture`), privacy scrubbing (`packages/privacy`) and OpenAdapt
Desktop (`packages/desktop`). New engine, replay, repair, policy, and backend
(`packages/capture`), privacy scrubbing (`packages/privacy`), OpenAdapt
Desktop (`packages/desktop`) and its menu-bar and tray controller
(`packages/tray`). New engine, replay, repair, policy, and backend
work belongs in `packages/flow`. Open new issues and pull requests here.

The [signed Production record](https://docs.openadapt.ai/production-lifecycle.json)
Expand All @@ -29,9 +30,12 @@ package availability, repository text, or a sibling repository.
Flow depends on it and re-exports it as `openadapt_flow.contracts`.
- **`packages/agent`**: the `openadapt-agent` package, which keeps the old
imports and commands working on top of `openadapt_flow.agent`.
- **Other repositories** (capture, privacy, desktop and the rest): open issues
only when their stated lifecycle and contribution guide match the proposed
work.
- **`packages/capture`, `packages/privacy`, `packages/desktop`,
`packages/tray`**: each keeps its own README, tests and lockfile. Open issues
and pull requests here.
- **Other repositories** (research such as openadapt-ml and the rest): open
issues only when their stated lifecycle and contribution guide match the
proposed work.

## Getting started

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ MCP server. The product packages live in this repository:
| [`openadapt-capture`](https://pypi.org/project/openadapt-capture/) | The desktop recorder: `openadapt[capture]` | [`packages/capture/`](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/capture) |
| [`openadapt-privacy`](https://pypi.org/project/openadapt-privacy/) | Finds and redacts personal and health data: `openadapt[privacy]` | [`packages/privacy/`](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/privacy) |
| [`openadapt-desktop`](https://pypi.org/project/openadapt-desktop/) | OpenAdapt Desktop ([download](https://openadapt.ai/download)) | [`packages/desktop/`](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/desktop) |
| [`openadapt-tray`](https://pypi.org/project/openadapt-tray/) | Menu-bar and system-tray controls and status for OpenAdapt Desktop | [`packages/tray/`](https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/tray) |

Each package installs only what it imports. For example, `pip install openadapt-privacy` doesn't install the engine or the desktop app. CI checks each package's install size and dependency list ([install weight](https://github.com/OpenAdaptAI/OpenAdapt/blob/main/docs/monorepo/INSTALL_WEIGHT.md)).

Expand Down
2 changes: 1 addition & 1 deletion docs/design/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ with the [current documentation](https://docs.openadapt.ai) or the canonical

## Documents

- [System Tray App](openadapt-tray.md) - Design specification for the OpenAdapt system tray application
- [System Tray App](openadapt-tray.md) - Design specification for the OpenAdapt system tray application (it now ships from [`packages/tray`](../../packages/tray))
- [Tray Logging](tray-logging.md) - Logging architecture for the tray application
- [Telemetry](telemetry-design.md) - Telemetry and analytics design
14 changes: 12 additions & 2 deletions docs/design/openadapt-tray.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# openadapt-tray Package Design

> **Status:** historical. This is the design written before the tray was
> built. The tray ships as `openadapt-tray` from
> [`packages/tray`](../../packages/tray) in this repository, and its
> [README](../../packages/tray/README.md) and
> [PROTOCOL.md](../../packages/tray/docs/PROTOCOL.md) describe what it does
> today. The shipped tray differs from this design: it controls recording in
> OpenAdapt Desktop over Desktop's loopback socket instead of running the CLI,
> shows how many cloud runs need a person, has no training or replay
> controls, and doesn't start at login.

## Overview

`openadapt-tray` is a cross-platform system tray application that provides a graphical interface for the OpenAdapt ecosystem. It serves as a thin orchestration layer, allowing users to control recording, monitor training, view captures, and access settings without using the command line.
Expand Down Expand Up @@ -59,7 +69,7 @@ The legacy implementation uses **PySide6/Qt** for cross-platform system tray fun
### Package Structure

```
openadapt-tray/
packages/tray/
├── src/openadapt_tray/
│ ├── __init__.py # Package exports, version
│ ├── __main__.py # Entry point: python -m openadapt_tray
Expand Down Expand Up @@ -1060,7 +1070,7 @@ openadapt-tray-gui = "openadapt_tray.app:main"
[project.urls]
Homepage = "https://openadapt.ai"
Documentation = "https://docs.openadapt.ai"
Repository = "https://github.com/OpenAdaptAI/openadapt-tray"
Repository = "https://github.com/OpenAdaptAI/OpenAdapt/tree/main/packages/tray"

[build-system]
requires = ["hatchling"]
Expand Down
1 change: 1 addition & 0 deletions docs/monorepo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ reach back past the fold.
| `packages/capture` | OpenAdaptAI/openadapt-capture | `612412c4` | #1205 | [openadapt-capture-commit-map.tsv](openadapt-capture-commit-map.tsv) |
| `packages/privacy` | OpenAdaptAI/openadapt-privacy | `4938a8e7` | #1266 | [openadapt-privacy-commit-map.tsv](openadapt-privacy-commit-map.tsv) |
| `packages/desktop` | OpenAdaptAI/openadapt-desktop | `9447a0a1` | #1267 | [openadapt-desktop-commit-map.tsv](openadapt-desktop-commit-map.tsv) |
| `packages/tray` | OpenAdaptAI/openadapt-tray | `e979dbbf` | #1356 | [openadapt-tray-commit-map.tsv](openadapt-tray-commit-map.tsv) |

## How a fold is done

Expand Down
Loading
Loading