Skip to content

Releases: Thin-Remote/thinr-cli

1.3.5

Choose a tag to compare

@github-actions github-actions released this 24 Sep 13:38

Fixed

  • thinr_ls describes 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

Choose a tag to compare

@github-actions github-actions released this 24 Sep 13:26

Fixed

  • thinr_script_delete resolves the script by the name the agent reports, so
    both battery and battery.sh remove 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_write refuses a name that would replace one of the device's
    built-in resources (monitoring, system, cmd, update, agent) unless
    force: true is passed. Installing monitoring.sh used 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_devices shows when each device last changed state: connected since
    for a live one, offline since for 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_ls explains 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_profiles states that profiles are not accounts, and that user
    addresses another account on the same server.

1.3.3

Choose a tag to compare

@github-actions github-actions released this 24 Sep 12:44

Changed

  • MCP tools take the target device as device_id. A tool argument named
    device never 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 with device is required however 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. device is no longer accepted.

1.3.2

Choose a tag to compare

@github-actions github-actions released this 24 Sep 12:13

Fixed

  • Device properties and device status now honour the user argument.
    thinr_property_get, thinr_property_set and the playbook property
    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 single resolveUser. 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

Choose a tag to compare

@github-actions github-actions released this 24 Sep 00:13

Fixed

  • Device resources now honour the user argument, so an admin acting on
    another account reaches that account's devices. thinr_resource_list,
    thinr_resource_call and the thinr_script_* tools accepted the
    argument but addressed the active profile's own account, which answered
    "Device not found"; playbook resource and script actions had the same
    gap. Not-found errors now name the account they looked in.

1.3.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 23:54

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. Run thinr login to 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 streaming exec now 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

Choose a tag to compare

@github-actions github-actions released this 10 Jun 12:51

Added

  • thinr with 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. Interactive confirm by default, --yes to skip in
    scripts, idempotent on a missing device. Useful after re-provisioning
    an agent under a new hostname leaves the old ip-… record offline.
  • MCP: thinr_device_delete — same operation for AI clients.
  • MCP: thinr_push and thinr_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 in thinr_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, --all switch to include offline
    devices. Live progress shows a single spinner with done/total
    counters; the final render uses a cli-table3 table per device
    plus a compact Output: section and a one-line totals bar.
  • thinr_product_exec MCP 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 looping thinr_exec per 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. runPool plus 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 cat is now thinr device read (cat kept as
    a hidden alias). New thinr device write <deviceId> <path> [content] accepts the payload as an argument or on stdin.
  • MCP: thinr_delete renamed to thinr_rm, thinr_move renamed to
    thinr_mv. No backwards-compatibility aliases.
  • Playbook actions: delete → rm, move → mv. The write
    action now only accepts inline content; use the new push
    action to upload a local file (source, destination). New
    pull action downloads a remote file to the local disk.
  • cli-table3 added as a direct dependency to render the
    product-exec summary.

Removed

  • thinr dashboard subcommand. The dashboard is now the default for
    bare thinr; the explicit subcommand had not shipped to anyone yet.

1.2.0-alpha.1

1.2.0-alpha.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 17 Apr 04:58

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, --all switch to include offline
    devices. Live progress shows a single spinner with done/total
    counters; the final render uses a cli-table3 table per device
    plus a compact Output: section and a one-line totals bar.
  • thinr_product_exec MCP 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 looping thinr_exec per 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. runPool plus an internal try/catch in each worker
    keeps fleet-wide errors localised per device.

Changed

  • cli-table3 added as a direct dependency to render the
    product-exec summary.

1.1.0

Choose a tag to compare

