@thinger-io/cli-core 0.5.0 → 0.5.1
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 +12 -0
- package/lib/auth.js +25 -1
- package/lib/mcp/catalog.js +1 -1
- package/lib/mcp/tools-resource.js +5 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.1] - 2026-10-31
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `host` action `update_settings` says what the server does: it merges the
|
|
8
|
+
body into the host's custom settings (keys left out stay, `null` removes
|
|
9
|
+
one). Its confirmation plan no longer claims it removes the keys left
|
|
10
|
+
out of the body.
|
|
11
|
+
- The browser login on a server that does not know the CLI's OAuth client
|
|
12
|
+
(older than Thinger 7.5.0, or the client was removed) says so and offers
|
|
13
|
+
username and password or a token instead of failing.
|
|
14
|
+
|
|
3
15
|
## [0.5.0] - 2026-10-21
|
|
4
16
|
|
|
5
17
|
One grammar for every command, noun first:
|
package/lib/auth.js
CHANGED
|
@@ -110,7 +110,22 @@ export async function authenticate(opts = {}) {
|
|
|
110
110
|
if (method === 'userpass') {
|
|
111
111
|
await authenticateWithUserPass(opts);
|
|
112
112
|
} else if (method === 'oauth') {
|
|
113
|
-
await authenticateWithOAuth(opts, existing)
|
|
113
|
+
await authenticateWithOAuth(opts, existing).catch(async (error) => {
|
|
114
|
+
// A server older than the CLI's built-in OAuth client, or
|
|
115
|
+
// one whose admin removed it: sign in another way.
|
|
116
|
+
if (error.code !== 'oauth_client_unknown' || !process.stdin.isTTY) throw error;
|
|
117
|
+
console.log(warning(error.message));
|
|
118
|
+
const fallback = await ask(select, {
|
|
119
|
+
message: 'Sign in another way:',
|
|
120
|
+
choices: [
|
|
121
|
+
{ name: 'Username and password', value: 'userpass' },
|
|
122
|
+
{ name: 'Token', value: 'token' },
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
return fallback === 'userpass'
|
|
126
|
+
? authenticateWithUserPass(opts)
|
|
127
|
+
: authenticateWithToken(opts);
|
|
128
|
+
});
|
|
114
129
|
} else {
|
|
115
130
|
await authenticateWithToken(opts);
|
|
116
131
|
}
|
|
@@ -391,6 +406,15 @@ async function authenticateWithOAuth(opts, existing) {
|
|
|
391
406
|
spinner.succeed('OAuth User Code received');
|
|
392
407
|
} catch (error) {
|
|
393
408
|
spinner.fail('OAuth device-code request failed');
|
|
409
|
+
const status = error.response?.status;
|
|
410
|
+
if (status === 401 || status === 404) {
|
|
411
|
+
throw Object.assign(
|
|
412
|
+
new Error(
|
|
413
|
+
`The server does not know the OAuth client ${client_id} (Thinger 7.5.0 and later have it built in). Sign in with a token or username and password instead.`,
|
|
414
|
+
),
|
|
415
|
+
{ code: 'oauth_client_unknown' },
|
|
416
|
+
);
|
|
417
|
+
}
|
|
394
418
|
throw error;
|
|
395
419
|
}
|
|
396
420
|
|
package/lib/mcp/catalog.js
CHANGED
|
@@ -665,7 +665,7 @@ export const CATALOG = {
|
|
|
665
665
|
method: 'put',
|
|
666
666
|
path: 'settings',
|
|
667
667
|
description:
|
|
668
|
-
'
|
|
668
|
+
'Patch the host settings with `body` (JSON merge: keys left out stay, null removes one); read them first. Confirm with the user first.',
|
|
669
669
|
},
|
|
670
670
|
},
|
|
671
671
|
},
|
|
@@ -1493,11 +1493,13 @@ export function resourceTools({
|
|
|
1493
1493
|
.then((r) => r.data)
|
|
1494
1494
|
.catch(() => undefined);
|
|
1495
1495
|
if (isRecord(now) && isRecord(body)) {
|
|
1496
|
+
// The server merges the body (JSON merge-patch): keys left
|
|
1497
|
+
// out stay, a null removes one.
|
|
1498
|
+
const removed = Object.keys(body).filter((k) => body[k] === null && k in now);
|
|
1496
1499
|
const changed = Object.keys(body).filter(
|
|
1497
|
-
(k) => JSON.stringify(now[k]) !== JSON.stringify(body[k]),
|
|
1500
|
+
(k) => body[k] !== null && JSON.stringify(now[k]) !== JSON.stringify(body[k]),
|
|
1498
1501
|
);
|
|
1499
|
-
|
|
1500
|
-
return `It would replace the settings of ${target}: changes ${some(changed)}; removes ${some(dropped)} (left out of the body).`;
|
|
1502
|
+
return `It would patch the settings of ${target}: changes ${some(changed)}; removes ${some(removed)}; the rest stays.`;
|
|
1501
1503
|
}
|
|
1502
1504
|
}
|
|
1503
1505
|
if (action === 'test_notification') {
|
package/package.json
CHANGED