@mu-cabin/muc-cli 0.5.4 → 0.5.6
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/REFERENCE.md +8 -2
- package/dist/muc.mjs +20 -7
- package/package.json +1 -1
package/REFERENCE.md
CHANGED
|
@@ -353,7 +353,11 @@ as the personal `~/.muc` account and is mutually exclusive with
|
|
|
353
353
|
separate iPad slot, so desktop and phone coexist; a real iPad may conflict.
|
|
354
354
|
- **REST `tokenPwd`.** A fresh `muc login` rotates the account's refresh
|
|
355
355
|
token; other devices on that account get logged out when their token
|
|
356
|
-
next refreshes.
|
|
356
|
+
next refreshes. Remembered-password daemon recovery is different: it uses
|
|
357
|
+
`createTokenPwd=false`, refreshing only accessToken and preserving the
|
|
358
|
+
phone's auto-login credential. The issuing REST platform is persisted as
|
|
359
|
+
`restPlatform` and reused by every refresh path; it is independent from the
|
|
360
|
+
daemon's TCP slot (`iPad` remains `os:"iOS" + browser:"iPad"`).
|
|
357
361
|
|
|
358
362
|
The fix is to give the daemon its **own account**, stored under
|
|
359
363
|
`~/.muc/assistant/` (next to its pid / socket / logs) and completely
|
|
@@ -614,7 +618,7 @@ defaultReaction: [点赞]
|
|
|
614
618
|
| Path | Purpose | Mode |
|
|
615
619
|
|---|---|---|
|
|
616
620
|
| `~/.muc/config.json` | tenant config: APP_KEY, APP_ID, signing secrets, hosts/ports | 600 |
|
|
617
|
-
| `~/.muc/credentials.json` | accessToken, tokenPwd, profile | 600 |
|
|
621
|
+
| `~/.muc/credentials.json` | accessToken, tokenPwd, issuing REST platform, profile | 600 |
|
|
618
622
|
| `~/.muc/device-id` | stable per-CLI deviceId (sha256 hex) | 600 |
|
|
619
623
|
| `~/.muc/remember.salt` | salt for the optional `--remember` password blob | 600 |
|
|
620
624
|
| `~/.muc/runtime/daemon.sock`, `daemon.pid`, `daemon-state.json`, `daemon-events-*.ndjson` | personal daemon IPC, pid/state, and raw event history | — |
|
|
@@ -629,6 +633,8 @@ files by hand.
|
|
|
629
633
|
## Changelog
|
|
630
634
|
|
|
631
635
|
#### Unreleased
|
|
636
|
+
- Persist the platform that issued each REST credential and reuse it for `/emp/login` refreshes. Existing personal credentials fall back to iOS and existing assistant credentials to Mac until the next successful login/refresh migrates them. This REST namespace is independent from the TCP iPad slot.
|
|
637
|
+
- Remembered-password recovery requests only a fresh `accessToken` (`createTokenPwd=false`) so daemon recovery no longer rotates another device's auto-login `tokenPwd`.
|
|
632
638
|
- Add the third iPad chat slot. Logical `--os iPad` serializes as `os:"iOS", browser:"iPad"` and is now the built-in default for personal commands, the personal daemon, and assistantd. Existing explicit `defaultChatOs` values remain authoritative.
|
|
633
639
|
- Slot safety guidance is now non-blocking: skills remind that a real iPad may be kicked and continue without asking for slot confirmation. Recipient, content, and destructive-action confirmations are unchanged.
|
|
634
640
|
- Add the personal daemon command family: `muc daemon-start`, `daemon-status`, `daemon-stop`, and `daemon-events`. Ordinary chat-channel commands now route only through the personal daemon and report `daemon_kind:"personal"` when routed.
|
package/dist/muc.mjs
CHANGED
|
@@ -22028,6 +22028,12 @@ function getDeviceName() {
|
|
|
22028
22028
|
return `${hostname()} (muc-cli)`;
|
|
22029
22029
|
}
|
|
22030
22030
|
|
|
22031
|
+
// src/lib/rest-platform.ts
|
|
22032
|
+
init_profile();
|
|
22033
|
+
function resolveRestPlatform(cred) {
|
|
22034
|
+
return cred?.restPlatform ?? (isAssistantProfile() ? PLATFORM_MAC : DEFAULT_REST_PLATFORM);
|
|
22035
|
+
}
|
|
22036
|
+
|
|
22031
22037
|
// src/lib/http.ts
|
|
22032
22038
|
var UA = `MUC/${APP_VERSION} (CLI; muc-cli/${CLI_VERSION})`;
|
|
22033
22039
|
function loginCmd() {
|
|
@@ -22107,6 +22113,7 @@ async function tryRefreshViaEmpGet() {
|
|
|
22107
22113
|
const next = {
|
|
22108
22114
|
...cred,
|
|
22109
22115
|
accessToken: res.data.accessToken,
|
|
22116
|
+
restPlatform: resolveRestPlatform(cred),
|
|
22110
22117
|
accessTokenExpireAt: accessTokenExpiry ?? cred.accessTokenExpireAt,
|
|
22111
22118
|
savedAt: Date.now()
|
|
22112
22119
|
};
|
|
@@ -22134,7 +22141,7 @@ async function refreshAccessTokenWithTokenPwd() {
|
|
|
22134
22141
|
);
|
|
22135
22142
|
}
|
|
22136
22143
|
const cfg = requireConfig();
|
|
22137
|
-
const platform3 =
|
|
22144
|
+
const platform3 = resolveRestPlatform(cred);
|
|
22138
22145
|
const appVersion = platform3 === PLATFORM_IOS ? APP_VERSION_IOS : APP_VERSION;
|
|
22139
22146
|
const form = {
|
|
22140
22147
|
account: cred.uid,
|
|
@@ -22199,6 +22206,7 @@ async function refreshAccessTokenWithTokenPwd() {
|
|
|
22199
22206
|
const fresh = {
|
|
22200
22207
|
...cred,
|
|
22201
22208
|
accessToken: res.data.accessToken,
|
|
22209
|
+
restPlatform: platform3,
|
|
22202
22210
|
// Capture rotated tokenPwd if the server returned one; otherwise keep
|
|
22203
22211
|
// the existing value. Server may rotate tokenPwd on every successful
|
|
22204
22212
|
// /emp/login (single-use refresh-token semantics) — if it does and we
|
|
@@ -22282,7 +22290,7 @@ async function doRefreshViaRememberedPwd() {
|
|
|
22282
22290
|
);
|
|
22283
22291
|
}
|
|
22284
22292
|
const cfg = requireConfig();
|
|
22285
|
-
const platform3 =
|
|
22293
|
+
const platform3 = resolveRestPlatform(cred);
|
|
22286
22294
|
const appVersion = platform3 === PLATFORM_IOS ? APP_VERSION_IOS : APP_VERSION;
|
|
22287
22295
|
const form = {
|
|
22288
22296
|
account: cred.uid,
|
|
@@ -22296,8 +22304,8 @@ async function doRefreshViaRememberedPwd() {
|
|
|
22296
22304
|
deviceName: cred.deviceName || getDeviceName(),
|
|
22297
22305
|
passwordType: 0,
|
|
22298
22306
|
// plaintext password (DES-encoded), not tokenPwd
|
|
22299
|
-
createTokenPwd:
|
|
22300
|
-
//
|
|
22307
|
+
createTokenPwd: false,
|
|
22308
|
+
// accessToken only; do not rotate phone auto-login
|
|
22301
22309
|
encrypt: true
|
|
22302
22310
|
};
|
|
22303
22311
|
form.sign = signRest(form, cfg.signSecretRest);
|
|
@@ -22349,6 +22357,7 @@ async function doRefreshViaRememberedPwd() {
|
|
|
22349
22357
|
const fresh = {
|
|
22350
22358
|
...cred,
|
|
22351
22359
|
accessToken: res.data.accessToken,
|
|
22360
|
+
restPlatform: platform3,
|
|
22352
22361
|
tokenPwd: res.data.tokenPwdInfo?.tokenPwd ?? cred.tokenPwd,
|
|
22353
22362
|
tokenPwdExpireAt: newTokenPwdExpiry ?? cred.tokenPwdExpireAt,
|
|
22354
22363
|
accessTokenExpireAt: newAccessTokenExpiry ?? cred.accessTokenExpireAt,
|
|
@@ -22567,7 +22576,7 @@ function register(program3, variant) {
|
|
|
22567
22576
|
const deviceId = getDeviceId();
|
|
22568
22577
|
const deviceName = getDeviceName();
|
|
22569
22578
|
const password = encryptPassword(rawPwd, pwdDesKeyOf(cfg));
|
|
22570
|
-
const platform3 = opts.platform ?? (isAssistant ? PLATFORM_MAC : DEFAULT_REST_PLATFORM);
|
|
22579
|
+
const platform3 = opts.platform ?? (existing?.uid === account ? existing.restPlatform : void 0) ?? (isAssistant ? PLATFORM_MAC : DEFAULT_REST_PLATFORM);
|
|
22571
22580
|
const appVersion = opts.appVersion ?? appVersionFor(platform3);
|
|
22572
22581
|
const form = {
|
|
22573
22582
|
account,
|
|
@@ -22625,6 +22634,7 @@ function register(program3, variant) {
|
|
|
22625
22634
|
name: userInfo2.name,
|
|
22626
22635
|
accessToken: data.accessToken,
|
|
22627
22636
|
tokenPwd: tokenPwd ?? existing?.tokenPwd,
|
|
22637
|
+
restPlatform: platform3,
|
|
22628
22638
|
deviceId,
|
|
22629
22639
|
deviceName,
|
|
22630
22640
|
savedAt: Date.now(),
|
|
@@ -24052,13 +24062,15 @@ async function tryRefreshViaEmpGet2(cred, cfg) {
|
|
|
24052
24062
|
}
|
|
24053
24063
|
}
|
|
24054
24064
|
async function refreshAccessTokenViaTokenPwd(cred, cfg) {
|
|
24065
|
+
const platform3 = resolveRestPlatform(cred);
|
|
24066
|
+
const appVersion = platform3 === PLATFORM_IOS ? APP_VERSION_IOS : APP_VERSION;
|
|
24055
24067
|
const form = {
|
|
24056
24068
|
account: cred.uid,
|
|
24057
24069
|
password: encryptPassword(cred.tokenPwd, pwdDesKeyOf(cfg)),
|
|
24058
24070
|
appName: APP_NAME,
|
|
24059
24071
|
appKey: cfg.appKey,
|
|
24060
|
-
appVersion
|
|
24061
|
-
platform:
|
|
24072
|
+
appVersion,
|
|
24073
|
+
platform: platform3,
|
|
24062
24074
|
osVersion: release3(),
|
|
24063
24075
|
deviceId: cred.deviceId,
|
|
24064
24076
|
deviceName: cred.deviceName,
|
|
@@ -24080,6 +24092,7 @@ async function refreshAccessTokenViaTokenPwd(cred, cfg) {
|
|
|
24080
24092
|
return {
|
|
24081
24093
|
...cred,
|
|
24082
24094
|
accessToken: data.accessToken,
|
|
24095
|
+
restPlatform: platform3,
|
|
24083
24096
|
accessTokenExpireAt: pickExpireMs(
|
|
24084
24097
|
data.accessTokenExpireTime,
|
|
24085
24098
|
data.accessTokenExpireAt,
|