paseo-plugin-machine-status 0.2.2 → 0.3.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.
package/OVERVIEW.md CHANGED
@@ -14,7 +14,7 @@ Machine Status shows what the daemon's Mac is doing while your agents work: CPU
14
14
 
15
15
  ## Setup
16
16
 
17
- - A macOS daemon on Paseo 0.8 to 0.13. On other platforms the screen says it cannot collect metrics.
17
+ - A macOS daemon on Paseo 0.11 to 0.13. On other platforms the screen says it cannot collect metrics.
18
18
  - Docker Desktop, OrbStack or Rancher Desktop for the Docker tab. Without one, the tab says which is missing.
19
19
 
20
20
  ## What it can change
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <p align="center"><img src="assets/icon.png" width="88" alt=""></p>
2
+
1
3
  <h1 align="center">paseo-plugin-machine-status</h1>
2
4
 
3
5
  <p align="center">
@@ -7,19 +9,18 @@
7
9
  </p>
8
10
 
9
11
  <p align="center">
10
- <img src="https://img.shields.io/badge/Paseo-0.8.x%20%E2%80%93%200.13.x-3987e5" alt="Supports Paseo 0.8.x through 0.13.x, including betas">
12
+ <a href="https://github.com/dutchakdev/paseo-plugin-machine-status/actions/workflows/ci.yml"><img src="https://github.com/dutchakdev/paseo-plugin-machine-status/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
13
+ <a href="https://www.npmjs.com/package/paseo-plugin-machine-status"><img src="https://img.shields.io/npm/v/paseo-plugin-machine-status" alt="npm"></a>
14
+ <img src="https://img.shields.io/badge/Paseo-0.11.x%20%E2%80%93%200.13.x-3987e5" alt="Supports Paseo 0.11.x through 0.13.x, including betas">
11
15
  <img src="https://img.shields.io/badge/macOS-only-9aa1a6" alt="macOS only">
12
- <img src="https://img.shields.io/badge/tests-237-199e70" alt="237 tests">
13
16
  <img src="https://img.shields.io/badge/dependencies-none-c98500" alt="No runtime dependencies">
14
17
  <img src="https://img.shields.io/badge/license-MIT-9aa1a6" alt="MIT licensed">
15
18
  </p>
16
19
 
17
20
  <p align="center">
18
- <img src="docs/preview.svg" alt="The dashboard: KPI tiles, a load history chart, memory breakdown and disk usage" width="920">
21
+ <img src="docs/screenshot.png" alt="The Machine screen in the Paseo desktop app: CPU, memory, swap and disk tiles, load and memory history, disk and swap, and the top processes" width="920">
19
22
  </p>
20
23
 
21
- <p align="center"><sub>Generated by <code>npm run preview</code> from the plugin&apos;s own palette, thresholds and chart geometry, so the picture cannot drift from the code.</sub></p>
22
-
23
24
  One sidebar item, three tabs, and a pill beside the message box.
24
25
 
25
26
  > Requires macOS. Metrics come from `vm_stat`, `sysctl`, `df`, `pmset` and
@@ -28,18 +29,29 @@ One sidebar item, three tabs, and a pill beside the message box.
28
29
 
29
30
  ## Install
30
31
 
31
- ```bash
32
- paseo plugin install npm:paseo-plugin-machine-status # Paseo 0.9 and newer
33
- paseo plugin ls # expect: running
34
- ```
35
-
36
- Paseo 0.8 has no npm sources, so install from Git there:
37
- `paseo plugin add dutchakdev/paseo-plugin-machine-status`. Either way,
38
- `paseo plugin update machine-status` pulls later releases. The plugin supports **Paseo 0.8.x through 0.13.x, including betas**,
39
- on both the daemon, which runs its collectors, and the app, which runs its screens.
40
-
41
- The manifest remains `>=0.8.0`, which already admits 0.9.x through 0.13.x. Paseo also checks a
42
- prerelease's stable version core, so `0.13.0-beta.1` satisfies this range; see
32
+ Plugins must be enabled daemon-wide first, under **Settings → Plugins → Enable
33
+ plugins** (the root `pluginsEnabled` field in `~/.paseo/config.json`). Then pick the
34
+ source that matches your Paseo:
35
+
36
+ | Paseo | Source | Command |
37
+ | ----- | ------ | ------- |
38
+ | 0.11 and newer | [Plugin directory](https://paseo.sh/plugins), the reviewed version | `paseo plugin add dutchakdev/machine-status` |
39
+ | 0.11 and newer | npm, the newest release before the directory approves it | `paseo plugin install npm:paseo-plugin-machine-status` |
40
+ | 0.8 to 0.10, 0.11.0 betas | GitHub, release 0.2.3, the last one for these versions | `paseo plugin add dutchakdev/paseo-plugin-machine-status --ref v0.2.3` |
41
+
42
+ `paseo plugin ls` should then show `machine-status` as `running`, and
43
+ `paseo plugin update machine-status` pulls later releases from the same source. From
44
+ Paseo 0.11 a bare `owner/name` names a directory entry, so a GitHub source there needs
45
+ the `git:` prefix: `git:dutchakdev/paseo-plugin-machine-status`.
46
+
47
+ The plugin supports **Paseo 0.11.x through 0.13.x, including betas**, on both the
48
+ daemon, which runs its collectors, and the app, which runs its screens.
49
+
50
+ The manifest asks for `>=0.11.0` because it declares the icon shown in the plugin
51
+ directory, and Paseo 0.8 to 0.10 refuse a manifest with a field they do not know.
52
+ Paseo also checks a prerelease's stable version core, so `0.13.0-beta.1` satisfies
53
+ this range. The 0.11.0 betas pass that check but predate the `icon` field, so they
54
+ refuse the manifest as well and need the release named in the install table; see
43
55
  [version requirements](https://paseo.sh/docs/plugins/reference#requirements).
44
56
 
45
57
  To work on it locally instead:
@@ -53,9 +65,6 @@ paseo plugin install "$PWD"
53
65
  paseo plugin ls # expect: running
54
66
  ```
55
67
 
56
- Plugins must be enabled daemon-wide first, under **Settings → Plugins → Enable
57
- plugins** (the root `pluginsEnabled` field in `~/.paseo/config.json`).
58
-
59
68
  Open it from the **Machine** sidebar item, or ⌘K → "Machine status". On Paseo 0.11
60
69
  and newer, ⌘K also offers "Machine: ports & services" and "Machine: Docker", which
61
70
  open straight on that tab, and the tab travels in the screen's link (`?tab=services`,
@@ -160,6 +169,12 @@ a documented anti-pattern.
160
169
 
161
170
  ### Colour
162
171
 
172
+ <p align="center">
173
+ <img src="docs/preview.png" alt="The dashboard drawn from sample data: KPI tiles, a load history chart, memory breakdown and disk usage" width="920">
174
+ </p>
175
+
176
+ <p align="center"><sub>Generated by <code>npm run preview</code> from sample data and the plugin&apos;s own palette, thresholds and chart geometry, so the colours cannot drift from the code.</sub></p>
177
+
163
178
  Chrome (backgrounds, text, borders) comes from Paseo's six theme tokens. Series
164
179
  colour does not: a categorical hue has to stay the same hue across themes or it
165
180
  stops identifying anything. Paseo never says which theme is active, so the plugin
@@ -335,6 +350,7 @@ npm run check # typecheck, then the tests
335
350
  paseo plugin reload machine-status # source edits need an explicit reload
336
351
  paseo plugin logs machine-status
337
352
  npm run preview # regenerates docs/preview.svg from the real palette
353
+ ./scripts/preview-png.sh # renders it to docs/preview.png for the plugin directory
338
354
  ```
339
355
 
340
356
  Tests cover the command-output parsers against captured real output, the path and
@@ -349,13 +365,16 @@ including a refusal to terminate the test runner itself.
349
365
  ### Paseo versions
350
366
 
351
367
  The SDK stays pinned to 0.8.0 for typechecking and tests, so the compiler proves
352
- the plugin uses only the oldest supported API. Paseo supplies the runtime instances
353
- on every supported release line, so none of it ships with the plugin.
368
+ the plugin uses only the 0.8 API, which every supported release still provides.
369
+ Paseo supplies the runtime instances on every supported release line, so none of
370
+ it ships with the plugin.
354
371
 
355
372
  Paseo 0.11 replaced surfaces with screens and kept the old calls as deprecated
356
- aliases. The manifest still admits 0.8, and each connected app evaluates the client
357
- entry against its own version, so `client/compat.tsx` describes the 0.11 additions
358
- locally and calls them only after checking that the app has them:
373
+ aliases. Up to 0.2.3 the manifest admitted 0.8, and each connected app evaluates the
374
+ client entry against its own version, so `client/compat.tsx` describes the 0.11
375
+ additions locally and calls them only after checking that the app has them. Since the
376
+ manifest asks for 0.11, every app that loads the plugin takes the first row; the
377
+ fallback stays in the code until it is removed on its own:
359
378
 
360
379
  | App version | Screen | Sidebar | Opens with | Tab shortcuts in ⌘K |
361
380
  | ----------- | ------ | ------- | ---------- | ------------------- |
Binary file
package/index.server.ts CHANGED
@@ -6,13 +6,14 @@ import {
6
6
  pruneDockerHandler,
7
7
  readContainerLogsHandler,
8
8
  readDockerHandler,
9
+ removeImageHandler,
9
10
  } from "./server/docker";
10
11
  import { explainProcessHandler } from "./server/explain";
11
12
  import { readMetricsHandler } from "./server/metrics";
12
13
  import { killProcessHandler, listProcessesHandler } from "./server/processes";
13
14
  import { readServicesHandler } from "./server/services";
14
15
  import { applyCleanup, killProcess, listProcesses, planCleanup, readMetrics } from "./shared/contracts";
15
- import { controlContainer, controlEngine, pruneDocker, readContainerLogs, readDocker } from "./shared/docker";
16
+ import { controlContainer, controlEngine, pruneDocker, readContainerLogs, readDocker, removeImage } from "./shared/docker";
16
17
  import { explainProcess } from "./shared/explain";
17
18
  import { readServices } from "./shared/services";
18
19
 
@@ -34,6 +35,7 @@ export default function contribute(server: PluginServerContext) {
34
35
  server.handle(controlEngine, controlEngineHandler);
35
36
  server.handle(readContainerLogs, readContainerLogsHandler);
36
37
  server.handle(pruneDocker, pruneDockerHandler);
38
+ server.handle(removeImage, removeImageHandler);
37
39
 
38
40
  // No timers, watchers or sockets are created at registration time, so there is
39
41
  // nothing to release. Paseo removes the handlers and stops the subprocess.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paseo-plugin-machine-status",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Machine dashboard, open ports and Docker control inside Paseo",
5
5
  "license": "MIT",
6
6
  "author": "dutchakdev",
@@ -43,6 +43,7 @@
43
43
  "files": [
44
44
  "paseo-plugin.json",
45
45
  "OVERVIEW.md",
46
+ "assets/icon.png",
46
47
  "index.client.tsx",
47
48
  "index.server.ts",
48
49
  "client/",
package/paseo-plugin.json CHANGED
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "id": "machine-status",
3
- "requirements": { "paseo": ">=0.8.0" }
3
+ "icon": "assets/icon.png",
4
+ "requirements": { "paseo": ">=0.11.0" }
4
5
  }
package/shared/docker.ts CHANGED
@@ -22,6 +22,14 @@ export const DockerUsageRowSchema = z.object({
22
22
  safeToReclaim: z.boolean(),
23
23
  });
24
24
 
25
+ /**
26
+ * The ids this plugin hands the client come from `{{.ID}}` in `docker ps` and
27
+ * `docker images`: hex, 12 characters, or 64 untruncated. Anything else, such
28
+ * as `--force`, would reach the Docker CLI as an argument, so it is refused at
29
+ * the contract rather than trusted because the client normally sends an id.
30
+ */
31
+ export const DockerIdSchema = z.string().regex(/^[0-9a-f]{12,64}$/, "Expected a Docker id");
32
+
25
33
  export const DockerImageSchema = z.object({
26
34
  id: z.string(),
27
35
  reference: z.string(),
@@ -62,7 +70,7 @@ export const controlEngine = defineRpc({
62
70
  export const readContainerLogs = defineRpc({
63
71
  name: "docker.logs",
64
72
  input: z.object({
65
- id: z.string().min(1),
73
+ id: DockerIdSchema,
66
74
  lines: z.number().int().min(10).max(500).default(120),
67
75
  }),
68
76
  output: z.object({ ok: z.boolean(), text: z.string(), error: z.string().nullable() }),
@@ -70,14 +78,14 @@ export const readContainerLogs = defineRpc({
70
78
 
71
79
  export const removeImage = defineRpc({
72
80
  name: "docker.image.remove",
73
- input: z.object({ id: z.string().min(1) }),
81
+ input: z.object({ id: DockerIdSchema }),
74
82
  output: z.object({ ok: z.boolean(), error: z.string().nullable() }),
75
83
  });
76
84
 
77
85
  export const controlContainer = defineRpc({
78
86
  name: "docker.control",
79
87
  input: z.object({
80
- id: z.string().min(1),
88
+ id: DockerIdSchema,
81
89
  action: z.enum(["start", "stop", "restart", "remove"]),
82
90
  }),
83
91
  output: z.object({ ok: z.boolean(), error: z.string().nullable() }),