Skip to content

tt.py as a standalone tool - #730

Merged
KenVanHoeylandt merged 2 commits into
mainfrom
tt-standalone
Nov 1, 2026
Merged

KenVanHoeylandt merged 2 commits into
mainfrom
tt-standalone

Conversation

@KenVanHoeylandt

@KenVanHoeylandt KenVanHoeylandt commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

tt.py needed a manifest.properties to know which SDK version to download. Commands like shell, push, pull and screenshot don't need an app, but still forced you into an app folder, or into answering a "generate a new project?" question first.

What changed

Device info handout (firmware)

development-module has a new info hello mode on the existing TLS port 6667. The server answers one JSON line and closes the connection:

{"status":"accepted","info":{"vendor":"LilyGO","name":"T-Deck","id":"lilygo-tdeck","version":"0.8.0"}}
  • No client certificate, no trust prompt, no session slot and no session app. The info isn't sensitive.
  • Values come from CONFIG_TT_DEVICE_VENDOR, CONFIG_TT_DEVICE_NAME_SIMPLE, CONFIG_TT_DEVICE_ID and TT_VERSION.
  • Other modes are unchanged, and command is still shell-only.
  • Documented in the module README. Unit tests cover the hello parsing and the info line. A server test checks that no prompt is raised.

SDK version selection (tt.py)

Without a project, the SDK version is picked in this order:

  1. manifest.properties in ., Apps/*/ or apps/*/. A project always wins, and nothing else is read, queried or asked.
  2. .tactility/sdk_version in the current folder (set with tt sdk <version>).
  3. The version reported by the device from tt host.
  4. A prompt. The answer is stored in .tactility/sdk_version, so it's asked once per folder.

tt.py queries the device with stdlib ssl, without verifying the certificate and without a client identity.

Built-in host and sdk commands

Both only read and write .tactility/ in the current folder, so they no longer need an SDK. This also fixes tt host <new> first querying the previously stored host and failing with "No route to host".

  • tt host prints the stored host or none. tt host <hostname> stores it, asks the device for its info and prints it. A failed query only warns.
  • tt sdk prints the SDK version in use and its source (project, local setting, or device). When a project is found, it says that a stored version isn't used. tt sdk <version> stores a version.
  • Tools/host.py is removed. _device_host.py stays, since app.py and shell.py read the same file.

tt app create replaces the "generate a new project?" question

  • The question and the project generation are gone from tt.py.
  • app.py has a new create action. It asks for the project type, package id, app id and app name, and uses the SDK version tt selected. It refuses if manifest.properties or main/ already exist.
  • The templates (Buildscripts/TactilitySDK/NewProject/) now ship inside tools.zip under NewProject/. new-project.zip, its index.json entry and Buildscripts/CDN/new_project.py are removed. release-tools-current.py and the CI actions copy NewProject/ into the tools folder.
  • tt.py reads prompt answers one byte at a time. Otherwise piped answers would be swallowed before app.py starts.

Notes for review

  • Dev versions: the device sends TT_VERSION as-is, for example 0.8.0-dev. This only works if the CDN has sdk/<that version>/.
  • Platforms: the device path passes no platform list, so only the tools are installed. tt app build still needs a manifest for its platforms.
  • Precedence: a stored .tactility/sdk_version beats the device, even after the host is changed. Delete the file to switch back to the device.
  • Older SDKs: an SDK published before this change has no NewProject/ in its tools, so tt app create fails for it with "has no new project templates".

Summary by CodeRabbit

  • New Features
    • Create GUI, terminal, and module projects with app create, then build them separately.
    • Use the built-in tt host and tt sdk commands to manage device and SDK settings. Without a project manifest, SDK selection can use a stored version, device information, or an interactive prompt.
    • Query device information using the development protocol without a client certificate.
  • Documentation
    • Clarified the device information exchange in the development-module guide.

@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Findings

Actionable comments posted: 5

Caution

Review failed

The pull request is closed.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 76d82801-4cca-4254-94a9-0af5b75f6040
Commits

Reviewing files that changed from the base of the PR and between 3e1305a and 8d1de38.

Files selected for processing: 5
  • Buildscripts/TactilitySDK/Tools/app.py
  • Modules/development-module/source/protocol.cpp
  • Modules/development-module/tests/source/protocol_test.cpp
  • Tests/Python/tt_test.py
  • tt.py

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

Walkthrough

