@thinremote/thinr-cli 1.3.4 → 1.4.0

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +117 -123
  3. package/bin/thinr.js +43 -105
  4. package/commands/_shared.js +10 -90
  5. package/commands/device/_shared.js +2 -2
  6. package/commands/device/exec.js +2 -2
  7. package/commands/device/fs.js +2 -2
  8. package/commands/device/index.js +5 -19
  9. package/commands/device/logs.js +4 -4
  10. package/commands/device/status.js +1 -1
  11. package/commands/device/transfer.js +2 -2
  12. package/commands/device/update.js +8 -2
  13. package/commands/fleet/upgrade.js +3 -3
  14. package/commands/playbook/run.js +2 -2
  15. package/commands/playbook/validate.js +2 -2
  16. package/commands/product/_shared.js +1 -1
  17. package/commands/product/exec.js +2 -2
  18. package/commands/product/fs.js +2 -2
  19. package/commands/product/index.js +4 -11
  20. package/commands/product/logs.js +2 -2
  21. package/commands/product/metric.js +2 -2
  22. package/commands/product/playbook.js +5 -5
  23. package/commands/product/property.js +4 -4
  24. package/commands/product/push.js +2 -2
  25. package/commands/product/resource.js +4 -4
  26. package/commands/product/status.js +3 -3
  27. package/dist/dashboard.js +12 -12
  28. package/docs/guides/thinremote-metrics-logs.md +59 -0
  29. package/docs/guides/thinremote-playbooks.md +133 -0
  30. package/docs/guides/thinremote-scripts.md +115 -0
  31. package/docs/guides/thinremote.md +116 -0
  32. package/lib/command-stream.js +3 -2
  33. package/lib/console.js +6 -6
  34. package/lib/constants.js +1 -19
  35. package/lib/dashboard/event-stream.js +5 -5
  36. package/lib/device-api.js +4 -4
  37. package/lib/guides.js +41 -0
  38. package/lib/identity.js +75 -0
  39. package/lib/local-files.js +54 -0
  40. package/lib/mcp/{tools-install.js → agent-install.js} +12 -61
  41. package/lib/mcp/helpers.js +5 -25
  42. package/lib/mcp/playbook-ops.js +393 -0
  43. package/lib/mcp/registry.js +9 -43
  44. package/lib/mcp/resource-hooks.js +53 -0
  45. package/lib/mcp/resource-types.js +857 -0
  46. package/lib/mcp/tools-exec.js +217 -177
  47. package/lib/monitoring.js +3 -3
  48. package/lib/playbook/actions.js +30 -18
  49. package/lib/playbook/expression.js +1 -4
  50. package/lib/playbook/fleet.js +4 -1
  51. package/lib/playbook/loader.js +16 -8
  52. package/lib/playbook/runner.js +40 -8
  53. package/lib/playbook/schema.js +108 -34
  54. package/lib/product/log-presets.js +1 -1
  55. package/lib/product/logs.js +2 -2
  56. package/lib/product-orchestrator.js +14 -9
  57. package/lib/product.js +29 -227
  58. package/lib/proxy.js +4 -4
  59. package/lib/status.js +13 -5
  60. package/package.json +4 -2
  61. package/commands/device/delete.js +0 -53
  62. package/commands/device/list.js +0 -55
  63. package/commands/device/property.js +0 -52
  64. package/commands/device/resource.js +0 -52
  65. package/commands/logout.js +0 -47
  66. package/commands/product/list.js +0 -86
  67. package/commands/product/props.js +0 -125
  68. package/commands/profile.js +0 -173
  69. package/lib/alarms.js +0 -223
  70. package/lib/api.js +0 -89
  71. package/lib/auth.js +0 -428
  72. package/lib/bucket.js +0 -82
  73. package/lib/concurrency.js +0 -52
  74. package/lib/config.js +0 -230
  75. package/lib/devices.js +0 -60
  76. package/lib/errors.js +0 -65
  77. package/lib/format.js +0 -114
  78. package/lib/mcp/server.js +0 -67
  79. package/lib/mcp/tools-alarms.js +0 -507
  80. package/lib/mcp/tools-buckets.js +0 -99
  81. package/lib/mcp/tools-devices.js +0 -235
  82. package/lib/mcp/tools-filesystem.js +0 -281
  83. package/lib/mcp/tools-logs.js +0 -225
  84. package/lib/mcp/tools-playbook.js +0 -210
  85. package/lib/mcp/tools-products.js +0 -1557
  86. package/lib/mcp/tools-profile.js +0 -635
  87. package/lib/mcp/tools-profiles.js +0 -30
  88. package/lib/mcp/tools-properties.js +0 -79
  89. package/lib/mcp/tools-resources.js +0 -78
  90. package/lib/mcp/tools-scripts.js +0 -212
  91. package/lib/mcp/tools-tokens.js +0 -369
  92. package/lib/output.js +0 -114
  93. package/lib/paths.js +0 -32
  94. package/lib/profile.js +0 -657
  95. package/lib/property.js +0 -75
  96. package/lib/resource.js +0 -151
  97. package/lib/storage.js +0 -117
  98. package/lib/tokens.js +0 -366
@@ -1,46 +1,12 @@
1
1
  // @ts-check