@github-actions github-actions released this 16 Apr 15:33

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, shell exec, filesystem (read/write/ls/mkdir/delete/
    move), typed resource calls, 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. Matches kubectl / git idioms.
  • thinr device list [pattern] with case-insensitive regex filtering on
    the server side (replaces the old thinr devices).
  • thinr device exec <deviceId> <command...> with streaming stdout/stderr,
    SIGINT cancellation, --json envelope, and --legacy one-shot fallback
    for older agents.
  • thinr device update check|apply for managing agent upgrades.
  • thinr device resource with per-resource input/output schema
    introspection, and thinr 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, the THINR_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|delete for managing configured
    environments.
  • --json / -j output 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, --user admin impersonation flag plumbed through every
    device-scoped operation (CLI + MCP).
  • THINR_INSECURE=1 env var to accept self-signed TLS certificates
    against non-localhost hosts (localhost / 127.0.0.1 are always
    accepted).
  • Device property setter via PUT (setDeviceProperty in the CLI,
    thinr_property_set in MCP).
  • thinr_device_info MCP tool surfaces server-side product, asset group
    and description alongside the agent's own system_info.
  • Refresh-token flow on 401s: the CLI transparently swaps expired access
    tokens for a fresh one when a refresh_token is on record, and fails
    cleanly (with an actionable unauthorized error) 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, with server.js reduced to a thin bootstrap.
  • CLI device command split into one file per subcommand under
    commands/device/ (previously a single 17 KB module).
  • lib/device.js renamed to lib/devices.js (plural: operations on the
    fleet), paired with the low-level lib/device-api.js.
  • Interactive handlers (auth / console / proxy) no longer call
    process.exit from lib/*; 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 cause for better
    debugging.
  • Bad -i key=value values surface as a clean Commander
    InvalidArgumentError instead of a stack trace.
  • Node.js engine requirement bumped to >=18; .nvmrc pinned to 20.
  • The MCP server's initialize response now reports the CLI's
    package.json version in serverInfo.version (was hardcoded).
  • Runtime dependencies refreshed, including majors: @inquirer/prompts
    7 → 8, conf 14 → 15, open 10 → 11, ora 8 → 9. All npm audit
    advisories cleared (0 vulnerabilities on install).

Removed

  • thinr devices (use thinr device list instead).
  • thinr device mcp <deviceId> (use thinr mcp with per-call device
    parameter).
  • thinr device env launcher.

Tooling

  • ESLint 10 (flat config) + Prettier 3 with eslint-config-prettier
    bridge. Scripts: npm run lint / lint:fix / format /
    format:check.
  • TypeScript checkJs via per-file // @ts-check opt-in; 21 files
    under lib/mcp/ and commands/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_TOKEN secret to npm
    Trusted Publishing (OIDC), with --provenance attestations on every
    publish. GitHub Actions bumped to checkout@v5 / setup-node@v5.

1.1.0-alpha.2

1.1.0-alpha.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Apr 15:26

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, shell exec, filesystem (read/write/ls/mkdir/delete/
    move), typed resource calls, 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. Matches kubectl / git idioms.
  • thinr device list [pattern] with case-insensitive regex filtering on
    the server side (replaces the old thinr devices).
  • thinr device exec <deviceId> <command...> with streaming stdout/stderr,
    SIGINT cancellation, --json envelope, and --legacy one-shot fallback
    for older agents.
  • thinr device update check|apply for managing agent upgrades.
  • thinr device resource with per-resource input/output schema
    introspection, and thinr 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, the THINR_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|delete for managing configured
    environments.
  • --json / -j output 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, --user admin impersonation flag plumbed through every
    device-scoped operation (CLI + MCP).
  • THINR_INSECURE=1 env var to accept self-signed TLS certificates
    against non-localhost hosts (localhost / 127.0.0.1 are always
    accepted).
  • Device property setter via PUT (setDeviceProperty in the CLI,
    thinr_property_set in MCP).
  • thinr_device_info MCP tool surfaces server-side product, asset group
    and description alongside the agent's own system_info.
  • Refresh-token flow on 401s: the CLI transparently swaps expired access
    tokens for a fresh one when a refresh_token is on record, and fails
    cleanly (with an actionable unauthorized error) 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, with server.js reduced to a thin bootstrap.
  • CLI device command split into one file per subcommand under
    commands/device/ (previously a single 17 KB module).
  • lib/device.js renamed to lib/devices.js (plural: operations on the
    fleet), paired with the low-level lib/device-api.js.
  • Interactive handlers (auth / console / proxy) no longer call
    process.exit from lib/*; 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 cause for better
    debugging.
  • Bad -i key=value values surface as a clean Commander
    InvalidArgumentError instead of a stack trace.
  • Node.js engine requirement bumped to >=18; .nvmrc pinned to 20.

Removed

  • thinr devices (use thinr device list instead).
  • thinr device mcp <deviceId> (use thinr mcp with per-call device
    parameter).
  • thinr device env launcher.

Tooling

  • ESLint 10 (flat config) + Prettier 3 with eslint-config-prettier
    bridge. Scripts: npm run lint / lint:fix / format /
    format:check.
  • TypeScript checkJs via per-file // @ts-check opt-in; 21 files
    under lib/mcp/ and commands/device/ pass type-check today. Script:
    npm run typecheck.
  • Unit tests with node --test (zero deps): MCP registry invariants +
    error helpers. Script: npm test.