@xmanrui/dsh-im 0.2.1 → 0.2.2

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/lib/client.js CHANGED
@@ -493,7 +493,7 @@ var CSS = String.raw`
493
493
  --ddt-accent-deep: #0958d9;
494
494
  --ddt-accent-wash: #eaf3ff;
495
495
  --ddt-success: var(--dsw-alias-state-success-primary, #20a162);
496
- --ddt-warning: var(--dsw-alias-state-warning-primary, #d97706);
496
+ --ddt-warning: var(--dsw-alias-state-warn-primary, #d97706);
497
497
  --ddt-error: var(--dsw-alias-state-error-primary, #d54941);
498
498
  width: 100%;
499
499
  max-width: 880px;
@@ -514,13 +514,13 @@ var CSS = String.raw`
514
514
  .ddt-heading p { margin-top: 5px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; white-space: nowrap; }
515
515
  .ddt-tools, .ddt-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
516
516
  .ddt-tools { width: 100%; justify-content: space-between; flex-wrap: nowrap; }
517
- .ddt-badge { min-height: 30px; display: inline-flex; align-items: center; gap: 7px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-fill-secondary, #f2f3f5); font-size: 12px; white-space: nowrap; }
517
+ .ddt-badge { min-height: 30px; display: inline-flex; align-items: center; gap: 7px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font-size: 12px; white-space: nowrap; }
518
518
  .ddt-dot { width: 8px; height: 8px; flex: none; border-radius: 50%; background: #aeb3bb; }
519
519
  .ddt-dot[data-tone="success"] { background: var(--ddt-success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ddt-success) 14%, transparent); }
520
520
  .ddt-dot[data-tone="warning"] { background: var(--ddt-warning); }
521
521
  .ddt-dot[data-tone="error"] { background: var(--ddt-error); }
522
- .ddt-button { min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 0 13px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: inherit; font-size: 13px; font-weight: 560; text-decoration: none; cursor: pointer; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
523
- .ddt-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
522
+ .ddt-button { min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 0 13px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; text-decoration: none; cursor: pointer; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
523
+ .ddt-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
524
524
  .ddt-button:active:not(:disabled) { transform: translateY(1px); }
525
525
  .ddt-button:focus-visible { outline: 2px solid color-mix(in srgb, var(--ddt-accent) 70%, white); outline-offset: 2px; }
526
526
  .ddt-button:disabled { cursor: not-allowed; opacity: .55; }
@@ -528,7 +528,7 @@ var CSS = String.raw`
528
528
  .ddt-button[data-kind="primary"]:hover:not(:disabled) { border-color: var(--ddt-accent-deep); background: var(--ddt-accent-deep); }
529
529
  .ddt-button[data-kind="danger"] { color: var(--ddt-error); }
530
530
  .ddt-button[data-kind="quiet"] { min-height: 30px; padding: 0 10px; border-color: transparent; background: transparent; }
531
- .ddt-card { overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
531
+ .ddt-card { overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
532
532
  .ddt-cardBody { padding: 24px; }
533
533
  .ddt-empty { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
534
534
  .ddt-empty h3 { margin: 8px 0; font-size: 18px; }
@@ -538,7 +538,7 @@ var CSS = String.raw`
538
538
  .ddt-brandMark svg { filter: drop-shadow(0 3px 8px rgb(0 35 96 / 16%)); }
539
539
  .ddt-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: start; }
540
540
  .ddt-qrColumn { display: flex; flex-direction: column; align-items: center; gap: 12px; }
541
- .ddt-qrFrame { position: relative; width: min(270px, 100%); aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 16px; background: #fff; }
541
+ .ddt-qrFrame { position: relative; width: min(270px, 100%); aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: #fff; }
542
542
  .ddt-qrFrame::before { content: ''; position: absolute; inset: 6px; border: 1px solid rgb(22 119 255 / 10%); border-radius: 11px; pointer-events: none; }
543
543
  .ddt-qrFrame img { display: block; width: 100%; height: 100%; object-fit: contain; }
544
544
  .ddt-qrFallback { padding: 24px; color: #646a73; text-align: center; }
@@ -574,10 +574,10 @@ var CSS = String.raw`
574
574
  .ddt-accountIdentity p { margin-top: 4px; color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; }
575
575
  .ddt-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
576
576
  .ddt-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 20px 0; }
577
- .ddt-metric { min-width: 0; padding: 12px; border-radius: 9px; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
577
+ .ddt-metric { min-width: 0; padding: 12px; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
578
578
  .ddt-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; }
579
579
  .ddt-metric dd { overflow: hidden; margin: 5px 0 0; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
580
- .ddt-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
580
+ .ddt-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
581
581
  .ddt-accountFooter .ddt-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
582
582
  .ddt-accountFooter .ddt-button { flex: none; white-space: nowrap; }
583
583
  .ddt-summary { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
@@ -2206,7 +2206,7 @@ var CSS3 = String.raw`
2206
2206
  .bxf-page {
2207
2207
  --bxf-accent: var(--dsw-alias-state-business-primary, #3370ff);
2208
2208
  --bxf-success: var(--dsw-alias-state-success-primary, #20a162);
2209
- --bxf-warning: var(--dsw-alias-state-warning-primary, #d97706);
2209
+ --bxf-warning: var(--dsw-alias-state-warn-primary, #d97706);
2210
2210
  --bxf-error: var(--dsw-alias-state-error-primary, #d54941);
2211
2211
  box-sizing: border-box;
2212
2212
  width: 100%;
@@ -2595,7 +2595,7 @@ var CSS3 = String.raw`
2595
2595
 
2596
2596
  .bxf-connectedTop { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
2597
2597
  .bxf-botIdentity { min-width: 0; display: flex; align-items: center; gap: 13px; }
2598
- .bxf-avatar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
2598
+ .bxf-avatar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
2599
2599
  .bxf-botName { min-width: 0; }
2600
2600
  .bxf-botName h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 17px; line-height: 24px; font-weight: 650; }
2601
2601
  .bxf-botName p { overflow: hidden; color: var(--dsw-alias-label-tertiary, #8f959e); font-family: var(--ds-font-family-code, monospace); font-size: 12px; line-height: 18px; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
@@ -2609,7 +2609,7 @@ var CSS3 = String.raw`
2609
2609
  .bxf-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 17px; }
2610
2610
  .bxf-metric dd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 18px; font-weight: 550; margin: 3px 0 0; }
2611
2611
 
2612
- .bxf-connectedFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
2612
+ .bxf-connectedFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
2613
2613
  .bxf-healthSummary { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
2614
2614
  .bxf-healthSummary[data-error="true"] { color: var(--bxf-error); }
2615
2615
  .bxf-botActions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; justify-content: flex-end; }
@@ -4465,7 +4465,7 @@ var React8 = __toESM(require("react"), 1);
4465
4465
  var WECOM_STYLE_ID = "xmanrui-dsh-im-wecom-settings";
4466
4466
  var CSS6 = String.raw`
4467
4467
  .dwecom-page { --ddt-accent: #3370ff; --ddt-accent-deep: #245bdb; --ddt-accent-wash: #eef4ff; }
4468
- .dwecom-avatar, .dwecom-brand { color: #3370ff; background: #fff; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
4468
+ .dwecom-avatar, .dwecom-brand { color: #3370ff; background: #fff; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
4469
4469
  .dwecom-avatar svg, .dwecom-brand svg { display: block; }
4470
4470
  `;
4471
4471
  function installWecomStyles() {
@@ -5125,7 +5125,7 @@ var CSS7 = String.raw`
5125
5125
  --dxw-accent: #07c160;
5126
5126
  --dxw-accent-dark: #05994c;
5127
5127
  --dxw-success: var(--dsw-alias-state-success-primary, #20a162);
5128
- --dxw-warning: var(--dsw-alias-state-warning-primary, #d97706);
5128
+ --dxw-warning: var(--dsw-alias-state-warn-primary, #d97706);
5129
5129
  --dxw-error: var(--dsw-alias-state-error-primary, #d54941);
5130
5130
  width: 100%;
5131
5131
  max-width: 880px;
@@ -5144,20 +5144,20 @@ var CSS7 = String.raw`
5144
5144
  .dxw-heading p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; margin-top: 5px; white-space: nowrap; }
5145
5145
  .dxw-tools, .dxw-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
5146
5146
  .dxw-tools { width: 100%; justify-content: space-between; flex-wrap: nowrap; }
5147
- .dxw-badge { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-fill-secondary, #f2f3f5); font-size: 12px; white-space: nowrap; }
5147
+ .dxw-badge { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font-size: 12px; white-space: nowrap; }
5148
5148
  .dxw-dot { width: 8px; height: 8px; border-radius: 50%; background: #aeb3bb; flex: none; }
5149
5149
  .dxw-dot[data-tone="success"] { background: var(--dxw-success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dxw-success) 14%, transparent); }
5150
5150
  .dxw-dot[data-tone="warning"] { background: var(--dxw-warning); }
5151
5151
  .dxw-dot[data-tone="error"] { background: var(--dxw-error); }
5152
- .dxw-button { min-height: 34px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; padding: 0 13px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: inherit; font-size: 13px; font-weight: 560; cursor: pointer; text-decoration: none; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
5153
- .dxw-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
5152
+ .dxw-button { min-height: 34px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; padding: 0 13px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; cursor: pointer; text-decoration: none; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
5153
+ .dxw-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
5154
5154
  .dxw-button:active:not(:disabled) { transform: translateY(1px); }
5155
5155
  .dxw-button:focus-visible, .dxw-input:focus-visible { outline: 2px solid color-mix(in srgb, var(--dxw-accent) 70%, white); outline-offset: 2px; }
5156
5156
  .dxw-button:disabled { cursor: not-allowed; opacity: .55; }
5157
5157
  .dxw-button[data-kind="primary"] { color: white; border-color: var(--dxw-accent); background: var(--dxw-accent); }
5158
5158
  .dxw-button[data-kind="primary"]:hover:not(:disabled) { border-color: var(--dxw-accent-dark); background: var(--dxw-accent-dark); }
5159
5159
  .dxw-button[data-kind="danger"] { color: var(--dxw-error); }
5160
- .dxw-card { overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
5160
+ .dxw-card { overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
5161
5161
  .dxw-cardBody { padding: 24px; }
5162
5162
  .dxw-empty { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
5163
5163
  .dxw-empty h3 { font-size: 18px; margin-bottom: 8px; }
@@ -5167,7 +5167,7 @@ var CSS7 = String.raw`
5167
5167
  .dxw-logo svg { width: 62px; height: 62px; }
5168
5168
  .dxw-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: center; }
5169
5169
  .dxw-qrColumn { display: flex; flex-direction: column; align-items: center; gap: 12px; }
5170
- .dxw-qrFrame { position: relative; width: 270px; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 16px; background: white; }
5170
+ .dxw-qrFrame { position: relative; width: 270px; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: white; }
5171
5171
  .dxw-qrFrame img { display: block; width: 100%; height: 100%; object-fit: contain; }
5172
5172
  .dxw-qrFallback { padding: 24px; text-align: center; color: #646a73; }
5173
5173
  .dxw-expired { position: absolute; inset: 0; display: grid; place-items: center; padding: 30px; color: white; text-align: center; font-weight: 650; background: rgb(31 35 41 / 76%); backdrop-filter: blur(3px); }
@@ -5183,7 +5183,7 @@ var CSS7 = String.raw`
5183
5183
  .dxw-verify h3 { margin: 8px 0; font-size: 19px; }
5184
5184
  .dxw-verify p { color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.6; }
5185
5185
  .dxw-codeRow { display: flex; justify-content: center; gap: 10px; margin: 24px 0 10px; }
5186
- .dxw-input { width: 190px; height: 42px; padding: 0 14px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-body, white); color: inherit; font: inherit; font-size: 18px; letter-spacing: .16em; text-align: center; }
5186
+ .dxw-input { width: 190px; height: 42px; padding: 0 14px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-1, white); color: inherit; font: inherit; font-size: 18px; letter-spacing: .16em; text-align: center; }
5187
5187
  .dxw-statusNotice, .dxw-error { display: flex; align-items: center; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dxw-error) 28%, transparent); border-radius: 10px; color: var(--dxw-error); background: color-mix(in srgb, var(--dxw-error) 7%, transparent); font-size: 13px; }
5188
5188
  .dxw-error { align-items: flex-start; flex-direction: column; padding: 22px; }
5189
5189
  .dxw-error h3 { font-size: 17px; }
@@ -5198,10 +5198,10 @@ var CSS7 = String.raw`
5198
5198
  .dxw-accountIdentity p { color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; margin-top: 4px; }
5199
5199
  .dxw-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
5200
5200
  .dxw-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 20px 0; }
5201
- .dxw-metric { padding: 12px 14px; border-radius: 9px; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
5201
+ .dxw-metric { padding: 12px 14px; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
5202
5202
  .dxw-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; }
5203
5203
  .dxw-metric dd { overflow: hidden; margin: 5px 0 0; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
5204
- .dxw-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
5204
+ .dxw-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
5205
5205
  .dxw-accountFooter .dxw-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
5206
5206
  .dxw-accountFooter .dxw-button { flex: none; white-space: nowrap; }
5207
5207
  .dxw-summary { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
@@ -6548,7 +6548,7 @@ function WhatsappSettingsTab({ rpcCall }) {
6548
6548
  var IM_STYLE_ID = "xmanrui-dsh-im-settings";
6549
6549
  var CSS9 = String.raw`
6550
6550
  .dim-page {
6551
- --dim-blue: #3370ff;
6551
+ --dim-blue: var(--dsw-alias-state-business-primary, #3370ff);
6552
6552
  --dim-blue-soft: color-mix(in srgb, var(--dim-blue) 9%, transparent);
6553
6553
  width: 100%;
6554
6554
  max-width: 1080px;
@@ -6560,24 +6560,24 @@ var CSS9 = String.raw`
6560
6560
  .dim-title { margin: 0 0 26px; }
6561
6561
  .dim-title p { margin: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; white-space: nowrap; }
6562
6562
  .dim-layout { display: grid; grid-template-columns: 174px 1px minmax(0, 1fr); gap: 24px; align-items: start; }
6563
- .dim-rail { max-height: 520px; display: grid; align-content: start; gap: 8px; overflow-y: auto; padding: 1px 4px 1px 1px; scrollbar-width: thin; scrollbar-color: var(--dsw-alias-line-border, #dfe1e5) transparent; }
6563
+ .dim-rail { max-height: 520px; display: grid; align-content: start; gap: 8px; overflow-y: auto; padding: 1px 4px 1px 1px; scrollbar-width: thin; scrollbar-color: var(--dsw-alias-border-l2, #dfe1e5) transparent; }
6564
6564
  .dim-rail::-webkit-scrollbar { width: 4px; }
6565
- .dim-rail::-webkit-scrollbar-thumb { border-radius: 99px; background: var(--dsw-alias-line-border, #dfe1e5); }
6566
- .dim-channel { width: 100%; min-height: 48px; display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--dsw-alias-line-border, #eef0f3); border-radius: 14px; color: inherit; background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 2px 8px rgb(31 35 41 / 3%); font: inherit; text-align: left; cursor: pointer; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; }
6567
- .dim-channel:hover { border-color: color-mix(in srgb, var(--dim-blue) 25%, var(--dsw-alias-line-border, #eef0f3)); background: color-mix(in srgb, var(--dim-blue) 2%, var(--dsw-alias-bg-layer-3, #fff)); box-shadow: 0 5px 16px rgb(31 35 41 / 5%); }
6568
- .dim-channel[aria-selected="true"] { border-color: color-mix(in srgb, var(--dim-blue) 43%, white); color: var(--dim-blue); background: color-mix(in srgb, var(--dim-blue) 9%, white); box-shadow: 0 3px 12px rgb(51 112 255 / 7%); }
6569
- .dim-channel:focus-visible { outline: none; border-color: color-mix(in srgb, var(--dim-blue) 72%, white); box-shadow: 0 0 0 1px color-mix(in srgb, var(--dim-blue) 24%, transparent) inset, 0 3px 12px rgb(51 112 255 / 7%); }
6565
+ .dim-rail::-webkit-scrollbar-thumb { border-radius: 99px; background: var(--dsw-alias-border-l2, #dfe1e5); }
6566
+ .dim-channel { width: 100%; min-height: 48px; display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--dsw-alias-border-l2, #eef0f3); border-radius: 14px; color: inherit; background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 2px 8px rgb(31 35 41 / 3%); font: inherit; text-align: left; cursor: pointer; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; }
6567
+ .dim-channel:hover { border-color: color-mix(in srgb, var(--dim-blue) 25%, var(--dsw-alias-border-l2, #eef0f3)); background: color-mix(in srgb, var(--dim-blue) 2%, var(--dsw-alias-bg-layer-3, #fff)); box-shadow: 0 5px 16px rgb(31 35 41 / 5%); }
6568
+ .dim-channel[aria-selected="true"] { border-color: color-mix(in srgb, var(--dim-blue) 43%, var(--dsw-alias-border-l2, #dfe1e5)); color: var(--dim-blue); background: color-mix(in srgb, var(--dim-blue) 12%, var(--dsw-alias-bg-layer-3, #fff)); box-shadow: 0 3px 12px rgb(51 112 255 / 7%); }
6569
+ .dim-channel:focus-visible { outline: none; border-color: color-mix(in srgb, var(--dim-blue) 72%, var(--dsw-alias-border-l2, #dfe1e5)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--dim-blue) 24%, transparent) inset, 0 3px 12px rgb(51 112 255 / 7%); }
6570
6570
  .dim-logo { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 9px; box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
6571
6571
  .dim-logo svg { display: block; width: 20px; height: 20px; }
6572
6572
  .dim-logoWeixin { color: white; background: #07c160; }
6573
6573
  .dim-logoWeixin svg { width: 19px; height: 19px; }
6574
- .dim-logoFeishu { background: white; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
6574
+ .dim-logoFeishu { background: white; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
6575
6575
  .dim-logoFeishu svg { width: 28px; height: 28px; }
6576
6576
  .dim-logoDingtalk { color: white; background: #1677ff; }
6577
6577
  .dim-logoDingtalk svg { width: 24px; height: 24px; }
6578
6578
  .dim-logoQq { color: white; background: #1677ff; }
6579
6579
  .dim-logoQq svg { width: 21px; height: 21px; }
6580
- .dim-logoWecom { background: white; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
6580
+ .dim-logoWecom { background: white; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
6581
6581
  .dim-logoWecom svg { width: 22px; height: 22px; }
6582
6582
  .dim-logoTelegram { color: white; background: #229ed9; }
6583
6583
  .dim-logoTelegram svg { width: 21px; height: 21px; }
@@ -6587,7 +6587,7 @@ var CSS9 = String.raw`
6587
6587
  .dim-logoWhatsapp svg { width: 21px; height: 21px; }
6588
6588
  .dim-channelCopy { min-width: 0; display: block; }
6589
6589
  .dim-channelCopy strong { overflow: hidden; color: inherit; font-size: 14px; line-height: 20px; font-weight: 680; text-overflow: ellipsis; white-space: nowrap; }
6590
- .dim-divider { width: 1px; min-height: 520px; background: var(--dsw-alias-line-divider, #eef0f3); }
6590
+ .dim-divider { width: 1px; min-height: 520px; background: var(--dsw-alias-border-l1, #eef0f3); }
6591
6591
  .dim-panel { min-width: 0; container-type: inline-size; }
6592
6592
  .dim-panel .bxf-page, .dim-panel .dxw-page, .dim-panel .ddt-page, .dim-panel .dqq-page, .dim-panel .dwecom-page, .dim-panel .dwa-page { width: 100%; max-width: none; padding: 0 0 24px; }
6593
6593
  .dim-panel .bxf-heading, .dim-panel .dxw-heading, .dim-panel .ddt-heading { justify-content: flex-end; }
@@ -6595,13 +6595,13 @@ var CSS9 = String.raw`
6595
6595
  .dim-panel .dim-bindActions { min-width: 0; display: flex; align-items: center; flex-wrap: nowrap; gap: 8px; }
6596
6596
  .dim-panel .bxf-headingTools .dim-scanButton, .dim-panel .dxw-tools .dim-scanButton, .dim-panel .ddt-tools .dim-scanButton { flex: none; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 10px; border: 1px solid #1677ff; border-radius: 8px; color: #fff; background: #1677ff; box-shadow: none; font: inherit; font-size: 13px; font-weight: 560; white-space: nowrap; }
6597
6597
  .dim-panel .bxf-headingTools .dim-scanButton:hover:not(:disabled), .dim-panel .dxw-tools .dim-scanButton:hover:not(:disabled), .dim-panel .ddt-tools .dim-scanButton:hover:not(:disabled) { border-color: #0958d9; background: #0958d9; }
6598
- .dim-panel .dim-credentialButton { flex: none; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 10px; border: 1px solid #86909c; border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 5%); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
6598
+ .dim-panel .dim-credentialButton { flex: none; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 10px; border: 1px solid #86909c; border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 5%); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
6599
6599
  .dim-panel .dim-actionIcon { width: 15px; height: 15px; flex: 0 0 15px; }
6600
- .dim-panel .dim-credentialButton:hover:not(:disabled) { border-color: #4e5969; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
6601
- .dim-panel .dim-credentialButton[aria-pressed="true"] { border-color: #4e5969; background: var(--dsw-alias-fill-secondary, #f2f3f5); box-shadow: inset 0 0 0 1px rgb(78 89 105 / 8%); }
6602
- .dim-panel .bxf-headingTools .dim-onlineBadge, .dim-panel .dxw-tools .dim-onlineBadge, .dim-panel .ddt-tools .dim-onlineBadge { flex: none; min-height: 30px; display: inline-flex; align-items: center; gap: 0; padding: 0 11px; border: 0; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-fill-secondary, #f2f3f5); font: inherit; font-size: 12px; font-weight: 400; line-height: normal; white-space: nowrap; }
6600
+ .dim-panel .dim-credentialButton:hover:not(:disabled) { border-color: #4e5969; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
6601
+ .dim-panel .dim-credentialButton[aria-pressed="true"] { border-color: #4e5969; background: var(--dsw-alias-bg-module-platform, #f2f3f5); box-shadow: inset 0 0 0 1px rgb(78 89 105 / 8%); }
6602
+ .dim-panel .bxf-headingTools .dim-onlineBadge, .dim-panel .dxw-tools .dim-onlineBadge, .dim-panel .ddt-tools .dim-onlineBadge { flex: none; min-height: 30px; display: inline-flex; align-items: center; gap: 0; padding: 0 11px; border: 0; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font: inherit; font-size: 12px; font-weight: 400; line-height: normal; white-space: nowrap; }
6603
6603
  .dim-panel .dim-channelPage { width: 100%; max-width: none; display: flex; flex-direction: column; gap: 18px; padding: 0 0 24px; color: var(--dsw-alias-label-primary, #1f2329); box-sizing: border-box; }
6604
- .dim-panel .dim-surfaceCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
6604
+ .dim-panel .dim-surfaceCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
6605
6605
  .dim-panel .dim-surfaceCard::before { display: none; }
6606
6606
  .dim-panel .dim-surfaceBody { padding: 24px; }
6607
6607
  .dim-panel .dim-credentialPanel { display: grid; gap: 18px; padding: 20px; }
@@ -6609,7 +6609,7 @@ var CSS9 = String.raw`
6609
6609
  .dim-panel .dim-credentialForm { min-width: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 12px; }
6610
6610
  .dim-panel .dim-credentialFormSingle { grid-template-columns: minmax(0, 1fr); }
6611
6611
  .dim-panel .dim-credentialField { min-width: 0; display: grid; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; font-weight: 560; }
6612
- .dim-panel .dim-credentialField input { width: 100%; min-width: 0; height: 38px; padding: 0 11px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; outline: none; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: 13px ui-monospace, SFMono-Regular, Menlo, monospace; transition: border-color .16s ease, box-shadow .16s ease; }
6612
+ .dim-panel .dim-credentialField input { width: 100%; min-width: 0; height: 38px; padding: 0 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; outline: none; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: 13px ui-monospace, SFMono-Regular, Menlo, monospace; transition: border-color .16s ease, box-shadow .16s ease; }
6613
6613
  .dim-panel .dim-credentialField input:focus { border-color: #4e5969; box-shadow: 0 0 0 3px rgb(78 89 105 / 10%); }
6614
6614
  .dim-panel .dim-credentialField input::placeholder { color: var(--dsw-alias-label-tertiary, #8f959e); font-family: inherit; }
6615
6615
  .dim-panel .dim-credentialError, .dim-panel .dim-credentialActions { grid-column: 1 / -1; }
@@ -6622,7 +6622,7 @@ var CSS9 = String.raw`
6622
6622
  .dim-panel .dim-loadingView { padding: 38px; color: var(--dsw-alias-label-secondary, #646a73); text-align: center; }
6623
6623
  .dim-panel .dim-loadingView h3 { margin: 0 0 7px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 17px; line-height: normal; font-weight: 650; }
6624
6624
  .dim-panel .dim-loadingView p { margin: 0; line-height: 1.6; }
6625
- .dim-panel .dim-spinner { width: 24px; height: 24px; margin: 0 auto 13px; border: 3px solid var(--dsw-alias-line-border, #e6e8eb); border-top-color: #1677ff; border-radius: 50%; animation: dim-spin .8s linear infinite; }
6625
+ .dim-panel .dim-spinner { width: 24px; height: 24px; margin: 0 auto 13px; border: 3px solid var(--dsw-alias-border-l2, #e6e8eb); border-top-color: #1677ff; border-radius: 50%; animation: dim-spin .8s linear infinite; }
6626
6626
  @keyframes dim-spin { to { transform: rotate(360deg); } }
6627
6627
  .dim-panel .dim-emptyView { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
6628
6628
  .dim-panel .dim-emptyCopy { min-width: 0; }
@@ -6632,47 +6632,47 @@ var CSS9 = String.raw`
6632
6632
  .dim-panel .dim-stateLabel { display: inline-flex; align-items: center; gap: 8px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; font-weight: 600; }
6633
6633
  .dim-panel .dim-stateDot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--dsw-alias-label-tertiary, #8f959e); box-shadow: none; }
6634
6634
  .dim-panel .dim-stateDot[data-tone="success"] { background: var(--dsw-alias-state-success-primary, #20a162); }
6635
- .dim-panel .dim-stateDot[data-tone="warning"] { background: var(--dsw-alias-state-warning-primary, #d97706); }
6635
+ .dim-panel .dim-stateDot[data-tone="warning"] { background: var(--dsw-alias-state-warn-primary, #d97706); }
6636
6636
  .dim-panel .dim-stateDot[data-tone="error"] { background: var(--dsw-alias-state-error-primary, #d54941); }
6637
6637
  .dim-panel .dim-viewActions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
6638
- .dim-panel .dim-viewActions .bxf-button, .dim-panel .dim-viewActions .dxw-button, .dim-panel .dim-viewActions .ddt-button { min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); box-shadow: none; font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
6638
+ .dim-panel .dim-viewActions .bxf-button, .dim-panel .dim-viewActions .dxw-button, .dim-panel .dim-viewActions .ddt-button { min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: none; font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
6639
6639
  .dim-panel .dim-viewActions .bxf-button[data-kind="primary"], .dim-panel .dim-viewActions .dxw-button[data-kind="primary"], .dim-panel .dim-viewActions .ddt-button[data-kind="primary"] { border-color: #1677ff; color: #fff; background: #1677ff; box-shadow: none; }
6640
6640
  .dim-panel .dim-viewActions .bxf-button[data-kind="danger"], .dim-panel .dim-viewActions .dxw-button[data-kind="danger"], .dim-panel .dim-viewActions .ddt-button[data-kind="danger"] { color: var(--dsw-alias-state-error-primary, #d54941); }
6641
6641
  .dim-panel .dim-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: start; }
6642
6642
  .dim-panel .dim-qrColumn { width: 100%; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; }
6643
- .dim-panel .dim-qrFrame { position: relative; width: min(270px, 100%); height: auto; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 16px; background: #fff; }
6644
- .dim-panel .dim-qrFrame::before { content: ""; position: absolute; inset: 7px; z-index: 0; border: 1px solid color-mix(in srgb, #1677ff 16%, var(--dsw-alias-line-border, #dfe1e5)); border-radius: 12px; pointer-events: none; }
6643
+ .dim-panel .dim-qrFrame { position: relative; width: min(270px, 100%); height: auto; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 16px; background: #fff; }
6644
+ .dim-panel .dim-qrFrame::before { content: ""; position: absolute; inset: 7px; z-index: 0; border: 1px solid color-mix(in srgb, #1677ff 16%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 12px; pointer-events: none; }
6645
6645
  .dim-panel .dim-qrFrame::after { display: none; }
6646
6646
  .dim-panel .dim-qrFrame img { position: relative; z-index: 1; width: 100%; height: 100%; display: block; object-fit: contain; }
6647
6647
  .dim-panel .dim-qrFallback { position: relative; z-index: 1; display: grid; place-items: center; gap: 8px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 1.5; text-align: center; }
6648
- .dim-panel .dim-qrExpired { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; padding: 20px; color: var(--dsw-alias-label-primary, #1f2329); background: rgb(255 255 255 / 92%); font-size: 15px; line-height: 1.6; font-weight: 650; text-align: center; white-space: pre-line; backdrop-filter: blur(3px); }
6648
+ .dim-panel .dim-qrExpired { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; padding: 20px; color: var(--dsw-static-neutral-bluish-1000, #0f1115); background: rgb(255 255 255 / 92%); font-size: 15px; line-height: 1.6; font-weight: 650; text-align: center; white-space: pre-line; backdrop-filter: blur(3px); }
6649
6649
  .dim-panel .dim-countdown { width: min(270px, 100%); margin: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; }
6650
6650
  .dim-panel .dim-countdownTop { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
6651
6651
  .dim-panel .dim-countdownTop strong { color: var(--dsw-alias-label-primary, #1f2329); font-weight: 650; }
6652
- .dim-panel .dim-progress { height: 4px; overflow: hidden; margin: 0; border-radius: 99px; background: var(--dsw-alias-fill-secondary, #eef0f3); }
6652
+ .dim-panel .dim-progress { height: 4px; overflow: hidden; margin: 0; border-radius: 99px; background: var(--dsw-alias-bg-module-platform, #eef0f3); }
6653
6653
  .dim-panel .dim-progress span { display: block; width: var(--bxf-progress, var(--dxw-progress, var(--ddt-progress, 0%))); height: 100%; border-radius: inherit; background: #1677ff; transition: width .25s linear; }
6654
6654
  .dim-panel .dim-qrCopy { min-width: 0; overflow-wrap: anywhere; }
6655
6655
  .dim-panel .dim-qrCopy h3 { margin: 9px 0 8px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 18px; line-height: 1.35; font-weight: 650; }
6656
6656
  .dim-panel .dim-qrCopy > p { margin: 0; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.65; }
6657
6657
  .dim-panel .dim-steps { margin: 18px 0 16px; padding: 0; list-style: none; counter-reset: dim-step; }
6658
6658
  .dim-panel .dim-steps li { position: relative; min-height: 28px; display: flex; align-items: center; padding: 5px 0 5px 36px; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.5; counter-increment: dim-step; }
6659
- .dim-panel .dim-steps li::before { content: counter(dim-step); position: absolute; left: 0; top: 4px; width: 25px; height: 25px; display: grid; place-items: center; border-radius: 8px; color: #1677ff; background: color-mix(in srgb, #1677ff 10%, white); font-size: 12px; font-weight: 650; }
6659
+ .dim-panel .dim-steps li::before { content: counter(dim-step); position: absolute; left: 0; top: 4px; width: 25px; height: 25px; display: grid; place-items: center; border-radius: 8px; color: #4d93f8; background: color-mix(in srgb, #1677ff 16%, var(--dsw-alias-bg-layer-1, #fff)); font-size: 12px; font-weight: 650; }
6660
6660
  .dim-panel .dim-specialView { padding: 32px; text-align: center; }
6661
- .dim-panel .dim-statusNotice { display: flex; align-items: flex-start; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 22%, white); border-radius: 10px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 6%, white); font-size: 13px; line-height: 1.5; }
6662
- .dim-panel .dim-inlineError { display: flex; align-items: flex-start; flex-direction: column; gap: 10px; padding: 22px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 6%, white); }
6661
+ .dim-panel .dim-statusNotice { display: flex; align-items: flex-start; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 22%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 10px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 8%, var(--dsw-alias-bg-layer-1, #fff)); font-size: 13px; line-height: 1.5; }
6662
+ .dim-panel .dim-inlineError { display: flex; align-items: flex-start; flex-direction: column; gap: 10px; padding: 22px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 8%, var(--dsw-alias-bg-layer-1, #fff)); }
6663
6663
  .dim-panel .dim-inlineError > div { min-width: 0; }
6664
6664
  .dim-panel .dim-inlineError h3 { margin: 0; color: inherit; font-size: 17px; line-height: 1.35; font-weight: 650; }
6665
6665
  .dim-panel .dim-inlineError p { margin: 7px 0 0; color: inherit; line-height: 1.6; }
6666
- .dim-panel .dim-confirm { padding: 18px 24px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
6666
+ .dim-panel .dim-confirm { padding: 18px 24px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
6667
6667
  .dim-panel .dim-confirm strong, .dim-panel .dim-confirm h4 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 14px; line-height: 1.4; font-weight: 650; }
6668
6668
  .dim-panel .dim-confirm p { margin: 7px 0 0; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.6; }
6669
- .dim-panel .dim-cardFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
6669
+ .dim-panel .dim-cardFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
6670
6670
  .dim-panel .dim-cardSummary { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font: inherit; font-size: 12px; font-weight: 400; line-height: normal; }
6671
6671
  .dim-panel .dim-cardActions { flex: none; display: flex; align-items: center; flex-wrap: nowrap; gap: 8px; margin: 0 0 0 auto; }
6672
- .dim-panel .dim-cardActions .dim-cardAction { flex: none; min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
6673
- .dim-panel .dim-cardActions .dim-cardAction:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
6672
+ .dim-panel .dim-cardActions .dim-cardAction { flex: none; min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
6673
+ .dim-panel .dim-cardActions .dim-cardAction:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
6674
6674
  .dim-panel .dim-cardActions .dim-cardAction[data-kind="danger"] { color: var(--dsw-alias-state-error-primary, #d54941); }
6675
- .dim-panel .dim-botCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
6675
+ .dim-panel .dim-botCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
6676
6676
  .dim-panel .dim-botCard::before { display: none; }
6677
6677
  .dim-panel .dim-botCardBody { position: relative; padding: 24px; }
6678
6678
  .dim-panel .dim-botCardTop { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
@@ -6685,10 +6685,10 @@ var CSS9 = String.raw`
6685
6685
  .dim-panel .dim-botCard .dim-botHealth { flex: none; min-height: 0; display: inline-flex; align-items: center; gap: 7px; padding: 0; border: 0; border-radius: 0; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; font: inherit; font-size: 12px; font-weight: 400; line-height: normal; white-space: nowrap; }
6686
6686
  .dim-panel .dim-botCard .dim-healthDot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: #aeb3bb; box-shadow: none; }
6687
6687
  .dim-panel .dim-botCard .dim-healthDot[data-tone="success"] { background: var(--dsw-alias-state-success-primary, #20a162); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dsw-alias-state-success-primary, #20a162) 14%, transparent); }
6688
- .dim-panel .dim-botCard .dim-healthDot[data-tone="warning"] { background: var(--dsw-alias-state-warning-primary, #d97706); }
6688
+ .dim-panel .dim-botCard .dim-healthDot[data-tone="warning"] { background: var(--dsw-alias-state-warn-primary, #d97706); }
6689
6689
  .dim-panel .dim-botCard .dim-healthDot[data-tone="error"] { background: var(--dsw-alias-state-error-primary, #d54941); }
6690
6690
  .dim-panel .dim-botMetrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 20px 0; }
6691
- .dim-panel .dim-botMetric { min-width: 0; padding: 12px; border: 0; border-radius: 9px; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
6691
+ .dim-panel .dim-botMetric { min-width: 0; padding: 12px; border: 0; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
6692
6692
  .dim-panel .dim-botMetric dt { margin: 0; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; font-weight: 400; line-height: normal; }
6693
6693
  .dim-panel .dim-botMetric dd { overflow: hidden; margin: 5px 0 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; font-weight: 400; line-height: normal; text-overflow: ellipsis; white-space: nowrap; }
6694
6694
  .dim-panel .dim-botCard .dim-cardFooter { margin-top: 0; }
package/lib/index.js CHANGED
@@ -64,7 +64,7 @@ ${R}`),f.pop(),`{${K}}`}case"number":return isFinite(Q)?String(Q):r?r(Q):"null";
64
64
  `).trim()}var bm=class{#A;#e;#t=null;#a=null;#s=new Map;#n="";#I=!1;#g=null;constructor({promptRpcId:r,afterSeq:o=-1}){this.#A=r,this.#e=o}get finished(){return this.#I}get answer(){return this.#n.trim()}get reason(){return this.#g}consume(r){let o=null,i=[...r].map(e=>e?.event??e).filter(Boolean).sort((e,a)=>(e.seq??-1)-(a.seq??-1));for(let e of i){let a=e.seq??-1;if(!(a<=this.#e)){if(this.#e=a,e.type==="turn/start"&&(this.#t=e.data?.turn??null),e.type==="user/message"&&e.data?.source?.rpcId===this.#A){this.#a=this.#t;continue}if(this.#a!==null){if(e.type==="turn/end"){if(e.data?.turn!==this.#a)continue;this.#I=!0,this.#g=e.data?.reason??null,this.#t=null;continue}if(e.data?.turn===this.#a){if(e.type==="assistant/chunk"&&e.data?.chunk?.type==="text-delta"){let A=e.data?.step??0,t=e.data.chunk.index??0,s=`${A}:${t}`;this.#s.set(s,(this.#s.get(s)??"")+e.data.chunk.text);let g=`${A}:`,c=[...this.#s.entries()].filter(([l])=>l.startsWith(g)).sort(([l],[C])=>Number(l.split(":")[1])-Number(C.split(":")[1])).map(([,l])=>l).join(`
65
65
  `).trim();c&&c!==this.#n&&(this.#n=c,o={type:"text",text:c});continue}if(e.type==="assistant/message"){let A=d7(e);A&&A!==this.#n&&(this.#n=A,o={type:"text",text:A});continue}e.type==="tool/call"?o={type:"tool",name:e.data?.name??"\u5DE5\u5177"}:e.type==="tool/result"&&(o={type:"status",text:"\u6B63\u5728\u6574\u7406\u7ED3\u679C\u2026"})}}}}return o}},sh=class extends Error{constructor(r,o){super(`${r}: ${o?.message??"unknown Harness RPC error"}`),this.name="HarnessRpcError",this.method=r,this.code=o?.code??"internal",this.details=o?.details??{}}},gh=class{#A;#e;#t;#a;#s;#n;#I=null;constructor({baseUrl:r,workspace:o,agentPreset:i="standard",autostart:e=!1,dshBin:a="dsh",fetchImpl:A=fetch}){this.#A=new URL(r),this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A}async rpc(r,o={},i=3e4,e={}){let a=e.rpcId??`dingtalk-${Jk()}`,A=AbortSignal.timeout(i),t=e.signal?AbortSignal.any([e.signal,A]):A,s=await this.#n(new URL(`/api/${r}`,this.#A),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({type:"client-request",rpcId:a,method:r,payload:o}),signal:t});if(!s.ok)throw new Error(`Harness transport ${r} failed: HTTP ${s.status}`);let g=await s.json();if(g?.type!=="server-response"||g?.rpcId!==a)throw new Error(`Harness returned an invalid response for ${r}`);if(!g.result?.ok)throw new sh(r,g.result?.error);return g.result.value}async health(r={}){return await this.rpc("host.describe",{},5e3,r),!0}async ensureRunning(r={}){try{return await this.health(r)}catch(e){if(!this.#a)throw e}if(!this.#I||this.#I.exitCode!==null){let e=this.#A.port||(this.#A.protocol==="https:"?"443":"80");this.#I=h7(this.#s,["web","--host",this.#A.hostname,"--port",e],{cwd:this.#e,env:process.env,stdio:["ignore","inherit","inherit"]}),this.#I.on("error",a=>{console.error("[dsh-dingtalk] failed to start Harness:",a.message)})}let o=Date.now()+6e4,i;for(;Date.now()<o;){await jk(1e3,r.signal);try{return await this.health(r)}catch(e){i=e}}throw new Error(`Harness did not become ready: ${i?.message??"timeout"}`)}async workspaceId(r={}){let{items:o}=await this.rpc("workspace.list",{},3e4,r),i=o.find(a=>a.path===this.#e);return i?i.workspaceId:(await this.rpc("workspace.create",{path:this.#e},3e4,r)).workspace.workspaceId}async createSession(r={}){await this.ensureRunning(r);let o=await this.workspaceId(r);return(await this.rpc("session.create",{workspaceId:o,agentPreset:this.#t},3e4,r)).sessionId}async sessionExists(r,o={}){try{return await this.rpc("session.history",{sessionId:r,maxMessages:1},3e4,o),!0}catch(i){if(i instanceof sh&&i.code==="session-not-found")return!1;throw i}}async ask(r,o,i={}){typeof i=="number"&&(i={timeoutMs:i});let e=i.timeoutMs??6e5,a=i.signal,A=typeof i.onUpdate=="function"?i.onUpdate:null;await this.ensureRunning({signal:a});let t=await this.rpc("session.history",{sessionId:r,maxMessages:1},3e4,{signal:a}),s=Math.max(-1,...(t.events??[]).map(({event:C})=>C.seq??-1)),g=`dingtalk-${Jk()}`,c=new bm({promptRpcId:g,afterSeq:s});await this.rpc("session.prompt",{sessionId:r,mode:"queue",content:[{type:"text",text:o}],clientTimeZone:Intl.DateTimeFormat().resolvedOptions().timeZone},3e4,{rpcId:g,signal:a});let l=Date.now()+e;for(;Date.now()<l;){await jk(300,a);let C=await this.rpc("session.history",{sessionId:r,maxMessages:50},3e4,{signal:a}),u=c.consume(C.events??[]);if(u&&A)try{await A(u)}catch(Q){console.warn("[dsh-dingtalk] ignored a progress update failure:",Q.message)}if(c.finished){if(c.answer)return c.answer;throw new Error(`Harness turn ended without a text reply${c.reason?` (${JSON.stringify(c.reason)})`:""}`)}}throw new Error(`Harness reply timed out after ${Math.round(e/1e3)} seconds`)}stopManagedProcess(){this.#I?.exitCode===null&&this.#I.kill("SIGTERM")}};import{randomUUID as B7}from"node:crypto";import{mkdir as u7,readFile as Q7,rename as f7,unlink as y7,writeFile as m7}from"node:fs/promises";import{dirname as S7}from"node:path";var ch=Object.freeze({version:1,sessions:{},seenMessageIds:[],pendingSenders:{}});function _t(n){return typeof n=="string"&&n.trim()?n.trim():null}function qk(n){return(_t(n)??"\u9489\u9489\u7528\u6237").slice(0,100)}function D7(n,r){if(!n||typeof n!="object")return null;let o=_t(n.requestId)??_t(r),i=_t(n.staffId),e=_t(n.requestedAt)??_t(n.lastSeenAt),a=_t(n.lastSeenAt)??e;return!o||!i||!e||!a?null:{requestId:o,staffId:i,displayName:qk(n.displayName??n.nick),requestedAt:e,lastSeenAt:a}}function w7(n){if(!n||typeof n!="object")return structuredClone(ch);let r={};if(n.sessions&&typeof n.sessions=="object"&&!Array.isArray(n.sessions))for(let[e,a]of Object.entries(n.sessions)){let A=_t(e),t=_t(a);A&&t&&(r[A]=t)}let o={},i=Array.isArray(n.pendingSenders)?n.pendingSenders.map(e=>[e?.requestId,e]):Object.entries(n.pendingSenders&&typeof n.pendingSenders=="object"?n.pendingSenders:{});for(let[e,a]of i){let A=D7(a,e);if(!A)continue;let t=Object.values(o).find(s=>s.staffId===A.staffId);(!t||t.lastSeenAt<A.lastSeenAt)&&(t&&delete o[t.requestId],o[A.requestId]=A)}return{version:1,sessions:r,seenMessageIds:Array.isArray(n.seenMessageIds)?[...new Set(n.seenMessageIds.map(_t).filter(Boolean))].slice(-1e3):[],pendingSenders:o}}var Ih=class{#A;#e=structuredClone(ch);#t=Promise.resolve();#a;#s;constructor(r,{idFactory:o=B7,now:i=()=>new Date().toISOString()}={}){if(!_t(r))throw new TypeError("state path is required");if(typeof o!="function"||typeof i!="function")throw new TypeError("idFactory and now must be functions");this.#A=r,this.#a=o,this.#s=i}async load(){try{this.#e=w7(JSON.parse(await Q7(this.#A,"utf8")))}catch(r){if(r?.code!=="ENOENT")throw r;this.#e=structuredClone(ch),await this.#n()}return this}sessionFor(r){return this.#e.sessions[r]??null}async setSession(r,o){let i=_t(r),e=_t(o);if(!i||!e)throw new TypeError("key and sessionId are required");this.#e.sessions[i]=e,await this.#n()}async clearSession(r){let o=_t(r);!o||!(o in this.#e.sessions)||(delete this.#e.sessions[o],await this.#n())}hasSeen(r){let o=_t(r);return!!(o&&this.#e.seenMessageIds.includes(o))}async markSeen(r){let o=_t(r);if(!o)throw new TypeError("messageId is required");this.hasSeen(o)||(this.#e.seenMessageIds.push(o),this.#e.seenMessageIds.length>1e3&&this.#e.seenMessageIds.splice(0,this.#e.seenMessageIds.length-1e3),await this.#n())}pendingSenders(){return Object.values(this.#e.pendingSenders).sort((r,o)=>r.requestedAt.localeCompare(o.requestedAt)).map(r=>structuredClone(r))}pendingSender(r){let o=_t(r),i=o?this.#e.pendingSenders[o]:null;return i?structuredClone(i):null}async recordPendingSender(r,o,i){let e=r&&typeof r=="object"?r:{staffId:r,displayName:o,lastSeenAt:i},a=_t(e.staffId);if(!a)throw new TypeError("staffId is required");let A=_t(e.lastSeenAt)??_t(e.requestedAt)??this.#s(),t=Object.values(this.#e.pendingSenders).find(g=>g.staffId===a),s={requestId:t?.requestId??`ding_sender_${this.#a()}`,staffId:a,displayName:qk(e.displayName??e.nick??o),requestedAt:t?.requestedAt??A,lastSeenAt:A};return this.#e.pendingSenders[s.requestId]=s,await this.#n(),structuredClone(s)}async removePendingSender(r){let o=_t(r);return!o||!this.#e.pendingSenders[o]?!1:(delete this.#e.pendingSenders[o],await this.#n(),!0)}async removePendingSenderByStaffId(r){let o=_t(r),i=o?Object.values(this.#e.pendingSenders).find(e=>e.staffId===o):null;return i?this.removePendingSender(i.requestId):!1}snapshot(){return structuredClone(this.#e)}async remove(){await this.#t;try{await y7(this.#A)}catch(r){if(r?.code!=="ENOENT")throw r}this.#e=structuredClone(ch)}async#n(){let r=`${JSON.stringify(this.#e,null,2)}
66
66
  `,o=this.#t.then(async()=>{await u7(S7(this.#A),{recursive:!0,mode:448});let i=`${this.#A}.tmp`;await m7(i,r,{encoding:"utf8",mode:384}),await f7(i,this.#A)});this.#t=o.then(()=>{},()=>{}),await o}};var Vk=Object.freeze([250,1e3,3e3,5e3,1e4,3e4]);function O7(n){if(!Array.isArray(n)||n.length===0)return[...Vk];let r=n.filter(o=>Number.isFinite(o)&&o>=0);return r.length>0?r:[...Vk]}var lh=class{#A;#e;#t;#a;#s;#n;#I;#g=null;#o=null;#r=0;#i=!1;#c=!1;#l;#E;constructor({controller:r,harness:o,logger:i=console,retryDelaysMs:e,healthyIntervalMs:a=15e3,setTimeoutImpl:A=setTimeout,clearTimeoutImpl:t=clearTimeout}){if(!r||typeof r.initialize!="function"||typeof r.status!="function")throw new TypeError("ConnectionSupervisor requires a controller");if(!o||typeof o.ensureRunning!="function")throw new TypeError("ConnectionSupervisor requires a Harness client");this.#A=r,this.#e=o,this.#t=i,this.#a=O7(e),this.#s=Number.isFinite(a)&&a>=0?a:15e3,this.#n=A,this.#I=t,this.#l=new Promise(s=>{this.#E=s})}get ready(){return this.#l}start(){return this.#c||this.#i?this:(this.#c=!0,this.#C(0),this)}async close(){this.#i||(this.#i=!0,this.#g!==null&&this.#I(this.#g),this.#g=null,await this.#o?.catch(()=>{}),this.#E?.(null),this.#E=null)}#C(r){this.#i||(this.#g=this.#n(()=>{this.#g=null,this.#p()},r),this.#g?.unref?.())}async#p(){if(this.#i||this.#o)return;let r=this.#h();this.#o=r;try{await r}finally{this.#o===r&&(this.#o=null)}}async#h(){try{if(await this.#e.ensureRunning(),this.#i)return;let r=await this.#A.initialize();if(this.#i)return;this.#E?.(r),this.#E=null;let{configured:o,connected:i}=r.totals;if(i<o){let e=this.#a[Math.min(this.#r,this.#a.length-1)];this.#r+=1,this.#t.warn?.(`[dsh-dingtalk] ${i}/${o} bots connected; retrying in ${e}ms`),this.#C(e);return}this.#r=0,this.#C(this.#s)}catch(r){if(this.#i)return;let o=this.#a[Math.min(this.#r,this.#a.length-1)];this.#r+=1,this.#t.warn?.(`[dsh-dingtalk] connection reconciliation failed; retrying in ${o}ms`,r),this.#C(o)}}};function _m(n){return new lh(n)}function _7(n,r){if(r!==void 0)return new URL(r);let o=n?.port;if(!Number.isInteger(o)||o<1||o>65535)throw new Error("dsh-dingtalk requires an initialized DSH webServer port");return new URL(`http://127.0.0.1:${o}`)}function N7(n){let r=Wg(n.dshHome??process.env.DSH_HOME??Eh(b7(),".dsh")),o=Wg(n.dataDir??Eh(r,"integrations","dsh-dingtalk"));return{root:o,config:Wg(n.configPath??Eh(o,"config.json")),bots:Wg(n.botsDir??Eh(o,"bots"))}}async function Nm(n,r={},o={}){if(!n?.credentials)throw new TypeError("dsh-dingtalk requires ctx.credentials");if(!n?.webServer)throw new TypeError("dsh-dingtalk requires ctx.webServer");let i=o.ConfigStore??Ah,e=o.DeviceAuth??ah,a=o.StateStore??Ih,A=o.HarnessClient??gh,t=o.Controller??Ml,s=o.Runtime??Tl,g=o.createConnectionSupervisor??_m,c=typeof n.logger=="function"?n.logger("dsh-dingtalk"):n.logger??console,l=N7(r),C=await new i(l.config).load(),u=o.deviceAuth??new e({baseUrl:r.registrationBaseUrl}),Q=new Map,f=k=>Wg(l.bots,k,"state.json"),y=async k=>{let U=Q.get(k);return U||(U=await new a(f(k)).load(),Q.set(k,U)),U},m=new A({baseUrl:_7(n.webServer,r.harnessBaseUrl),workspace:Wg(r.workspace??process.cwd()),agentPreset:r.agentPreset??"standard",autostart:!1,dshBin:r.dshBin??"dsh"}),R=new t({deviceAuth:u,credentials:n.credentials,configStore:C,logger:c,createRuntime:async({botId:k,config:U,clientSecret:K})=>{let F=await y(k);return new s({config:U,clientSecret:K,harness:m,state:F,replyTimeoutMs:r.replyTimeoutMs??6e5,maxMessageChars:r.maxMessageChars??4e3,connectTimeoutMs:r.connectTimeoutMs??15e3,logger:{error:(...q)=>c.error?.(`[${k}]`,...q),warn:(...q)=>c.warn?.(`[${k}]`,...q),info:(...q)=>c.info?.(`[${k}]`,...q),debug:(...q)=>c.debug?.(`[${k}]`,...q)}})},deleteState:async({botId:k})=>{let U=Q.get(k);if(Q.delete(k),U&&typeof U.remove=="function"){await U.remove();return}try{await M7(f(k))}catch(K){if(K?.code!=="ENOENT")throw K}}}),T=g({controller:R,harness:m,logger:c,retryDelaysMs:r.retryDelaysMs,healthyIntervalMs:r.healthyIntervalMs}).start();return{controller:R,ready:T.ready,async close(){await T.close(),await R.close(),m.stopManagedProcess()}}}import R7 from"qrcode";var T7=new Set(["loopback","trusted-host"]);function za(n){if(n===void 0)return"loopback";if(T7.has(n))return n;throw new TypeError('dsh-im rpcAuthority must be "loopback" or "trusted-host"')}var Wk="/dingtalk",Vt=Object.freeze({status:"connection.status",beginProvisioning:"provision.begin",pollProvisioning:"provision.poll",cancelProvisioning:"provision.cancel",bindCredentials:"bot.bind-credentials",reconnectBot:"bot.reconnect",deleteBot:"bot.delete",approveSender:"bot.sender.approve",revokeSender:"bot.sender.revoke"}),Zk=Object.freeze(Object.values(Vt)),k7=new Set(["clientSecret","client_secret","deviceCode","device_code","secretRef","staffId","senderStaffId","verificationUrl","verificationUri","userCode"]);function Rm(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function cn(n,r){return Rm(n)&&Object.keys(n).every(o=>r.includes(o))}function Ss(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{1,128}$/.test(n)}function zk(n,r){return typeof n=="string"&&n.trim().length>0&&n.length<=r}function v7(n,r){return Rm(r)?n===Vt.status?cn(r,[])?null:"connection.status does not accept fields.":n===Vt.beginProvisioning?cn(r,["locale"])&&(r.locale===void 0||r.locale==="zh-CN")?null:"provision.begin received unsupported fields.":[Vt.pollProvisioning,Vt.cancelProvisioning].includes(n)?cn(r,["attemptId"])&&Ss(r.attemptId)?null:`${n} requires an attemptId.`:n===Vt.bindCredentials?cn(r,["clientId","clientSecret"])&&zk(r.clientId,256)&&zk(r.clientSecret,1024)?null:"bot.bind-credentials requires Client ID and Client Secret.":n===Vt.reconnectBot?cn(r,["botId"])&&Ss(r.botId)?null:"bot.reconnect requires a botId.":n===Vt.deleteBot?cn(r,["botId","confirm"])&&Ss(r.botId)&&r.confirm===!0?null:"bot.delete requires a botId and confirm=true.":n===Vt.approveSender?cn(r,["botId","requestId","confirm"])&&Ss(r.botId)&&Ss(r.requestId)&&r.confirm===!0?null:"bot.sender.approve requires botId, requestId, and confirm=true.":n===Vt.revokeSender?cn(r,["botId","senderKey","confirm"])&&Ss(r.botId)&&Ss(r.senderKey)&&r.confirm===!0?null:"bot.sender.revoke requires botId, senderKey, and confirm=true.":"Unknown DingTalk endpoint.":"Payload must be an object."}function Ch(n){return{ok:!1,error:{code:"bad-request",message:n}}}function ph(){return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}}function P7(){return{ok:!1,error:{code:"dingtalk-operation-failed",message:"\u9489\u9489\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}}function Xg(n){if(Array.isArray(n))return n.map(Xg);if(!Rm(n))return n;let r={};for(let[o,i]of Object.entries(n))k7.has(o)||(r[o]=Xg(i));return r}async function G7(n){return R7.toDataURL(n,{type:"image/png",errorCorrectionLevel:"M",margin:2,width:320})}async function Tm(n,r){return!n||typeof n.verificationUrl!="string"?Xg(n):Xg({...n,qrCodeDataUrl:await r(n.verificationUrl)})}async function Zg(n,r){let o=structuredClone(n);return o?.provisioning&&(o.provisioning=await Tm(o.provisioning,r)),Xg(o)}function F7(n){for(let r of["status","startProvisioning","registrationStatus","cancelProvisioning","bindCredentials","reconnectBot","deleteBot","approveSender","revokeSender"])if(typeof n?.[r]!="function")throw new TypeError(`A complete DingTalk controller is required (${r})`)}function Xk(n,{encodeQr:r=G7}={}){F7(n);let o=new Map,i=e=>{let a=o.get(e);return a||(o.size>=16&&o.delete(o.keys().next().value),a=Promise.resolve().then(()=>r(e)),o.set(e,a)),a};return async(e,a,A)=>{if(A?.aborted)return ph();if(!Zk.includes(e))return Ch("Unknown DingTalk endpoint.");let t=v7(e,a);if(t)return Ch(t);try{let s;if(e===Vt.status)s=await Zg(await n.status(),i);else if(e===Vt.beginProvisioning){let g=await n.startProvisioning({signal:A});if(A?.aborted)return await n.cancelProvisioning(g.attemptId),ph();s=await Tm(g,i)}else if(e===Vt.pollProvisioning){let g=await n.registrationStatus(a.attemptId);if(!g)return Ch("The provisioning attempt no longer exists.");s=await Tm(g,i)}else if(e===Vt.cancelProvisioning){if(s=await n.cancelProvisioning(a.attemptId),!s)return Ch("The provisioning attempt no longer exists.");s=Xg(s)}else e===Vt.bindCredentials?s=await Zg(await n.bindCredentials(a),i):e===Vt.reconnectBot?s=await Zg(await n.reconnectBot(a.botId),i):e===Vt.deleteBot?s=await Zg(await n.deleteBot(a.botId),i):e===Vt.approveSender?s=await Zg(await n.approveSender(a.botId,a.requestId),i):s=await Zg(await n.revokeSender(a.botId,a.senderKey),i);return A?.aborted?ph():{ok:!0,value:s}}catch{return A?.aborted?ph():P7()}}}function hh(n,r,o,i){if(!n?.connection?.rpc||typeof n.connection.rpc.handle!="function")throw new TypeError("DSH Host Connection RPC is required");return n.connection.rpc.handle(Wk,Xk(r,o),{authority:za(i)})}async function $k(n,r={}){if(r?.controller)return hh(n,r.controller,r.rpcOptions,r.rpcAuthority);let o=await Nm(n,r,r.internals),i=hh(n,o.controller,r.rpcOptions,r.rpcAuthority);return n.effect(()=>async()=>{await o.close()},"dsh-dingtalk: close bot connections"),i}import{createHash as L7}from"node:crypto";import{mkdir as U7,readFile as H7,rename as K7,unlink as Y7,writeFile as x7}from"node:fs/promises";import{dirname as J7}from"node:path";var km=Object.freeze({version:1,bots:Object.freeze([])});function mo(n){return typeof n=="string"&&n.trim()?n.trim():null}function ev(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Rl(n,{botPrefix:r,tokenRefPrefix:o}){let i=mo(n);if(!i)throw new TypeError("platformId is required");let e=L7("sha256").update(i).digest("hex").slice(0,24);return{botId:`${r}_${e}`,tokenRef:`${o}_${e.toUpperCase()}`}}function dh(n,r){let o=mo(n)??"";return o.length<=10?o?`${o.slice(0,3)}\u2022\u2022\u2022`:r:`${o.slice(0,6)}\u2022\u2022\u2022\u2022${o.slice(-4)}`}var $g=class{#A;#e;#t;#a;#s;#n;#I=km;#g=Promise.resolve();constructor(r,{channel:o,botPrefix:i,tokenRefPrefix:e}){this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=new RegExp(`^${ev(i)}_[a-f0-9]{24}$`),this.#n=new RegExp(`^${ev(e)}_[A-F0-9]{24}$`)}async load(){try{let r=this.#r(JSON.parse(await H7(this.#A,"utf8")));if(!r)throw new Error(`dsh-im ${this.#e} config contains invalid bot data`);this.#I=r}catch(r){if(r?.code!=="ENOENT")throw r;this.#I=km}return this}list(){return structuredClone(this.#I.bots)}get(r){let o=this.#I.bots.find(i=>i.botId===r);return o?structuredClone(o):null}getByPlatformId(r){let o=this.#I.bots.find(i=>i.platformId===r);return o?structuredClone(o):null}async save(r){let o=this.#o(r);if(!o)throw new Error(`Refusing to persist incomplete ${this.#e} bot data`);return this.#i(i=>{let e=i.find(t=>t.platformId===o.platformId&&t.botId!==o.botId),a=i.find(t=>t.tokenRef===o.tokenRef&&t.botId!==o.botId);if(e||a)throw new Error(`Duplicate ${this.#e} bot identity`);let A=i.findIndex(t=>t.botId===o.botId);return A===-1?i.push(o):i[A]=o,structuredClone(o)})}async remove(r){if(!this.#s.test(r))throw new TypeError(`Invalid ${this.#e} bot id`);return this.#i(o=>{let i=o.findIndex(a=>a.botId===r);if(i===-1)return null;let[e]=o.splice(i,1);return structuredClone(e)})}async clear(){let r=this.#g.then(async()=>{try{await Y7(this.#A)}catch(o){if(o?.code!=="ENOENT")throw o}this.#I=km});this.#g=r.then(()=>{},()=>{}),await r}#o(r){if(!r||typeof r!="object")return null;let o=mo(r.platformId),i=mo(r.botId),e=mo(r.tokenRef),a=mo(r.name);if(!o||!i||!e||!a||!this.#s.test(i)||!this.#n.test(e))return null;let A=Rl(o,{botPrefix:this.#t,tokenRefPrefix:this.#a});return A.botId!==i||A.tokenRef!==e?null:Object.freeze({botId:i,platformId:o,tokenRef:e,name:a,username:mo(r.username),createdAt:mo(r.createdAt)??new Date().toISOString(),connectedAt:mo(r.connectedAt)})}#r(r){if(!r||r.version!==1||!Array.isArray(r.bots))return null;let o=r.bots.map(A=>this.#o(A));if(o.some(A=>A===null))return null;let i=new Set,e=new Set,a=new Set;for(let A of o){if(i.has(A.botId)||e.has(A.platformId)||a.has(A.tokenRef))return null;i.add(A.botId),e.add(A.platformId),a.add(A.tokenRef)}return Object.freeze({version:1,bots:Object.freeze(o)})}async#i(r){let o,i=this.#g.then(async()=>{let e=[...this.#I.bots];o=r(e);let a=Object.freeze({version:1,bots:Object.freeze(e)});await this.#c(a),this.#I=a});return this.#g=i.then(()=>{},()=>{}),await i,o}async#c(r){await U7(J7(this.#A),{recursive:!0,mode:448});let o=`${this.#A}.tmp`;await x7(o,`${JSON.stringify(r,null,2)}
67
- `,{encoding:"utf8",mode:384}),await K7(o,this.#A)}};var Av=Object.freeze({botPrefix:"discord",tokenRefPrefix:"DSH_DISCORD_BOT_TOKEN"});function tv(n){return Rl(n,Av)}function av(n){return dh(n,"Discord\u673A\u5668\u4EBA")}var Bh=class extends $g{constructor(r){super(r,{channel:"Discord",...Av})}};function kl(n){return typeof n=="string"&&n.trim()?n.trim():null}function uh(n,r){return Object.freeze({code:n,message:r})}var ec=class{#A;#e;#t;#a;#s;#n;#I;#g;#o;#r=new Map;#i=new Map;#c=new Map;#l=0;#E=!1;constructor({descriptor:r,credentials:o,configStore:i,inspectToken:e,deriveIdentity:a,maskPlatformId:A,createRuntime:t,deleteState:s=async()=>{},logger:g=console}){if(!r?.key||!r?.label||!r?.connectionLabel)throw new TypeError("TokenBotController requires a channel descriptor");if(!o||typeof o.resolve!="function"||typeof o.set!="function"||typeof o.unset!="function")throw new TypeError(`${r.label} requires the DSH credential provider`);if(!i||typeof i.list!="function"||typeof i.save!="function"||typeof i.remove!="function")throw new TypeError(`${r.label} requires a config store`);if(typeof e!="function"||typeof a!="function"||typeof A!="function"||typeof t!="function")throw new TypeError(`${r.label} controller dependencies are incomplete`);this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t,this.#g=s,this.#o=g}async initialize(){if(this.#E)return this.status();for(let r of this.#t.list())await this.#u(r.botId,async()=>{if(this.#E||this.#r.get(r.botId)?.status?.ready)return;let o=await this.#h(r.tokenRef);if(!o){this.#i.set(r.botId,uh("missing-token",`${this.#A.label}\u673A\u5668\u4EBA\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u79FB\u9664\u540E\u91CD\u65B0\u63A5\u5165\u3002`));return}try{await this.#C(r,o),this.#i.delete(r.botId)}catch(i){this.#i.set(r.botId,uh("connection-failed",`${this.#A.label}\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002`)),this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${r.botId} failed to initialize:`,i)}finally{this.#B()}});return this.status()}async bindCredentials({token:r}={}){if(this.#E)throw new Error(`${this.#A.label} controller is closed`);let o=kl(r);if(!o)throw new TypeError(`${this.#A.label} Bot Token is required`);let i=await this.#a(o),e=kl(i?.platformId),a=kl(i?.name);if(!e||!a)throw new Error(`${this.#A.label} returned an invalid bot identity`);let A=this.#s(e);return await this.#u(A.botId,async()=>{if(this.#E)throw new Error(`${this.#A.label} controller is closed`);let t=this.#t.getByPlatformId(e),s=await this.#e.resolve(A.tokenRef).catch(()=>{}),g={botId:A.botId,platformId:e,tokenRef:A.tokenRef,name:a,username:kl(i.username),createdAt:t?.createdAt??new Date().toISOString(),connectedAt:new Date().toISOString()};await this.#e.set(A.tokenRef,o);try{await this.#t.save(g)}catch(c){throw await this.#d(A.tokenRef,s),c}try{await this.#C(g,o),this.#i.delete(A.botId)}catch(c){this.#i.set(A.botId,uh("connection-failed",`${this.#A.label}\u673A\u5668\u4EBA\u5DF2\u63A5\u5165\uFF0C\u6D88\u606F\u8FDE\u63A5\u6682\u672A\u5C31\u7EEA\u3002`)),this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${A.botId} credential connection failed:`,c)}this.#B()}),this.status()}async reconnectBot(r){let o=this.#t.get(r);if(!o)throw new Error(`Unknown ${this.#A.label} bot`);return await this.#u(r,async()=>{let i=await this.#h(o.tokenRef);if(!i)throw new Error(`${this.#A.label} bot token is missing`);try{await this.#C(o,i),this.#i.delete(r)}catch(e){throw this.#i.set(r,uh("connection-failed",`${this.#A.label}\u8FDE\u63A5\u4ECD\u672A\u5C31\u7EEA\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`)),e}finally{this.#B()}}),this.status()}async deleteBot(r){let o=this.#t.get(r);if(!o)throw new Error(`Unknown ${this.#A.label} bot`);return await this.#u(r,async()=>{let i=await this.#e.resolve(o.tokenRef).catch(()=>{});await this.#p(r);try{await this.#e.unset(o.tokenRef),await this.#t.remove(r)}catch(e){throw i?.value&&(await this.#e.set(o.tokenRef,i.value).catch(()=>{}),await this.#C(o,i.value).catch(()=>{})),new Error(`Unable to remove the ${this.#A.label} bot safely.`,{cause:e})}await this.#g({botId:r,config:o}).catch(e=>{this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${r} state cleanup failed:`,e)}),this.#i.delete(r),this.#B()}),this.status()}status(){let r=this.#t.list().map(i=>{let e=this.#r.get(i.botId)?.status??null,a=e?.ready===!0&&e.connectionState==="connected"&&e.harnessReachable===!0,A=a?"connected":e?.connectionState==="connecting"?"connecting":this.#i.has(i.botId)||e?.connectionState==="failed"?"error":"offline";return{botId:i.botId,state:A,connected:a,configured:!0,bot:{name:i.name,username:i.username,idMasked:this.#n(i.platformId)},health:{status:a?"healthy":A==="error"?"error":"offline",summary:a?`${this.#A.label}${this.#A.connectionLabel}\u8FD0\u884C\u6B63\u5E38`:A==="error"?`${this.#A.label}\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5`:`${this.#A.label}\u8FDE\u63A5\u5F53\u524D\u79BB\u7EBF`,lastCheckedAt:e?.lastCheckedAt??null,lastConnectedAt:e?.lastConnectedAt??null},stats:{messagesReceived:e?.messagesReceived??0,messagesReplied:e?.messagesReplied??0},error:structuredClone(this.#i.get(i.botId)??null)}}),o=r.filter(i=>i.connected).length;return{schemaVersion:1,revision:this.#l,state:r.length===0?"disconnected":o===r.length?"connected":o>0?"degraded":"offline",bots:r,totals:{configured:r.length,connected:o}}}async close(){this.#E||(this.#E=!0,await Promise.allSettled([...this.#c.values()]),await Promise.allSettled([...this.#r.keys()].map(r=>this.#p(r))))}async#C(r,o){if(this.#E)throw new Error(`${this.#A.label} controller is closed`);if(await this.#p(r.botId),this.#E)throw new Error(`${this.#A.label} controller is closed`);let i=await this.#I({botId:r.botId,config:r,token:o});if(!i||typeof i.start!="function"||typeof i.stop!="function")throw new TypeError(`createRuntime returned an invalid ${this.#A.label} runtime`);this.#r.set(r.botId,i);try{await i.start()}catch(e){throw await i.stop().catch(()=>{}),this.#r.delete(r.botId),e}}async#p(r){let o=this.#r.get(r);this.#r.delete(r),await o?.stop().catch(i=>{this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${r} failed to stop cleanly:`,i)})}async#h(r){let o=await this.#e.resolve(r).catch(()=>{});return kl(o?.value)}async#d(r,o){o?.value?await this.#e.set(r,o.value).catch(()=>{}):await this.#e.unset(r).catch(()=>{})}#u(r,o){let a=(this.#c.get(r)??Promise.resolve()).catch(()=>{}).then(o).finally(()=>{this.#c.get(r)===a&&this.#c.delete(r)});return this.#c.set(r,a),a}#B(){this.#l+=1}};var j7="https://discord.com/api/v10/";function vl(n){return typeof n=="string"&&n.trim()?n.trim():null}function q7(n,r){let o=AbortSignal.timeout(r);return n?AbortSignal.any([n,o]):o}function V7(n,r){return new Promise((o,i)=>{if(r?.aborted){i(r.reason??new DOMException("Aborted","AbortError"));return}let e=setTimeout(o,n);e?.unref?.(),r?.addEventListener("abort",()=>{clearTimeout(e),i(r.reason??new DOMException("Aborted","AbortError"))},{once:!0})})}function Ac(n,r){let o=vl(n);if(!o||!/^\d{5,30}$/.test(o))throw new TypeError(`Invalid Discord ${r}`);return o}function z7(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{20,}$/.test(n.trim())}var Pl=class{#A;#e;#t;constructor({token:r,fetchImpl:o=fetch,baseUrl:i=j7}){if(!z7(r))throw new TypeError("Discord Bot Token is invalid");if(typeof o!="function")throw new TypeError("DiscordApi requires fetch");this.#A=r.trim(),this.#e=o,this.#t=new URL(i)}getCurrentUser(r={}){return this.#a("users/@me",{...r,method:"GET"})}getGatewayBot(r={}){return this.#a("gateway/bot",{...r,method:"GET"})}createMessage({channelId:r,content:o,replyToMessageId:i,signal:e}){return this.#a(`channels/${Ac(r,"channel id")}/messages`,{method:"POST",signal:e,body:{content:o,allowed_mentions:{parse:[],replied_user:!1},...i?{message_reference:{message_id:Ac(i,"message id"),channel_id:Ac(r,"channel id"),fail_if_not_exists:!1}}:{}}})}editMessage({channelId:r,messageId:o,content:i,signal:e}){return this.#a(`channels/${Ac(r,"channel id")}/messages/${Ac(o,"message id")}`,{method:"PATCH",signal:e,body:{content:i,allowed_mentions:{parse:[],replied_user:!1}}})}sendTyping({channelId:r,signal:o}){return this.#a(`channels/${Ac(r,"channel id")}/typing`,{method:"POST",signal:o,expectBody:!1})}async#a(r,{method:o,body:i,signal:e,timeoutMs:a=15e3,expectBody:A=!0,retry:t=!0}){let s;try{s=await this.#e(new URL(r,this.#t),{method:o,headers:{authorization:`Bot ${this.#A}`,"content-type":"application/json","user-agent":"DeepSeek-Harness-dsh-im (https://github.com/xmanrui/dsh-im, 0.2.1)"},...i===void 0?{}:{body:JSON.stringify(i)},signal:q7(e,a),redirect:"error"})}catch(c){throw c?.name==="AbortError"||c?.name==="TimeoutError"?c:new Error(`Discord ${o} transport failed`)}let g=null;if(A||s.status===429||!s.ok)try{g=await s.json()}catch{if(A)throw new Error(`Discord ${o} returned invalid JSON`)}if(s.status===429&&t){let c=Math.min(1e4,Math.max(50,Number(g?.retry_after)*1e3||1e3));return await V7(c,e),this.#a(r,{method:o,body:i,signal:e,timeoutMs:a,expectBody:A,retry:!1})}if(!s.ok){let c=new Error(vl(g?.message)??`Discord API failed with HTTP ${s.status}`);throw c.code=`discord-${s.status}`,c}return A?g:null}};async function rv(n,r={}){let i=await new Pl({token:n,...r}).getCurrentUser();if(!i?.id||i?.bot!==!0)throw new Error("Discord token does not belong to a bot");return{platformId:String(i.id),name:vl(i.global_name)??vl(i.username)??"Discord\u673A\u5668\u4EBA",username:vl(i.username)}}function Qh(n){return typeof n=="string"?n.trim():""}function _i(){return{messagesReceived:0,messagesReplied:0,messagesRejected:0,lastMessageAt:null,lastReplyAt:null,lastRejectedAt:null,lastError:null}}var In=class{#A;#e;#t;#a;#s;#n;#I;#g=new Map;constructor({descriptor:r,bot:o,harness:i,state:e,status:a=_i(),logger:A=console,replyTimeoutMs:t=6e5}){if(!r?.key||!r?.label)throw new TypeError("A channel descriptor is required");if(!o||typeof o.sendText!="function")throw new TypeError("A bot client is required");if(!i||!e)throw new TypeError("Harness client and state store are required");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t}get status(){return structuredClone(this.#s)}accept(r){let o=Qh(r?.conversationId),i=r?.kind==="group"?"group":"direct",e=`${i}:${o}`,A=(this.#g.get(e)??Promise.resolve()).catch(()=>{}).then(()=>this.#o({...r,kind:i,conversationId:o})).finally(()=>{this.#g.get(e)===A&&this.#g.delete(e)});return this.#g.set(e,A),A}async waitForIdle(){await Promise.allSettled([...this.#g.values()])}async#o(r){let o=Qh(r.messageId),i=Qh(r.senderId);if(!o||!i||!r.conversationId||r.senderIsBot===!0||this.#a.hasSeen(o))return;if(this.#s.messagesReceived+=1,this.#s.lastMessageAt=new Date().toISOString(),r.kind==="group"&&r.addressed!==!0){this.#s.messagesRejected+=1,this.#s.lastRejectedAt=new Date().toISOString();return}let e=r.replyTarget,a=Qh(r.content);try{if(!a){await this.#e.sendText(e,"\u76EE\u524D\u4EC5\u652F\u6301\u6587\u5B57\u6D88\u606F\u3002"),await this.#a.markSeen(o);return}let A=a.toLowerCase();if(A==="/help"){await this.#e.sendText(e,[`${this.#A.label}\u673A\u5668\u4EBA\u5DF2\u8FDE\u63A5 DeepSeek Harness\u3002`,"","\u76F4\u63A5\u53D1\u9001\u6587\u5B57\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002","/new \u5F00\u542F\u4E00\u4E2A\u5168\u65B0\u4F1A\u8BDD","/status \u68C0\u67E5\u8FDE\u63A5\u72B6\u6001","/help \u663E\u793A\u672C\u5E2E\u52A9"].join(`
67
+ `,{encoding:"utf8",mode:384}),await K7(o,this.#A)}};var Av=Object.freeze({botPrefix:"discord",tokenRefPrefix:"DSH_DISCORD_BOT_TOKEN"});function tv(n){return Rl(n,Av)}function av(n){return dh(n,"Discord\u673A\u5668\u4EBA")}var Bh=class extends $g{constructor(r){super(r,{channel:"Discord",...Av})}};function kl(n){return typeof n=="string"&&n.trim()?n.trim():null}function uh(n,r){return Object.freeze({code:n,message:r})}var ec=class{#A;#e;#t;#a;#s;#n;#I;#g;#o;#r=new Map;#i=new Map;#c=new Map;#l=0;#E=!1;constructor({descriptor:r,credentials:o,configStore:i,inspectToken:e,deriveIdentity:a,maskPlatformId:A,createRuntime:t,deleteState:s=async()=>{},logger:g=console}){if(!r?.key||!r?.label||!r?.connectionLabel)throw new TypeError("TokenBotController requires a channel descriptor");if(!o||typeof o.resolve!="function"||typeof o.set!="function"||typeof o.unset!="function")throw new TypeError(`${r.label} requires the DSH credential provider`);if(!i||typeof i.list!="function"||typeof i.save!="function"||typeof i.remove!="function")throw new TypeError(`${r.label} requires a config store`);if(typeof e!="function"||typeof a!="function"||typeof A!="function"||typeof t!="function")throw new TypeError(`${r.label} controller dependencies are incomplete`);this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t,this.#g=s,this.#o=g}async initialize(){if(this.#E)return this.status();for(let r of this.#t.list())await this.#u(r.botId,async()=>{if(this.#E||this.#r.get(r.botId)?.status?.ready)return;let o=await this.#h(r.tokenRef);if(!o){this.#i.set(r.botId,uh("missing-token",`${this.#A.label}\u673A\u5668\u4EBA\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u79FB\u9664\u540E\u91CD\u65B0\u63A5\u5165\u3002`));return}try{await this.#C(r,o),this.#i.delete(r.botId)}catch(i){this.#i.set(r.botId,uh("connection-failed",`${this.#A.label}\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002`)),this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${r.botId} failed to initialize:`,i)}finally{this.#B()}});return this.status()}async bindCredentials({token:r}={}){if(this.#E)throw new Error(`${this.#A.label} controller is closed`);let o=kl(r);if(!o)throw new TypeError(`${this.#A.label} Bot Token is required`);let i=await this.#a(o),e=kl(i?.platformId),a=kl(i?.name);if(!e||!a)throw new Error(`${this.#A.label} returned an invalid bot identity`);let A=this.#s(e);return await this.#u(A.botId,async()=>{if(this.#E)throw new Error(`${this.#A.label} controller is closed`);let t=this.#t.getByPlatformId(e),s=await this.#e.resolve(A.tokenRef).catch(()=>{}),g={botId:A.botId,platformId:e,tokenRef:A.tokenRef,name:a,username:kl(i.username),createdAt:t?.createdAt??new Date().toISOString(),connectedAt:new Date().toISOString()};await this.#e.set(A.tokenRef,o);try{await this.#t.save(g)}catch(c){throw await this.#d(A.tokenRef,s),c}try{await this.#C(g,o),this.#i.delete(A.botId)}catch(c){this.#i.set(A.botId,uh("connection-failed",`${this.#A.label}\u673A\u5668\u4EBA\u5DF2\u63A5\u5165\uFF0C\u6D88\u606F\u8FDE\u63A5\u6682\u672A\u5C31\u7EEA\u3002`)),this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${A.botId} credential connection failed:`,c)}this.#B()}),this.status()}async reconnectBot(r){let o=this.#t.get(r);if(!o)throw new Error(`Unknown ${this.#A.label} bot`);return await this.#u(r,async()=>{let i=await this.#h(o.tokenRef);if(!i)throw new Error(`${this.#A.label} bot token is missing`);try{await this.#C(o,i),this.#i.delete(r)}catch(e){throw this.#i.set(r,uh("connection-failed",`${this.#A.label}\u8FDE\u63A5\u4ECD\u672A\u5C31\u7EEA\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`)),e}finally{this.#B()}}),this.status()}async deleteBot(r){let o=this.#t.get(r);if(!o)throw new Error(`Unknown ${this.#A.label} bot`);return await this.#u(r,async()=>{let i=await this.#e.resolve(o.tokenRef).catch(()=>{});await this.#p(r);try{await this.#e.unset(o.tokenRef),await this.#t.remove(r)}catch(e){throw i?.value&&(await this.#e.set(o.tokenRef,i.value).catch(()=>{}),await this.#C(o,i.value).catch(()=>{})),new Error(`Unable to remove the ${this.#A.label} bot safely.`,{cause:e})}await this.#g({botId:r,config:o}).catch(e=>{this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${r} state cleanup failed:`,e)}),this.#i.delete(r),this.#B()}),this.status()}status(){let r=this.#t.list().map(i=>{let e=this.#r.get(i.botId)?.status??null,a=e?.ready===!0&&e.connectionState==="connected"&&e.harnessReachable===!0,A=a?"connected":e?.connectionState==="connecting"?"connecting":this.#i.has(i.botId)||e?.connectionState==="failed"?"error":"offline";return{botId:i.botId,state:A,connected:a,configured:!0,bot:{name:i.name,username:i.username,idMasked:this.#n(i.platformId)},health:{status:a?"healthy":A==="error"?"error":"offline",summary:a?`${this.#A.label}${this.#A.connectionLabel}\u8FD0\u884C\u6B63\u5E38`:A==="error"?`${this.#A.label}\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5`:`${this.#A.label}\u8FDE\u63A5\u5F53\u524D\u79BB\u7EBF`,lastCheckedAt:e?.lastCheckedAt??null,lastConnectedAt:e?.lastConnectedAt??null},stats:{messagesReceived:e?.messagesReceived??0,messagesReplied:e?.messagesReplied??0},error:structuredClone(this.#i.get(i.botId)??null)}}),o=r.filter(i=>i.connected).length;return{schemaVersion:1,revision:this.#l,state:r.length===0?"disconnected":o===r.length?"connected":o>0?"degraded":"offline",bots:r,totals:{configured:r.length,connected:o}}}async close(){this.#E||(this.#E=!0,await Promise.allSettled([...this.#c.values()]),await Promise.allSettled([...this.#r.keys()].map(r=>this.#p(r))))}async#C(r,o){if(this.#E)throw new Error(`${this.#A.label} controller is closed`);if(await this.#p(r.botId),this.#E)throw new Error(`${this.#A.label} controller is closed`);let i=await this.#I({botId:r.botId,config:r,token:o});if(!i||typeof i.start!="function"||typeof i.stop!="function")throw new TypeError(`createRuntime returned an invalid ${this.#A.label} runtime`);this.#r.set(r.botId,i);try{await i.start()}catch(e){throw await i.stop().catch(()=>{}),this.#r.delete(r.botId),e}}async#p(r){let o=this.#r.get(r);this.#r.delete(r),await o?.stop().catch(i=>{this.#o.warn?.(`[dsh-im:${this.#A.key}] bot ${r} failed to stop cleanly:`,i)})}async#h(r){let o=await this.#e.resolve(r).catch(()=>{});return kl(o?.value)}async#d(r,o){o?.value?await this.#e.set(r,o.value).catch(()=>{}):await this.#e.unset(r).catch(()=>{})}#u(r,o){let a=(this.#c.get(r)??Promise.resolve()).catch(()=>{}).then(o).finally(()=>{this.#c.get(r)===a&&this.#c.delete(r)});return this.#c.set(r,a),a}#B(){this.#l+=1}};var j7="https://discord.com/api/v10/";function vl(n){return typeof n=="string"&&n.trim()?n.trim():null}function q7(n,r){let o=AbortSignal.timeout(r);return n?AbortSignal.any([n,o]):o}function V7(n,r){return new Promise((o,i)=>{if(r?.aborted){i(r.reason??new DOMException("Aborted","AbortError"));return}let e=setTimeout(o,n);e?.unref?.(),r?.addEventListener("abort",()=>{clearTimeout(e),i(r.reason??new DOMException("Aborted","AbortError"))},{once:!0})})}function Ac(n,r){let o=vl(n);if(!o||!/^\d{5,30}$/.test(o))throw new TypeError(`Invalid Discord ${r}`);return o}function z7(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{20,}$/.test(n.trim())}var Pl=class{#A;#e;#t;constructor({token:r,fetchImpl:o=fetch,baseUrl:i=j7}){if(!z7(r))throw new TypeError("Discord Bot Token is invalid");if(typeof o!="function")throw new TypeError("DiscordApi requires fetch");this.#A=r.trim(),this.#e=o,this.#t=new URL(i)}getCurrentUser(r={}){return this.#a("users/@me",{...r,method:"GET"})}getGatewayBot(r={}){return this.#a("gateway/bot",{...r,method:"GET"})}createMessage({channelId:r,content:o,replyToMessageId:i,signal:e}){return this.#a(`channels/${Ac(r,"channel id")}/messages`,{method:"POST",signal:e,body:{content:o,allowed_mentions:{parse:[],replied_user:!1},...i?{message_reference:{message_id:Ac(i,"message id"),channel_id:Ac(r,"channel id"),fail_if_not_exists:!1}}:{}}})}editMessage({channelId:r,messageId:o,content:i,signal:e}){return this.#a(`channels/${Ac(r,"channel id")}/messages/${Ac(o,"message id")}`,{method:"PATCH",signal:e,body:{content:i,allowed_mentions:{parse:[],replied_user:!1}}})}sendTyping({channelId:r,signal:o}){return this.#a(`channels/${Ac(r,"channel id")}/typing`,{method:"POST",signal:o,expectBody:!1})}async#a(r,{method:o,body:i,signal:e,timeoutMs:a=15e3,expectBody:A=!0,retry:t=!0}){let s;try{s=await this.#e(new URL(r,this.#t),{method:o,headers:{authorization:`Bot ${this.#A}`,"content-type":"application/json","user-agent":"DeepSeek-Harness-dsh-im (https://github.com/xmanrui/dsh-im, 0.2.2)"},...i===void 0?{}:{body:JSON.stringify(i)},signal:q7(e,a),redirect:"error"})}catch(c){throw c?.name==="AbortError"||c?.name==="TimeoutError"?c:new Error(`Discord ${o} transport failed`)}let g=null;if(A||s.status===429||!s.ok)try{g=await s.json()}catch{if(A)throw new Error(`Discord ${o} returned invalid JSON`)}if(s.status===429&&t){let c=Math.min(1e4,Math.max(50,Number(g?.retry_after)*1e3||1e3));return await V7(c,e),this.#a(r,{method:o,body:i,signal:e,timeoutMs:a,expectBody:A,retry:!1})}if(!s.ok){let c=new Error(vl(g?.message)??`Discord API failed with HTTP ${s.status}`);throw c.code=`discord-${s.status}`,c}return A?g:null}};async function rv(n,r={}){let i=await new Pl({token:n,...r}).getCurrentUser();if(!i?.id||i?.bot!==!0)throw new Error("Discord token does not belong to a bot");return{platformId:String(i.id),name:vl(i.global_name)??vl(i.username)??"Discord\u673A\u5668\u4EBA",username:vl(i.username)}}function Qh(n){return typeof n=="string"?n.trim():""}function _i(){return{messagesReceived:0,messagesReplied:0,messagesRejected:0,lastMessageAt:null,lastReplyAt:null,lastRejectedAt:null,lastError:null}}var In=class{#A;#e;#t;#a;#s;#n;#I;#g=new Map;constructor({descriptor:r,bot:o,harness:i,state:e,status:a=_i(),logger:A=console,replyTimeoutMs:t=6e5}){if(!r?.key||!r?.label)throw new TypeError("A channel descriptor is required");if(!o||typeof o.sendText!="function")throw new TypeError("A bot client is required");if(!i||!e)throw new TypeError("Harness client and state store are required");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t}get status(){return structuredClone(this.#s)}accept(r){let o=Qh(r?.conversationId),i=r?.kind==="group"?"group":"direct",e=`${i}:${o}`,A=(this.#g.get(e)??Promise.resolve()).catch(()=>{}).then(()=>this.#o({...r,kind:i,conversationId:o})).finally(()=>{this.#g.get(e)===A&&this.#g.delete(e)});return this.#g.set(e,A),A}async waitForIdle(){await Promise.allSettled([...this.#g.values()])}async#o(r){let o=Qh(r.messageId),i=Qh(r.senderId);if(!o||!i||!r.conversationId||r.senderIsBot===!0||this.#a.hasSeen(o))return;if(this.#s.messagesReceived+=1,this.#s.lastMessageAt=new Date().toISOString(),r.kind==="group"&&r.addressed!==!0){this.#s.messagesRejected+=1,this.#s.lastRejectedAt=new Date().toISOString();return}let e=r.replyTarget,a=Qh(r.content);try{if(!a){await this.#e.sendText(e,"\u76EE\u524D\u4EC5\u652F\u6301\u6587\u5B57\u6D88\u606F\u3002"),await this.#a.markSeen(o);return}let A=a.toLowerCase();if(A==="/help"){await this.#e.sendText(e,[`${this.#A.label}\u673A\u5668\u4EBA\u5DF2\u8FDE\u63A5 DeepSeek Harness\u3002`,"","\u76F4\u63A5\u53D1\u9001\u6587\u5B57\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002","/new \u5F00\u542F\u4E00\u4E2A\u5168\u65B0\u4F1A\u8BDD","/status \u68C0\u67E5\u8FDE\u63A5\u72B6\u6001","/help \u663E\u793A\u672C\u5E2E\u52A9"].join(`
68
68
  `)),await this.#a.markSeen(o);return}if(A==="/status"){await this.#t.ensureRunning(),await this.#e.sendText(e,`${this.#A.label}\u673A\u5668\u4EBA\u4E0E DeepSeek Harness \u8FDE\u63A5\u6B63\u5E38\u3002`),await this.#a.markSeen(o);return}let t=`${r.kind}:${r.conversationId}`;if(A==="/new"){await this.#a.clearSession(t),await this.#e.sendText(e,"\u5DF2\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002\u8BF7\u53D1\u9001\u4F60\u7684\u95EE\u9898\u3002"),await this.#a.markSeen(o);return}let s=this.#a.sessionFor(t);(!s||!await this.#t.sessionExists(s))&&(s=await this.#t.createSession(),await this.#a.setSession(t,s)),await this.#e.sendTyping?.(e).catch(C=>{this.#n.warn?.(`[dsh-im:${this.#A.key}] typing indicator failed:`,C)});let g=null,c=!1;if(typeof this.#e.openStream=="function")try{g=await this.#e.openStream(e)}catch(C){this.#n.warn?.(`[dsh-im:${this.#A.key}] unable to start a streamed reply; using text:`,C)}let l=await this.#t.ask(s,a,{timeoutMs:this.#I,onUpdate:g?async C=>{let u=C.type==="text"?C.text:C.type==="tool"?`\u6B63\u5728\u4F7F\u7528${C.name}\u2026`:C.text;u&&await g.update(u)}:void 0});if(g)try{await g.finish(l),c=!0}catch(C){g.cancel?.(),this.#n.warn?.(`[dsh-im:${this.#A.key}] streamed reply finalization failed; using text:`,C)}c||await this.#e.sendText(e,l),await this.#a.markSeen(o),this.#s.messagesReplied+=1,this.#s.lastReplyAt=new Date().toISOString(),this.#s.lastError=null}catch(A){this.#s.lastError=A?.message??String(A),this.#n.error?.(`[dsh-im:${this.#A.key}] failed to process a message:`,A);try{await this.#e.sendText(e,"\u6D88\u606F\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"),await this.#a.markSeen(o)}catch(t){this.#n.error?.(`[dsh-im:${this.#A.key}] failed to send the safe error reply:`,t)}}}};var vm=Object.freeze({key:"discord",label:"Discord",connectionLabel:" Gateway \u957F\u8FDE\u63A5"}),fh=class extends In{constructor(r){super({descriptor:vm,...r})}};var Gl=class extends ec{constructor(r){super({...r,descriptor:vm,inspectToken:r.inspectToken??rv,deriveIdentity:tv,maskPlatformId:av})}};import{spawn as W7}from"node:child_process";import{randomUUID as iv}from"node:crypto";var ov=n=>new Promise(r=>setTimeout(r,n));function Z7(n){return(n?.data?.message?.content??[]).filter(r=>r.type==="text"&&typeof r.text=="string").map(r=>r.text).join(`
69
69
  `).trim()}var Pm=class{#A;#e;#t=null;#a=null;#s=new Map;#n="";#I=!1;#g=null;constructor({promptRpcId:r,afterSeq:o=-1}){this.#A=r,this.#e=o}get finished(){return this.#I}get answer(){return this.#n.trim()}get reason(){return this.#g}consume(r){let o=null,i=[...r].map(e=>e?.event??e).filter(Boolean).sort((e,a)=>(e.seq??-1)-(a.seq??-1));for(let e of i){let a=e.seq??-1;if(!(a<=this.#e)){if(this.#e=a,e.type==="turn/start"&&(this.#t=e.data?.turn??null),e.type==="user/message"&&e.data?.source?.rpcId===this.#A){this.#a=this.#t;continue}if(this.#a!==null){if(e.type==="turn/end"){if(e.data?.turn!==this.#a)continue;this.#I=!0,this.#g=e.data?.reason??null,this.#t=null;continue}if(e.data?.turn===this.#a){if(e.type==="assistant/chunk"&&e.data?.chunk?.type==="text-delta"){let A=e.data?.step??0,t=e.data.chunk.index??0,s=`${A}:${t}`;this.#s.set(s,(this.#s.get(s)??"")+e.data.chunk.text);let g=`${A}:`,c=[...this.#s.entries()].filter(([l])=>l.startsWith(g)).sort(([l],[C])=>Number(l.split(":")[1])-Number(C.split(":")[1])).map(([,l])=>l).join(`
70
70
  `).trim();c&&c!==this.#n&&(this.#n=c,o={type:"text",text:c});continue}if(e.type==="assistant/message"){let A=Z7(e);A&&A!==this.#n&&(this.#n=A,o={type:"text",text:A});continue}e.type==="tool/call"?o={type:"tool",name:e.data?.name??"\u5DE5\u5177"}:e.type==="tool/result"&&(o={type:"status",text:"\u6B63\u5728\u6574\u7406\u7ED3\u679C\u2026"})}}}}return o}},yh=class extends Error{constructor(r,o){super(`${r}: ${o?.message??"unknown Harness RPC error"}`),this.name="HarnessRpcError",this.method=r,this.code=o?.code??"internal",this.details=o?.details??{}}},Wa=class{#A;#e;#t;#a;#s;#n=null;constructor({baseUrl:r,workspace:o,agentPreset:i="standard",autostart:e=!1,dshBin:a="dsh"}){this.#A=new URL(r),this.#e=o,this.#t=i,this.#a=e,this.#s=a}async rpc(r,o={},i=3e4,e={}){let a=e.rpcId??`weixin-${iv()}`,A=await fetch(new URL(`/api/${r}`,this.#A),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({type:"client-request",rpcId:a,method:r,payload:o}),signal:AbortSignal.timeout(i)});if(!A.ok)throw new Error(`Harness transport ${r} failed: HTTP ${A.status}`);let t=await A.json();if(t?.type!=="server-response"||t?.rpcId!==a)throw new Error(`Harness returned an invalid response for ${r}`);if(!t.result?.ok)throw new yh(r,t.result?.error);return t.result.value}async health(){return await this.rpc("host.describe",{},5e3),!0}async ensureRunning(){try{return await this.health()}catch(i){if(!this.#a)throw i}if(!this.#n||this.#n.exitCode!==null){let i=this.#A.port||(this.#A.protocol==="https:"?"443":"80");this.#n=W7(this.#s,["web","--host",this.#A.hostname,"--port",i],{cwd:this.#e,env:process.env,stdio:["ignore","inherit","inherit"]}),this.#n.on("error",e=>{console.error("[dsh-weixin] failed to start Harness:",e.message)})}let r=Date.now()+6e4,o;for(;Date.now()<r;){await ov(1e3);try{return await this.health()}catch(i){o=i}}throw new Error(`Harness did not become ready: ${o?.message??"timeout"}`)}async workspaceId(){let{items:r}=await this.rpc("workspace.list",{}),o=r.find(e=>e.path===this.#e);return o?o.workspaceId:(await this.rpc("workspace.create",{path:this.#e})).workspace.workspaceId}async createSession(){await this.ensureRunning();let r=await this.workspaceId();return(await this.rpc("session.create",{workspaceId:r,agentPreset:this.#t})).sessionId}async sessionExists(r){try{return await this.rpc("session.history",{sessionId:r,maxMessages:1}),!0}catch(o){if(o instanceof yh&&o.code==="session-not-found")return!1;throw o}}async ask(r,o,i={}){typeof i=="number"&&(i={timeoutMs:i});let e=i.timeoutMs??6e5,a=typeof i.onUpdate=="function"?i.onUpdate:null;await this.ensureRunning();let A=await this.rpc("session.history",{sessionId:r,maxMessages:1}),t=Math.max(-1,...(A.events??[]).map(({event:l})=>l.seq??-1)),s=`weixin-${iv()}`,g=new Pm({promptRpcId:s,afterSeq:t});await this.rpc("session.prompt",{sessionId:r,mode:"queue",content:[{type:"text",text:o}],clientTimeZone:Intl.DateTimeFormat().resolvedOptions().timeZone},3e4,{rpcId:s});let c=Date.now()+e;for(;Date.now()<c;){await ov(300);let l=await this.rpc("session.history",{sessionId:r,maxMessages:50}),C=g.consume(l.events??[]);if(C&&a)try{await a(C)}catch(u){console.warn("[dsh-weixin] ignored a progress update failure:",u.message)}if(g.finished){if(g.answer)return g.answer;throw new Error(`Harness turn ended without a text reply${g.reason?` (${JSON.stringify(g.reason)})`:""}`)}}throw new Error(`Harness reply timed out after ${Math.round(e/1e3)} seconds`)}stopManagedProcess(){this.#n?.exitCode===null&&this.#n.kill("SIGTERM")}};var mh=class extends Wa{};function ln(n,r){let o=typeof n=="string"?n.trim():"";if(!o)return[];let i=[],e=o;for(;e.length>r;){let a=e.lastIndexOf(`
@@ -167,7 +167,7 @@ ${a.join(`
167
167
  `,{encoding:"utf8",mode:384}),await zpe(o,this.#A)}};var ru=class extends Wa{};var Ahe="https://work.weixin.qq.com/ai/qc/generate",the="https://work.weixin.qq.com/ai/qc/query_result";function XY(){return process.platform==="win32"?2:process.platform==="linux"?3:1}function Vc(n){return typeof n=="string"&&n.trim()?n.trim():null}function ahe(n){let r=Vc(n);if(!r)return null;try{let o=new URL(r);return o.protocol==="https:"&&o.hostname==="work.weixin.qq.com"&&(!o.port||o.port==="443")?o.href:null}catch{return null}}function rhe(n,r){return n?AbortSignal.any([n,AbortSignal.timeout(r)]):AbortSignal.timeout(r)}async function $Y(n,r,o){let i=await n(r,{method:"GET",redirect:"error",signal:rhe(o,1e4),headers:{accept:"application/json"}});if(!i.ok)throw new Error(`Enterprise WeChat QR service returned HTTP ${i.status}`);return i.json()}var iu=class{#A;#e;#t;#a;constructor({fetch:r=globalThis.fetch,clock:o=()=>Date.now(),source:i="deepseek-harness",platform:e=XY()}={}){if(typeof r!="function")throw new TypeError("A fetch implementation is required");this.#A=r,this.#e=o,this.#t=i,this.#a=[1,2,3].includes(e)?e:XY()}async start({signal:r}={}){let o=new URL(Ahe);o.searchParams.set("source",this.#t),o.searchParams.set("plat",String(this.#a));let i=await $Y(this.#A,o,r),e=Vc(i?.data?.scode),a=ahe(i?.data?.auth_url);if(!e||!a)throw new Error("Enterprise WeChat QR service returned invalid data");return{scode:e,verificationUrl:a,expiresAt:this.#e()+3e5,pollIntervalMs:3e3}}async poll({scode:r,signal:o}={}){let i=Vc(r);if(!i)throw new TypeError("Enterprise WeChat QR poll code is required");let e=new URL(the);e.searchParams.set("scode",i);let a=await $Y(this.#A,e,o),A=Vc(a?.data?.status)?.toLowerCase();if(A==="success"){let t=Vc(a?.data?.bot_info?.botid),s=Vc(a?.data?.bot_info?.secret);if(!t||!s)throw new Error("Enterprise WeChat QR result omitted bot credentials");return{status:"success",remoteBotId:t,secret:s}}return["expired","timeout"].includes(A)?{status:"expired"}:["fail","failed","error"].includes(A)?{status:"failed"}:{status:"waiting"}}};import{mkdir as ihe,readFile as ohe,rename as nhe,unlink as she,writeFile as ghe}from"node:fs/promises";import{dirname as che}from"node:path";var ou=Object.freeze({version:1,sessions:{},seenMessageIds:[]});function Ihe(n){if(!n||typeof n!="object")return structuredClone(ou);let r={};if(n.sessions&&typeof n.sessions=="object"&&!Array.isArray(n.sessions))for(let[o,i]of Object.entries(n.sessions))typeof o=="string"&&typeof i=="string"&&i&&(r[o]=i);return{version:1,sessions:r,seenMessageIds:Array.isArray(n.seenMessageIds)?n.seenMessageIds.filter(o=>typeof o=="string").slice(-1e3):[]}}var nu=class{#A;#e=structuredClone(ou);#t=Promise.resolve();constructor(r){this.#A=r}async load(){try{this.#e=Ihe(JSON.parse(await ohe(this.#A,"utf8")))}catch(r){if(r?.code!=="ENOENT")throw r;this.#e=structuredClone(ou),await this.#a()}return this}sessionFor(r){return this.#e.sessions[r]??null}async setSession(r,o){this.#e.sessions[r]=o,await this.#a()}async clearSession(r){delete this.#e.sessions[r],await this.#a()}hasSeen(r){return this.#e.seenMessageIds.includes(r)}async markSeen(r){this.hasSeen(r)||(this.#e.seenMessageIds.push(r),this.#e.seenMessageIds.length>1e3&&this.#e.seenMessageIds.splice(0,this.#e.seenMessageIds.length-1e3),await this.#a())}async remove(){try{await she(this.#A)}catch(r){if(r?.code!=="ENOENT")throw r}this.#e=structuredClone(ou)}async#a(){let r=`${JSON.stringify(this.#e,null,2)}
168
168
  `,o=this.#t.then(async()=>{await ihe(che(this.#A),{recursive:!0,mode:448});let i=`${this.#A}.tmp`;await ghe(i,r,{encoding:"utf8",mode:384}),await nhe(i,this.#A)});this.#t=o.then(()=>{},()=>{}),await o}};import{randomUUID as lhe}from"node:crypto";var ex=new Set(["pending","connecting"]),gC=new Set(["connected","failed","cancelled","expired"]);function og(n){return typeof n=="string"&&n.trim()?n.trim():null}function ar(n,r){return Object.freeze({code:n,message:r})}function ng(n){return n?{attemptId:n.id,status:n.state,pollIntervalMs:n.pollIntervalMs,qrRevision:n.qrRevision,...n.verificationUrl?{verificationUrl:n.verificationUrl}:{},...n.expiresAt?{expiresAt:n.expiresAt}:{},...n.botId?{botId:n.botId}:{},...n.error?{error:structuredClone(n.error)}:{}}:null}var cC=class{#A;#e;#t;#a;#s;#n;#I=new Map;#g=new Map;#o=new Map;#r=null;#i=new Map;#c=0;#l=!1;constructor({qrAuth:r,credentials:o,configStore:i,createRuntime:e,deleteState:a=async()=>{},logger:A=console}){if(!r||typeof r.start!="function"||typeof r.poll!="function")throw new TypeError("Enterprise WeChat QR auth is required");if(!o||typeof o.resolve!="function"||typeof o.set!="function"||typeof o.unset!="function")throw new TypeError("WecomController requires the DSH credential provider");if(!i||typeof i.list!="function"||typeof i.save!="function"||typeof i.remove!="function")throw new TypeError("WecomController requires a config store");if(typeof e!="function")throw new TypeError("createRuntime is required");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A}async initialize(){if(this.#l)return this.status();for(let r of this.#t.list())await this.#Q(r.botId,async()=>{let o=this.#I.get(r.botId)?.status;if(this.#l||o?.ready||o?.wecomConnectionState==="connecting")return;let i=await this.#u(r.secretRef);if(!i){this.#g.set(r.botId,ar("missing-secret","\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u79FB\u9664\u540E\u91CD\u65B0\u626B\u7801\u3002"));return}try{await this.#h(r,i),this.#g.delete(r.botId)}catch{this.#g.set(r.botId,ar("connection-failed","\u4F01\u4E1A\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002")),this.#n.warn?.(`[dsh-im:wecom] bot ${r.botId} failed to initialize`)}finally{this.#f()}});return this.status()}async startProvisioning(){if(this.#l)throw new Error("Enterprise WeChat controller is closed");this.#r&&await this.cancelProvisioning(this.#r);let r={id:lhe(),state:"pending",createdAt:Date.now(),expiresAt:null,pollIntervalMs:3e3,qrRevision:1,verificationUrl:null,scode:null,botId:null,error:null,controller:new AbortController,polling:null,transition:null};this.#o.set(r.id,r),this.#r=r.id,this.#f();try{let o=await this.#A.start({signal:r.controller.signal});if(r.scode=og(o.scode),r.verificationUrl=og(o.verificationUrl),r.expiresAt=Number(o.expiresAt),r.pollIntervalMs=Math.min(1e4,Math.max(500,Number(o.pollIntervalMs)||3e3)),!r.scode||!r.verificationUrl||!Number.isFinite(r.expiresAt))throw new Error("Enterprise WeChat QR auth returned incomplete data");return this.#f(),ng(r)}catch(o){throw r.state=r.controller.signal.aborted?"cancelled":"failed",r.error=r.controller.signal.aborted?ar("cancelled","\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002"):ar("qr-start-failed","\u65E0\u6CD5\u751F\u6210\u4F01\u4E1A\u5FAE\u4FE1\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"),this.#y(r),o}}async registrationStatus(r){let o=this.#o.get(r);if(!o||gC.has(o.state))return ng(o);if(o.state==="connecting")return await o.transition?.catch(()=>{}),ng(o);if(Date.now()>=o.expiresAt)return o.state="expired",o.error=ar("expired","\u4F01\u4E1A\u5FAE\u4FE1\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002"),o.controller.abort(),this.#y(o),ng(o);if(!o.polling){let i=this.#E(o).finally(()=>{o.polling===i&&(o.polling=null)});o.polling=i}return await o.polling.catch(()=>{}),ng(o)}async bindCredentials({botId:r,secret:o}={}){if(this.#l)throw new Error("Enterprise WeChat controller is closed");let i=og(r),e=og(o);if(!i||!e)throw new TypeError("Enterprise WeChat Bot ID and Secret are required");if(this.#r&&await this.cancelProvisioning(this.#r),this.#l)throw new Error("Enterprise WeChat controller is closed");let a=au(i);return await this.#Q(a.botId,async()=>{if(this.#l)throw new Error("Enterprise WeChat controller is closed");let A=this.#t.getByRemoteBotId(i),t=await this.#e.resolve(a.secretRef).catch(()=>{});if(this.#l)throw new Error("Enterprise WeChat controller is closed");let s={botId:a.botId,remoteBotId:i,secretRef:a.secretRef,createdAt:A?.createdAt??new Date().toISOString(),connectedAt:new Date().toISOString()};await this.#e.set(a.secretRef,e);try{await this.#t.save(s)}catch(g){throw await this.#B(a.secretRef,t),g}try{await this.#h(s,e),this.#g.delete(a.botId)}catch{this.#g.set(a.botId,ar("connection-failed","\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u5DF2\u7ED1\u5B9A\uFF0C\u6D88\u606F\u8FDE\u63A5\u6682\u672A\u5C31\u7EEA\u3002")),this.#n.warn?.(`[dsh-im:wecom] bot ${a.botId} credential connection failed`)}this.#f()}),this.status()}async cancelProvisioning(r){let o=this.#o.get(r);return o?(gC.has(o.state)||(o.controller.abort(),await Promise.allSettled([o.polling,o.transition].filter(Boolean)),gC.has(o.state)||(o.state="cancelled"),o.error??=ar("cancelled","\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002"),this.#y(o)),ng(o)):null}async reconnectBot(r){let o=this.#t.get(r);if(!o)throw new Error("Unknown Enterprise WeChat bot");return await this.#Q(r,async()=>{let i=await this.#u(o.secretRef);if(!i)throw new Error("Enterprise WeChat bot secret is missing");try{await this.#h(o,i),this.#g.delete(r)}catch(e){throw this.#g.set(r,ar("connection-failed","\u4F01\u4E1A\u5FAE\u4FE1\u8FDE\u63A5\u4ECD\u672A\u5C31\u7EEA\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")),e}finally{this.#f()}}),this.status()}async deleteBot(r){let o=this.#t.get(r);if(!o)throw new Error("Unknown Enterprise WeChat bot");return await this.#Q(r,async()=>{let i=await this.#e.resolve(o.secretRef).catch(()=>{});await this.#d(r);try{await this.#e.unset(o.secretRef),await this.#t.remove(r)}catch(e){throw i?.value&&(await this.#e.set(o.secretRef,i.value).catch(()=>{}),await this.#h(o,i.value).catch(()=>{})),new Error("Unable to remove the Enterprise WeChat bot safely.",{cause:e})}await this.#s({botId:r,config:o}).catch(e=>{this.#n.warn?.(`[dsh-im:wecom] bot ${r} state cleanup failed:`,e)}),this.#g.delete(r),this.#f()}),this.status()}status(){let r=this.#t.list().map(e=>{let a=this.#I.get(e.botId)?.status??null,A=a?.ready===!0&&a.wecomConnectionState==="connected"&&a.harnessReachable===!0,t=A?"connected":a?.wecomConnectionState==="connecting"?"connecting":this.#g.has(e.botId)||a?.wecomConnectionState==="failed"?"error":"offline";return{botId:e.botId,state:t,connected:A,configured:!0,bot:{name:"\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA",appIdMasked:WY(e.remoteBotId)},health:{status:A?"healthy":t==="error"?"error":"offline",summary:A?"\u4F01\u4E1A\u5FAE\u4FE1 WebSocket \u957F\u8FDE\u63A5\u8FD0\u884C\u6B63\u5E38":t==="error"?"\u4F01\u4E1A\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5":"\u4F01\u4E1A\u5FAE\u4FE1\u8FDE\u63A5\u5F53\u524D\u79BB\u7EBF",lastCheckedAt:a?.lastCheckedAt??null,lastConnectedAt:a?.lastConnectedAt??null},stats:{messagesReceived:a?.messagesReceived??0,messagesReplied:a?.messagesReplied??0},error:structuredClone(this.#g.get(e.botId)??null)}}),o=r.filter(e=>e.connected).length,i=this.#r?this.#o.get(this.#r):null;return{schemaVersion:1,revision:this.#c,state:i&&ex.has(i.state)?"provisioning":r.length===0?"disconnected":o===r.length?"connected":o>0?"degraded":"offline",bots:r,totals:{configured:r.length,connected:o},...i&&ex.has(i.state)?{provisioning:ng(i)}:{}}}async close(){this.#l||(this.#l=!0,this.#r&&await this.cancelProvisioning(this.#r),await Promise.allSettled([...this.#i.values()]),await Promise.allSettled([...this.#I.keys()].map(r=>this.#d(r))))}async#E(r){try{let o=await this.#A.poll({scode:r.scode,signal:r.controller.signal});if(r.controller.signal.aborted||gC.has(r.state)||o.status==="waiting")return;if(o.status==="expired"){r.state="expired",r.error=ar("expired","\u4F01\u4E1A\u5FAE\u4FE1\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002"),this.#y(r);return}if(o.status!=="success"){r.state="failed",r.error=ar("qr-connect-failed","\u4F01\u4E1A\u5FAE\u4FE1\u626B\u7801\u6CA1\u6709\u5B8C\u6210\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801\u3002"),this.#y(r);return}r.state="connecting",r.verificationUrl=null,r.expiresAt=null,r.scode=null,this.#f();let i=this.#C(r,o);r.transition=i,await i}catch{if(r.controller.signal.aborted)return;r.state="failed",r.error=ar("qr-connect-failed","\u4F01\u4E1A\u5FAE\u4FE1\u626B\u7801\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801\u3002"),this.#n.warn?.("[dsh-im:wecom] QR polling failed"),this.#y(r)}}async#C(r,o){try{let i=og(o.remoteBotId),e=og(o.secret);if(!i||!e)throw new Error("Enterprise WeChat authorization returned incomplete credentials");r.botId=await this.#p(r,{remoteBotId:i,secret:e}),r.state="connected",r.error=null}catch{r.controller.signal.aborted?(r.state="cancelled",r.error=ar("cancelled","\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002")):(r.state="failed",r.error=ar("activation-failed","\u4F01\u4E1A\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u65E0\u6CD5\u5B89\u5168\u4FDD\u5B58\u63A5\u5165\u914D\u7F6E\u3002"),this.#n.error?.("[dsh-im:wecom] provisioning failed"))}finally{this.#y(r)}}async#p(r,{remoteBotId:o,secret:i}){let e=au(o),a=this.#t.getByRemoteBotId(o),A=await this.#e.resolve(e.secretRef).catch(()=>{}),t={botId:e.botId,remoteBotId:o,secretRef:e.secretRef,createdAt:a?.createdAt??new Date().toISOString(),connectedAt:new Date().toISOString()};return this.#Q(e.botId,async()=>{await this.#e.set(e.secretRef,i);try{if(r.controller.signal.aborted)throw new DOMException("Cancelled","AbortError");await this.#t.save(t)}catch(s){throw await this.#B(e.secretRef,A),s}try{if(r.controller.signal.aborted)throw new DOMException("Cancelled","AbortError");await this.#h(t,i),this.#g.delete(e.botId)}catch(s){if(r.controller.signal.aborted)throw await this.#d(e.botId),a?await this.#t.save(a).catch(()=>{}):await this.#t.remove(e.botId).catch(()=>{}),await this.#B(e.secretRef,A),s;this.#g.set(e.botId,ar("connection-failed","\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u5DF2\u7ED1\u5B9A\uFF0C\u6D88\u606F\u8FDE\u63A5\u6682\u672A\u5C31\u7EEA\u3002")),this.#n.warn?.(`[dsh-im:wecom] bot ${e.botId} activation connection failed`)}return this.#f(),e.botId})}async#h(r,o){if(this.#l)throw new Error("Enterprise WeChat controller is closed");if(await this.#d(r.botId),this.#l)throw new Error("Enterprise WeChat controller is closed");let i=await this.#a({botId:r.botId,config:r,secret:o});if(!i||typeof i.start!="function"||typeof i.stop!="function")throw new TypeError("createRuntime returned an invalid Enterprise WeChat runtime");this.#I.set(r.botId,i);try{await i.start()}catch(e){throw await i.stop().catch(()=>{}),this.#I.delete(r.botId),e}}async#d(r){let o=this.#I.get(r);this.#I.delete(r),await o?.stop().catch(i=>{this.#n.warn?.(`[dsh-im:wecom] bot ${r} failed to stop cleanly:`,i)})}async#u(r){let o=await this.#e.resolve(r).catch(()=>{});return og(o?.value)}async#B(r,o){o?.value?await this.#e.set(r,o.value).catch(()=>{}):await this.#e.unset(r).catch(()=>{})}#Q(r,o){let a=(this.#i.get(r)??Promise.resolve()).catch(()=>{}).then(o).finally(()=>{this.#i.get(r)===a&&this.#i.delete(r)});return this.#i.set(r,a),a}#y(r){r.scode=null,r.verificationUrl=null,r.expiresAt=null,this.#r===r.id&&(this.#r=null),this.#f();let o=[...this.#o.values()].filter(i=>gC.has(i.state));for(;o.length>16;)this.#o.delete(o.shift().id)}#f(){this.#c+=1}};import{WSAuthFailureError as Bhe,WSClient as uhe,WSReconnectExhaustedError as Qhe}from"@wecom/aibot-node-sdk";import{generateReqId as Ehe}from"@wecom/aibot-node-sdk";var Che=["\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u5DF2\u8FDE\u63A5 DeepSeek Harness\u3002","","\u76F4\u63A5\u53D1\u9001\u6587\u5B57\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002","/new \u5F00\u542F\u4E00\u4E2A\u5168\u65B0\u4F1A\u8BDD","/status \u68C0\u67E5\u8FDE\u63A5\u72B6\u6001","/help \u663E\u793A\u672C\u5E2E\u52A9"].join(`
169
169
  `),phe=18e3;function c_(n){return n?.body&&typeof n.body=="object"?n.body:{}}function Ax(n){let r=c_(n);return r.chattype==="group"?`group:${r.chatid}`:`direct:${r.from?.userid}`}function hhe(n){let r=c_(n);return r.msgtype==="text"?typeof r.text?.content=="string"?r.text.content.trim():"":r.msgtype==="voice"?typeof r.voice?.content=="string"?r.voice.content.trim():"":r.msgtype==="mixed"&&Array.isArray(r.mixed?.msg_item)?r.mixed.msg_item.filter(o=>o?.msgtype==="text"&&typeof o.text?.content=="string").map(o=>o.text.content).join(`
170
- `).trim():""}function su(n,r=phe){let o=String(n??"").trim();if(!o)return[];let i=[],e="",a=0;for(let A of o){let t=Buffer.byteLength(A);e&&a+t>r?(i.push(e),e=A,a=t):(e+=A,a+=t)}return e&&i.push(e),i}function dhe(n){return n?.type==="text"?n.text:n?.type==="tool"?`\u6B63\u5728\u4F7F\u7528${n.name}\u2026`:n?.text}function I_(){return{messagesReceived:0,messagesReplied:0,messagesRejected:0,lastMessageAt:null,lastReplyAt:null,lastRejectedAt:null,lastError:null}}var gu=class{#A;#e;#t;#a;#s;#n;#I;#g=new Map;constructor({client:r,harness:o,state:i,status:e=I_(),logger:a=console,replyTimeoutMs:A=6e5,generateStreamId:t=Ehe}){if(!r||typeof r.replyStream!="function"||typeof r.sendMessage!="function")throw new TypeError("Enterprise WeChat client is required");if(!o||!i)throw new TypeError("Harness client and state store are required");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t}get status(){return structuredClone(this.#a)}accept(r){let o=Ax(r),e=(this.#g.get(o)??Promise.resolve()).catch(()=>{}).then(()=>this.#i(r)).finally(()=>{this.#g.get(o)===e&&this.#g.delete(o)});return this.#g.set(o,e),e}async waitForIdle(){await Promise.allSettled([...this.#g.values()])}async#o(r,o){for(let i of su(o))await this.#A.sendMessage(r,{msgtype:"markdown",markdown:{content:i}})}async#r(r,o,i){let e=su(i);if(e.length!==0)try{await this.#A.replyStream(r,this.#I("stream"),e[0],!0);for(let a of e.slice(1))await this.#A.sendMessage(o,{msgtype:"markdown",markdown:{content:a}})}catch{await this.#o(o,i)}}async#i(r){let o=c_(r),i=typeof o.msgid=="string"?o.msgid:"",e=typeof o.from?.userid=="string"?o.from.userid:"",a=o.chattype==="group"?o.chatid:e;if(!i||!e||!a||!["single","group"].includes(o.chattype)||this.#t.hasSeen(i))return;this.#a.messagesReceived+=1,this.#a.lastMessageAt=new Date().toISOString();let A=hhe(r),t=null,s=!1;try{if(!A){await this.#r(r,a,"\u76EE\u524D\u652F\u6301\u6587\u5B57\u3001\u8BED\u97F3\u8F6C\u5199\u548C\u56FE\u6587\u6DF7\u6392\u4E2D\u7684\u6587\u5B57\u6D88\u606F\u3002"),await this.#t.markSeen(i);return}let g=A.toLowerCase();if(g==="/help"){await this.#r(r,a,Che),await this.#t.markSeen(i);return}if(g==="/status"){await this.#e.ensureRunning(),await this.#r(r,a,"\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u4E0E DeepSeek Harness \u8FDE\u63A5\u6B63\u5E38\u3002"),await this.#t.markSeen(i);return}let c=Ax(r);if(g==="/new"){await this.#t.clearSession(c),await this.#r(r,a,"\u5DF2\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002\u8BF7\u53D1\u9001\u4F60\u7684\u95EE\u9898\u3002"),await this.#t.markSeen(i);return}let l=this.#t.sessionFor(c);(!l||!await this.#e.sessionExists(l))&&(l=await this.#e.createSession(),await this.#t.setSession(c,l)),t=this.#I("stream");try{await this.#A.replyStream(r,t,"\u6B63\u5728\u601D\u8003\u4E2D\u2026",!1),s=!0}catch(f){this.#s.warn?.("[dsh-im:wecom] unable to start a stream; using an active reply:",f)}let C=await this.#e.ask(l,A,{timeoutMs:this.#n,onUpdate:s&&typeof this.#A.replyStreamNonBlocking=="function"?async f=>{let y=su(dhe(f))[0];y&&await this.#A.replyStreamNonBlocking(r,t,y,!1)}:void 0}),u=su(C||"\u4EFB\u52A1\u5DF2\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u751F\u6210\u53EF\u663E\u793A\u7684\u6587\u672C\u3002"),Q=!1;if(s&&u.length>0)try{await this.#A.replyStream(r,t,u[0],!0);for(let f of u.slice(1))await this.#A.sendMessage(a,{msgtype:"markdown",markdown:{content:f}});Q=!0}catch(f){this.#s.warn?.("[dsh-im:wecom] stream finalization failed; using an active reply:",f)}Q||await this.#o(a,C),await this.#t.markSeen(i),this.#a.messagesReplied+=1,this.#a.lastReplyAt=new Date().toISOString(),this.#a.lastError=null}catch(g){this.#a.lastError=g?.message??String(g),this.#s.error?.("[dsh-im:wecom] failed to process an inbound message");try{s&&t?await this.#A.replyStream(r,t,"\u6D88\u606F\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",!0):await this.#r(r,a,"\u6D88\u606F\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"),await this.#t.markSeen(i)}catch{this.#s.error?.("[dsh-im:wecom] failed to send the safe error reply")}}}};function fhe(){let n=new Error("Enterprise WeChat WebSocket authentication timed out");return n.code="connect-timeout",n}function yhe(){return{startedAt:null,ready:!1,wecomConnectionState:"idle",harnessReachable:!1,lastCheckedAt:null,lastConnectedAt:null,lastError:null,...I_()}}var IC=class{#A;#e;#t;#a;#s;#n;#I;#g;#o;#r=yhe();#i=null;#c=null;#l=null;#E=null;constructor({config:r,secret:o,harness:i,state:e,logger:a=console,replyTimeoutMs:A=6e5,connectTimeoutMs:t=2e4,maxReconnectAttempts:s=10,createClient:g=c=>new uhe(c)}){if(!r||!o||!i||!e)throw new TypeError("WecomRuntime requires config, secret, Harness, and state");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t,this.#g=s,this.#o=g}get status(){return structuredClone(this.#r)}async start(){if(this.#r.ready&&this.#i)return this.status;if(this.#l)return this.#l;let r=new AbortController;return this.#E=r,this.#l=this.#C(r.signal).finally(()=>{this.#E===r&&(this.#E=null),this.#l=null}),this.#l}async#C(r){await this.#p(),r.throwIfAborted(),this.#r.startedAt=new Date().toISOString(),this.#r.wecomConnectionState="connecting",this.#r.lastError=null,await this.#t.ensureRunning(),this.#r.harnessReachable=!0;let o={debug(){},info(){},warn(){},error(){}},i=this.#o({botId:this.#A.remoteBotId,secret:this.#e,logger:o,maxReconnectAttempts:this.#g});if(!i||typeof i.connect!="function"||typeof i.disconnect!="function")throw new TypeError("Enterprise WeChat client factory returned an invalid client");this.#i=i,this.#c=new gu({client:i,harness:this.#t,state:this.#a,status:this.#r,logger:this.#s,replyTimeoutMs:this.#n});let e,a,A=!1,t=new Promise((Q,f)=>{e=Q,a=f}),s=()=>{if(this.#i!==i||r.aborted)return;A=!0;let Q=Date.now();this.#r.ready=!0,this.#r.wecomConnectionState="connected",this.#r.lastCheckedAt=Q,this.#r.lastConnectedAt=Q,this.#r.lastError=null,e()},g=()=>{this.#i===i&&(this.#r.ready=!1,this.#r.wecomConnectionState="connecting",this.#r.lastCheckedAt=Date.now())},c=()=>{this.#i===i&&(this.#r.ready=!1,this.#r.wecomConnectionState="connecting",this.#r.lastCheckedAt=Date.now())},l=Q=>{if(this.#i!==i)return;let f=Q instanceof Bhe||Q instanceof Qhe;!A&&f&&a(Q),f&&(this.#r.ready=!1,this.#r.wecomConnectionState="failed"),this.#r.lastError=f?Q.name:"connection-error",this.#s.warn?.(`[dsh-im:wecom] bot ${this.#A.botId} connection error`)},C=Q=>this.#c?.accept(Q);i.on("authenticated",s),i.on("disconnected",g),i.on("reconnecting",c),i.on("error",l),i.on("message",C);let u;try{return i.connect(),await Promise.race([t,new Promise((Q,f)=>{r.addEventListener("abort",()=>f(r.reason),{once:!0})}),new Promise((Q,f)=>{u=setTimeout(()=>f(fhe()),this.#I)})]),this.status}catch(Q){throw r.aborted?(await this.#p(),Q):(this.#r.ready=!1,this.#r.wecomConnectionState="failed",this.#r.lastError=Q?.message??String(Q),await this.#p(),Q)}finally{clearTimeout(u)}}async stop(){let r=this.#l;return this.#E?.abort(new DOMException("Enterprise WeChat runtime stopped","AbortError")),await this.#p(),await r?.catch(()=>{}),this.status}async#p(){let r=this.#i,o=this.#c;this.#i=null,this.#c=null;try{r?.disconnect(),r?.removeAllListeners?.()}catch{this.#s.warn?.(`[dsh-im:wecom] bot ${this.#A.botId} failed to stop cleanly`)}await o?.waitForIdle(),this.#r.ready=!1,this.#r.wecomConnectionState="idle"}};var tx=Object.freeze([250,1e3,3e3,5e3,1e4,3e4]);function mhe(n){if(!Array.isArray(n)||n.length===0)return[...tx];let r=n.filter(o=>Number.isFinite(o)&&o>=0);return r.length>0?r:[...tx]}var cu=class{#A;#e;#t;#a;#s;#n;#I;#g=null;#o=null;#r=0;#i=!1;#c=!1;#l;#E;constructor({controller:r,harness:o,logger:i=console,retryDelaysMs:e,healthyIntervalMs:a=15e3,setTimeoutImpl:A=setTimeout,clearTimeoutImpl:t=clearTimeout}){if(!r||typeof r.initialize!="function"||typeof r.status!="function")throw new TypeError("ConnectionSupervisor requires a controller");if(!o||typeof o.ensureRunning!="function")throw new TypeError("ConnectionSupervisor requires a Harness client");this.#A=r,this.#e=o,this.#t=i,this.#a=mhe(e),this.#s=Number.isFinite(a)&&a>=0?a:15e3,this.#n=A,this.#I=t,this.#l=new Promise(s=>{this.#E=s})}get ready(){return this.#l}start(){return this.#c||this.#i?this:(this.#c=!0,this.#C(0),this)}async close(){this.#i||(this.#i=!0,this.#g!==null&&this.#I(this.#g),this.#g=null,await this.#o?.catch(()=>{}),this.#E?.(null),this.#E=null)}#C(r){this.#i||(this.#g=this.#n(()=>{this.#g=null,this.#p()},r),this.#g?.unref?.())}async#p(){if(this.#i||this.#o)return;let r=this.#h();this.#o=r;try{await r}finally{this.#o===r&&(this.#o=null)}}async#h(){try{if(await this.#e.ensureRunning(),this.#i)return;let r=await this.#A.initialize();if(this.#i)return;this.#E?.(r),this.#E=null;let{configured:o,connected:i}=r.totals;if(i<o){let e=this.#a[Math.min(this.#r,this.#a.length-1)];this.#r+=1,this.#t.warn?.(`[dsh-im:wecom] ${i}/${o} bots connected; retrying in ${e}ms`),this.#C(e);return}this.#r=0,this.#C(this.#s)}catch(r){if(this.#i)return;let o=this.#a[Math.min(this.#r,this.#a.length-1)];this.#r+=1,this.#t.warn?.(`[dsh-im:wecom] connection reconciliation failed; retrying in ${o}ms`,r),this.#C(o)}}};function l_(n){return new cu(n)}function whe(n,r){if(r!==void 0)return new URL(r);let o=n?.port;if(!Number.isInteger(o)||o<1||o>65535)throw new Error("dsh-im Enterprise WeChat requires an initialized DSH webServer port");return new URL(`http://127.0.0.1:${o}`)}function Ohe(n){let r=zc(n.dshHome??process.env.DSH_HOME??Iu(Dhe(),".dsh")),o=zc(n.dataDir??Iu(r,"integrations","dsh-wecom"));return{config:zc(n.configPath??Iu(o,"config.json")),bots:zc(n.botsDir??Iu(o,"bots"))}}async function E_(n,r={},o={}){if(!n?.credentials)throw new TypeError("dsh-im Enterprise WeChat requires ctx.credentials");if(!n?.webServer)throw new TypeError("dsh-im Enterprise WeChat requires ctx.webServer");let i=o.ConfigStore??tu,e=o.StateStore??nu,a=o.HarnessClient??ru,A=o.Controller??cC,t=o.Runtime??IC,s=o.QrAuth??iu,g=o.createConnectionSupervisor??l_,c=typeof n.logger=="function"?n.logger("dsh-im:wecom"):n.logger??console,l=Ohe(r),C=await new i(l.config).load(),u=o.qrAuth??new s({source:r.qrSource??"deepseek-harness",platform:r.qrPlatform}),Q=new Map,f=k=>zc(l.bots,k,"state.json"),y=async k=>{let U=Q.get(k);return U||(U=await new e(f(k)).load(),Q.set(k,U)),U},m=new a({baseUrl:whe(n.webServer,r.harnessBaseUrl),workspace:zc(r.workspace??process.cwd()),agentPreset:r.agentPreset??"standard",autostart:!1,dshBin:r.dshBin??"dsh"}),R=new A({qrAuth:u,credentials:n.credentials,configStore:C,logger:c,createRuntime:async({botId:k,config:U,secret:K})=>new t({config:U,secret:K,harness:m,state:await y(k),replyTimeoutMs:r.replyTimeoutMs??6e5,connectTimeoutMs:r.connectTimeoutMs??2e4,maxReconnectAttempts:r.maxReconnectAttempts??10,logger:{error:(...F)=>c.error?.(`[${k}]`,...F),warn:(...F)=>c.warn?.(`[${k}]`,...F),info:(...F)=>c.info?.(`[${k}]`,...F),debug:(...F)=>c.debug?.(`[${k}]`,...F)}}),deleteState:async({botId:k})=>{let U=Q.get(k);if(Q.delete(k),U&&typeof U.remove=="function")return U.remove();try{await She(f(k))}catch(K){if(K?.code!=="ENOENT")throw K}}}),T=g({controller:R,harness:m,logger:c,retryDelaysMs:r.retryDelaysMs,healthyIntervalMs:r.healthyIntervalMs}).start();return{controller:R,ready:T.ready,async close(){await T.close(),await R.close(),m.stopManagedProcess()}}}import Mhe from"qrcode";var rx="/wecom",La=Object.freeze({status:"connection.status",beginProvisioning:"provision.begin",pollProvisioning:"provision.poll",cancelProvisioning:"provision.cancel",bindCredentials:"bot.bind-credentials",reconnectBot:"bot.reconnect",deleteBot:"bot.delete"}),ix=Object.freeze(Object.values(La)),bhe=new Set(["secret","secretRef","scode","remoteBotId","verificationUrl","bot_info","botid"]);function h_(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function Wc(n,r){return h_(n)&&Object.keys(n).every(o=>r.includes(o))}function C_(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{1,128}$/.test(n)}function ax(n,r){return typeof n=="string"&&n.trim().length>0&&n.length<=r}function _he(n,r){return h_(r)?n===La.status?Wc(r,[])?null:"connection.status does not accept fields.":n===La.beginProvisioning?Wc(r,["locale"])&&(r.locale===void 0||r.locale==="zh-CN")?null:"provision.begin received unsupported fields.":[La.pollProvisioning,La.cancelProvisioning].includes(n)?Wc(r,["attemptId"])&&C_(r.attemptId)?null:`${n} requires an attemptId.`:n===La.bindCredentials?Wc(r,["botId","secret"])&&ax(r.botId,512)&&ax(r.secret,1024)?null:"bot.bind-credentials requires Bot ID and Secret.":n===La.reconnectBot?Wc(r,["botId"])&&C_(r.botId)?null:"bot.reconnect requires a botId.":n===La.deleteBot?Wc(r,["botId","confirm"])&&C_(r.botId)&&r.confirm===!0?null:"bot.delete requires a botId and confirm=true.":"Unknown Enterprise WeChat endpoint.":"Payload must be an object."}function Zc(n){if(Array.isArray(n))return n.map(Zc);if(!h_(n))return n;let r={};for(let[o,i]of Object.entries(n))bhe.has(o)||(r[o]=Zc(i));return r}async function Nhe(n){return Mhe.toDataURL(n,{type:"image/png",errorCorrectionLevel:"M",margin:2,width:320})}async function p_(n,r){return!n||typeof n.verificationUrl!="string"?Zc(n):Zc({...n,qrCodeDataUrl:await r(n.verificationUrl)})}async function lu(n,r){let o=structuredClone(n);return o?.provisioning&&(o.provisioning=await p_(o.provisioning,r)),Zc(o)}function ox(n,{encodeQr:r=Nhe}={}){for(let e of["status","startProvisioning","registrationStatus","cancelProvisioning","bindCredentials","reconnectBot","deleteBot"])if(typeof n?.[e]!="function")throw new TypeError(`A complete Enterprise WeChat controller is required (${e})`);let o=new Map,i=e=>{let a=o.get(e);return a||(o.size>=16&&o.delete(o.keys().next().value),a=Promise.resolve().then(()=>r(e)),o.set(e,a)),a};return async(e,a,A)=>{if(A?.aborted)return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}};if(!ix.includes(e))return{ok:!1,error:{code:"bad-request",message:"Unknown Enterprise WeChat endpoint."}};let t=_he(e,a);if(t)return{ok:!1,error:{code:"bad-request",message:t}};try{let s;if(e===La.status)s=await lu(await n.status(),i);else if(e===La.beginProvisioning)s=await p_(await n.startProvisioning(),i);else if(e===La.pollProvisioning){let g=await n.registrationStatus(a.attemptId);if(!g)return{ok:!1,error:{code:"bad-request",message:"The provisioning attempt no longer exists."}};s=await p_(g,i)}else e===La.cancelProvisioning?s=Zc(await n.cancelProvisioning(a.attemptId)):e===La.bindCredentials?s=await lu(await n.bindCredentials(a),i):e===La.reconnectBot?s=await lu(await n.reconnectBot(a.botId),i):s=await lu(await n.deleteBot(a.botId),i);return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!0,value:s}}catch{return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!1,error:{code:"wecom-operation-failed",message:"\u4F01\u4E1A\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}}}}function Eu(n,r,o,i){if(!n?.connection?.rpc||typeof n.connection.rpc.handle!="function")throw new TypeError("DSH Host Connection RPC is required");return n.connection.rpc.handle(rx,ox(r,o),{authority:za(i)})}async function nx(n,r={}){if(r?.controller)return Eu(n,r.controller,r.rpcOptions,r.rpcAuthority);let o=await E_(n,r,r.internals),i=Eu(n,o.controller,r.rpcOptions,r.rpcAuthority);return n.effect(()=>async()=>o.close(),"dsh-im: close Enterprise WeChat bot connections"),i}import{unlink as Ide}from"node:fs/promises";import{homedir as lde}from"node:os";import{join as yu,resolve as AI}from"node:path";import{createHash as Yhe}from"node:crypto";import{mkdir as xhe,readFile as Jhe,rename as jhe,unlink as qhe,writeFile as Vhe}from"node:fs/promises";import{dirname as zhe}from"node:path";import{randomBytes as The,randomUUID as Rhe}from"node:crypto";var pu="https://ilinkai.weixin.qq.com/",khe="2.4.6",vhe="3",Phe="bot",Ghe=2<<16|1024|6,Fhe=15e3,sx=35e3,Lhe=new Set(["wait","scaned","confirmed","expired","scaned_but_redirect","need_verifycode","verify_code_blocked","binded_redirect"]),ct=class extends Error{constructor(r,o,i={}){super(o,i),this.name="WeixinApiError",this.code=r,this.status=i.status}};function ci(n){return typeof n=="string"&&n.trim()?n.trim():null}function d_(n){let r=n.toLowerCase().replace(/\.$/,"");return r==="weixin.qq.com"||r.endsWith(".weixin.qq.com")}function $c(n){let r;try{r=new URL(n)}catch{throw new ct("invalid-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u8FDE\u63A5\u5730\u5740\u3002")}if(r.protocol!=="https:"||!d_(r.hostname)||r.port!==""&&r.port!=="443")throw new ct("untrusted-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u8FDE\u63A5\u5730\u5740\u3002");return r.username="",r.password="",r.search="",r.hash="",r.pathname.endsWith("/")||(r.pathname+="/"),r.toString()}function Uhe(n){let r=ci(n);if(!r)throw new ct("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u5730\u5740\u3002");let o;try{o=new URL(r)}catch{throw new ct("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u626B\u7801\u5730\u5740\u3002")}if(o.protocol!=="https:"||!d_(o.hostname))throw new ct("untrusted-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u626B\u7801\u5730\u5740\u3002");return o.toString()}function cx(){return{"iLink-App-Id":Phe,"iLink-App-ClientVersion":String(Ghe)}}function Hhe(n){let r={...cx(),"content-type":"application/json",AuthorizationType:"ilink_bot_token","X-WECHAT-UIN":Buffer.from(String(The(4).readUInt32BE(0)),"utf8").toString("base64")};return ci(n)&&(r.Authorization=`Bearer ${n.trim()}`),r}function Cu(){return{channel_version:khe,bot_agent:"DeepSeekHarness/0.2.1"}}function gx(n){return n?.reason instanceof Error?n.reason:new DOMException("The operation was aborted","AbortError")}async function Xc(n,{method:r,baseUrl:o,endpoint:i,body:e,token:a,timeoutMs:A=Fhe,signal:t,authenticated:s=!0}){let g=$c(o),c=new URL(i,g);if(!d_(c.hostname))throw new ct("untrusted-endpoint","\u62D2\u7EDD\u8BBF\u95EE\u4E0D\u53D7\u4FE1\u4EFB\u7684\u5FAE\u4FE1\u670D\u52A1\u5730\u5740\u3002");let l=new AbortController,C=!1,u=()=>l.abort(t?.reason);if(t?.aborted)throw gx(t);t?.addEventListener("abort",u,{once:!0});let Q=A>0?setTimeout(()=>{C=!0,l.abort()},A):null;try{let f=await n(c,{method:r,headers:s?Hhe(a):cx(),...e===void 0?{}:{body:JSON.stringify(e)},signal:l.signal});if(!f.ok)throw new ct("http-error",`\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${f.status}\uFF09\u3002`,{status:f.status});try{return await f.json()}catch(y){throw new ct("invalid-response","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002",{cause:y})}}catch(f){throw t?.aborted?gx(t):C?new ct("timeout","\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002",{cause:f}):f instanceof ct?f:new ct("network-error","\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE\u5FAE\u4FE1\u670D\u52A1\u3002",{cause:f})}finally{Q&&clearTimeout(Q),t?.removeEventListener("abort",u)}}function Khe(n){if(!n||typeof n!="object"||!Lhe.has(n.status))throw new ct("invalid-login-status","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u626B\u7801\u72B6\u6001\u3002");return n}function Ix({fetchImpl:n=fetch}={}){if(typeof n!="function")throw new TypeError("fetchImpl must be a function");return Object.freeze({async beginLogin({localTokens:r=[],botType:o=vhe,signal:i}={}){let e=[...new Set(r.map(ci).filter(Boolean))].slice(-10),a=await Xc(n,{method:"POST",baseUrl:pu,endpoint:`ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(o)}`,body:{local_token_list:e},timeoutMs:1e4,signal:i}),A=ci(a?.qrcode);if(!A)throw new ct("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u4E8C\u7EF4\u7801\u4EE4\u724C\u3002");return{qrcode:A,qrcodeUrl:Uhe(a.qrcode_img_content)}},async pollLogin({qrcode:r,baseUrl:o=pu,verifyCode:i,signal:e}){let a=ci(r);if(!a)throw new TypeError("qrcode is required");let A=`ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(a)}`;ci(i)&&(A+=`&verify_code=${encodeURIComponent(i.trim())}`);let t=await Xc(n,{method:"GET",baseUrl:o,endpoint:A,timeoutMs:sx,signal:e,authenticated:!1});return Khe(t)},async getUpdates({baseUrl:r,token:o,getUpdatesBuf:i="",timeoutMs:e,signal:a}){try{return await Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/getupdates",body:{get_updates_buf:i,base_info:Cu()},token:o,timeoutMs:e??sx,signal:a})}catch(A){if(A instanceof ct&&A.code==="timeout")return{ret:0,msgs:[],get_updates_buf:i};throw A}},async sendText({baseUrl:r,token:o,toUserId:i,text:e,contextToken:a,runId:A,signal:t}){let s=ci(i),g=ci(e);if(!s||!g)throw new TypeError("toUserId and text are required");let c=await Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/sendmessage",token:o,signal:t,body:{msg:{from_user_id:"",to_user_id:s,client_id:`dsh-weixin-${Rhe()}`,message_type:2,message_state:2,item_list:[{type:1,text_item:{text:g}}],...ci(a)?{context_token:a.trim()}:{},...ci(A)?{run_id:A.trim()}:{}},base_info:Cu()}});if(c?.ret!==void 0&&c.ret!==0)throw new ct("send-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u56DE\u590D\u6D88\u606F\u3002");return!0},async notifyStart({baseUrl:r,token:o,signal:i}){let e=await Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/msg/notifystart",token:o,signal:i,timeoutMs:1e4,body:{base_info:Cu()}});if(e?.ret!==void 0&&e.ret!==0)throw new ct("start-rejected","\u5FAE\u4FE1\u8D26\u53F7\u8FDE\u63A5\u542F\u52A8\u5931\u8D25\u3002");return e},async notifyStop({baseUrl:r,token:o,signal:i}){return Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/msg/notifystop",token:o,signal:i,timeoutMs:1e4,body:{base_info:Cu()}})}})}function lx(n){for(let r of n?.item_list??[]){if(r?.type===1&&typeof r.text_item?.text=="string"){let o=r.text_item.text.trim();if(o)return o}if(r?.type===3&&typeof r.voice_item?.text=="string"){let o=r.voice_item.text.trim();if(o)return o}}return null}function Ex(n){return n?.message_id!==void 0&&n.message_id!==null?String(n.message_id):ci(n?.client_id)}function Cx(n,r=4e3){if(n.length<=r)return[n];let o=[],i=n;for(;i.length>r;){let e=i.lastIndexOf(`
170
+ `).trim():""}function su(n,r=phe){let o=String(n??"").trim();if(!o)return[];let i=[],e="",a=0;for(let A of o){let t=Buffer.byteLength(A);e&&a+t>r?(i.push(e),e=A,a=t):(e+=A,a+=t)}return e&&i.push(e),i}function dhe(n){return n?.type==="text"?n.text:n?.type==="tool"?`\u6B63\u5728\u4F7F\u7528${n.name}\u2026`:n?.text}function I_(){return{messagesReceived:0,messagesReplied:0,messagesRejected:0,lastMessageAt:null,lastReplyAt:null,lastRejectedAt:null,lastError:null}}var gu=class{#A;#e;#t;#a;#s;#n;#I;#g=new Map;constructor({client:r,harness:o,state:i,status:e=I_(),logger:a=console,replyTimeoutMs:A=6e5,generateStreamId:t=Ehe}){if(!r||typeof r.replyStream!="function"||typeof r.sendMessage!="function")throw new TypeError("Enterprise WeChat client is required");if(!o||!i)throw new TypeError("Harness client and state store are required");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t}get status(){return structuredClone(this.#a)}accept(r){let o=Ax(r),e=(this.#g.get(o)??Promise.resolve()).catch(()=>{}).then(()=>this.#i(r)).finally(()=>{this.#g.get(o)===e&&this.#g.delete(o)});return this.#g.set(o,e),e}async waitForIdle(){await Promise.allSettled([...this.#g.values()])}async#o(r,o){for(let i of su(o))await this.#A.sendMessage(r,{msgtype:"markdown",markdown:{content:i}})}async#r(r,o,i){let e=su(i);if(e.length!==0)try{await this.#A.replyStream(r,this.#I("stream"),e[0],!0);for(let a of e.slice(1))await this.#A.sendMessage(o,{msgtype:"markdown",markdown:{content:a}})}catch{await this.#o(o,i)}}async#i(r){let o=c_(r),i=typeof o.msgid=="string"?o.msgid:"",e=typeof o.from?.userid=="string"?o.from.userid:"",a=o.chattype==="group"?o.chatid:e;if(!i||!e||!a||!["single","group"].includes(o.chattype)||this.#t.hasSeen(i))return;this.#a.messagesReceived+=1,this.#a.lastMessageAt=new Date().toISOString();let A=hhe(r),t=null,s=!1;try{if(!A){await this.#r(r,a,"\u76EE\u524D\u652F\u6301\u6587\u5B57\u3001\u8BED\u97F3\u8F6C\u5199\u548C\u56FE\u6587\u6DF7\u6392\u4E2D\u7684\u6587\u5B57\u6D88\u606F\u3002"),await this.#t.markSeen(i);return}let g=A.toLowerCase();if(g==="/help"){await this.#r(r,a,Che),await this.#t.markSeen(i);return}if(g==="/status"){await this.#e.ensureRunning(),await this.#r(r,a,"\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u4E0E DeepSeek Harness \u8FDE\u63A5\u6B63\u5E38\u3002"),await this.#t.markSeen(i);return}let c=Ax(r);if(g==="/new"){await this.#t.clearSession(c),await this.#r(r,a,"\u5DF2\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002\u8BF7\u53D1\u9001\u4F60\u7684\u95EE\u9898\u3002"),await this.#t.markSeen(i);return}let l=this.#t.sessionFor(c);(!l||!await this.#e.sessionExists(l))&&(l=await this.#e.createSession(),await this.#t.setSession(c,l)),t=this.#I("stream");try{await this.#A.replyStream(r,t,"\u6B63\u5728\u601D\u8003\u4E2D\u2026",!1),s=!0}catch(f){this.#s.warn?.("[dsh-im:wecom] unable to start a stream; using an active reply:",f)}let C=await this.#e.ask(l,A,{timeoutMs:this.#n,onUpdate:s&&typeof this.#A.replyStreamNonBlocking=="function"?async f=>{let y=su(dhe(f))[0];y&&await this.#A.replyStreamNonBlocking(r,t,y,!1)}:void 0}),u=su(C||"\u4EFB\u52A1\u5DF2\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u751F\u6210\u53EF\u663E\u793A\u7684\u6587\u672C\u3002"),Q=!1;if(s&&u.length>0)try{await this.#A.replyStream(r,t,u[0],!0);for(let f of u.slice(1))await this.#A.sendMessage(a,{msgtype:"markdown",markdown:{content:f}});Q=!0}catch(f){this.#s.warn?.("[dsh-im:wecom] stream finalization failed; using an active reply:",f)}Q||await this.#o(a,C),await this.#t.markSeen(i),this.#a.messagesReplied+=1,this.#a.lastReplyAt=new Date().toISOString(),this.#a.lastError=null}catch(g){this.#a.lastError=g?.message??String(g),this.#s.error?.("[dsh-im:wecom] failed to process an inbound message");try{s&&t?await this.#A.replyStream(r,t,"\u6D88\u606F\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",!0):await this.#r(r,a,"\u6D88\u606F\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"),await this.#t.markSeen(i)}catch{this.#s.error?.("[dsh-im:wecom] failed to send the safe error reply")}}}};function fhe(){let n=new Error("Enterprise WeChat WebSocket authentication timed out");return n.code="connect-timeout",n}function yhe(){return{startedAt:null,ready:!1,wecomConnectionState:"idle",harnessReachable:!1,lastCheckedAt:null,lastConnectedAt:null,lastError:null,...I_()}}var IC=class{#A;#e;#t;#a;#s;#n;#I;#g;#o;#r=yhe();#i=null;#c=null;#l=null;#E=null;constructor({config:r,secret:o,harness:i,state:e,logger:a=console,replyTimeoutMs:A=6e5,connectTimeoutMs:t=2e4,maxReconnectAttempts:s=10,createClient:g=c=>new uhe(c)}){if(!r||!o||!i||!e)throw new TypeError("WecomRuntime requires config, secret, Harness, and state");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A,this.#I=t,this.#g=s,this.#o=g}get status(){return structuredClone(this.#r)}async start(){if(this.#r.ready&&this.#i)return this.status;if(this.#l)return this.#l;let r=new AbortController;return this.#E=r,this.#l=this.#C(r.signal).finally(()=>{this.#E===r&&(this.#E=null),this.#l=null}),this.#l}async#C(r){await this.#p(),r.throwIfAborted(),this.#r.startedAt=new Date().toISOString(),this.#r.wecomConnectionState="connecting",this.#r.lastError=null,await this.#t.ensureRunning(),this.#r.harnessReachable=!0;let o={debug(){},info(){},warn(){},error(){}},i=this.#o({botId:this.#A.remoteBotId,secret:this.#e,logger:o,maxReconnectAttempts:this.#g});if(!i||typeof i.connect!="function"||typeof i.disconnect!="function")throw new TypeError("Enterprise WeChat client factory returned an invalid client");this.#i=i,this.#c=new gu({client:i,harness:this.#t,state:this.#a,status:this.#r,logger:this.#s,replyTimeoutMs:this.#n});let e,a,A=!1,t=new Promise((Q,f)=>{e=Q,a=f}),s=()=>{if(this.#i!==i||r.aborted)return;A=!0;let Q=Date.now();this.#r.ready=!0,this.#r.wecomConnectionState="connected",this.#r.lastCheckedAt=Q,this.#r.lastConnectedAt=Q,this.#r.lastError=null,e()},g=()=>{this.#i===i&&(this.#r.ready=!1,this.#r.wecomConnectionState="connecting",this.#r.lastCheckedAt=Date.now())},c=()=>{this.#i===i&&(this.#r.ready=!1,this.#r.wecomConnectionState="connecting",this.#r.lastCheckedAt=Date.now())},l=Q=>{if(this.#i!==i)return;let f=Q instanceof Bhe||Q instanceof Qhe;!A&&f&&a(Q),f&&(this.#r.ready=!1,this.#r.wecomConnectionState="failed"),this.#r.lastError=f?Q.name:"connection-error",this.#s.warn?.(`[dsh-im:wecom] bot ${this.#A.botId} connection error`)},C=Q=>this.#c?.accept(Q);i.on("authenticated",s),i.on("disconnected",g),i.on("reconnecting",c),i.on("error",l),i.on("message",C);let u;try{return i.connect(),await Promise.race([t,new Promise((Q,f)=>{r.addEventListener("abort",()=>f(r.reason),{once:!0})}),new Promise((Q,f)=>{u=setTimeout(()=>f(fhe()),this.#I)})]),this.status}catch(Q){throw r.aborted?(await this.#p(),Q):(this.#r.ready=!1,this.#r.wecomConnectionState="failed",this.#r.lastError=Q?.message??String(Q),await this.#p(),Q)}finally{clearTimeout(u)}}async stop(){let r=this.#l;return this.#E?.abort(new DOMException("Enterprise WeChat runtime stopped","AbortError")),await this.#p(),await r?.catch(()=>{}),this.status}async#p(){let r=this.#i,o=this.#c;this.#i=null,this.#c=null;try{r?.disconnect(),r?.removeAllListeners?.()}catch{this.#s.warn?.(`[dsh-im:wecom] bot ${this.#A.botId} failed to stop cleanly`)}await o?.waitForIdle(),this.#r.ready=!1,this.#r.wecomConnectionState="idle"}};var tx=Object.freeze([250,1e3,3e3,5e3,1e4,3e4]);function mhe(n){if(!Array.isArray(n)||n.length===0)return[...tx];let r=n.filter(o=>Number.isFinite(o)&&o>=0);return r.length>0?r:[...tx]}var cu=class{#A;#e;#t;#a;#s;#n;#I;#g=null;#o=null;#r=0;#i=!1;#c=!1;#l;#E;constructor({controller:r,harness:o,logger:i=console,retryDelaysMs:e,healthyIntervalMs:a=15e3,setTimeoutImpl:A=setTimeout,clearTimeoutImpl:t=clearTimeout}){if(!r||typeof r.initialize!="function"||typeof r.status!="function")throw new TypeError("ConnectionSupervisor requires a controller");if(!o||typeof o.ensureRunning!="function")throw new TypeError("ConnectionSupervisor requires a Harness client");this.#A=r,this.#e=o,this.#t=i,this.#a=mhe(e),this.#s=Number.isFinite(a)&&a>=0?a:15e3,this.#n=A,this.#I=t,this.#l=new Promise(s=>{this.#E=s})}get ready(){return this.#l}start(){return this.#c||this.#i?this:(this.#c=!0,this.#C(0),this)}async close(){this.#i||(this.#i=!0,this.#g!==null&&this.#I(this.#g),this.#g=null,await this.#o?.catch(()=>{}),this.#E?.(null),this.#E=null)}#C(r){this.#i||(this.#g=this.#n(()=>{this.#g=null,this.#p()},r),this.#g?.unref?.())}async#p(){if(this.#i||this.#o)return;let r=this.#h();this.#o=r;try{await r}finally{this.#o===r&&(this.#o=null)}}async#h(){try{if(await this.#e.ensureRunning(),this.#i)return;let r=await this.#A.initialize();if(this.#i)return;this.#E?.(r),this.#E=null;let{configured:o,connected:i}=r.totals;if(i<o){let e=this.#a[Math.min(this.#r,this.#a.length-1)];this.#r+=1,this.#t.warn?.(`[dsh-im:wecom] ${i}/${o} bots connected; retrying in ${e}ms`),this.#C(e);return}this.#r=0,this.#C(this.#s)}catch(r){if(this.#i)return;let o=this.#a[Math.min(this.#r,this.#a.length-1)];this.#r+=1,this.#t.warn?.(`[dsh-im:wecom] connection reconciliation failed; retrying in ${o}ms`,r),this.#C(o)}}};function l_(n){return new cu(n)}function whe(n,r){if(r!==void 0)return new URL(r);let o=n?.port;if(!Number.isInteger(o)||o<1||o>65535)throw new Error("dsh-im Enterprise WeChat requires an initialized DSH webServer port");return new URL(`http://127.0.0.1:${o}`)}function Ohe(n){let r=zc(n.dshHome??process.env.DSH_HOME??Iu(Dhe(),".dsh")),o=zc(n.dataDir??Iu(r,"integrations","dsh-wecom"));return{config:zc(n.configPath??Iu(o,"config.json")),bots:zc(n.botsDir??Iu(o,"bots"))}}async function E_(n,r={},o={}){if(!n?.credentials)throw new TypeError("dsh-im Enterprise WeChat requires ctx.credentials");if(!n?.webServer)throw new TypeError("dsh-im Enterprise WeChat requires ctx.webServer");let i=o.ConfigStore??tu,e=o.StateStore??nu,a=o.HarnessClient??ru,A=o.Controller??cC,t=o.Runtime??IC,s=o.QrAuth??iu,g=o.createConnectionSupervisor??l_,c=typeof n.logger=="function"?n.logger("dsh-im:wecom"):n.logger??console,l=Ohe(r),C=await new i(l.config).load(),u=o.qrAuth??new s({source:r.qrSource??"deepseek-harness",platform:r.qrPlatform}),Q=new Map,f=k=>zc(l.bots,k,"state.json"),y=async k=>{let U=Q.get(k);return U||(U=await new e(f(k)).load(),Q.set(k,U)),U},m=new a({baseUrl:whe(n.webServer,r.harnessBaseUrl),workspace:zc(r.workspace??process.cwd()),agentPreset:r.agentPreset??"standard",autostart:!1,dshBin:r.dshBin??"dsh"}),R=new A({qrAuth:u,credentials:n.credentials,configStore:C,logger:c,createRuntime:async({botId:k,config:U,secret:K})=>new t({config:U,secret:K,harness:m,state:await y(k),replyTimeoutMs:r.replyTimeoutMs??6e5,connectTimeoutMs:r.connectTimeoutMs??2e4,maxReconnectAttempts:r.maxReconnectAttempts??10,logger:{error:(...F)=>c.error?.(`[${k}]`,...F),warn:(...F)=>c.warn?.(`[${k}]`,...F),info:(...F)=>c.info?.(`[${k}]`,...F),debug:(...F)=>c.debug?.(`[${k}]`,...F)}}),deleteState:async({botId:k})=>{let U=Q.get(k);if(Q.delete(k),U&&typeof U.remove=="function")return U.remove();try{await She(f(k))}catch(K){if(K?.code!=="ENOENT")throw K}}}),T=g({controller:R,harness:m,logger:c,retryDelaysMs:r.retryDelaysMs,healthyIntervalMs:r.healthyIntervalMs}).start();return{controller:R,ready:T.ready,async close(){await T.close(),await R.close(),m.stopManagedProcess()}}}import Mhe from"qrcode";var rx="/wecom",La=Object.freeze({status:"connection.status",beginProvisioning:"provision.begin",pollProvisioning:"provision.poll",cancelProvisioning:"provision.cancel",bindCredentials:"bot.bind-credentials",reconnectBot:"bot.reconnect",deleteBot:"bot.delete"}),ix=Object.freeze(Object.values(La)),bhe=new Set(["secret","secretRef","scode","remoteBotId","verificationUrl","bot_info","botid"]);function h_(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function Wc(n,r){return h_(n)&&Object.keys(n).every(o=>r.includes(o))}function C_(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{1,128}$/.test(n)}function ax(n,r){return typeof n=="string"&&n.trim().length>0&&n.length<=r}function _he(n,r){return h_(r)?n===La.status?Wc(r,[])?null:"connection.status does not accept fields.":n===La.beginProvisioning?Wc(r,["locale"])&&(r.locale===void 0||r.locale==="zh-CN")?null:"provision.begin received unsupported fields.":[La.pollProvisioning,La.cancelProvisioning].includes(n)?Wc(r,["attemptId"])&&C_(r.attemptId)?null:`${n} requires an attemptId.`:n===La.bindCredentials?Wc(r,["botId","secret"])&&ax(r.botId,512)&&ax(r.secret,1024)?null:"bot.bind-credentials requires Bot ID and Secret.":n===La.reconnectBot?Wc(r,["botId"])&&C_(r.botId)?null:"bot.reconnect requires a botId.":n===La.deleteBot?Wc(r,["botId","confirm"])&&C_(r.botId)&&r.confirm===!0?null:"bot.delete requires a botId and confirm=true.":"Unknown Enterprise WeChat endpoint.":"Payload must be an object."}function Zc(n){if(Array.isArray(n))return n.map(Zc);if(!h_(n))return n;let r={};for(let[o,i]of Object.entries(n))bhe.has(o)||(r[o]=Zc(i));return r}async function Nhe(n){return Mhe.toDataURL(n,{type:"image/png",errorCorrectionLevel:"M",margin:2,width:320})}async function p_(n,r){return!n||typeof n.verificationUrl!="string"?Zc(n):Zc({...n,qrCodeDataUrl:await r(n.verificationUrl)})}async function lu(n,r){let o=structuredClone(n);return o?.provisioning&&(o.provisioning=await p_(o.provisioning,r)),Zc(o)}function ox(n,{encodeQr:r=Nhe}={}){for(let e of["status","startProvisioning","registrationStatus","cancelProvisioning","bindCredentials","reconnectBot","deleteBot"])if(typeof n?.[e]!="function")throw new TypeError(`A complete Enterprise WeChat controller is required (${e})`);let o=new Map,i=e=>{let a=o.get(e);return a||(o.size>=16&&o.delete(o.keys().next().value),a=Promise.resolve().then(()=>r(e)),o.set(e,a)),a};return async(e,a,A)=>{if(A?.aborted)return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}};if(!ix.includes(e))return{ok:!1,error:{code:"bad-request",message:"Unknown Enterprise WeChat endpoint."}};let t=_he(e,a);if(t)return{ok:!1,error:{code:"bad-request",message:t}};try{let s;if(e===La.status)s=await lu(await n.status(),i);else if(e===La.beginProvisioning)s=await p_(await n.startProvisioning(),i);else if(e===La.pollProvisioning){let g=await n.registrationStatus(a.attemptId);if(!g)return{ok:!1,error:{code:"bad-request",message:"The provisioning attempt no longer exists."}};s=await p_(g,i)}else e===La.cancelProvisioning?s=Zc(await n.cancelProvisioning(a.attemptId)):e===La.bindCredentials?s=await lu(await n.bindCredentials(a),i):e===La.reconnectBot?s=await lu(await n.reconnectBot(a.botId),i):s=await lu(await n.deleteBot(a.botId),i);return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!0,value:s}}catch{return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!1,error:{code:"wecom-operation-failed",message:"\u4F01\u4E1A\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}}}}function Eu(n,r,o,i){if(!n?.connection?.rpc||typeof n.connection.rpc.handle!="function")throw new TypeError("DSH Host Connection RPC is required");return n.connection.rpc.handle(rx,ox(r,o),{authority:za(i)})}async function nx(n,r={}){if(r?.controller)return Eu(n,r.controller,r.rpcOptions,r.rpcAuthority);let o=await E_(n,r,r.internals),i=Eu(n,o.controller,r.rpcOptions,r.rpcAuthority);return n.effect(()=>async()=>o.close(),"dsh-im: close Enterprise WeChat bot connections"),i}import{unlink as Ide}from"node:fs/promises";import{homedir as lde}from"node:os";import{join as yu,resolve as AI}from"node:path";import{createHash as Yhe}from"node:crypto";import{mkdir as xhe,readFile as Jhe,rename as jhe,unlink as qhe,writeFile as Vhe}from"node:fs/promises";import{dirname as zhe}from"node:path";import{randomBytes as The,randomUUID as Rhe}from"node:crypto";var pu="https://ilinkai.weixin.qq.com/",khe="2.4.6",vhe="3",Phe="bot",Ghe=2<<16|1024|6,Fhe=15e3,sx=35e3,Lhe=new Set(["wait","scaned","confirmed","expired","scaned_but_redirect","need_verifycode","verify_code_blocked","binded_redirect"]),ct=class extends Error{constructor(r,o,i={}){super(o,i),this.name="WeixinApiError",this.code=r,this.status=i.status}};function ci(n){return typeof n=="string"&&n.trim()?n.trim():null}function d_(n){let r=n.toLowerCase().replace(/\.$/,"");return r==="weixin.qq.com"||r.endsWith(".weixin.qq.com")}function $c(n){let r;try{r=new URL(n)}catch{throw new ct("invalid-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u8FDE\u63A5\u5730\u5740\u3002")}if(r.protocol!=="https:"||!d_(r.hostname)||r.port!==""&&r.port!=="443")throw new ct("untrusted-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u8FDE\u63A5\u5730\u5740\u3002");return r.username="",r.password="",r.search="",r.hash="",r.pathname.endsWith("/")||(r.pathname+="/"),r.toString()}function Uhe(n){let r=ci(n);if(!r)throw new ct("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u5730\u5740\u3002");let o;try{o=new URL(r)}catch{throw new ct("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u626B\u7801\u5730\u5740\u3002")}if(o.protocol!=="https:"||!d_(o.hostname))throw new ct("untrusted-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u626B\u7801\u5730\u5740\u3002");return o.toString()}function cx(){return{"iLink-App-Id":Phe,"iLink-App-ClientVersion":String(Ghe)}}function Hhe(n){let r={...cx(),"content-type":"application/json",AuthorizationType:"ilink_bot_token","X-WECHAT-UIN":Buffer.from(String(The(4).readUInt32BE(0)),"utf8").toString("base64")};return ci(n)&&(r.Authorization=`Bearer ${n.trim()}`),r}function Cu(){return{channel_version:khe,bot_agent:"DeepSeekHarness/0.2.2"}}function gx(n){return n?.reason instanceof Error?n.reason:new DOMException("The operation was aborted","AbortError")}async function Xc(n,{method:r,baseUrl:o,endpoint:i,body:e,token:a,timeoutMs:A=Fhe,signal:t,authenticated:s=!0}){let g=$c(o),c=new URL(i,g);if(!d_(c.hostname))throw new ct("untrusted-endpoint","\u62D2\u7EDD\u8BBF\u95EE\u4E0D\u53D7\u4FE1\u4EFB\u7684\u5FAE\u4FE1\u670D\u52A1\u5730\u5740\u3002");let l=new AbortController,C=!1,u=()=>l.abort(t?.reason);if(t?.aborted)throw gx(t);t?.addEventListener("abort",u,{once:!0});let Q=A>0?setTimeout(()=>{C=!0,l.abort()},A):null;try{let f=await n(c,{method:r,headers:s?Hhe(a):cx(),...e===void 0?{}:{body:JSON.stringify(e)},signal:l.signal});if(!f.ok)throw new ct("http-error",`\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${f.status}\uFF09\u3002`,{status:f.status});try{return await f.json()}catch(y){throw new ct("invalid-response","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002",{cause:y})}}catch(f){throw t?.aborted?gx(t):C?new ct("timeout","\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002",{cause:f}):f instanceof ct?f:new ct("network-error","\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE\u5FAE\u4FE1\u670D\u52A1\u3002",{cause:f})}finally{Q&&clearTimeout(Q),t?.removeEventListener("abort",u)}}function Khe(n){if(!n||typeof n!="object"||!Lhe.has(n.status))throw new ct("invalid-login-status","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u626B\u7801\u72B6\u6001\u3002");return n}function Ix({fetchImpl:n=fetch}={}){if(typeof n!="function")throw new TypeError("fetchImpl must be a function");return Object.freeze({async beginLogin({localTokens:r=[],botType:o=vhe,signal:i}={}){let e=[...new Set(r.map(ci).filter(Boolean))].slice(-10),a=await Xc(n,{method:"POST",baseUrl:pu,endpoint:`ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(o)}`,body:{local_token_list:e},timeoutMs:1e4,signal:i}),A=ci(a?.qrcode);if(!A)throw new ct("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u4E8C\u7EF4\u7801\u4EE4\u724C\u3002");return{qrcode:A,qrcodeUrl:Uhe(a.qrcode_img_content)}},async pollLogin({qrcode:r,baseUrl:o=pu,verifyCode:i,signal:e}){let a=ci(r);if(!a)throw new TypeError("qrcode is required");let A=`ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(a)}`;ci(i)&&(A+=`&verify_code=${encodeURIComponent(i.trim())}`);let t=await Xc(n,{method:"GET",baseUrl:o,endpoint:A,timeoutMs:sx,signal:e,authenticated:!1});return Khe(t)},async getUpdates({baseUrl:r,token:o,getUpdatesBuf:i="",timeoutMs:e,signal:a}){try{return await Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/getupdates",body:{get_updates_buf:i,base_info:Cu()},token:o,timeoutMs:e??sx,signal:a})}catch(A){if(A instanceof ct&&A.code==="timeout")return{ret:0,msgs:[],get_updates_buf:i};throw A}},async sendText({baseUrl:r,token:o,toUserId:i,text:e,contextToken:a,runId:A,signal:t}){let s=ci(i),g=ci(e);if(!s||!g)throw new TypeError("toUserId and text are required");let c=await Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/sendmessage",token:o,signal:t,body:{msg:{from_user_id:"",to_user_id:s,client_id:`dsh-weixin-${Rhe()}`,message_type:2,message_state:2,item_list:[{type:1,text_item:{text:g}}],...ci(a)?{context_token:a.trim()}:{},...ci(A)?{run_id:A.trim()}:{}},base_info:Cu()}});if(c?.ret!==void 0&&c.ret!==0)throw new ct("send-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u56DE\u590D\u6D88\u606F\u3002");return!0},async notifyStart({baseUrl:r,token:o,signal:i}){let e=await Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/msg/notifystart",token:o,signal:i,timeoutMs:1e4,body:{base_info:Cu()}});if(e?.ret!==void 0&&e.ret!==0)throw new ct("start-rejected","\u5FAE\u4FE1\u8D26\u53F7\u8FDE\u63A5\u542F\u52A8\u5931\u8D25\u3002");return e},async notifyStop({baseUrl:r,token:o,signal:i}){return Xc(n,{method:"POST",baseUrl:r,endpoint:"ilink/bot/msg/notifystop",token:o,signal:i,timeoutMs:1e4,body:{base_info:Cu()}})}})}function lx(n){for(let r of n?.item_list??[]){if(r?.type===1&&typeof r.text_item?.text=="string"){let o=r.text_item.text.trim();if(o)return o}if(r?.type===3&&typeof r.voice_item?.text=="string"){let o=r.voice_item.text.trim();if(o)return o}}return null}function Ex(n){return n?.message_id!==void 0&&n.message_id!==null?String(n.message_id):ci(n?.client_id)}function Cx(n,r=4e3){if(n.length<=r)return[n];let o=[],i=n;for(;i.length>r;){let e=i.lastIndexOf(`
171
171
  `,r);e<Math.floor(r*.6)&&(e=r),o.push(i.slice(0,e)),i=i.slice(e).replace(/^\n+/,"")}return i&&o.push(i),o}var B_=Object.freeze({version:1,accounts:Object.freeze([])});function Tn(n){return typeof n=="string"&&n.trim()?n.trim():null}function px(n){let r=Tn(n);return r&&/^wx_[a-f0-9]{24}$/.test(r)?r:null}function Whe(n){let r=Tn(n);return r&&/^DSH_WEIXIN_BOT_TOKEN_[A-F0-9]{24}$/.test(r)?r:null}function u_(n){let r=Tn(n);if(!r)throw new TypeError("accountId is required");let o=Yhe("sha256").update(r).digest("hex").slice(0,24);return{botId:`wx_${o}`,tokenRef:`DSH_WEIXIN_BOT_TOKEN_${o.toUpperCase()}`}}function hx(n){let r=Tn(n)??"";return r.length<=10?r?`${r.slice(0,3)}\u2022\u2022\u2022`:"\u5FAE\u4FE1\u673A\u5668\u4EBA":`${r.slice(0,6)}\u2022\u2022\u2022\u2022${r.slice(-4)}`}function dx(n){if(!n||typeof n!="object")return null;let r=Tn(n.accountId),o=Tn(n.ownerUserId),i=px(n.botId),e=Whe(n.tokenRef);if(!r||!o||!i||!e)return null;let a=u_(r);if(a.botId!==i||a.tokenRef!==e)return null;let A;try{A=$c(n.baseUrl)}catch{return null}return Object.freeze({botId:i,accountId:r,tokenRef:e,ownerUserId:o,baseUrl:A,createdAt:Tn(n.createdAt)??new Date().toISOString(),connectedAt:Tn(n.connectedAt)})}function Zhe(n){if(!n||n.version!==1||!Array.isArray(n.accounts))return null;let r=n.accounts.map(dx);if(r.some(a=>a===null))return null;let o=new Set,i=new Set,e=new Set;for(let a of r){if(o.has(a.botId)||i.has(a.accountId)||e.has(a.tokenRef))return null;o.add(a.botId),i.add(a.accountId),e.add(a.tokenRef)}return Object.freeze({version:1,accounts:Object.freeze(r)})}var hu=class{#A;#e=B_;#t=Promise.resolve();constructor(r){this.#A=r}async load(){try{let r=Zhe(JSON.parse(await Jhe(this.#A,"utf8")));if(!r)throw new Error("dsh-weixin config contains invalid account data");this.#e=r}catch(r){if(r?.code!=="ENOENT")throw r;this.#e=B_}return this}list(){return structuredClone(this.#e.accounts)}get(r){let o=this.#e.accounts.find(i=>i.botId===r);return o?structuredClone(o):null}getByAccountId(r){let o=this.#e.accounts.find(i=>i.accountId===r);return o?structuredClone(o):null}async save(r){let o=dx(r);if(!o)throw new Error("Refusing to persist incomplete dsh-weixin account data");return this.#a(i=>{let e=i.find(t=>t.accountId===o.accountId&&t.botId!==o.botId),a=i.find(t=>t.tokenRef===o.tokenRef&&t.botId!==o.botId);if(e||a)throw new Error("Duplicate Weixin account identity");let A=i.findIndex(t=>t.botId===o.botId);return A===-1?i.push(o):i[A]=o,structuredClone(o)})}async remove(r){if(!px(r))throw new TypeError("Invalid Weixin bot id");return this.#a(o=>{let i=o.findIndex(a=>a.botId===r);if(i===-1)return null;let[e]=o.splice(i,1);return structuredClone(e)})}async clear(){let r=this.#t.then(async()=>{try{await qhe(this.#A)}catch(o){if(o?.code!=="ENOENT")throw o}this.#e=B_});this.#t=r.then(()=>{},()=>{}),await r}async#a(r){let o,i=this.#t.then(async()=>{let e=[...this.#e.accounts];o=r(e);let a=Object.freeze({version:1,accounts:Object.freeze(e)});await this.#s(a),this.#e=a});return this.#t=i.then(()=>{},()=>{}),await i,o}async#s(r){await xhe(zhe(this.#A),{recursive:!0,mode:448});let o=`${this.#A}.tmp`;await Vhe(o,`${JSON.stringify(r,null,2)}
172
172
  `,{encoding:"utf8",mode:384}),await jhe(o,this.#A)}};import{mkdir as Xhe,readFile as $he,rename as ede,unlink as Ade,writeFile as tde}from"node:fs/promises";import{dirname as ade}from"node:path";var du=Object.freeze({version:1,sessions:{},seenMessageIds:[],getUpdatesBuf:""});function rde(n){if(!n||typeof n!="object")return structuredClone(du);let r={};if(n.sessions&&typeof n.sessions=="object"&&!Array.isArray(n.sessions))for(let[o,i]of Object.entries(n.sessions))typeof o=="string"&&typeof i=="string"&&i&&(r[o]=i);return{version:1,sessions:r,seenMessageIds:Array.isArray(n.seenMessageIds)?n.seenMessageIds.filter(o=>typeof o=="string").slice(-1e3):[],getUpdatesBuf:typeof n.getUpdatesBuf=="string"?n.getUpdatesBuf:""}}var Bu=class{#A;#e=structuredClone(du);#t=Promise.resolve();constructor(r){this.#A=r}async load(){try{this.#e=rde(JSON.parse(await $he(this.#A,"utf8")))}catch(r){if(r?.code!=="ENOENT")throw r;this.#e=structuredClone(du),await this.#a()}return this}sessionFor(r){return this.#e.sessions[r]??null}async setSession(r,o){this.#e.sessions[r]=o,await this.#a()}async clearSession(r){delete this.#e.sessions[r],await this.#a()}hasSeen(r){return this.#e.seenMessageIds.includes(r)}async markSeen(r){this.hasSeen(r)||(this.#e.seenMessageIds.push(r),this.#e.seenMessageIds.length>1e3&&this.#e.seenMessageIds.splice(0,this.#e.seenMessageIds.length-1e3),await this.#a())}getUpdatesBuf(){return this.#e.getUpdatesBuf}async setGetUpdatesBuf(r){typeof r!="string"||r===this.#e.getUpdatesBuf||(this.#e.getUpdatesBuf=r,await this.#a())}snapshot(){return structuredClone(this.#e)}async remove(){try{await Ade(this.#A)}catch(r){if(r?.code!=="ENOENT")throw r}this.#e=structuredClone(du)}async#a(){let r=`${JSON.stringify(this.#e,null,2)}
173
173
  `,o=this.#t.then(async()=>{await Xhe(ade(this.#A),{recursive:!0,mode:448});let i=`${this.#A}.tmp`;await tde(i,r,{encoding:"utf8",mode:384}),await ede(i,this.#A)});this.#t=o.then(()=>{},()=>{}),await o}};import{randomUUID as ide}from"node:crypto";var Bx=new Set(["starting","pending","scanned","needs_verification","connecting"]),uu=new Set(["connected","expired","failed","cancelled"]),ux=5*6e4;function eI(n){return typeof n=="string"&&n.trim()?n.trim():null}function ode(){return new DOMException("Provisioning was cancelled","AbortError")}function Qx(n,r){let o=eI(n);return o?$c(o.includes("://")?o:`https://${o}`):$c(r)}function lC(n){return n?{attemptId:n.id,status:n.state,...n.verificationUrl?{verificationUrl:n.verificationUrl}:{},...n.expiresAt?{expiresAt:n.expiresAt}:{},pollIntervalMs:1e3,...n.state==="needs_verification"?{verificationRequired:!0}:{},...n.botId?{botId:n.botId}:{},...n.alreadyConnected?{alreadyConnected:!0}:{},...n.error?{error:structuredClone(n.error)}:{}}:null}function dr(n,r){return Object.freeze({code:n,message:r})}var EC=class{#A;#e;#t;#a;#s;#n;#I=new Map;#g=new Map;#o=new Map;#r=null;#i=new Map;#c=0;#l=!1;constructor({api:r,credentials:o,configStore:i,createRuntime:e,deleteState:a=async()=>{},logger:A=console}){if(!r||typeof r.beginLogin!="function"||typeof r.pollLogin!="function")throw new TypeError("WeixinController requires a Weixin API client");if(!o||typeof o.resolve!="function"||typeof o.set!="function"||typeof o.unset!="function")throw new TypeError("WeixinController requires the DSH credential provider");if(!i||typeof i.list!="function"||typeof i.save!="function"||typeof i.remove!="function")throw new TypeError("WeixinController requires a config store");if(typeof e!="function")throw new TypeError("createRuntime is required");this.#A=r,this.#e=o,this.#t=i,this.#a=e,this.#s=a,this.#n=A}async initialize(){if(this.#l)return this.status();for(let r of this.#t.list())this.#I.get(r.botId)?.status?.ready!==!0&&await this.#Q(r.botId,async()=>{let i=this.#t.get(r.botId);if(!(!i||this.#l))try{let e=await this.#d(i.tokenRef);if(!e){this.#g.set(i.botId,dr("missing-token","\u767B\u5F55\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u79FB\u9664\u8D26\u53F7\u540E\u91CD\u65B0\u626B\u7801\u3002"));return}await this.#p(i,e),this.#g.delete(i.botId)}catch(e){this.#g.set(i.botId,dr("connection-failed","\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002")),this.#n.warn?.(`[dsh-weixin] account ${i.botId} failed to initialize:`,e)}finally{this.#f()}});return this.status()}async startProvisioning(){if(this.#l)throw new Error("dsh-weixin controller is closed");this.#r&&await this.cancelProvisioning(this.#r);let r={id:ide(),state:"starting",createdAt:Date.now(),expiresAt:Date.now()+ux,controller:new AbortController,pendingVerifyCode:null,verifyResolve:null,currentBaseUrl:pu,error:null,botId:null,task:null};this.#o.set(r.id,r),this.#r=r.id,this.#f();try{let o=(await Promise.all(this.#t.list().slice(-10).map(async e=>this.#d(e.tokenRef)))).filter(Boolean),i=await this.#A.beginLogin({localTokens:o,signal:r.controller.signal});return this.#B(r),r.qrcode=i.qrcode,r.verificationUrl=i.qrcodeUrl,r.state="pending",r.expiresAt=Date.now()+ux,this.#f(),r.task=this.#E(r),lC(r)}catch(o){throw r.controller.signal.aborted?(r.state="cancelled",r.error=dr("cancelled","\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002")):(r.state="failed",r.error=dr(o instanceof ct?o.code:"qr-start-failed",o instanceof ct?o.message:"\u65E0\u6CD5\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")),this.#r===r.id&&(this.#r=null),this.#f(),o}}registrationStatus(r){return lC(this.#o.get(r))}async submitVerification(r,o){let i=this.#o.get(r);if(!i||i.state!=="needs_verification")throw new Error("The provisioning attempt is not waiting for a verification code");let e=eI(o);if(!e||!/^\d{4,8}$/.test(e))throw new TypeError("Verification code must contain 4 to 8 digits");return i.pendingVerifyCode=e,i.state="scanned",i.verifyResolve?.(),i.verifyResolve=null,this.#f(),lC(i)}async cancelProvisioning(r){let o=this.#o.get(r);return o?(uu.has(o.state)||(o.controller.abort(),o.verifyResolve?.(),o.verifyResolve=null,await o.task?.catch(()=>{}),uu.has(o.state)||(o.state="cancelled"),o.error??=dr("cancelled","\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002")),this.#r===o.id&&(this.#r=null),this.#f(),lC(o)):null}async reconnectBot(r){let o=this.#t.get(r);if(!o)throw new Error("Unknown Weixin account");return await this.#Q(r,async()=>{let i=await this.#d(o.tokenRef);if(!i)throw new Error("The Weixin token is missing");try{await this.#p(o,i),this.#g.delete(r)}catch(e){throw this.#g.set(r,dr("connection-failed","\u5FAE\u4FE1\u8FDE\u63A5\u4ECD\u672A\u5C31\u7EEA\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")),e}finally{this.#f()}}),this.status()}async deleteBot(r){let o=this.#t.get(r);if(!o)throw new Error("Unknown Weixin account");return await this.#Q(r,async()=>{let i=await this.#e.resolve(o.tokenRef).catch(()=>{});await this.#h(r);try{await this.#e.unset(o.tokenRef),await this.#t.remove(r)}catch(e){throw i?.value&&(await this.#e.set(o.tokenRef,i.value).catch(()=>{}),await this.#p(o,i.value).catch(()=>{})),new Error("Unable to remove the Weixin account safely.",{cause:e})}try{await this.#s({botId:r,config:o})}catch(e){this.#n.warn?.(`[dsh-weixin] account ${r} state cleanup failed:`,e)}this.#g.delete(r),this.#f()}),this.status()}status(){let r=this.#t.list().map(e=>{let a=this.#I.get(e.botId)?.status??null,A=a?.ready===!0&&a.weixinConnectionState==="connected"&&a.harnessReachable===!0,t=A?"connected":a?.weixinConnectionState==="connecting"?"connecting":this.#g.has(e.botId)||a?.weixinConnectionState==="failed"?"error":"offline",s=this.#g.get(e.botId)??(t==="error"?dr("connection-failed","\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002"):null);return{botId:e.botId,state:t,connected:A,configured:!0,bot:{name:"\u5FAE\u4FE1\u673A\u5668\u4EBA",accountIdMasked:hx(e.accountId)},health:{status:A?"healthy":t==="error"?"error":"offline",summary:A?"\u5FAE\u4FE1\u6D88\u606F\u957F\u8F6E\u8BE2\u8FD0\u884C\u6B63\u5E38":t==="error"?"\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5":"\u5FAE\u4FE1\u8FDE\u63A5\u5F53\u524D\u79BB\u7EBF",lastCheckedAt:a?.lastCheckedAt??null},stats:{messagesReceived:a?.messagesReceived??0,messagesReplied:a?.messagesReplied??0},error:s?structuredClone(s):null}}),o=r.filter(e=>e.connected).length,i=this.#r?this.#o.get(this.#r):null;return{schemaVersion:1,revision:this.#c,state:i&&Bx.has(i.state)?"provisioning":r.length===0?"disconnected":o===r.length?"connected":o>0?"degraded":"offline",bots:r,totals:{configured:r.length,connected:o},...i&&Bx.has(i.state)?{provisioning:lC(i)}:{}}}async close(){this.#l||(this.#l=!0,this.#r&&await this.cancelProvisioning(this.#r),await Promise.allSettled([...this.#I.keys()].map(r=>this.#h(r))))}async#E(r){try{for(;!r.controller.signal.aborted&&Date.now()<r.expiresAt;){r.state==="needs_verification"&&!r.pendingVerifyCode&&(await new Promise(i=>{r.verifyResolve=i,r.controller.signal.aborted&&i()}),r.verifyResolve=null,this.#B(r));let o=await this.#A.pollLogin({qrcode:r.qrcode,baseUrl:r.currentBaseUrl,verifyCode:r.pendingVerifyCode,signal:r.controller.signal});if(this.#B(r),o.status==="wait")r.state="pending";else if(o.status==="scaned")r.pendingVerifyCode=null,r.state="scanned";else if(o.status==="need_verifycode")r.pendingVerifyCode=null,r.state="needs_verification";else if(o.status==="verify_code_blocked"){r.state="failed",r.error=dr("verification-blocked","\u914D\u5BF9\u7801\u591A\u6B21\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801\u3002");break}else if(o.status==="expired"){r.state="expired",r.error=dr("expired","\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002");break}else if(o.status==="scaned_but_redirect")r.currentBaseUrl=Qx(o.redirect_host,r.currentBaseUrl),r.state="scanned";else if(o.status==="binded_redirect"){let i=this.#t.list().find(e=>this.#I.get(e.botId)?.status?.ready===!0)??this.#t.list()[0];i?(r.state="connected",r.botId=i.botId,r.alreadyConnected=!0):(r.state="failed",r.error=dr("already-bound","\u8BE5\u5FAE\u4FE1\u8D26\u53F7\u5DF2\u7ED1\u5B9A\uFF0C\u4F46\u672C\u673A\u6CA1\u6709\u53EF\u6062\u590D\u7684\u51ED\u636E\u3002"));break}else if(o.status==="confirmed"){let i=eI(o.bot_token),e=eI(o.ilink_bot_id),a=eI(o.ilink_user_id);if(!i||!e||!a)throw new ct("incomplete-login","\u5FAE\u4FE1\u6388\u6743\u6210\u529F\uFF0C\u4F46\u8FD4\u56DE\u7684\u8D26\u53F7\u51ED\u636E\u4E0D\u5B8C\u6574\u3002");r.state="connecting",this.#f();let A=Qx(o.baseurl,r.currentBaseUrl);r.botId=await this.#C(r,{token:i,accountId:e,ownerUserId:a,baseUrl:A}),r.state="connected",r.error=null;break}this.#f()}!r.controller.signal.aborted&&Date.now()>=r.expiresAt&&!uu.has(r.state)&&(r.state="expired",r.error=dr("expired","\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002"))}catch(o){r.controller.signal.aborted||o?.name==="AbortError"?(r.state="cancelled",r.error=dr("cancelled","\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002")):(r.state="failed",r.error=dr(o instanceof ct?o.code:"activation-failed",o instanceof ct?o.message:"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u65E0\u6CD5\u4FDD\u5B58\u51ED\u636E\u6216\u542F\u52A8\u6D88\u606F\u8FDE\u63A5\u3002"),this.#n.error?.("[dsh-weixin] provisioning failed:",o))}finally{r.pendingVerifyCode=null,r.verifyResolve?.(),r.verifyResolve=null,this.#r===r.id&&(this.#r=null),this.#f(),this.#y()}}async#C(r,{token:o,accountId:i,ownerUserId:e,baseUrl:a}){let A=u_(i),t=this.#t.getByAccountId(i),s={botId:A.botId,accountId:i,tokenRef:A.tokenRef,ownerUserId:e,baseUrl:a,createdAt:t?.createdAt??new Date().toISOString(),connectedAt:new Date().toISOString()},g=await this.#e.resolve(A.tokenRef).catch(()=>{});return this.#Q(A.botId,async()=>{await this.#e.set(A.tokenRef,o);try{return this.#B(r),await this.#t.save(s),this.#B(r),await this.#p(s,o),this.#B(r),this.#g.delete(A.botId),this.#f(),A.botId}catch(c){throw await this.#h(A.botId),t?await this.#t.save(t).catch(()=>{}):this.#t.get(A.botId)&&await this.#t.remove(A.botId).catch(()=>{}),await this.#u(A.tokenRef,g),t&&g?.value&&await this.#p(t,g.value).catch(()=>{}),c}})}async#p(r,o){await this.#h(r.botId);let i=await this.#a({botId:r.botId,config:r,token:o});if(!i||typeof i.start!="function"||typeof i.stop!="function")throw new TypeError("createRuntime returned an invalid Weixin runtime");try{await i.start(),this.#I.set(r.botId,i)}catch(e){throw await i.stop().catch(()=>{}),e}}async#h(r){let o=this.#I.get(r);this.#I.delete(r),await o?.stop().catch(i=>{this.#n.warn?.(`[dsh-weixin] account ${r} failed to stop cleanly:`,i)})}async#d(r){let o=await this.#e.resolve(r).catch(()=>{});return eI(o?.value)}async#u(r,o){try{o?.value?await this.#e.set(r,o.value):await this.#e.unset(r)}catch(i){this.#n.error?.(`[dsh-weixin] failed to restore credential ${r}:`,i)}}#B(r){if(r.controller.signal.aborted||this.#r!==r.id)throw ode()}#Q(r,o){let a=(this.#i.get(r)??Promise.resolve()).catch(()=>{}).then(o).finally(()=>{this.#i.get(r)===a&&this.#i.delete(r)});return this.#i.set(r,a),a}#y(){for(let[r,o]of this.#o)r!==this.#r&&uu.has(o.state)&&this.#o.size>16&&this.#o.delete(r)}#f(){this.#c+=1}};var nde=["\u5FAE\u4FE1\u5DF2\u8FDE\u63A5 DeepSeek Harness\u3002","","\u76F4\u63A5\u53D1\u9001\u6587\u5B57\u6216\u5E26\u6587\u5B57\u8BC6\u522B\u7ED3\u679C\u7684\u8BED\u97F3\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002","/new \u5F00\u542F\u4E00\u4E2A\u5168\u65B0\u4F1A\u8BDD","/status \u68C0\u67E5\u8FDE\u63A5\u72B6\u6001","/help \u663E\u793A\u672C\u5E2E\u52A9"].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmanrui/dsh-im",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "通过扫码或机器人凭据把IM机器人接入DeepSeek Harness(支持飞书、微信、钉钉、企业微信、QQ、Telegram、Discord和WhatsApp)。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -6,7 +6,7 @@ const CSS = String.raw`
6
6
  --ddt-accent-deep: #0958d9;
7
7
  --ddt-accent-wash: #eaf3ff;
8
8
  --ddt-success: var(--dsw-alias-state-success-primary, #20a162);
9
- --ddt-warning: var(--dsw-alias-state-warning-primary, #d97706);
9
+ --ddt-warning: var(--dsw-alias-state-warn-primary, #d97706);
10
10
  --ddt-error: var(--dsw-alias-state-error-primary, #d54941);
11
11
  width: 100%;
12
12
  max-width: 880px;
@@ -27,13 +27,13 @@ const CSS = String.raw`
27
27
  .ddt-heading p { margin-top: 5px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; white-space: nowrap; }
28
28
  .ddt-tools, .ddt-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
29
29
  .ddt-tools { width: 100%; justify-content: space-between; flex-wrap: nowrap; }
30
- .ddt-badge { min-height: 30px; display: inline-flex; align-items: center; gap: 7px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-fill-secondary, #f2f3f5); font-size: 12px; white-space: nowrap; }
30
+ .ddt-badge { min-height: 30px; display: inline-flex; align-items: center; gap: 7px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font-size: 12px; white-space: nowrap; }
31
31
  .ddt-dot { width: 8px; height: 8px; flex: none; border-radius: 50%; background: #aeb3bb; }
32
32
  .ddt-dot[data-tone="success"] { background: var(--ddt-success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ddt-success) 14%, transparent); }
33
33
  .ddt-dot[data-tone="warning"] { background: var(--ddt-warning); }
34
34
  .ddt-dot[data-tone="error"] { background: var(--ddt-error); }
35
- .ddt-button { min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 0 13px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: inherit; font-size: 13px; font-weight: 560; text-decoration: none; cursor: pointer; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
36
- .ddt-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
35
+ .ddt-button { min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 0 13px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; text-decoration: none; cursor: pointer; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
36
+ .ddt-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
37
37
  .ddt-button:active:not(:disabled) { transform: translateY(1px); }
38
38
  .ddt-button:focus-visible { outline: 2px solid color-mix(in srgb, var(--ddt-accent) 70%, white); outline-offset: 2px; }
39
39
  .ddt-button:disabled { cursor: not-allowed; opacity: .55; }
@@ -41,7 +41,7 @@ const CSS = String.raw`
41
41
  .ddt-button[data-kind="primary"]:hover:not(:disabled) { border-color: var(--ddt-accent-deep); background: var(--ddt-accent-deep); }
42
42
  .ddt-button[data-kind="danger"] { color: var(--ddt-error); }
43
43
  .ddt-button[data-kind="quiet"] { min-height: 30px; padding: 0 10px; border-color: transparent; background: transparent; }
44
- .ddt-card { overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
44
+ .ddt-card { overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
45
45
  .ddt-cardBody { padding: 24px; }
46
46
  .ddt-empty { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
47
47
  .ddt-empty h3 { margin: 8px 0; font-size: 18px; }
@@ -51,7 +51,7 @@ const CSS = String.raw`
51
51
  .ddt-brandMark svg { filter: drop-shadow(0 3px 8px rgb(0 35 96 / 16%)); }
52
52
  .ddt-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: start; }
53
53
  .ddt-qrColumn { display: flex; flex-direction: column; align-items: center; gap: 12px; }
54
- .ddt-qrFrame { position: relative; width: min(270px, 100%); aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 16px; background: #fff; }
54
+ .ddt-qrFrame { position: relative; width: min(270px, 100%); aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: #fff; }
55
55
  .ddt-qrFrame::before { content: ''; position: absolute; inset: 6px; border: 1px solid rgb(22 119 255 / 10%); border-radius: 11px; pointer-events: none; }
56
56
  .ddt-qrFrame img { display: block; width: 100%; height: 100%; object-fit: contain; }
57
57
  .ddt-qrFallback { padding: 24px; color: #646a73; text-align: center; }
@@ -87,10 +87,10 @@ const CSS = String.raw`
87
87
  .ddt-accountIdentity p { margin-top: 4px; color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; }
88
88
  .ddt-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
89
89
  .ddt-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 20px 0; }
90
- .ddt-metric { min-width: 0; padding: 12px; border-radius: 9px; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
90
+ .ddt-metric { min-width: 0; padding: 12px; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
91
91
  .ddt-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; }
92
92
  .ddt-metric dd { overflow: hidden; margin: 5px 0 0; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
93
- .ddt-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
93
+ .ddt-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
94
94
  .ddt-accountFooter .ddt-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
95
95
  .ddt-accountFooter .ddt-button { flex: none; white-space: nowrap; }
96
96
  .ddt-summary { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
@@ -4,7 +4,7 @@ const CSS = String.raw`
4
4
  .bxf-page {
5
5
  --bxf-accent: var(--dsw-alias-state-business-primary, #3370ff);
6
6
  --bxf-success: var(--dsw-alias-state-success-primary, #20a162);
7
- --bxf-warning: var(--dsw-alias-state-warning-primary, #d97706);
7
+ --bxf-warning: var(--dsw-alias-state-warn-primary, #d97706);
8
8
  --bxf-error: var(--dsw-alias-state-error-primary, #d54941);
9
9
  box-sizing: border-box;
10
10
  width: 100%;
@@ -393,7 +393,7 @@ const CSS = String.raw`
393
393
 
394
394
  .bxf-connectedTop { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
395
395
  .bxf-botIdentity { min-width: 0; display: flex; align-items: center; gap: 13px; }
396
- .bxf-avatar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
396
+ .bxf-avatar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
397
397
  .bxf-botName { min-width: 0; }
398
398
  .bxf-botName h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 17px; line-height: 24px; font-weight: 650; }
399
399
  .bxf-botName p { overflow: hidden; color: var(--dsw-alias-label-tertiary, #8f959e); font-family: var(--ds-font-family-code, monospace); font-size: 12px; line-height: 18px; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
@@ -407,7 +407,7 @@ const CSS = String.raw`
407
407
  .bxf-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 17px; }
408
408
  .bxf-metric dd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 18px; font-weight: 550; margin: 3px 0 0; }
409
409
 
410
- .bxf-connectedFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
410
+ .bxf-connectedFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
411
411
  .bxf-healthSummary { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
412
412
  .bxf-healthSummary[data-error="true"] { color: var(--bxf-error); }
413
413
  .bxf-botActions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; justify-content: flex-end; }
@@ -2,7 +2,7 @@ export const WECOM_STYLE_ID = 'xmanrui-dsh-im-wecom-settings';
2
2
 
3
3
  const CSS = String.raw`
4
4
  .dwecom-page { --ddt-accent: #3370ff; --ddt-accent-deep: #245bdb; --ddt-accent-wash: #eef4ff; }
5
- .dwecom-avatar, .dwecom-brand { color: #3370ff; background: #fff; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
5
+ .dwecom-avatar, .dwecom-brand { color: #3370ff; background: #fff; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
6
6
  .dwecom-avatar svg, .dwecom-brand svg { display: block; }
7
7
  `;
8
8
 
@@ -5,7 +5,7 @@ const CSS = String.raw`
5
5
  --dxw-accent: #07c160;
6
6
  --dxw-accent-dark: #05994c;
7
7
  --dxw-success: var(--dsw-alias-state-success-primary, #20a162);
8
- --dxw-warning: var(--dsw-alias-state-warning-primary, #d97706);
8
+ --dxw-warning: var(--dsw-alias-state-warn-primary, #d97706);
9
9
  --dxw-error: var(--dsw-alias-state-error-primary, #d54941);
10
10
  width: 100%;
11
11
  max-width: 880px;
@@ -24,20 +24,20 @@ const CSS = String.raw`
24
24
  .dxw-heading p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; margin-top: 5px; white-space: nowrap; }
25
25
  .dxw-tools, .dxw-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
26
26
  .dxw-tools { width: 100%; justify-content: space-between; flex-wrap: nowrap; }
27
- .dxw-badge { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-fill-secondary, #f2f3f5); font-size: 12px; white-space: nowrap; }
27
+ .dxw-badge { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font-size: 12px; white-space: nowrap; }
28
28
  .dxw-dot { width: 8px; height: 8px; border-radius: 50%; background: #aeb3bb; flex: none; }
29
29
  .dxw-dot[data-tone="success"] { background: var(--dxw-success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dxw-success) 14%, transparent); }
30
30
  .dxw-dot[data-tone="warning"] { background: var(--dxw-warning); }
31
31
  .dxw-dot[data-tone="error"] { background: var(--dxw-error); }
32
- .dxw-button { min-height: 34px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; padding: 0 13px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: inherit; font-size: 13px; font-weight: 560; cursor: pointer; text-decoration: none; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
33
- .dxw-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
32
+ .dxw-button { min-height: 34px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; padding: 0 13px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; cursor: pointer; text-decoration: none; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
33
+ .dxw-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
34
34
  .dxw-button:active:not(:disabled) { transform: translateY(1px); }
35
35
  .dxw-button:focus-visible, .dxw-input:focus-visible { outline: 2px solid color-mix(in srgb, var(--dxw-accent) 70%, white); outline-offset: 2px; }
36
36
  .dxw-button:disabled { cursor: not-allowed; opacity: .55; }
37
37
  .dxw-button[data-kind="primary"] { color: white; border-color: var(--dxw-accent); background: var(--dxw-accent); }
38
38
  .dxw-button[data-kind="primary"]:hover:not(:disabled) { border-color: var(--dxw-accent-dark); background: var(--dxw-accent-dark); }
39
39
  .dxw-button[data-kind="danger"] { color: var(--dxw-error); }
40
- .dxw-card { overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
40
+ .dxw-card { overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
41
41
  .dxw-cardBody { padding: 24px; }
42
42
  .dxw-empty { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
43
43
  .dxw-empty h3 { font-size: 18px; margin-bottom: 8px; }
@@ -47,7 +47,7 @@ const CSS = String.raw`
47
47
  .dxw-logo svg { width: 62px; height: 62px; }
48
48
  .dxw-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: center; }
49
49
  .dxw-qrColumn { display: flex; flex-direction: column; align-items: center; gap: 12px; }
50
- .dxw-qrFrame { position: relative; width: 270px; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 16px; background: white; }
50
+ .dxw-qrFrame { position: relative; width: 270px; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: white; }
51
51
  .dxw-qrFrame img { display: block; width: 100%; height: 100%; object-fit: contain; }
52
52
  .dxw-qrFallback { padding: 24px; text-align: center; color: #646a73; }
53
53
  .dxw-expired { position: absolute; inset: 0; display: grid; place-items: center; padding: 30px; color: white; text-align: center; font-weight: 650; background: rgb(31 35 41 / 76%); backdrop-filter: blur(3px); }
@@ -63,7 +63,7 @@ const CSS = String.raw`
63
63
  .dxw-verify h3 { margin: 8px 0; font-size: 19px; }
64
64
  .dxw-verify p { color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.6; }
65
65
  .dxw-codeRow { display: flex; justify-content: center; gap: 10px; margin: 24px 0 10px; }
66
- .dxw-input { width: 190px; height: 42px; padding: 0 14px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-body, white); color: inherit; font: inherit; font-size: 18px; letter-spacing: .16em; text-align: center; }
66
+ .dxw-input { width: 190px; height: 42px; padding: 0 14px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-1, white); color: inherit; font: inherit; font-size: 18px; letter-spacing: .16em; text-align: center; }
67
67
  .dxw-statusNotice, .dxw-error { display: flex; align-items: center; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dxw-error) 28%, transparent); border-radius: 10px; color: var(--dxw-error); background: color-mix(in srgb, var(--dxw-error) 7%, transparent); font-size: 13px; }
68
68
  .dxw-error { align-items: flex-start; flex-direction: column; padding: 22px; }
69
69
  .dxw-error h3 { font-size: 17px; }
@@ -78,10 +78,10 @@ const CSS = String.raw`
78
78
  .dxw-accountIdentity p { color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; margin-top: 4px; }
79
79
  .dxw-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
80
80
  .dxw-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 20px 0; }
81
- .dxw-metric { padding: 12px 14px; border-radius: 9px; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
81
+ .dxw-metric { padding: 12px 14px; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
82
82
  .dxw-metric dt { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; }
83
83
  .dxw-metric dd { overflow: hidden; margin: 5px 0 0; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
84
- .dxw-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
84
+ .dxw-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
85
85
  .dxw-accountFooter .dxw-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
86
86
  .dxw-accountFooter .dxw-button { flex: none; white-space: nowrap; }
87
87
  .dxw-summary { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
@@ -2,7 +2,7 @@ export const IM_STYLE_ID = 'xmanrui-dsh-im-settings';
2
2
 
3
3
  const CSS = String.raw`
4
4
  .dim-page {
5
- --dim-blue: #3370ff;
5
+ --dim-blue: var(--dsw-alias-state-business-primary, #3370ff);
6
6
  --dim-blue-soft: color-mix(in srgb, var(--dim-blue) 9%, transparent);
7
7
  width: 100%;
8
8
  max-width: 1080px;
@@ -14,24 +14,24 @@ const CSS = String.raw`
14
14
  .dim-title { margin: 0 0 26px; }
15
15
  .dim-title p { margin: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; white-space: nowrap; }
16
16
  .dim-layout { display: grid; grid-template-columns: 174px 1px minmax(0, 1fr); gap: 24px; align-items: start; }
17
- .dim-rail { max-height: 520px; display: grid; align-content: start; gap: 8px; overflow-y: auto; padding: 1px 4px 1px 1px; scrollbar-width: thin; scrollbar-color: var(--dsw-alias-line-border, #dfe1e5) transparent; }
17
+ .dim-rail { max-height: 520px; display: grid; align-content: start; gap: 8px; overflow-y: auto; padding: 1px 4px 1px 1px; scrollbar-width: thin; scrollbar-color: var(--dsw-alias-border-l2, #dfe1e5) transparent; }
18
18
  .dim-rail::-webkit-scrollbar { width: 4px; }
19
- .dim-rail::-webkit-scrollbar-thumb { border-radius: 99px; background: var(--dsw-alias-line-border, #dfe1e5); }
20
- .dim-channel { width: 100%; min-height: 48px; display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--dsw-alias-line-border, #eef0f3); border-radius: 14px; color: inherit; background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 2px 8px rgb(31 35 41 / 3%); font: inherit; text-align: left; cursor: pointer; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; }
21
- .dim-channel:hover { border-color: color-mix(in srgb, var(--dim-blue) 25%, var(--dsw-alias-line-border, #eef0f3)); background: color-mix(in srgb, var(--dim-blue) 2%, var(--dsw-alias-bg-layer-3, #fff)); box-shadow: 0 5px 16px rgb(31 35 41 / 5%); }
22
- .dim-channel[aria-selected="true"] { border-color: color-mix(in srgb, var(--dim-blue) 43%, white); color: var(--dim-blue); background: color-mix(in srgb, var(--dim-blue) 9%, white); box-shadow: 0 3px 12px rgb(51 112 255 / 7%); }
23
- .dim-channel:focus-visible { outline: none; border-color: color-mix(in srgb, var(--dim-blue) 72%, white); box-shadow: 0 0 0 1px color-mix(in srgb, var(--dim-blue) 24%, transparent) inset, 0 3px 12px rgb(51 112 255 / 7%); }
19
+ .dim-rail::-webkit-scrollbar-thumb { border-radius: 99px; background: var(--dsw-alias-border-l2, #dfe1e5); }
20
+ .dim-channel { width: 100%; min-height: 48px; display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--dsw-alias-border-l2, #eef0f3); border-radius: 14px; color: inherit; background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 2px 8px rgb(31 35 41 / 3%); font: inherit; text-align: left; cursor: pointer; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; }
21
+ .dim-channel:hover { border-color: color-mix(in srgb, var(--dim-blue) 25%, var(--dsw-alias-border-l2, #eef0f3)); background: color-mix(in srgb, var(--dim-blue) 2%, var(--dsw-alias-bg-layer-3, #fff)); box-shadow: 0 5px 16px rgb(31 35 41 / 5%); }
22
+ .dim-channel[aria-selected="true"] { border-color: color-mix(in srgb, var(--dim-blue) 43%, var(--dsw-alias-border-l2, #dfe1e5)); color: var(--dim-blue); background: color-mix(in srgb, var(--dim-blue) 12%, var(--dsw-alias-bg-layer-3, #fff)); box-shadow: 0 3px 12px rgb(51 112 255 / 7%); }
23
+ .dim-channel:focus-visible { outline: none; border-color: color-mix(in srgb, var(--dim-blue) 72%, var(--dsw-alias-border-l2, #dfe1e5)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--dim-blue) 24%, transparent) inset, 0 3px 12px rgb(51 112 255 / 7%); }
24
24
  .dim-logo { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 9px; box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
25
25
  .dim-logo svg { display: block; width: 20px; height: 20px; }
26
26
  .dim-logoWeixin { color: white; background: #07c160; }
27
27
  .dim-logoWeixin svg { width: 19px; height: 19px; }
28
- .dim-logoFeishu { background: white; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
28
+ .dim-logoFeishu { background: white; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
29
29
  .dim-logoFeishu svg { width: 28px; height: 28px; }
30
30
  .dim-logoDingtalk { color: white; background: #1677ff; }
31
31
  .dim-logoDingtalk svg { width: 24px; height: 24px; }
32
32
  .dim-logoQq { color: white; background: #1677ff; }
33
33
  .dim-logoQq svg { width: 21px; height: 21px; }
34
- .dim-logoWecom { background: white; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
34
+ .dim-logoWecom { background: white; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
35
35
  .dim-logoWecom svg { width: 22px; height: 22px; }
36
36
  .dim-logoTelegram { color: white; background: #229ed9; }
37
37
  .dim-logoTelegram svg { width: 21px; height: 21px; }
@@ -41,7 +41,7 @@ const CSS = String.raw`
41
41
  .dim-logoWhatsapp svg { width: 21px; height: 21px; }
42
42
  .dim-channelCopy { min-width: 0; display: block; }
43
43
  .dim-channelCopy strong { overflow: hidden; color: inherit; font-size: 14px; line-height: 20px; font-weight: 680; text-overflow: ellipsis; white-space: nowrap; }
44
- .dim-divider { width: 1px; min-height: 520px; background: var(--dsw-alias-line-divider, #eef0f3); }
44
+ .dim-divider { width: 1px; min-height: 520px; background: var(--dsw-alias-border-l1, #eef0f3); }
45
45
  .dim-panel { min-width: 0; container-type: inline-size; }
46
46
  .dim-panel .bxf-page, .dim-panel .dxw-page, .dim-panel .ddt-page, .dim-panel .dqq-page, .dim-panel .dwecom-page, .dim-panel .dwa-page { width: 100%; max-width: none; padding: 0 0 24px; }
47
47
  .dim-panel .bxf-heading, .dim-panel .dxw-heading, .dim-panel .ddt-heading { justify-content: flex-end; }
@@ -49,13 +49,13 @@ const CSS = String.raw`
49
49
  .dim-panel .dim-bindActions { min-width: 0; display: flex; align-items: center; flex-wrap: nowrap; gap: 8px; }
50
50
  .dim-panel .bxf-headingTools .dim-scanButton, .dim-panel .dxw-tools .dim-scanButton, .dim-panel .ddt-tools .dim-scanButton { flex: none; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 10px; border: 1px solid #1677ff; border-radius: 8px; color: #fff; background: #1677ff; box-shadow: none; font: inherit; font-size: 13px; font-weight: 560; white-space: nowrap; }
51
51
  .dim-panel .bxf-headingTools .dim-scanButton:hover:not(:disabled), .dim-panel .dxw-tools .dim-scanButton:hover:not(:disabled), .dim-panel .ddt-tools .dim-scanButton:hover:not(:disabled) { border-color: #0958d9; background: #0958d9; }
52
- .dim-panel .dim-credentialButton { flex: none; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 10px; border: 1px solid #86909c; border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 5%); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
52
+ .dim-panel .dim-credentialButton { flex: none; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 0 10px; border: 1px solid #86909c; border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 5%); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
53
53
  .dim-panel .dim-actionIcon { width: 15px; height: 15px; flex: 0 0 15px; }
54
- .dim-panel .dim-credentialButton:hover:not(:disabled) { border-color: #4e5969; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
55
- .dim-panel .dim-credentialButton[aria-pressed="true"] { border-color: #4e5969; background: var(--dsw-alias-fill-secondary, #f2f3f5); box-shadow: inset 0 0 0 1px rgb(78 89 105 / 8%); }
56
- .dim-panel .bxf-headingTools .dim-onlineBadge, .dim-panel .dxw-tools .dim-onlineBadge, .dim-panel .ddt-tools .dim-onlineBadge { flex: none; min-height: 30px; display: inline-flex; align-items: center; gap: 0; padding: 0 11px; border: 0; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-fill-secondary, #f2f3f5); font: inherit; font-size: 12px; font-weight: 400; line-height: normal; white-space: nowrap; }
54
+ .dim-panel .dim-credentialButton:hover:not(:disabled) { border-color: #4e5969; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
55
+ .dim-panel .dim-credentialButton[aria-pressed="true"] { border-color: #4e5969; background: var(--dsw-alias-bg-module-platform, #f2f3f5); box-shadow: inset 0 0 0 1px rgb(78 89 105 / 8%); }
56
+ .dim-panel .bxf-headingTools .dim-onlineBadge, .dim-panel .dxw-tools .dim-onlineBadge, .dim-panel .ddt-tools .dim-onlineBadge { flex: none; min-height: 30px; display: inline-flex; align-items: center; gap: 0; padding: 0 11px; border: 0; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font: inherit; font-size: 12px; font-weight: 400; line-height: normal; white-space: nowrap; }
57
57
  .dim-panel .dim-channelPage { width: 100%; max-width: none; display: flex; flex-direction: column; gap: 18px; padding: 0 0 24px; color: var(--dsw-alias-label-primary, #1f2329); box-sizing: border-box; }
58
- .dim-panel .dim-surfaceCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
58
+ .dim-panel .dim-surfaceCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
59
59
  .dim-panel .dim-surfaceCard::before { display: none; }
60
60
  .dim-panel .dim-surfaceBody { padding: 24px; }
61
61
  .dim-panel .dim-credentialPanel { display: grid; gap: 18px; padding: 20px; }
@@ -63,7 +63,7 @@ const CSS = String.raw`
63
63
  .dim-panel .dim-credentialForm { min-width: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 12px; }
64
64
  .dim-panel .dim-credentialFormSingle { grid-template-columns: minmax(0, 1fr); }
65
65
  .dim-panel .dim-credentialField { min-width: 0; display: grid; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; font-weight: 560; }
66
- .dim-panel .dim-credentialField input { width: 100%; min-width: 0; height: 38px; padding: 0 11px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; outline: none; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: 13px ui-monospace, SFMono-Regular, Menlo, monospace; transition: border-color .16s ease, box-shadow .16s ease; }
66
+ .dim-panel .dim-credentialField input { width: 100%; min-width: 0; height: 38px; padding: 0 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; outline: none; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: 13px ui-monospace, SFMono-Regular, Menlo, monospace; transition: border-color .16s ease, box-shadow .16s ease; }
67
67
  .dim-panel .dim-credentialField input:focus { border-color: #4e5969; box-shadow: 0 0 0 3px rgb(78 89 105 / 10%); }
68
68
  .dim-panel .dim-credentialField input::placeholder { color: var(--dsw-alias-label-tertiary, #8f959e); font-family: inherit; }
69
69
  .dim-panel .dim-credentialError, .dim-panel .dim-credentialActions { grid-column: 1 / -1; }
@@ -76,7 +76,7 @@ const CSS = String.raw`
76
76
  .dim-panel .dim-loadingView { padding: 38px; color: var(--dsw-alias-label-secondary, #646a73); text-align: center; }
77
77
  .dim-panel .dim-loadingView h3 { margin: 0 0 7px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 17px; line-height: normal; font-weight: 650; }
78
78
  .dim-panel .dim-loadingView p { margin: 0; line-height: 1.6; }
79
- .dim-panel .dim-spinner { width: 24px; height: 24px; margin: 0 auto 13px; border: 3px solid var(--dsw-alias-line-border, #e6e8eb); border-top-color: #1677ff; border-radius: 50%; animation: dim-spin .8s linear infinite; }
79
+ .dim-panel .dim-spinner { width: 24px; height: 24px; margin: 0 auto 13px; border: 3px solid var(--dsw-alias-border-l2, #e6e8eb); border-top-color: #1677ff; border-radius: 50%; animation: dim-spin .8s linear infinite; }
80
80
  @keyframes dim-spin { to { transform: rotate(360deg); } }
81
81
  .dim-panel .dim-emptyView { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
82
82
  .dim-panel .dim-emptyCopy { min-width: 0; }
@@ -86,47 +86,47 @@ const CSS = String.raw`
86
86
  .dim-panel .dim-stateLabel { display: inline-flex; align-items: center; gap: 8px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; font-weight: 600; }
87
87
  .dim-panel .dim-stateDot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--dsw-alias-label-tertiary, #8f959e); box-shadow: none; }
88
88
  .dim-panel .dim-stateDot[data-tone="success"] { background: var(--dsw-alias-state-success-primary, #20a162); }
89
- .dim-panel .dim-stateDot[data-tone="warning"] { background: var(--dsw-alias-state-warning-primary, #d97706); }
89
+ .dim-panel .dim-stateDot[data-tone="warning"] { background: var(--dsw-alias-state-warn-primary, #d97706); }
90
90
  .dim-panel .dim-stateDot[data-tone="error"] { background: var(--dsw-alias-state-error-primary, #d54941); }
91
91
  .dim-panel .dim-viewActions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
92
- .dim-panel .dim-viewActions .bxf-button, .dim-panel .dim-viewActions .dxw-button, .dim-panel .dim-viewActions .ddt-button { min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); box-shadow: none; font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
92
+ .dim-panel .dim-viewActions .bxf-button, .dim-panel .dim-viewActions .dxw-button, .dim-panel .dim-viewActions .ddt-button { min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: none; font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
93
93
  .dim-panel .dim-viewActions .bxf-button[data-kind="primary"], .dim-panel .dim-viewActions .dxw-button[data-kind="primary"], .dim-panel .dim-viewActions .ddt-button[data-kind="primary"] { border-color: #1677ff; color: #fff; background: #1677ff; box-shadow: none; }
94
94
  .dim-panel .dim-viewActions .bxf-button[data-kind="danger"], .dim-panel .dim-viewActions .dxw-button[data-kind="danger"], .dim-panel .dim-viewActions .ddt-button[data-kind="danger"] { color: var(--dsw-alias-state-error-primary, #d54941); }
95
95
  .dim-panel .dim-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: start; }
96
96
  .dim-panel .dim-qrColumn { width: 100%; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; }
97
- .dim-panel .dim-qrFrame { position: relative; width: min(270px, 100%); height: auto; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 16px; background: #fff; }
98
- .dim-panel .dim-qrFrame::before { content: ""; position: absolute; inset: 7px; z-index: 0; border: 1px solid color-mix(in srgb, #1677ff 16%, var(--dsw-alias-line-border, #dfe1e5)); border-radius: 12px; pointer-events: none; }
97
+ .dim-panel .dim-qrFrame { position: relative; width: min(270px, 100%); height: auto; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 16px; background: #fff; }
98
+ .dim-panel .dim-qrFrame::before { content: ""; position: absolute; inset: 7px; z-index: 0; border: 1px solid color-mix(in srgb, #1677ff 16%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 12px; pointer-events: none; }
99
99
  .dim-panel .dim-qrFrame::after { display: none; }
100
100
  .dim-panel .dim-qrFrame img { position: relative; z-index: 1; width: 100%; height: 100%; display: block; object-fit: contain; }
101
101
  .dim-panel .dim-qrFallback { position: relative; z-index: 1; display: grid; place-items: center; gap: 8px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 1.5; text-align: center; }
102
- .dim-panel .dim-qrExpired { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; padding: 20px; color: var(--dsw-alias-label-primary, #1f2329); background: rgb(255 255 255 / 92%); font-size: 15px; line-height: 1.6; font-weight: 650; text-align: center; white-space: pre-line; backdrop-filter: blur(3px); }
102
+ .dim-panel .dim-qrExpired { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; padding: 20px; color: var(--dsw-static-neutral-bluish-1000, #0f1115); background: rgb(255 255 255 / 92%); font-size: 15px; line-height: 1.6; font-weight: 650; text-align: center; white-space: pre-line; backdrop-filter: blur(3px); }
103
103
  .dim-panel .dim-countdown { width: min(270px, 100%); margin: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; }
104
104
  .dim-panel .dim-countdownTop { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
105
105
  .dim-panel .dim-countdownTop strong { color: var(--dsw-alias-label-primary, #1f2329); font-weight: 650; }
106
- .dim-panel .dim-progress { height: 4px; overflow: hidden; margin: 0; border-radius: 99px; background: var(--dsw-alias-fill-secondary, #eef0f3); }
106
+ .dim-panel .dim-progress { height: 4px; overflow: hidden; margin: 0; border-radius: 99px; background: var(--dsw-alias-bg-module-platform, #eef0f3); }
107
107
  .dim-panel .dim-progress span { display: block; width: var(--bxf-progress, var(--dxw-progress, var(--ddt-progress, 0%))); height: 100%; border-radius: inherit; background: #1677ff; transition: width .25s linear; }
108
108
  .dim-panel .dim-qrCopy { min-width: 0; overflow-wrap: anywhere; }
109
109
  .dim-panel .dim-qrCopy h3 { margin: 9px 0 8px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 18px; line-height: 1.35; font-weight: 650; }
110
110
  .dim-panel .dim-qrCopy > p { margin: 0; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.65; }
111
111
  .dim-panel .dim-steps { margin: 18px 0 16px; padding: 0; list-style: none; counter-reset: dim-step; }
112
112
  .dim-panel .dim-steps li { position: relative; min-height: 28px; display: flex; align-items: center; padding: 5px 0 5px 36px; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.5; counter-increment: dim-step; }
113
- .dim-panel .dim-steps li::before { content: counter(dim-step); position: absolute; left: 0; top: 4px; width: 25px; height: 25px; display: grid; place-items: center; border-radius: 8px; color: #1677ff; background: color-mix(in srgb, #1677ff 10%, white); font-size: 12px; font-weight: 650; }
113
+ .dim-panel .dim-steps li::before { content: counter(dim-step); position: absolute; left: 0; top: 4px; width: 25px; height: 25px; display: grid; place-items: center; border-radius: 8px; color: #4d93f8; background: color-mix(in srgb, #1677ff 16%, var(--dsw-alias-bg-layer-1, #fff)); font-size: 12px; font-weight: 650; }
114
114
  .dim-panel .dim-specialView { padding: 32px; text-align: center; }
115
- .dim-panel .dim-statusNotice { display: flex; align-items: flex-start; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 22%, white); border-radius: 10px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 6%, white); font-size: 13px; line-height: 1.5; }
116
- .dim-panel .dim-inlineError { display: flex; align-items: flex-start; flex-direction: column; gap: 10px; padding: 22px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 6%, white); }
115
+ .dim-panel .dim-statusNotice { display: flex; align-items: flex-start; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 22%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 10px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 8%, var(--dsw-alias-bg-layer-1, #fff)); font-size: 13px; line-height: 1.5; }
116
+ .dim-panel .dim-inlineError { display: flex; align-items: flex-start; flex-direction: column; gap: 10px; padding: 22px; color: var(--dsw-alias-state-error-primary, #d54941); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 8%, var(--dsw-alias-bg-layer-1, #fff)); }
117
117
  .dim-panel .dim-inlineError > div { min-width: 0; }
118
118
  .dim-panel .dim-inlineError h3 { margin: 0; color: inherit; font-size: 17px; line-height: 1.35; font-weight: 650; }
119
119
  .dim-panel .dim-inlineError p { margin: 7px 0 0; color: inherit; line-height: 1.6; }
120
- .dim-panel .dim-confirm { padding: 18px 24px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
120
+ .dim-panel .dim-confirm { padding: 18px 24px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
121
121
  .dim-panel .dim-confirm strong, .dim-panel .dim-confirm h4 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 14px; line-height: 1.4; font-weight: 650; }
122
122
  .dim-panel .dim-confirm p { margin: 7px 0 0; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.6; }
123
- .dim-panel .dim-cardFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-line-divider, #eef0f3); }
123
+ .dim-panel .dim-cardFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
124
124
  .dim-panel .dim-cardSummary { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font: inherit; font-size: 12px; font-weight: 400; line-height: normal; }
125
125
  .dim-panel .dim-cardActions { flex: none; display: flex; align-items: center; flex-wrap: nowrap; gap: 8px; margin: 0 0 0 auto; }
126
- .dim-panel .dim-cardActions .dim-cardAction { flex: none; min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-line-border, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-body, #fff); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
127
- .dim-panel .dim-cardActions .dim-cardAction:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
126
+ .dim-panel .dim-cardActions .dim-cardAction { flex: none; min-height: 34px; padding: 0 13px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; line-height: normal; white-space: nowrap; }
127
+ .dim-panel .dim-cardActions .dim-cardAction:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
128
128
  .dim-panel .dim-cardActions .dim-cardAction[data-kind="danger"] { color: var(--dsw-alias-state-error-primary, #d54941); }
129
- .dim-panel .dim-botCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-body, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
129
+ .dim-panel .dim-botCard { position: relative; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
130
130
  .dim-panel .dim-botCard::before { display: none; }
131
131
  .dim-panel .dim-botCardBody { position: relative; padding: 24px; }
132
132
  .dim-panel .dim-botCardTop { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
@@ -139,10 +139,10 @@ const CSS = String.raw`
139
139
  .dim-panel .dim-botCard .dim-botHealth { flex: none; min-height: 0; display: inline-flex; align-items: center; gap: 7px; padding: 0; border: 0; border-radius: 0; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; font: inherit; font-size: 12px; font-weight: 400; line-height: normal; white-space: nowrap; }
140
140
  .dim-panel .dim-botCard .dim-healthDot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: #aeb3bb; box-shadow: none; }
141
141
  .dim-panel .dim-botCard .dim-healthDot[data-tone="success"] { background: var(--dsw-alias-state-success-primary, #20a162); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dsw-alias-state-success-primary, #20a162) 14%, transparent); }
142
- .dim-panel .dim-botCard .dim-healthDot[data-tone="warning"] { background: var(--dsw-alias-state-warning-primary, #d97706); }
142
+ .dim-panel .dim-botCard .dim-healthDot[data-tone="warning"] { background: var(--dsw-alias-state-warn-primary, #d97706); }
143
143
  .dim-panel .dim-botCard .dim-healthDot[data-tone="error"] { background: var(--dsw-alias-state-error-primary, #d54941); }
144
144
  .dim-panel .dim-botMetrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 20px 0; }
145
- .dim-panel .dim-botMetric { min-width: 0; padding: 12px; border: 0; border-radius: 9px; background: var(--dsw-alias-fill-tertiary, #f7f8fa); }
145
+ .dim-panel .dim-botMetric { min-width: 0; padding: 12px; border: 0; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
146
146
  .dim-panel .dim-botMetric dt { margin: 0; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; font-weight: 400; line-height: normal; }
147
147
  .dim-panel .dim-botMetric dd { overflow: hidden; margin: 5px 0 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; font-weight: 400; line-height: normal; text-overflow: ellipsis; white-space: nowrap; }
148
148
  .dim-panel .dim-botCard .dim-cardFooter { margin-top: 0; }
@@ -108,7 +108,7 @@ export class DiscordApi {
108
108
  headers: {
109
109
  authorization: `Bot ${this.#token}`,
110
110
  'content-type': 'application/json',
111
- 'user-agent': 'DeepSeek-Harness-dsh-im (https://github.com/xmanrui/dsh-im, 0.2.1)',
111
+ 'user-agent': 'DeepSeek-Harness-dsh-im (https://github.com/xmanrui/dsh-im, 0.2.2)',
112
112
  },
113
113
  ...(body === undefined ? {} : { body: JSON.stringify(body) }),
114
114
  signal: requestSignal(signal, timeoutMs),
@@ -92,7 +92,7 @@ function authenticatedHeaders(token) {
92
92
  function baseInfo() {
93
93
  return {
94
94
  channel_version: WEIXIN_PROTOCOL_VERSION,
95
- bot_agent: 'DeepSeekHarness/0.2.1',
95
+ bot_agent: 'DeepSeekHarness/0.2.2',
96
96
  };
97
97
  }
98
98