2
- import { tools as devicesTools } from './tools-devices.js';
3
- import { tools as filesystemTools } from './tools-filesystem.js';
4
2
  import { tools as execTools } from './tools-exec.js';
5
- import { tools as resourcesTools } from './tools-resources.js';
6
- import { tools as propertiesTools } from './tools-properties.js';
7
- import { tools as scriptsTools } from './tools-scripts.js';
8
- import { tools as productsTools } from './tools-products.js';
9
- import { tools as playbookTools } from './tools-playbook.js';
10
- import { tools as profilesTools } from './tools-profiles.js';
11
- import { tools as installTools } from './tools-install.js';
12
- import { tools as bucketsTools } from './tools-buckets.js';
13
- import { tools as logsTools } from './tools-logs.js';
14
- import { tools as productProfileTools } from './tools-profile.js';
15
- import { tools as tokensTools } from './tools-tokens.js';
16
- import { tools as alarmsTools } from './tools-alarms.js';
17
3
 
18
- export const tools = [
19
- ...devicesTools,
20
- ...filesystemTools,
21
- ...execTools,
22
- ...resourcesTools,
23
- ...propertiesTools,
24
- ...scriptsTools,
25
- ...productsTools,
26
- ...playbookTools,
27
- ...profilesTools,
28
- ...installTools,
29
- ...bucketsTools,
30
- ...logsTools,
31
- ...productProfileTools,
32
- ...tokensTools,
33
- ...alarmsTools,
34
- ];
35
-
36
- // Inject the optional `profile` parameter on every tool so callers can
37
- // target any configured environment per-call without changing the saved
38
- // default. `thinr_profiles` is the lookup itself, so it's exempt.
39
- for (const t of tools) {
40
- if (t.name === 'thinr_profiles') continue;
41
- t.inputSchema.properties = t.inputSchema.properties || {};
42
- t.inputSchema.properties.profile = {
43
- type: 'string',
44
- description: 'CLI profile to use for this call (see thinr_profiles). Omit for the default.',
45
- };
46
- }
4
+ /**
5
+ * ThinRemote's own MCP tools: only `device_exec`, the command on one device
6
+ * or a fleet. Everything else ThinRemote adds is served by the generic
7
+ * `resource_*` tools of @thinger-io/cli-core: its resource types (a
8
+ * device's files and scripts; a product's scripts, metrics, log sources
9
+ * and playbooks) and its actions on devices, in resource-types.js, and
10
+ * what it adds to the server's types, in resource-hooks.js.
11
+ */
12
+ export const tools = [...execTools];
@@ -0,0 +1,53 @@
1
+ // @ts-check
2
+ import { deleteStorage } from '@thinger-io/cli-core/storage';
3
+ import { toolName } from '@thinger-io/cli-core/mcp/naming';
4
+ import { getAPI } from './helpers.js';
5
+
6
+ /** Where the rest of what an agent offers is, keyed by what it is. */
7
+ const agentMap = (device) => ({
8
+ monitoring: `live: ${toolName('device_resource_call')} resource "monitoring"; history: ${toolName('bucket_data_read')} bucket "monitoring" device "${device}" (fields cpu.usage, memory.usage, disk.root.usage, network.rx_rate, load.1m…), kept only when the device's product has a monitoring bucket (ThinRemote products do): empty otherwise`,
9
+ files: `${toolName('resource_list')} / _get / _create / _update / _delete type "device_fs" parent "${device}"`,
10
+ scripts: `type "device_script" parent "${device}"`,
11
+ commands: `${toolName('device_exec')} device "${device}"`,
12
+ agent_update: `${toolName('resource_call')} type "device" action "agent_update" id "${device}"`,
13
+ });
14
+
15
+ /**
16
+ * What ThinRemote adds to the generic `resource_*` tools of cli-core, which
17
+ * run these after their own hooks:
18
+ *
19
+ * - Reading a device also asks its agent, when it is connected, for the
20
+ * system it runs on (hostname, OS, architecture…) and the base path of
21
+ * its filesystem: what the server record cannot know. Best effort: a slow
22
+ * or old agent leaves the record as it is. It also says where the rest of
23
+ * what the agent offers is (monitoring, files, scripts, commands), so a
24
+ * model that starts from the device finds it.
25
+ * - Deleting a product also deletes its file storage, which holds the
26
+ * product's scripts and only ThinRemote products have.
27
+ *
28
+ * @type {Record<string, import('@thinger-io/cli-core/mcp/resource-hooks').ResourceHooks>}
29
+ */
30
+ export const resourceHooks = {
31
+ device: {
32
+ async afterGet(record, ctx) {
33
+ if (!record?.connection?.active) return record;
34
+ const { api } = getAPI(ctx.id, ctx.user);
35
+ const agent = {};
36
+ try {
37
+ agent.system_info = await api.getResource('system');
38
+ } catch {}
39
+ try {
40
+ agent.fs_base_path = (await api.info('/')).path || '/';
41
+ } catch {}
42
+ if (!Object.keys(agent).length) return record;
43
+ return { ...record, agent: { ...agent, where: agentMap(ctx.id) } };
44
+ },
45
+ },
46
+ product: {
47
+ async afterDelete(ctx) {
48
+ if (await deleteStorage(ctx.id, ctx.user)) {
49
+ return `Also deleted its file storage "${ctx.id}" (product scripts).`;
50
+ }
51
+ },
52
+ },
53
+ };