Releases: Thin-Remote/thinr-cli
Releases · Thin-Remote/thinr-cli
Release list
1.3.5
Fixed
thinr_lsdescribes what "/" actually resolves to: the agent process's
working directory, which is normally the filesystem root. 1.3.4 said it was
a base directory "usually /var/log", which was a stale service definition on
one device rather than how installs behave.
1.3.4
Fixed
thinr_script_deleteresolves the script by the name the agent reports, so
bothbatteryandbattery.shremove the same file. It used to build the
path from the argument verbatim, which meant following its own description
("without extension") returned a bare 404. A name that matches nothing now
lists the scripts that are registered.
Changed
thinr_script_writerefuses a name that would replace one of the device's
built-in resources (monitoring,system,cmd,update,agent) unless
force: trueis passed. Installingmonitoring.shused to shadow the real
monitoring resource silently. Its description now also states that the
script runs with the agent's privileges, root in a system install.thinr_devicesshows when each device last changed state:connected since
for a live one,offline sincefor a dead one. The timestamp was already in
the response; finding out whether something dropped minutes or months ago
meant a trip to the monitoring history.thinr_lsexplains that/resolves to the agent's base directory while
every other absolute path is literal, and a listing of/now says which
directory it came from. Nothing is confined to that directory, so reading a
/listing as the root filesystem was an easy wrong conclusion to draw.thinr_profilesstates that profiles are not accounts, and thatuser
addresses another account on the same server.
1.3.3
Changed
- MCP tools take the target device as
device_id. A tool argument named
devicenever reaches this server through Claude Desktop's remote-devices
bridge, which claims that name for its own call routing and strips it, so
every tool needing a device failed withdevice is requiredhowever the
caller spelled the call, while tools without one worked. Reproduced on one
machine with one binary: a direct JSON-RPC call succeeded, the same call
through Claude Desktop arrived without the field, and renaming the argument
fixed it with nothing else changed.deviceis no longer accepted.
1.3.2
Fixed
- Device properties and device status now honour the
userargument.
thinr_property_get,thinr_property_setand the playbookproperty
actions accepted it but addressed the active profile's own account, the
same gap fixed for resources in 1.3.1.
Changed
- Account-scoped API paths are built in one place (
lib/paths.js): the
/v{1,2,3}/users/{account}prefixes and the device prefix, all resolving
the account through a singleresolveUser. Five modules carried private
copies of the same three lines and four more interpolated the account by
hand. A test fails the build if any module starts doing that again, which
is what keeps the account from being silently dropped: omitting it
produces a URL that works against your own account and only breaks when
acting on behalf of another. - Not-found errors from properties and status name the account they looked
in, matching the resource helpers.
1.3.1
Fixed
- Device resources now honour the
userargument, so an admin acting on
another account reaches that account's devices.thinr_resource_list,
thinr_resource_calland thethinr_script_*tools accepted the
argument but addressed the active profile's own account, which answered
"Device not found"; playbookresourceand script actions had the same
gap. Not-found errors now name the account they looked in.
1.3.0
Added
thinr login— re-authenticate the current profile in place, without
deleting and recreating it. Renews an expired session in one step and
defaults the server prompt to the profile's existing server.
Changed
- Session-expiry errors now point to the working command: "Session
expired. Runthinr loginto sign in again." (previously suggested
thinr, which opens the dashboard instead of re-authenticating). - More robust token refresh for WebSocket sessions: the interactive
console and streamingexecnow refresh an expired access token
before the handshake and retry once on a 401, matching the
refresh-on-401 behaviour of HTTP calls.
1.2.0
Added
thinrwith no arguments now launches the interactive dashboard
directly when stdout is a TTY (and a configuration exists), so the
fleet view is one keystroke away. Non-TTY contexts (pipes, scripts)
fall back to--help. First-time users still get the auth flow,
then drop straight into the dashboard.- TUI dashboard: alarms panel on the overview tab, with rule- and
instance-level views, severity colouring and live updates over the
same event stream the rest of the dashboard already uses. thinr device delete <deviceId>— remove a device record from the
platform. Interactiveconfirmby default,--yesto skip in
scripts, idempotent on a missing device. Useful after re-provisioning
an agent under a new hostname leaves the oldip-…record offline.- MCP:
thinr_device_delete— same operation for AI clients. - MCP:
thinr_pushandthinr_pull— upload a local file to a
device and download a remote file to local disk, respectively.
Rounds out filesystem parity with the CLI so an agent can move
binary or large payloads that don't fit inline inthinr_write. - MCP: alarms tools (
thinr_alarm_instances,
thinr_alarm_instance_get,thinr_alarm_instance_stats,
thinr_alarm_instance_update,thinr_alarm_instance_delete,
thinr_alarm_rules,thinr_alarm_rule_read,thinr_alarm_rule_write,
thinr_alarm_rule_delete) — list, inspect and manage alarm
instances and rules from AI clients, with state/severity parsing
shared with the dashboard. - MCP: product profile config tools (buckets, properties, API
resources) and access-token tools (user-level and device-level). thinr product exec <productId> <command...>— run a shell command
in parallel on every active device of a product, with bounded
concurrency (-c, --concurrency, default 10), per-device timeout
(--timeout, default 30 s),--fail-fast, asset-group filter
(-g, --group) and an-a, --allswitch to include offline
devices. Live progress shows a single spinner with done/total
counters; the final render uses acli-table3table per device
plus a compactOutput:section and a one-line totals bar.thinr_product_execMCP tool — the same fan-out as the CLI
subcommand, returning a consolidated text report so an AI agent
can roll out a change across a whole fleet in a single call
instead of loopingthinr_execper device.lib/concurrency.js#runPool— tiny helper used by both entry
points; keeps at most N workers in flight and returns a parallel
results array.runPoolplus an internal try/catch in each worker
keeps fleet-wide errors localised per device.
Changed
- Unified filesystem verbs across CLI, MCP and playbooks so the same
eight nouns mean the same thing everywhere:read/write
(inline content) ·push/pull(local ↔ remote file transfer)
·ls·mkdir·rm·mv. - CLI:
thinr device catis nowthinr device read(catkept as
a hidden alias). Newthinr device write <deviceId> <path> [content]accepts the payload as an argument or on stdin. - MCP:
thinr_deleterenamed tothinr_rm,thinr_moverenamed to
thinr_mv. No backwards-compatibility aliases. - Playbook actions:
delete→rm,move→mv. Thewrite
action now only accepts inlinecontent; use the newpush
action to upload a local file (source,destination). New
pullaction downloads a remote file to the local disk. cli-table3added as a direct dependency to render the
product-exec summary.
Removed
thinr dashboardsubcommand. The dashboard is now the default for
barethinr; the explicit subcommand had not shipped to anyone yet.
1.2.0-alpha.1
Added
thinr product exec <productId> <command...>— run a shell command
in parallel on every active device of a product, with bounded
concurrency (-c, --concurrency, default 10), per-device timeout
(--timeout, default 30 s),--fail-fast, asset-group filter
(-g, --group) and an-a, --allswitch to include offline
devices. Live progress shows a single spinner with done/total
counters; the final render uses acli-table3table per device
plus a compactOutput:section and a one-line totals bar.thinr_product_execMCP tool — the same fan-out as the CLI
subcommand, returning a consolidated text report so an AI agent
can roll out a change across a whole fleet in a single call
instead of loopingthinr_execper device.lib/concurrency.js#runPool— tiny helper used by both entry
points; keeps at most N workers in flight and returns a parallel
results array.runPoolplus an internal try/catch in each worker
keeps fleet-wide errors localised per device.
Changed
cli-table3added as a direct dependency to render the
product-exec summary.
1.1.0
Major release: MCP server for AI clients, subcommand-first CLI, JSON
output, multi-profile configuration, product-level fan-outs, and a
consistent error taxonomy across both interfaces.
Added
- MCP server (
thinr mcp) exposing ~26 typed tools over stdio for AI
clients (Claude Code, Claude Desktop, and any other MCP host). Covers
discovery, shellexec, filesystem (read/write/ls/mkdir/delete/
move), typedresourcecalls, properties, scripts (device- and
product-level), products, monitoring and agent updates, plus a profiles
lookup. MCP errors carry the same{ code }taxonomy as the CLI JSON
mode (exposed on_meta) so clients can pattern-match without parsing
human strings. - Subcommand-first CLI UX:
thinr device <action> <deviceId>/
thinr product <action> <productId>replaces the previous top-level
flag shape. Matcheskubectl/gitidioms. thinr device list [pattern]with case-insensitive regex filtering on
the server side (replaces the oldthinr devices).thinr device exec <deviceId> <command...>with streaming stdout/stderr,
SIGINT cancellation,--jsonenvelope, and--legacyone-shot fallback
for older agents.thinr device update check|applyfor managing agent upgrades.thinr device resourcewith per-resource input/output schema
introspection, andthinr product resource/thinr product property
for fleet fan-outs.- Multi-profile configuration store (
~/.config/thinr-cli/config.json):
one profile per server, selected via--profile, theTHINR_PROFILE
env var, or a per-call MCP parameter. Legacy single-file configs are
detected and migrated in-memory on read. thinr profile list|current|use|deletefor managing configured
environments.--json/-joutput envelope on every data-producing command with a
stable{ code }taxonomy:not_configured,not_found,
unauthorized,server_error,network_error,input_error,
timeout,cancelled,error.-u, --useradmin impersonation flag plumbed through every
device-scoped operation (CLI + MCP).THINR_INSECURE=1env var to accept self-signed TLS certificates
against non-localhost hosts (localhost / 127.0.0.1 are always
accepted).- Device property setter via PUT (
setDevicePropertyin the CLI,
thinr_property_setin MCP). thinr_device_infoMCP tool surfaces server-side product, asset group
and description alongside the agent's ownsystem_info.- Refresh-token flow on 401s: the CLI transparently swaps expired access
tokens for a fresh one when arefresh_tokenis on record, and fails
cleanly (with an actionableunauthorizederror) when it isn't.
Changed
- MCP server internals: tool schema and handler now paired in a
registry, so they cannot drift apart. Tools grouped by area under
lib/mcp/tools-*.js, withserver.jsreduced to a thin bootstrap. - CLI
devicecommand split into one file per subcommand under
commands/device/(previously a single 17 KB module). lib/device.jsrenamed tolib/devices.js(plural: operations on the
fleet), paired with the low-levellib/device-api.js.- Interactive handlers (auth / console / proxy) no longer call
process.exitfromlib/*; the CLI entry owns the exit code. - Centralised API error classification in
lib/errors.js— one
{ message, code, status }contract consumed by both CLI JSON mode
and MCP_meta. - Re-thrown auth errors chain the original
causefor better
debugging. - Bad
-i key=valuevalues surface as a clean Commander
InvalidArgumentErrorinstead of a stack trace. - Node.js engine requirement bumped to
>=18;.nvmrcpinned to 20. - The MCP server's
initializeresponse now reports the CLI's
package.jsonversion inserverInfo.version(was hardcoded). - Runtime dependencies refreshed, including majors:
@inquirer/prompts
7 → 8,conf14 → 15,open10 → 11,ora8 → 9. All npm audit
advisories cleared (0 vulnerabilities on install).
Removed
thinr devices(usethinr device listinstead).thinr device mcp <deviceId>(usethinr mcpwith per-calldevice
parameter).thinr device envlauncher.
Tooling
- ESLint 10 (flat config) + Prettier 3 with
eslint-config-prettier
bridge. Scripts:npm run lint/lint:fix/format/
format:check. - TypeScript
checkJsvia per-file// @ts-checkopt-in; 21 files
underlib/mcp/andcommands/device/pass type-check today. Script:
npm run typecheck. - Unit tests with
node --test(zero deps): MCP registry invariants +
error helpers. Script:npm test. - Publish pipeline migrated from a long-lived
NPM_TOKENsecret to npm
Trusted Publishing (OIDC), with--provenanceattestations on every
publish. GitHub Actions bumped tocheckout@v5/setup-node@v5.
1.1.0-alpha.2
Major release: MCP server for AI clients, subcommand-first CLI, JSON
output, multi-profile configuration, product-level fan-outs, and a
consistent error taxonomy across both interfaces.
Added
- MCP server (
thinr mcp) exposing ~26 typed tools over stdio for AI
clients (Claude Code, Claude Desktop, and any other MCP host). Covers
discovery, shellexec, filesystem (read/write/ls/mkdir/delete/
move), typedresourcecalls, properties, scripts (device- and
product-level), products, monitoring and agent updates, plus a profiles
lookup. MCP errors carry the same{ code }taxonomy as the CLI JSON
mode (exposed on_meta) so clients can pattern-match without parsing
human strings. - Subcommand-first CLI UX:
thinr device <action> <deviceId>/
thinr product <action> <productId>replaces the previous top-level
flag shape. Matcheskubectl/gitidioms. thinr device list [pattern]with case-insensitive regex filtering on
the server side (replaces the oldthinr devices).thinr device exec <deviceId> <command...>with streaming stdout/stderr,
SIGINT cancellation,--jsonenvelope, and--legacyone-shot fallback
for older agents.thinr device update check|applyfor managing agent upgrades.thinr device resourcewith per-resource input/output schema
introspection, andthinr product resource/thinr product property
for fleet fan-outs.- Multi-profile configuration store (
~/.config/thinr-cli/config.json):
one profile per server, selected via--profile, theTHINR_PROFILE
env var, or a per-call MCP parameter. Legacy single-file configs are
detected and migrated in-memory on read. thinr profile list|current|use|deletefor managing configured
environments.--json/-joutput envelope on every data-producing command with a
stable{ code }taxonomy:not_configured,not_found,
unauthorized,server_error,network_error,input_error,
timeout,cancelled,error.-u, --useradmin impersonation flag plumbed through every
device-scoped operation (CLI + MCP).THINR_INSECURE=1env var to accept self-signed TLS certificates
against non-localhost hosts (localhost / 127.0.0.1 are always
accepted).- Device property setter via PUT (
setDevicePropertyin the CLI,
thinr_property_setin MCP). thinr_device_infoMCP tool surfaces server-side product, asset group
and description alongside the agent's ownsystem_info.- Refresh-token flow on 401s: the CLI transparently swaps expired access
tokens for a fresh one when arefresh_tokenis on record, and fails
cleanly (with an actionableunauthorizederror) when it isn't.
Changed
- MCP server internals: tool schema and handler now paired in a
registry, so they cannot drift apart. Tools grouped by area under
lib/mcp/tools-*.js, withserver.jsreduced to a thin bootstrap. - CLI
devicecommand split into one file per subcommand under
commands/device/(previously a single 17 KB module). lib/device.jsrenamed tolib/devices.js(plural: operations on the
fleet), paired with the low-levellib/device-api.js.- Interactive handlers (auth / console / proxy) no longer call
process.exitfromlib/*; the CLI entry owns the exit code. - Centralised API error classification in
lib/errors.js— one
{ message, code, status }contract consumed by both CLI JSON mode
and MCP_meta. - Re-thrown auth errors chain the original
causefor better
debugging. - Bad
-i key=valuevalues surface as a clean Commander
InvalidArgumentErrorinstead of a stack trace. - Node.js engine requirement bumped to
>=18;.nvmrcpinned to 20.
Removed
thinr devices(usethinr device listinstead).thinr device mcp <deviceId>(usethinr mcpwith per-calldevice
parameter).thinr device envlauncher.
Tooling
- ESLint 10 (flat config) + Prettier 3 with
eslint-config-prettier
bridge. Scripts:npm run lint/lint:fix/format/
format:check. - TypeScript
checkJsvia per-file// @ts-checkopt-in; 21 files
underlib/mcp/andcommands/device/pass type-check today. Script:
npm run typecheck. - Unit tests with
node --test(zero deps): MCP registry invariants +
error helpers. Script:npm test.