SDK packaging now includes project templates in the tools tree, and the app tool creates GUI, terminal, and module projects from those templates. The CLI adds built-in host and SDK commands and checks saved and device SDK versions during target selection. The development protocol adds an info mode that returns device details in a JSON line without requiring a client certificate or prompt.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 52.38% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main objective: making tt.py work as a standalone tool. The supporting changes to SDK selection, project creation, device information, and tests are consistent with …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title clearly identifies the main objective: making tt.py work as a standalone tool. The supporting changes to SDK selection, project creation, device information, and tests are consistent with that objective.

Full details: Docstring Coverage

Explanation

Docstring coverage is 52.38% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 21 functions across 13 files. (3 skipped: 3 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Nitpick comments: 3
Tests/Python/tt_test.py: 1

254-254: Trivial · Maintainability & Code Quality · Poor tradeoff

Cover the real query_device_info success path with a test.

test_sdk_shows_the_device_version_when_it_leads replaces query_device_info with a lambda, so the parser in tt.py never runs in that test. The Python host tests cover only the failure path, and no Python test serves a successful info reply. A change to the TLS hello, the newline framing, or the info/version keys can leave the suite passing. In that case sdk falls back to none after a stderr message.

Add a test that starts a local TLS listener, sends one newline-terminated JSON line with status and info.version, and asserts that the real query_device_info returns that version. The device answers the info hello without a client certificate (Modules/development-module/source/server.cpp:284-288), so the test listener needs no client-certificate setup.

Modules/development-module/tests/source/server_test.cpp: 2

418-419: Trivial · Maintainability & Code Quality · Quick win

Add a certificate-less info test case.

The new an info hello is answered without a prompt test connects with &identity(0), so it always sends a client certificate. If the server began to require a certificate for info, this test would still pass. The existing certificate-less test uses only shell mode, so no test covers a certificate-less info hello.

Add a test that connects with TestClient(nullptr) in info mode and expects the request to be accepted.

Suggested test
     CHECK_EQ(promptCount, 0);
 }
 
+TEST_CASE("an info hello is answered without a client certificate") {
+    ensureFixture();
+    promptCount = 0;
+
+    TestClient client(nullptr);
+    const std::string line = connectAndGreet(client, "info");
+    CHECK_NE(line.find(R"("status":"accepted")"), std::string::npos);
+    CHECK_EQ(promptCount, 0);
+}
+
 TEST_CASE("a client that is accepted once gets a shell") {

419-423: Trivial · Maintainability & Code Quality · Quick win

Assert that the info session closes after its response.

The new info-mode test reads the greeting line but does not check that the server closes the connection. A server that sent the line and kept the session open would still pass. The info branch closes the session, and the README documents the close, so this assertion guards that documented behavior. No other test covers it.

🧪 Suggested fix
     CHECK_EQ(promptCount, 0);
+    CHECK(client.waitForClose());
 }

Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9b4ab31a-6a49-4961-910d-3c5a1a61a93f
Commits

Reviewing files that changed from the base of the PR and between 4095b44 and 3e1305a.

Files selected for processing: 18
  • .github/actions/build-sdk-posix/action.yml
  • .github/actions/build-sdk/action.yml
  • Buildscripts/CDN/generate-sdk-files.py
  • Buildscripts/CDN/new_project.py
  • Buildscripts/TactilitySDK/Tools/app.py
  • Buildscripts/TactilitySDK/Tools/host.py
  • Buildscripts/release-tools-current.py
  • Buildscripts/test-new-project.sh
  • Modules/development-module/README.md
  • Modules/development-module/private/development/protocol.h
  • Modules/development-module/private/development/session.h
  • Modules/development-module/source/protocol.cpp
  • Modules/development-module/source/server.cpp
  • Modules/development-module/source/session.cpp
  • Modules/development-module/tests/source/protocol_test.cpp
  • Modules/development-module/tests/source/server_test.cpp
  • Tests/Python/tt_test.py
  • tt.py
Files with no reviewable changes: 2
  • Buildscripts/CDN/new_project.py
  • Buildscripts/TactilitySDK/Tools/host.py

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread Buildscripts/CDN/generate-sdk-files.py Resolved
Comment thread Buildscripts/release-tools-current.py Resolved
Comment thread Buildscripts/TactilitySDK/Tools/app.py Resolved
Comment thread tt.py Resolved
Comment thread tt.py Resolved
Comment thread tt.py Resolved
Comment thread tt.py Resolved
@KenVanHoeylandt
KenVanHoeylandt merged commit d72bddf into main Nov 1, 2026
11 of 21 checks passed
@KenVanHoeylandt
KenVanHoeylandt deleted the tt-standalone branch November 1, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant