Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9c0a9fe
Fix live client controls and add shared host presentations
DRSDavidSoft Oct 27, 2026
908f829
Retire rejected touch pointers and preserve nested network guard checks
DRSDavidSoft Oct 27, 2026
23fc157
Add guarded managed files and harden static asset serving
DRSDavidSoft Oct 27, 2026
7373e9e
Integrate pinned portable-shell catalogue, VT100 and safe completion
DRSDavidSoft Oct 27, 2026
2a17b8c
Complete bundled TCP terminal and verify portable shell stub replacem…
DRSDavidSoft Oct 27, 2026
e24797a
Fix keycontroller navigation and bounded live telemetry and IPC
DRSDavidSoft Oct 27, 2026
33b0447
fix(desktop): add persistent box selection and reconnect controls
DRSDavidSoft Oct 27, 2026
8622e7d
ci: preserve immutable donor whitespace without relaxing product checks
DRSDavidSoft Oct 27, 2026
ea08686
fix(mobile): restore key presses and move boxes into Game workspace
DRSDavidSoft Oct 27, 2026
6a8d911
feat(shell): negotiate terminal geometry and add contextual game TUI
DRSDavidSoft Oct 27, 2026
c78a402
fix(shell): unify pixel topology and contextual command catalogue
DRSDavidSoft Oct 27, 2026
9421679
feat: add removable DRS Snake host app and gated board engine
DRSDavidSoft Oct 27, 2026
e924adc
feat(clients): add explicit host Wi-Fi join and management
DRSDavidSoft Oct 27, 2026
286c4fe
fix(ci): validate donor statuses and empty storage inventories
DRSDavidSoft Oct 27, 2026
6940e63
feat(tooling): import donor documentation gates and CI artifact summary
DRSDavidSoft Oct 27, 2026
e49cb37
fix(ci): avoid shell interpolation warning in artifact summary
DRSDavidSoft Oct 27, 2026
0bcaf8e
feat(telemetry): separate CI resource budgets from live observations
DRSDavidSoft Oct 27, 2026
510b6d7
fix(web): retain reload dialog ownership until reads complete
DRSDavidSoft Oct 27, 2026
46a68b3
feat(keycontroller): add board-owned runtime minigames across clients
DRSDavidSoft Oct 27, 2026
f40f688
fix(snake): add finite sound cues and safe tablet exit restoration
DRSDavidSoft Oct 27, 2026
b985bac
fix(snake): admit actual table capability and role
DRSDavidSoft Oct 27, 2026
38917f0
feat(snake): add read-only board readiness probe
DRSDavidSoft Oct 27, 2026
c3bf1b2
fix(snake): simplify visible game branding
DRSDavidSoft Oct 27, 2026
6b9d75f
fix(snake): add tablet D-pad and immediate swipe steering
DRSDavidSoft Oct 27, 2026
bc57d9f
docs: record paired keycontroller minigame deployment
DRSDavidSoft Oct 27, 2026
bf158e3
feat(mobile): redesign keycontroller live box workspace
DRSDavidSoft Oct 27, 2026
62c5dc5
docs: record verified tablet designer delivery
DRSDavidSoft Oct 27, 2026
bca9ff5
fix: separate key workspace controls and schedule winner audio locally
DRSDavidSoft Oct 27, 2026
b571b37
fix: enrich minigame feedback and preserve acknowledged command sessions
DRSDavidSoft Oct 28, 2026
cb6ff1d
fix: polish device terminal navigation completion and tone commands
DRSDavidSoft Oct 28, 2026
30fad46
fix(discovery): advertise per-board UPnP icons and correct descriptions
DRSDavidSoft Oct 28, 2026
4028373
feat(ssh): gate native S3 shell and bounded public SCP downloads
DRSDavidSoft Oct 28, 2026
24e3147
fix(leds): restart Fire cold and render rotatable matrix flames
DRSDavidSoft Oct 28, 2026
2337100
fix(peers): cache verified LAN routes and bound relay resolution
DRSDavidSoft Oct 28, 2026
cfad951
fix(peers): recover changed hints without memory admission lockout
DRSDavidSoft Oct 28, 2026
06815b6
feat(network): add configurable clock and advanced diagnostics
DRSDavidSoft Oct 28, 2026
21c11a0
fix(desktop): consume asynchronous wifi scan results
DRSDavidSoft Oct 28, 2026
b09650e
feat(esp): add gated transactional SCP SFTP and FTP uploads
DRSDavidSoft Oct 28, 2026
378016e
fix(handoff): reconcile client drafts and repair review and contract …
DRSDavidSoft Oct 28, 2026
89b4a6f
fix(ci): align integration fixtures with current runtime owners
DRSDavidSoft Oct 28, 2026
33f276a
fix(games): fence settings writes and finalize source handoff checks
DRSDavidSoft Oct 28, 2026
3ee583a
fix(storage): isolate host layers and make RX failure fixtures determ…
DRSDavidSoft Oct 28, 2026
b0b5dbb
docs(handoff): keep API routes contiguous and refresh review inventory
DRSDavidSoft Oct 28, 2026
8102f04
fix(avr): guard ESP-owned key dispatch in table builds
DRSDavidSoft Oct 28, 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
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
*.bin binary
*.apk binary
*.zip binary
# Immutable donor snapshot: retain its hash-verified original trailing whitespace.
# Pakar adaptations and all other source remain subject to whitespace checks.
third_party/portable-shell/upstream/** whitespace=-blank-at-eol,-blank-at-eof
64 changes: 60 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ jobs:
shell: pwsh
run: |
$taskPins = Get-Content tools/firmware-dependencies.json -Raw | ConvertFrom-Json
$taskJson = @($taskPins.libraries | Where-Object name -eq 'ArduinoJson')
if ($taskJson.Count -ne 1 -or $taskJson[0].version -notmatch '^\d+\.\d+\.\d+$') { throw 'Missing exact ArduinoJson pin' }
arduino-cli lib update-index
if ($LASTEXITCODE -ne 0) { throw 'Host-test library index failed' }
arduino-cli lib install ('ArduinoJson@' + $taskJson[0].version)
if ($LASTEXITCODE -ne 0) { throw 'Pinned host-test headers failed' }
foreach ($taskName in @('ArduinoJson','LibSSH-ESP32')) {
$taskLibrary = @($taskPins.libraries | Where-Object name -eq $taskName)
if ($taskLibrary.Count -ne 1 -or $taskLibrary[0].version -notmatch '^\d+\.\d+\.\d+$') { throw "Missing exact $taskName pin" }
arduino-cli lib install ($taskName + '@' + $taskLibrary[0].version)
if ($LASTEXITCODE -ne 0) { throw 'Pinned host-test headers failed' }
}
- run: node tools/ci-checks.mjs quality
- run: node tests/led_backend_integration_test.mjs
- run: node tests/web_led_backend_test.mjs
Expand Down Expand Up @@ -105,6 +107,9 @@ jobs:
needs: quality
runs-on: ubuntu-24.04
timeout-minutes: 60
permissions:
contents: read
actions: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
Expand All @@ -124,6 +129,13 @@ jobs:
bash tools/test-pc-flags.sh
# ESP8266 source/tooling is retained, but its full image currently
# exceeds physical RAM/flash budgets and is not a release target.
# Board-owned key games need both ends compiled, not only host fixtures.
# Subsequent table builds restore the canonical release artifacts.
pwsh -NoProfile -File tools/build-firmware.ps1 -Target avr -GameMode first-wins -LinkMode buffered -AvrRadio -Jobs 2
pwsh -NoProfile -File tools/build-firmware.ps1 -Target esp32s3 -GameMode first-wins -LinkMode buffered -S3FlashMB 16 -S3Psram opi -S3LedGpio -S3LedRmtDma -S3Bluetooth disabled -Jobs 2
# Optional encrypted transport + transactional SCP/SFTP and opt-in FTP; later builds
# restore the default SSH-excluded artifact in the same SDK cache.
pwsh -NoProfile -File tools/build-firmware.ps1 -Target esp32s3 -GameMode first-wins -LinkMode buffered -S3FlashMB 16 -S3Psram opi -S3LedGpio -S3LedRmtDma -S3Bluetooth disabled -S3Ssh -S3Scp -S3Sftp -S3Ftp -Jobs 2
bash build.sh polling avr
bash build.sh busy-wire avr
bash build.sh buffered avr
Expand All @@ -137,6 +149,34 @@ jobs:
# builds a no-matrix image, which must not be the release artifact.
bash build.sh buffered esp32s3 --s3-flash-mb 16 --s3-psram opi --s3-led-gpio --s3-led-rmt-dma
node tools/firmware-report.mjs --require --write
- name: Previous successful main resource baseline
env:
GH_TOKEN: ${{ github.token }}
run: |
if run=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow build.yml --branch main --status success --limit 1 --json databaseId --jq '.[0].databaseId // empty'); then
if [[ -n "$run" ]]; then
if ! gh run download "$run" --repo "$GITHUB_REPOSITORY" --name PakarController-resources --dir build/resource-baseline; then
echo 'No retained resource baseline available; absolute budgets still enforced.'
fi
fi
else
echo 'Baseline lookup unavailable; absolute budgets still enforced.'
fi
- name: Resource budgets and historical comparison
run: |
args=()
if [[ -f build/resource-baseline/resource-report.json ]]; then
args+=(--baseline build/resource-baseline/resource-report.json)
fi
node tools/resource-report.mjs --write "${args[@]}"
- name: Publish resource report
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: PakarController-resources
path: build/resource-report.json
retention-days: 90
if-no-files-found: warn
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: PakarController-firmware
Expand Down Expand Up @@ -288,6 +328,9 @@ jobs:
needs: [lint, tooling, quality, firmware, windows-desktop, android-preview, release]
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
actions: read
steps:
- env:
LINT: ${{ needs.lint.result }}
Expand All @@ -297,6 +340,7 @@ jobs:
WINDOWS: ${{ needs.windows-desktop.result }}
ANDROID: ${{ needs.android-preview.result }}
RELEASE: ${{ needs.release.result }}
GH_TOKEN: ${{ github.token }}
run: |
{
echo '# PakarController build verification'; echo
Expand All @@ -310,5 +354,17 @@ jobs:
echo "| Draft release | $RELEASE |"
echo; echo '> CI does not prove physical operation or deployment.'
} >> "$GITHUB_STEP_SUMMARY"
# Adapt Pealayer's real run-artifact summary; enumerate every page.
{
echo; echo '## Run artifacts'; echo
echo '| Artifact | Bytes | Expires |'; echo '|---|---:|---|'
} >> "$GITHUB_STEP_SUMMARY"
if artifact_rows=$(gh api --paginate "repos/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/artifacts" --jq '.artifacts[] | "| \(.name) | \(.size_in_bytes) | \(.expires_at) |"'); then
if [[ -n "$artifact_rows" ]]; then printf '%s\n' "$artifact_rows" >> "$GITHUB_STEP_SUMMARY"; else
echo '| None produced by this run | — | — |' >> "$GITHUB_STEP_SUMMARY"
fi
else
echo '| Inventory unavailable; inspect this run | — | — |' >> "$GITHUB_STEP_SUMMARY"
fi
[[ "$LINT" == success && "$TOOLING" == success && "$QUALITY" == success && "$FIRMWARE" == success && "$WINDOWS" == success && "$ANDROID" == success ]]
[[ "$RELEASE" == success || "$RELEASE" == skipped ]]
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- FIRST on every task, missing capability or tool/build failure: read docs/REUSE-PREFLIGHT.md and run tools/consult-reuse.ps1 -Concern <affected capability>. Inspect every matching mapping/pending action, then read actual donor sources/dependencies before replacement code or declaring unavailable. Reuse Pealayer/PCController/PU implementations and tests, not just their style. Update the existing hash-bound file ledger and GitHub issue with every useful omission; screened/unread files are never accepted exclusions. Add an index route when a failure has no match. Build/stage/capture gates are mandatory and must not be bypassed by direct commands.

- Preserve existing user/concurrent changes. Donor checkouts remain read-only unless the user requests changes there.
- Native hover/press regression rule: every action, toggle (including Arrange boxes), selectable row and menu must retain the same allocated rectangle, padding, font, text origin, border width/radius and sibling positions across idle/hover/press/focus/selected/disabled states. Hover changes color only; paint custom strokes Inside. Do not add a hardcoded Button stroke after egui has calculated its frame margins, or use stock selectable labels without verifying their geometry. Reuse the existing control-density/dialog helpers and Pealayer 5b3d5c1 fix; test actual pointer transitions in both themes, densities and fractional DPI (response rectangles AND text origins). A static screenshot or zero expansion alone is insufficient. Never silently swallow an explicit enabled trigger: dispatch through the same acknowledged hardware command owner as the corresponding physical action, or show the current blocking reason.
- GitHub coordination: before merging read the complete diff, conversations, reviews and every review-thread page (including outdated/unresolved threads); consult github-coordination and docs/GITHUB-COORDINATION.md. Use tools/audit-github-conversations.mjs for exhaustive read-only enumeration. Downloaded records are pending until manually reviewed; closed/merged is not resolved. Request Copilot when useful, distinguish quota/request from completed review, and fix/reply to actual findings. Never bypass required checks or auto-resolve unrelated donor comments.
- Capability regexes are NOT exhaustive inventory. Consult donor-audit (optionally -Origin / literal -SourcePath) too; inspect AuditOnly, omissions and remaining actions. Keep the existing authoritative ledger, receipt and owning issue synchronized. On a failure, stop blind retries and record which actual donor source/tool/test was consulted and the selected recovery; never convert unread or unrouted files into exclusions.
- Use hostname-first device access. A build, loopback fixture or screenshot is not physical acceptance.
Expand Down
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-10b981.svg)](LICENSE)
[![Rust · egui](https://img.shields.io/badge/Desktop-Rust%20%7C%20egui-f59e0b?logo=rust)](desktop)
[![ESP + AVR](https://img.shields.io/badge/Firmware-ESP32--S3%20%2B%20ATmega328P-06b6d4)](firmware)
[![Android preview](https://img.shields.io/badge/Android-preview-8b5cf6?logo=android)](https://github.com/atomicdeploy/PakarController/pull/1)
[![Android preview](https://img.shields.io/badge/Android-preview-8b5cf6?logo=android)](mobile/README.md)

[Overview](#overview) · [Architecture](#architecture) · [Build](#build) · [CI/CD](#continuous-integration--delivery) · [Roadmap](https://github.com/atomicdeploy/PakarController/issues/2)
[Overview](#overview) · [Get started](#get-started) · [Architecture](#architecture) · [Build](#build) · [Guides](docs/README.md) · [Roadmap](https://github.com/atomicdeploy/PakarController/issues/2)

</div>

Expand All @@ -40,6 +40,24 @@ lock and atomic cell-color imports. Rust and Flutter support genuine Excel,
CSV and JSON documents; the embedded Web UI supports CSV and JSON.
See [board roles, lock semantics and assignment APIs](docs/CELL-ASSIGNMENTS.md).

## Get started

| Your task | Start here |
|---|---|
| Control a provisioned board | Open its configured hostname in a browser, or select it in the Rust/Android Devices view. Check the returned board identity before issuing commands. |
| Connect by USB, without Wi-Fi | Select **USB** and its actual enumerated port in the desktop app. Only one upstream connection is active; sharing is a separate opt-in. |
| Join a board's access point | Use **Host Wi-Fi** in the client. OS approval and network credentials are separate from API authentication. [Platform behavior](docs/HOST-WIFI.md). |
| Build on a new workstation | Run `pakar.cmd doctor` (or `bash pakar.sh doctor`), then follow [Build](#build). Default plans do not flash or install anything. |
| Develop or hand off work | Use the [documentation hub](docs/README.md), [contribution guide](CONTRIBUTING.md), and [current GitHub PRs](https://github.com/atomicdeploy/PakarController/pulls). |

### Downloads and verification

Engineering packages are attached to successful [Build workflow runs](https://github.com/atomicdeploy/PakarController/actions/workflows/build.yml).
Select the intended commit, not just the newest timestamp. Firmware, Windows and
Android outputs are separate artifacts; release packaging adds SHA-256 manifests
and provenance. A successful build is not a deployment or a stable-release claim.
See [release policy and verification](docs/REPOSITORY-GOVERNANCE.md).

<details>
<summary><b>Web device-settings preview</b> — actual embedded UI, simulated device state</summary>

Expand Down Expand Up @@ -229,7 +247,9 @@ Logical IDs retain their 10×8 indexing, but the current visual table has 20
interleaved columns and four rows: `1,11,2,12,...,10,20`. The first column is
`1,21,41,61`; the next is `11,31,51,71`, half a cell lower. Cell1 is not offset
downward. Each table cell has six LEDs; physical strip order is a separate
editable permutation. Snake is currently compiled out, not a selectable game.
editable permutation. The optional board-owned Snake engine is excluded by
default; the removable host mini-app is documented separately and remains hidden
from normal board menus. See [host mini-app installation](mini-apps/snake/README.md).
The interactive terminal now has contextual pages, shared Find/selection,
explicit bulk white/red/off actions and the shared CLI command palette.
See [terminal controls and remaining acceptance](docs/TERMINAL-UI.md).
Expand All @@ -238,13 +258,15 @@ Staggered graphics, richer editors and full TUI parity remain open in issue #2.
## Continuous integration & delivery

The [CI/CD pipeline](.github/workflows/build.yml) checks generated interface,
branding and donor-evidence contracts, tests both UART build variants, builds
branding and donor-evidence contracts, tests all three AVR link profiles, builds
the Windows client and analyzes/tests/builds the Android preview. It stops at
the first failed command. Timeouts, superseded-run cancellation and short artifact
retention bound wasted work. The tooling matrix checks shared CLI fixtures and
guarded command plans on Windows/Linux/macOS; these are not native package or
hardware acceptance. [CodeQL](.github/workflows/codeql.yml) scans Actions
and JavaScript; it does not claim Rust, AVR C++ or physical hardware coverage.
Maintained entry guides also have a dependency-free local-link and heading check,
adapted from PCController. It runs offline and does not crawl external websites.

The expanded pipeline supports version tags and explicit owner dispatch for **draft prereleases**, with
Windows and two-board firmware packages, Android preview, SHA-256 checksums,
Expand All @@ -260,6 +282,7 @@ does not certify that a current GitHub run passed or a device was updated.

| Start here | Purpose |
|---|---|
| [Documentation hub](docs/README.md) | Task-oriented reading order, tooling and verification boundaries |
| [Hardware](docs/HARDWARE.md) | Pin mapping and wiring |
| [API](docs/API.md) | Device transport and commands |
| [Bluetooth LE](docs/BLUETOOTH.md) | S3 offline Android control, identity, settings and transport limits |
Expand Down
22 changes: 22 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@

PakarController is integration code built from earlier AtomicDeploy projects.

- `tools/check-doc-links.mjs` adapts `localLinkReference`, Markdown heading
normalization/anchor enumeration and local-link checking from PCController's
`.github/scripts/repository-check.mjs` and `repository-policy.mjs`, read at
`b0111ae0c80dc34149ea1044de7dd5488920301b`. Used under its MIT option; see
`docs/licenses/PCController-MIT.txt`. Pakar adds fenced-example handling for
link scanning, HTML branding links, repository boundaries and offline fixtures;
donor-specific privacy/license/required-path policies are not copied wholesale.

- `firmware/esp/src/PortableShellCore.h` adapts command descriptors/lookup and
VT100 formatting from `atomicdeploy/portable-shell` revision
`67c5dcb8a63f4055cbdaf02e9ff271c53b46410d` (requested branch
`copilot/organize-readme-into-plan`). Copyright (c) 2024 Portable Shell
Contributors, MIT. The complete license and 16 original regular files are
retained in `third_party/portable-shell/upstream/`; its root CodeQL symlink is
inventoried but not recreated. The original C runtime is reference-only;
the bounded adaptation is used by Pakar's single authenticated device shell.
Tests adapt the donor's command/context/VT100 scenarios and extend them with
non-executing completion, secret isolation and fragmented-input assertions.
`tools/telnet-shell.mjs` also adapts the donor's TCP read/write callback model
into real cross-platform stdin/stdout streams, with incremental Telnet
negotiation, deadlines and backpressure instead of blocking POSIX calls.

- `tools/prepare-avr-image.mjs` adapts Intel HEX validation, AVR jump encoding,
unused-vector validation and boot-chain merging from PCController
`Tools/Bootloader/Urboot-Custom/build.mjs` at
Expand Down
7 changes: 7 additions & 0 deletions assets/web/application-utilities.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading