@andrian.yablonskyy/thub-agent 1.1.13 → 1.1.15
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/README.md +13 -3
- package/RELEASE.md +7 -0
- package/eslint.config.js +3 -0
- package/package.json +2 -2
- package/src/cli.js +6 -15
- package/src/config.js +5 -6
- package/src/report.js +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# @andrian.yablonskyy/thub-agent
|
|
2
2
|
|
|
3
|
-
The Agent CLI (`thub`) is a self-hosted job network that lets CI/CD pipelines and individual developers run firmware tests on real hardware or emulators in a private lab. `thub` is the single entry point for both: it's stateless, everything it knows comes from the [Coordinator](https://github.com/andrianyablonskyy/thub-coordinator) API, and it runs identically on a GitHub-hosted runner and a developer laptop — a developer reproducing a CI failure runs exactly the same command the pipeline runs.
|
|
3
|
+
The Agent CLI (`thub`) is a self-hosted job network that lets CI/CD pipelines and individual developers run firmware tests on real hardware or emulators in a private lab. `thub` is the single entry point for both: it's stateless, everything it knows comes from the [Coordinator](https://github.com/users/andrianyablonskyy/packages/container/package/thub-coordinator) API, and it runs identically on a GitHub-hosted runner and a developer laptop — a developer reproducing a CI failure runs exactly the same command the pipeline runs.
|
|
4
4
|
|
|
5
|
-
See how this fits with the [Coordinator](https://github.com/andrianyablonskyy/thub-coordinator) and the [Client](https://github.com/andrianyablonskyy/thub-client).
|
|
5
|
+
See how this fits with the [Coordinator](https://github.com/users/andrianyablonskyy/packages/container/package/thub-coordinator) and the [Client](https://github.com/andrianyablonskyy/thub-client). The Coordinator runs from its Docker image, `ghcr.io/andrianyablonskyy/thub-coordinator`:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
docker run -d --name thub -p 8080:8080 -v thub-data:/var/lib/thub \
|
|
9
|
+
-e THUB_PUBLIC_URL=https://thub.example.com \
|
|
10
|
+
-e THUB_SESSION_SECRET="$(openssl rand -hex 32)" -e THUB_CLIENT_JOIN_KEY="$(openssl rand -hex 24)" \
|
|
11
|
+
-e THUB_ADMIN_PASSWORD='<first admin password>' -e THUB_LICENSE='<license>' \
|
|
12
|
+
ghcr.io/andrianyablonskyy/thub-coordinator:latest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Then create a CI token or an access key on its dashboard for `thub`.
|
|
6
16
|
|
|
7
17
|
## Install
|
|
8
18
|
|
|
@@ -14,7 +24,7 @@ npx -y @andrian.yablonskyy/thub-agent run --type sw --download-file "$IMAGE_URL"
|
|
|
14
24
|
|
|
15
25
|
## Configuration
|
|
16
26
|
|
|
17
|
-
Read from flags (`--url`, `--key`), then environment (`THUB_URL`, `THUB_KEY
|
|
27
|
+
Read from flags (`--url`, `--key`), then environment (`THUB_URL`, `THUB_KEY`), then `~/.config/thub/agent.json`, then a bundled default. `url`/`key` are required by the time a command actually talks to the Coordinator; `group`/`user` are optional everywhere.
|
|
18
28
|
|
|
19
29
|
`npm install -g` creates `~/.config/thub/agent.json` for you (blank `url`/`token`, so nothing works until you set them) if it doesn't already exist — a re-install never overwrites it. Fill it in with `thub config set`:
|
|
20
30
|
|
package/RELEASE.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
What changed in each release, newest first. `## Unreleased` collects the changes since the version on npm; `bin/publish` turns that heading into the version and date it releases.
|
|
4
4
|
|
|
5
|
+
## 1.1.14 — 2026-10-09
|
|
6
|
+
|
|
7
|
+
### Removed
|
|
8
|
+
|
|
9
|
+
- **`--token`, `THUB_TOKEN` and the config file's `token`.** Use `--key`, `THUB_KEY` and `key`; `thub config set` accepts `url` and `key` only.
|
|
10
|
+
- The unused `PLATFORMS` export of `report.js`.
|
|
11
|
+
|
|
5
12
|
## 1.1.13 — 2026-10-09
|
|
6
13
|
|
|
7
14
|
Changes since 1.1.12.
|
package/eslint.config.js
CHANGED
|
@@ -29,6 +29,9 @@ module.exports = [
|
|
|
29
29
|
},
|
|
30
30
|
rules: {
|
|
31
31
|
// Core JS
|
|
32
|
+
// Dead code: unused variables, imports and functions. Unused trailing
|
|
33
|
+
// arguments are fine when named _x (an Express error handler's next).
|
|
34
|
+
'no-unused-vars': ['error', { args: 'after-used', argsIgnorePattern: '^_', caughtErrors: 'none', ignoreRestSiblings: true }],
|
|
32
35
|
'prefer-const': 'error',
|
|
33
36
|
strict: ['error', 'global'],
|
|
34
37
|
camelcase: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrian.yablonskyy/thub-agent",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"description": "TestHub Agent CLI — the single entry point CI/CD and developers use to submit and follow test jobs",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "Andrian Yablonskyy <andrian.yablonskyy@gmail.com>",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"lint:fix": "eslint . --fix"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@andrian.yablonskyy/thub-common": "^
|
|
18
|
+
"@andrian.yablonskyy/thub-common": "^2.0.1",
|
|
19
19
|
"commander": "^13.1.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
package/src/cli.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
-
const { Command
|
|
18
|
+
const { Command } = require('commander'),
|
|
19
19
|
{
|
|
20
20
|
ApiClient, EXIT_CODES, ACTIVE_JOB_STATES, exitCodeForJobState, PACKAGES, fetchLatestVersion, isNewer, isValidVersion, formatDateTime,
|
|
21
21
|
parseEnvList, POWER_ACTIONS, DEFAULT_RESET_DELAY_SEC, MAX_RESET_DELAY_SEC, powerRequestErrors
|
|
@@ -33,7 +33,6 @@ program
|
|
|
33
33
|
.description('TestHub Agent — submit test jobs and follow them, from CI or your laptop')
|
|
34
34
|
.option('--url <url>', 'Coordinator URL (overrides THUB_URL / config file)')
|
|
35
35
|
.option('--key <key>', 'Your access key (overrides THUB_KEY / config file)')
|
|
36
|
-
.addOption(new Option('--token <token>', 'Old name of --key').hideHelp())
|
|
37
36
|
.version(version);
|
|
38
37
|
|
|
39
38
|
// An admin-requested self-update (README §10.2) is applied at the start of
|
|
@@ -436,19 +435,12 @@ config
|
|
|
436
435
|
.argument('<name>', 'url | key')
|
|
437
436
|
.argument('<value>')
|
|
438
437
|
.action((name, value) => {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
if (!['url', 'key'].includes(setting)){
|
|
442
|
-
console.error(setting === 'group'
|
|
443
|
-
? 'Error: a job\'s group is set on the dashboard now (Users / CI tokens), not in the Agent'
|
|
444
|
-
: setting === 'user'
|
|
445
|
-
? 'Error: a job\'s user comes from your access key now (thub whoami shows it), not from the Agent'
|
|
446
|
-
: 'Error: the setting must be "url" or "key"');
|
|
438
|
+
if (!['url', 'key'].includes(name)){
|
|
439
|
+
console.error('Error: the setting must be "url" or "key"');
|
|
447
440
|
process.exit(EXIT_CODES.USAGE);
|
|
448
441
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
console.log(`Saved ${setting} to config`);
|
|
442
|
+
writeConfigFile({ ...readConfigFile(), [name]: value });
|
|
443
|
+
console.log(`Saved ${name} to config`);
|
|
452
444
|
});
|
|
453
445
|
|
|
454
446
|
// Who this access key belongs to (§10.3).
|
|
@@ -498,8 +490,7 @@ keyCommand
|
|
|
498
490
|
const { keySource } = resolveConnection(program.opts()),
|
|
499
491
|
{ key, username } = await client().post('/me/key/rotate');
|
|
500
492
|
if (keySource === 'file'){
|
|
501
|
-
|
|
502
|
-
writeConfigFile({ ...current, key });
|
|
493
|
+
writeConfigFile({ ...readConfigFile(), key });
|
|
503
494
|
console.log(`New access key for ${username} saved to ${CONFIG_PATH} — the old one has stopped working.`);
|
|
504
495
|
}
|
|
505
496
|
else {
|
package/src/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file packages/agent/src/config.js
|
|
3
|
-
* @description Agent config resolution: flags > env > config file > bundled default (url
|
|
3
|
+
* @description Agent config resolution: flags > env > config file > bundled default (url and access key)
|
|
4
4
|
*
|
|
5
5
|
* @author Andrian Yablonskyy
|
|
6
6
|
* @copyright Copyright (c) 2026 Andrian Yablonskyy. All rights reserved.
|
|
@@ -18,8 +18,7 @@ const fs = require('node:fs'),
|
|
|
18
18
|
path = require('node:path');
|
|
19
19
|
|
|
20
20
|
// §7: "Configuration is read from flags, then environment (THUB_URL,
|
|
21
|
-
// THUB_KEY), then ~/.config/thub/agent.json."
|
|
22
|
-
// be called a token: --token, THUB_TOKEN and a saved `token` still work.
|
|
21
|
+
// THUB_KEY), then ~/.config/thub/agent.json."
|
|
23
22
|
const CONFIG_PATH = path.join(os.homedir(), '.config', 'thub', 'agent.json'),
|
|
24
23
|
|
|
25
24
|
// Bundled with the package as a last-resort default, below the user's own
|
|
@@ -51,9 +50,9 @@ function writeConfigFile(config){
|
|
|
51
50
|
function resolveConnection(flags = {}){
|
|
52
51
|
const file = { ...readJsonFile(PACKAGE_DEFAULT_CONFIG_PATH), ...readConfigFile() },
|
|
53
52
|
url = flags.url || process.env.THUB_URL || file.url,
|
|
54
|
-
[token, keySource] = flags.key
|
|
55
|
-
: process.env.THUB_KEY
|
|
56
|
-
: file.key
|
|
53
|
+
[token, keySource] = flags.key ? [flags.key, 'flag']
|
|
54
|
+
: process.env.THUB_KEY ? [process.env.THUB_KEY, 'THUB_KEY']
|
|
55
|
+
: file.key ? [file.key, 'file'] : [null, null];
|
|
57
56
|
if (!url || !token){
|
|
58
57
|
const err = new Error(
|
|
59
58
|
'Missing Coordinator URL or access key. Set them with `thub config set url <url>` and `thub config set key <key>`, ' +
|
package/src/report.js
CHANGED