@thinger-io/cli-core 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.2] - 2026-10-17
4
+
5
+ ### Fixed
6
+
7
+ - The dashboard SDK ships with Thinger 7.4, not 7.5: the platform guides
8
+ mark as "since Thinger 7.4" what older servers lack, and the catalog
9
+ notes name Thinger 7.4 instead of develop builds (7.3.4-…). The SDK's
10
+ own base server keeps coming from its `compat.json`.
11
+
3
12
  ## [0.4.1] - 2026-10-16
4
13
 
5
14
  ### Fixed
@@ -1,8 +1,8 @@
1
1
  # Thinger concepts
2
2
 
3
3
  How a Thinger.io account is organized, for agents that create resources, dashboards or
4
- alarms. It describes Thinger 7.5: what needs a later version says "since Thinger X", and what
5
- older servers lack says "since Thinger 7.5" (a server's version: `GET /v1/server/version`).
4
+ alarms. It describes Thinger 7.4: what needs a later version says "since Thinger X", and what
5
+ older servers lack says "since Thinger 7.4" (a server's version: `GET /v1/server/version`).
6
6
  `GET /v1/server/events` lists the live events; the OpenAPI document lists every route. Related
7
7
  guides: product code (document `product-code`) and server administration (document
8
8
  `server-admin`). The dashboard SDK is the npm package `@thinger-io/dashboard-sdk`, documented in
@@ -37,7 +37,7 @@ A **project** groups resources of the account so they can be shared and browsed
37
37
  of the project's devices, and asking for another device is refused. It needs the bucket to
38
38
  carry a `device` tag (product buckets do); a bucket without it is not filtered. A project with
39
39
  no devices reads such a bucket as empty. It is **on by default for new projects** since Thinger
40
- 7.5 (send
40
+ 7.4 (send
41
41
  `config: {limit_bucket_access: false}` to opt out); for older projects, turn it on with
42
42
  `PUT /v1/users/<u>/projects/<p>` and `{config: {limit_bucket_access: true}}`, especially before
43
43
  sharing a project with members or public tokens.
@@ -159,7 +159,7 @@ Records get a `device` field; the bucket is created on the first write.
159
159
 
160
160
  **Field names**: `ts` is the record time. In MongoDB buckets `tags` and `_id` are reserved (they
161
161
  hold the record's tags and id): a record with a field of that name is refused, so rename it
162
- (`tag_count`, …). Since Thinger 7.5 the refusal names the field.
162
+ (`tag_count`, …). Since Thinger 7.4 the refusal names the field.
163
163
 
164
164
  **Reading** (`GET /v2/users/<u>/buckets/<b>/data`, or the SDK's `buckets.read`): records come as
165
165
  `{ ts, ...fields }`, newest first. Query: `min_ts` / `max_ts` (ms), `items` (default 50, **at most
@@ -218,7 +218,7 @@ when null matters.
218
218
 
219
219
  ## Geofences
220
220
 
221
- Since Thinger 7.5. The server checks geofences natively: do not compute zone entries and exits in your own code. A
221
+ Since Thinger 7.4. The server checks geofences natively: do not compute zone entries and exits in your own code. A
222
222
  property `geofences` on the device, or inherited from its type, group or product, holds a GeoJSON
223
223
  `FeatureCollection`. Each `Feature` is a `Polygon`, or a `Point` with `properties.radius` in
224
224
  meters. **Coordinates are `[lon, lat]`**, as in GeoJSON (the `location` property is `{lat, lon}`).
@@ -322,7 +322,7 @@ of the device.
322
322
  list, a field of the listed documents (nested ones with dots) filters by exact value (numbers
323
323
  as numbers, `true` / `false` also as booleans: `?connection.active=true` for connected devices),
324
324
  and a repeated parameter matches any of its values (nested fields and booleans since Thinger
325
- 7.5). Instance `state` values:
325
+ 7.4). Instance `state` values:
326
326
  0 none, 1 activated, 2 acknowledged, 3 latched, 4 shelved, 5 cleared. `severity` values:
327
327
  0 none, 1 low, 2 medium, 3 high, 4 critical.
328
328
  - Notifications on activation, normalization and reminders call **endpoints**:
@@ -330,7 +330,7 @@ of the device.
330
330
  (`name`, `severity`, `state`, `origin.id` = device, `evaluation.last_values`, `notification.type`…).
331
331
  - Test a rule, a single source or a notification before saving with
332
332
  `POST …/alarms/rules/<r>/test-rule`, `/test-source` and `/test-notification`. `test-rule` and
333
- `test-source` work before the rule exists (any new id; since Thinger 7.5); `test-source` takes a `check_interval`
333
+ `test-source` work before the rule exists (any new id; since Thinger 7.4); `test-source` takes a `check_interval`
334
334
  for bucket sources without aggregation (default: the rule's, or 1 minute).
335
335
 
336
336
  ## Endpoints, storages, tokens
@@ -2,14 +2,14 @@
2
2
 
3
3
  JavaScript that a product's profile calls to compute, transform or route data for its devices:
4
4
  resource values (including simulated devices), payload transforms, the device a product call is
5
- for. Platform concepts: the document `concepts`. It describes Thinger 7.5; what needs a later
5
+ for. Platform concepts: the document `concepts`. It describes Thinger 7.4; what needs a later
6
6
  version says "since Thinger X" (a server's version: `GET /v1/server/version`).
7
7
 
8
8
  ## Where it lives
9
9
 
10
10
  `PUT /v1/users/{user}/products/{product}/profile/code` with
11
11
  `{ "code": "<JavaScript>", "storage": "" }`, or `{ "storage": "<storage id>" }` to load
12
- `<storage>/index.js` from a file storage (with its `node_modules`). Since Thinger 7.5, add
12
+ `<storage>/index.js` from a file storage (with its `node_modules`). Since Thinger 7.4, add
13
13
  `"path": "<folder>"` to
14
14
  load `<storage>/<folder>/index.js` (and that folder's `node_modules`) instead: one storage can then
15
15
  hold a whole application, e.g. the dashboard in `app/` and each product's code in
@@ -3,7 +3,7 @@
3
3
  For agents acting as a server **admin**: host settings, domains and brands, user accounts,
4
4
  OAuth clients, identity providers and proxies. Every route here needs an admin session or
5
5
  token. Read the OpenAPI document for each body; this guide covers what the schemas cannot say:
6
- order of steps, side effects and risks. It describes Thinger 7.5; what needs a later version says
6
+ order of steps, side effects and risks. It describes Thinger 7.4; what needs a later version says
7
7
  "since Thinger X" (a server's version: `GET /v1/server/version`).
8
8
 
9
9
  Before changing anything, read the current value and tell the user what will change. Several
@@ -38,7 +38,7 @@ self-hosted server raise `accounts.limits.<collection>.max_count` (`projects`,
38
38
  brands limits are not shown by `GET settings`.
39
39
 
40
40
  On cloud instances the plan owns `accounts.limits.{accounts,brands,domains,members}`, `database`,
41
- `plugins`, `rate_limiter` and `http_server.hosts`: since Thinger 7.5, writing them returns 403.
41
+ `plugins`, `rate_limiter` and `http_server.hosts`: since Thinger 7.4, writing them returns 403.
42
42
  To raise them, the customer changes the plan.
43
43
 
44
44
  ## Custom domain with its own brand
@@ -103,7 +103,7 @@ export const CATALOG = {
103
103
  clone: 'Device_Clone',
104
104
  projects: 'Device_UpdateProjects',
105
105
  },
106
- notes: '`type` defaults to Generic (IOTMP). Generic and MQTT devices authenticate with `credentials`: when creating one without them, credentials are generated and returned once (the server stores them hashed). HTTP devices send data through {tool:device_data_send}; assign a product with update {product} ("" unassigns). Virtual devices have no hardware: every resource comes from their product\'s API (product code can compute it), and they need a `location` property ({lat, lon}) to appear on maps, or they are placed by their IP. Native geofences (7.3.4-144 and later): a `geofences` property on the device, or inherited from its asset type, group or product, holds a GeoJSON FeatureCollection ([lon, lat]; Polygon, or Point with properties.radius in meters; properties.onEnter / onExit name an endpoint or ""). Every change of the device `location` emits device_geofence_event (with geofence_id, geofence_properties, product, asset_type, asset_group): store it with a product profile bucket or flow whose source is that event. See the Geofences section of {tool:doc_read} id "concepts". A new Virtual device shows disconnected in the create answer and connects a moment later.',
106
+ notes: '`type` defaults to Generic (IOTMP). Generic and MQTT devices authenticate with `credentials`: when creating one without them, credentials are generated and returned once (the server stores them hashed). HTTP devices send data through {tool:device_data_send}; assign a product with update {product} ("" unassigns). Virtual devices have no hardware: every resource comes from their product\'s API (product code can compute it), and they need a `location` property ({lat, lon}) to appear on maps, or they are placed by their IP. Native geofences (Thinger 7.4 and later): a `geofences` property on the device, or inherited from its asset type, group or product, holds a GeoJSON FeatureCollection ([lon, lat]; Polygon, or Point with properties.radius in meters; properties.onEnter / onExit name an endpoint or ""). Every change of the device `location` emits device_geofence_event (with geofence_id, geofence_properties, product, asset_type, asset_group): store it with a product profile bucket or flow whose source is that event. See the Geofences section of {tool:doc_read} id "concepts". A new Virtual device shows disconnected in the create answer and connects a moment later.',
107
107
  actions: {
108
108
  stats: {
109
109
  op: 'Device_ReadStatistics',
@@ -268,7 +268,7 @@ export const CATALOG = {
268
268
  delete: 'Project_Delete',
269
269
  clone: 'Project_Clone',
270
270
  },
271
- notes: 'The project\'s own id is the short one ("plant_a"); resources name it "<owner>@<project>" ("alice@plant_a"). They join it when created with projects in the body, or through their own update: {projects: ["alice@plant_a"]}; the list replaces the previous one. List the resources of a project with filter {project: "<project>"}. Share it with other accounts through project_member (and project_role for their permissions). New projects limit bucket data to their own devices (config.limit_bucket_access, default true on 7.3.4-135 and later): reads and tag lists of a bucket through the project return only its devices\' records, so such buckets need a device tag. Turn it on for older projects with update {config: {limit_bucket_access: true}} before sharing them with members or project-scoped tokens.',
271
+ notes: 'The project\'s own id is the short one ("plant_a"); resources name it "<owner>@<project>" ("alice@plant_a"). They join it when created with projects in the body, or through their own update: {projects: ["alice@plant_a"]}; the list replaces the previous one. List the resources of a project with filter {project: "<project>"}. Share it with other accounts through project_member (and project_role for their permissions). New projects limit bucket data to their own devices (config.limit_bucket_access, default true for new projects since Thinger 7.4): reads and tag lists of a bucket through the project return only its devices\' records, so such buckets need a device tag. Turn it on for older projects with update {config: {limit_bucket_access: true}} before sharing them with members or project-scoped tokens.',
272
272
  },
273
273
  token: {
274
274
  description: 'Access tokens of the account, with their permission tree.',
@@ -284,7 +284,7 @@ export const CATALOG = {
284
284
  clone: 'Token_Clone',
285
285
  projects: 'Token_UpdateProjects',
286
286
  },
287
- notes: 'Permissions: `allow` (and optional `deny`) is {ResourceType: {id or "*": [actions] or "*"}}, e.g. {"Device": {"*": "*"}} or {"Device": {"sensor_1": ["ReadDeviceStatus", "AccessDeviceResources"]}}; {"*": {"*": "*"}} is full access. {tool:resource_describe} of any type lists its ResourceType and actions under `permissions`. The JWT (`access_token`) is returned by create and get, never by list. `expire` (unix ms) makes a token expire: it is signed into the JWT, so it cannot be changed on update (delete the token and create it again), and the server deletes the token afterwards. Without it a token does not expire: delete it to revoke it. Servers before 7.3.4-98 ignore `expire`.',
287
+ notes: 'Permissions: `allow` (and optional `deny`) is {ResourceType: {id or "*": [actions] or "*"}}, e.g. {"Device": {"*": "*"}} or {"Device": {"sensor_1": ["ReadDeviceStatus", "AccessDeviceResources"]}}; {"*": {"*": "*"}} is full access. {tool:resource_describe} of any type lists its ResourceType and actions under `permissions`. The JWT (`access_token`) is returned by create and get, never by list. `expire` (unix ms) makes a token expire: it is signed into the JWT, so it cannot be changed on update (delete the token and create it again), and the server deletes the token afterwards. Without it a token does not expire: delete it to revoke it. Servers before Thinger 7.4 ignore `expire`.',
288
288
  },
289
289
  alarm_rule: {
290
290
  description: 'Alarm rules: conditions on device or bucket data that raise alarm instances.',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinger-io/cli-core",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Shared core of the Thinger.io CLIs and their MCP servers: API client, auth, profiles, generic commands and MCP tools",
5
5
  "type": "module",
6
6
  "exports": {