Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 203 additions & 5 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tp7"
version = "0.1.0"
version = "0.1.1"
edition = "2024"
rust-version = "1.88"
authors = ["Toto Tvalavadze"]
Expand All @@ -18,7 +18,7 @@ clap = { version = "4.6.1", features = ["derive"] }
env_logger = "0.11.10"
futures = "0.3"
log = "0.4.29"
mtp-rs = "0.13.3"
mtp-rs = "0.32.0"
nusb = "0.2.3"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ tp7 -a push ./clip.wav /memo/clip.wav --overwrite
tp7 -a rm /memo/clip.wav --dry-run
```

For normal use, prefer `-a` / `--auto-connect`. Each command then handles the full TP-7 lifecycle: detect the recorder, switch to MTP if needed, open MTP, do the operation, and close cleanly.
For normal use, prefer `-a` / `--auto-connect`. Each command detects the
recorder, switches to MTP if needed, opens or reuses the MTP session, performs
the operation, and leaves the recorder ready for the next command.

`tp7 connect` and `tp7 eject` are diagnostic/manual-control commands. They are useful for checking whether MTP can be opened and released, but they are not a "mount once, run many commands, eject later" workflow.

Expand Down Expand Up @@ -63,6 +65,20 @@ tp7 -a ls -sS --human-readable /
tp7 -a ls -ltr /recordings
```

TP-7 file commands leave the recorder in MTP mode after they exit, so repeated
commands work without reconnecting or a resident helper process. `tp7 eject`
is the explicit way to close the device-side MTP session. On macOS,
`ptpcamerad` may claim the interface before `tp7`; when that happens,
`--take-over` can reclaim it and retry:

```sh
tp7 -a ls --take-over -lah /
```

`--take-over` only terminates a process when macOS reports `ptpcamerad` as the
exclusive owner of the TP-7 MTP interface. It does not terminate FieldKit,
OpenMTP, or unrecognized owners.

## Agent-friendly by design

`tp7` follows the same Project Humane conventions as the other local tools in this workspace: concise text output for people, deterministic `--json` for scripts and agents, non-zero exit codes on errors, explicit destructive commands, and dry-run support where a command can change files.
Expand Down
19 changes: 15 additions & 4 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ Device identity:
- Product: `TP-7`
- Vendor string: `teenage engineering`
- Vendor ID: `0x2367`
- Product ID: `0x0019`
- Product IDs: `0x0019` in the original observation; `0x8019` for the
audio/MIDI personality on another observed unit. The latter re-enumerates as
`0x0019` in MTP mode, so interface descriptors remain the authoritative mode
signal.
- Serial: `F1RTL11C`
- USB speed: high speed, 480 Mbps
- USB version: 2.0
Expand Down Expand Up @@ -209,7 +212,7 @@ Open validation tasks:

- Confirmed: `mtp-rs` can open the TP-7 once it is in MTP mode.
- Confirm object listing and transfers work with TP-7 recordings.
- Confirm whether `mtp-rs` exposes all required operations or whether we need small extensions.
- Confirmed: `mtp-rs` 0.32.0 includes the TP-7 session-reuse API upstream, so no vendored fork is required.
- Confirm whether `nusb` can handle any macOS device ownership edge cases cleanly.

Validated MTP status from `mtp-rs`:
Expand All @@ -224,6 +227,11 @@ Validated MTP status from `mtp-rs`:
- Capacity: `120244404224` bytes
- Free space observed: `112986914816` bytes

`mtp-rs` 0.32.0 moved its high-level API to backend-neutral device and storage
metadata. The CLI keeps the existing JSON keys for vendor-extension text and
free object counts, but reports them as `null` because those protocol-specific
values are no longer exposed by that API.

## Go Tooling Considered

Go is feasible but less attractive for this project.
Expand Down Expand Up @@ -280,6 +288,9 @@ Useful flags:
- `-t, --sort-time`: sort by modified time, newest first.
- `-r, --reverse`: reverse listing order.
- `-i, --ids`: show MTP object IDs.
- `--take-over`: after an exclusive-access failure, terminate and retry only
when macOS reports `ptpcamerad` as the exclusive owner of the TP-7 MTP
interface. Other owners remain untouched.
- `--json`

`tp7 tree [remote-path]`
Expand Down Expand Up @@ -511,7 +522,7 @@ MTP semantics:

Library risk:

- `mtp-rs` may need fixes or extensions for TP-7 quirks.
- Future TP-7 quirks may still require upstream `mtp-rs` fixes or extensions.
- `libmtp` fallback is likely reliable but adds C dependency and licensing considerations.

Mount risk:
Expand All @@ -525,7 +536,7 @@ Mount risk:
- Teenage Engineering TP-7 product page: <https://teenage.engineering/products/tp-7>
- Teenage Engineering TP-7 downloads/release notes: <https://teenage.engineering/downloads/tp-7>
- Microsoft MTP extensions overview: <https://learn.microsoft.com/en-us/windows/win32/wpd_sdk/supporting-mtp-extensions>
- `mtp-rs` crate docs: <https://docs.rs/crate/mtp-rs/0.11.0>
- `mtp-rs` crate docs: <https://docs.rs/crate/mtp-rs/0.32.0>
- `fuser` crate docs: <https://docs.rs/fuser>
- macFUSE: <https://macfuse.github.io/>
- Fuse-T: <https://www.fuse-t.org/>
Expand Down
Loading