@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 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 = DEFAULT_REST_PLATFORM;
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 = DEFAULT_REST_PLATFORM;
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: true,
22300
- // mint a fresh refresh token while we're here
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: APP_VERSION,
24061
- platform: PLATFORM_MAC,
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mu-cabin/muc-cli",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "Terminal client for MUC IM (com.meicloud.im.dh).",
5
5
  "license": "MIT",
6
6
  "type": "module",