fogact 1.1.7 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [简体中文](./README.zh-CN.md) | English
4
4
 
5
- FogAct is a simple activation helper for Claude Code and Codex. It is designed to be used like `npx yunyi-activator`: run one command, choose from the menu, paste your activation code or API key, and let the tool write the local config automatically.
5
+ FogAct is a simple activation helper for Claude Code and Codex. It is designed to be used like `npx fogact`: run one command, choose from the menu, paste your activation code, and let FogAct auto-detect the Codex / Claude entitlement before writing local config.
6
6
 
7
7
  ## Start
8
8
 
@@ -49,8 +49,8 @@ Minimum bootstrap requirement: the machine needs `curl` or `wget`. The installer
49
49
 
50
50
  1. Run `npx fogact`.
51
51
  2. Choose `1. Activate service`.
52
- 3. Select Claude Code or Codex when prompted.
53
- 4. Enter the activation code or API key.
52
+ 3. Enter the activation / redeem code.
53
+ 4. FogAct auto-detects the Codex / Claude entitlement and shows only supported targets.
54
54
  5. Confirm the plan and restart the target tool.
55
55
 
56
56
  FogAct backs up existing configuration before writing new files.
@@ -73,7 +73,7 @@ Most users only need `npx fogact`. Advanced operators can still use:
73
73
  fogact web
74
74
  ```
75
75
 
76
- The Web UI defaults to `http://localhost:34020/`. You can set `PORT`, `ADMIN_PASSWORD`, `NEWAPI_BASE_URL`, `NEWAPI_API_KEY`, `CLIPROXY_API_BASE`, or `CLIPROXY_UPSTREAM_CONFIG` when needed.
76
+ The Web UI defaults to `http://localhost:34020/`. You can set `PORT`, `ADMIN_PASSWORD`, `NEWAPI_BASE_URL`, `NEWAPI_API_KEY`, `FOGACT_API_BASE`, or `FOGACT_UPSTREAM_CONFIG` when needed.
77
77
 
78
78
  ## Repository
79
79
 
package/README.zh-CN.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # FogAct
2
2
 
3
- FogAct 是一个简单的 Claude Code / Codex 激活工具。它的使用方式要和 `npx yunyi-activator` 一样:用户只运行一个命令,进入菜单,输入激活码或 API Key,然后自动写入本地配置。
3
+ FogAct 是一个简单的 Claude Code / Codex 激活工具。它的使用方式要和 `npx fogact` 一样:用户只运行一个命令,进入菜单,输入激活码,FogAct 自动识别 Codex / Claude 能力并写入本地配置。
4
4
 
5
5
  [English](./README.md) | 简体中文
6
6
 
@@ -49,8 +49,8 @@ fogact
49
49
 
50
50
  1. 运行 `npx fogact`。
51
51
  2. 选择 `1. 激活服务`。
52
- 3. 根据提示选择 Claude Code 或 Codex。
53
- 4. 输入激活码或 API Key。
52
+ 3. 输入激活码 / 兑换码。
53
+ 4. FogAct 自动识别 Codex / Claude 能力,并只展示可激活的平台。
54
54
  5. 确认激活计划,然后重启对应工具。
55
55
 
56
56
  FogAct 写入新配置前会自动备份旧配置。
@@ -73,7 +73,7 @@ FogAct 写入新配置前会自动备份旧配置。
73
73
  fogact web
74
74
  ```
75
75
 
76
- Web UI 默认地址是 `http://localhost:34020/`。需要时可以设置 `PORT`、`ADMIN_PASSWORD`、`NEWAPI_BASE_URL`、`NEWAPI_API_KEY`、`CLIPROXY_API_BASE` 或 `CLIPROXY_UPSTREAM_CONFIG`。
76
+ Web UI 默认地址是 `http://localhost:34020/`。需要时可以设置 `PORT`、`ADMIN_PASSWORD`、`NEWAPI_BASE_URL`、`NEWAPI_API_KEY`、`FOGACT_API_BASE` 或 `FOGACT_UPSTREAM_CONFIG`。
77
77
 
78
78
  ## 项目链接
79
79
 
package/bin/web-server.js CHANGED
@@ -218,7 +218,7 @@ function trimTrailingSlash(value) {
218
218
  }
219
219
 
220
220
  function getUpstreamConfigPath() {
221
- return process.env.CLIPROXY_UPSTREAM_CONFIG || DEFAULT_CONFIG_PATH;
221
+ return process.env.FOGACT_UPSTREAM_CONFIG || DEFAULT_CONFIG_PATH;
222
222
  }
223
223
 
224
224
  function readRawUpstreamConfig() {
@@ -1277,10 +1277,18 @@ const server = http.createServer((req, res) => {
1277
1277
  return;
1278
1278
  }
1279
1279
 
1280
- // Proxy requests to yunyi.cfd API for user frontend
1280
+ // Proxy requests to configured upstream API for user frontend
1281
1281
  if (urlPath.startsWith("/proxy/")) {
1282
1282
  const targetPath = urlPath.replace("/proxy", "");
1283
- const targetUrl = `https://yunyi.cfd${targetPath}`;
1283
+ const proxyBaseUrl = trimTrailingSlash(process.env.FOGACT_PROXY_TARGET || readRawUpstreamConfig().baseUrl || "");
1284
+
1285
+ if (!proxyBaseUrl) {
1286
+ res.writeHead(502, { "Content-Type": "application/json" });
1287
+ res.end(JSON.stringify({ success: false, message: "Proxy target is not configured" }));
1288
+ return;
1289
+ }
1290
+
1291
+ const targetUrl = `${proxyBaseUrl}${targetPath}`;
1284
1292
 
1285
1293
  const options = {
1286
1294
  method: req.method,
@@ -7,7 +7,7 @@
7
7
  <meta name="description" content="输入 FogAct 激活码,完成服务绑定并查看额度与有效期。" />
8
8
  <script>
9
9
  ;(function () {
10
- var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || localStorage.getItem('yunyi_user_theme') || 'system';
10
+ var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || 'system';
11
11
  var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
12
12
  var isDark = theme === 'dark' || (theme === 'system' && prefersDark);
13
13
  document.documentElement.classList.toggle('dark', isDark);
@@ -270,7 +270,7 @@ const DEFAULT_SETTINGS = {
270
270
  notifyLowQuota: true
271
271
  },
272
272
  app: {
273
- appName: 'CLIProxy Client',
273
+ appName: 'FogAct Client',
274
274
  appDownloadUrl: '',
275
275
  iosUrl: '',
276
276
  androidUrl: '',
@@ -1277,7 +1277,7 @@ const LogsManagement = {
1277
1277
  };
1278
1278
 
1279
1279
  const SettingsManagement = {
1280
- storageKey: 'cliproxy_admin_settings_v1',
1280
+ storageKey: 'fogact_admin_settings_v1',
1281
1281
 
1282
1282
  sections: [
1283
1283
  {
@@ -7,7 +7,7 @@
7
7
 
8
8
  <script>
9
9
  ;(function () {
10
- var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || localStorage.getItem('yunyi_user_theme') || 'system';
10
+ var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || 'system';
11
11
  var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
12
12
  var isDark = theme === 'dark' || (theme === 'system' && prefersDark);
13
13
  document.documentElement.classList.toggle('dark', isDark);
@@ -731,33 +731,126 @@ body.market-dark .market-auth-card::before {
731
731
  color: var(--market-primary);
732
732
  }
733
733
 
734
- .market-quick-links {
734
+ .market-service-card {
735
+ position: relative;
736
+ overflow: hidden;
737
+ border: 1px solid var(--market-line);
738
+ border-radius: 28px;
739
+ padding: 18px;
740
+ background:
741
+ radial-gradient(circle at 8% 0%, color-mix(in srgb, var(--market-primary) 14%, transparent), transparent 42%),
742
+ var(--market-panel);
743
+ box-shadow: var(--market-shadow-soft);
744
+ }
745
+
746
+ .market-service-head {
735
747
  display: grid;
736
- grid-template-columns: repeat(2, minmax(0, 1fr));
737
- gap: 8px;
738
- margin-top: 16px;
748
+ grid-template-columns: 44px 1fr auto;
749
+ gap: 12px;
750
+ align-items: center;
739
751
  }
740
752
 
741
- .market-quick-links a {
753
+ .market-service-icon {
742
754
  display: inline-flex;
743
755
  align-items: center;
744
756
  justify-content: center;
745
- min-height: 36px;
746
- border: 1px solid var(--market-line);
747
- border-radius: 14px;
757
+ width: 44px;
758
+ height: 44px;
759
+ border-radius: 16px;
760
+ color: #fff;
761
+ background: linear-gradient(135deg, var(--market-primary), var(--market-primary-3));
762
+ box-shadow: 0 14px 32px color-mix(in srgb, var(--market-primary) 24%, transparent);
763
+ }
764
+
765
+ .market-service-head p,
766
+ .market-service-head h3,
767
+ .market-service-copy {
768
+ margin: 0;
769
+ }
770
+
771
+ .market-service-head p {
772
+ color: var(--market-muted);
773
+ font-size: 12px;
774
+ font-weight: 900;
775
+ }
776
+
777
+ .market-service-head h3 {
778
+ margin-top: 3px;
748
779
  color: var(--market-ink);
780
+ font-family: var(--market-headline);
781
+ font-size: 17px;
782
+ letter-spacing: -0.04em;
783
+ }
784
+
785
+ .market-port-badge {
786
+ display: inline-flex;
787
+ align-items: center;
788
+ gap: 6px;
789
+ height: 32px;
790
+ padding: 0 10px;
791
+ border: 1px solid var(--market-line);
792
+ border-radius: 999px;
793
+ color: var(--market-muted);
749
794
  background: var(--market-panel-muted);
795
+ font-size: 12px;
796
+ font-weight: 900;
797
+ }
798
+
799
+ .market-service-copy {
800
+ margin-top: 14px;
801
+ color: var(--market-muted);
802
+ font-size: 13px;
803
+ line-height: 1.65;
804
+ }
805
+
806
+ .market-entry-grid {
807
+ display: grid;
808
+ grid-template-columns: repeat(2, minmax(0, 1fr));
809
+ gap: 10px;
810
+ margin-top: 16px;
811
+ }
812
+
813
+ .market-entry-card {
814
+ display: grid;
815
+ gap: 5px;
816
+ min-height: 92px;
817
+ border: 1px solid var(--market-line);
818
+ border-radius: 18px;
819
+ padding: 13px;
820
+ color: var(--market-ink);
821
+ background: color-mix(in srgb, var(--market-panel-strong) 78%, transparent);
750
822
  text-decoration: none;
823
+ transition: transform 0.18s ease, border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
824
+ }
825
+
826
+ .market-entry-card .material-symbols-outlined {
827
+ width: 30px;
828
+ height: 30px;
829
+ border-radius: 12px;
830
+ display: inline-flex;
831
+ align-items: center;
832
+ justify-content: center;
833
+ color: var(--market-primary);
834
+ background: color-mix(in srgb, var(--market-primary) 12%, transparent);
835
+ font-size: 18px;
836
+ }
837
+
838
+ .market-entry-card strong {
751
839
  font-size: 13px;
752
- font-weight: 800;
753
- transition: transform 0.18s ease, border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
840
+ font-weight: 900;
754
841
  }
755
842
 
756
- .market-quick-links a:hover {
757
- transform: translateY(-1px);
843
+ .market-entry-card small {
844
+ color: var(--market-muted);
845
+ font-size: 12px;
846
+ font-weight: 700;
847
+ }
848
+
849
+ .market-entry-card:hover {
850
+ transform: translateY(-2px);
758
851
  border-color: color-mix(in srgb, var(--market-primary) 42%, var(--market-line));
759
- color: var(--market-primary);
760
- background: color-mix(in srgb, var(--market-primary) 10%, var(--market-panel-muted));
852
+ background: color-mix(in srgb, var(--market-primary) 8%, var(--market-panel-strong));
853
+ box-shadow: var(--market-shadow-soft);
761
854
  }
762
855
 
763
856
  .market-result-list {
@@ -1212,190 +1305,6 @@ body.market-user {
1212
1305
  transform: translateY(-1px);
1213
1306
  }
1214
1307
 
1215
- /* Distinct motion layer */
1216
- .market-orbit-stage {
1217
- position: absolute;
1218
- inset: auto 28px 28px auto;
1219
- width: min(48vw, 440px);
1220
- height: min(48vw, 440px);
1221
- pointer-events: none;
1222
- opacity: 0.98;
1223
- }
1224
-
1225
- .market-orbit-stage::before,
1226
- .market-orbit-stage::after {
1227
- content: "";
1228
- position: absolute;
1229
- inset: 12%;
1230
- border: 1px solid color-mix(in srgb, var(--market-ink) 12%, transparent);
1231
- border-radius: 999px;
1232
- background:
1233
- radial-gradient(circle at center, color-mix(in srgb, var(--market-primary) 7%, transparent), transparent 62%);
1234
- animation: orbitSpin 22s linear infinite;
1235
- }
1236
-
1237
- .market-orbit-stage::after {
1238
- inset: 25%;
1239
- border-style: dashed;
1240
- animation-duration: 16s;
1241
- animation-direction: reverse;
1242
- opacity: 0.72;
1243
- }
1244
-
1245
- .market-orbit-core {
1246
- position: absolute;
1247
- left: 50%;
1248
- top: 50%;
1249
- z-index: 2;
1250
- display: grid;
1251
- place-items: center;
1252
- width: 132px;
1253
- height: 132px;
1254
- padding: 18px;
1255
- border: 1px solid color-mix(in srgb, var(--market-primary) 30%, var(--market-line));
1256
- border-radius: 36px;
1257
- color: var(--market-ink);
1258
- background:
1259
- linear-gradient(145deg, color-mix(in srgb, var(--market-panel-strong) 92%, transparent), var(--market-panel-muted)),
1260
- radial-gradient(circle at 30% 20%, color-mix(in srgb, var(--market-primary) 24%, transparent), transparent 58%);
1261
- box-shadow: 0 24px 60px color-mix(in srgb, var(--market-primary) 20%, transparent);
1262
- transform: translate(-50%, -50%) rotate(-2deg);
1263
- }
1264
-
1265
- .market-orbit-core .material-symbols-outlined {
1266
- display: inline-flex;
1267
- align-items: center;
1268
- justify-content: center;
1269
- width: 42px;
1270
- height: 42px;
1271
- border-radius: 16px;
1272
- color: #fff;
1273
- background: linear-gradient(135deg, var(--market-primary), var(--market-primary-2));
1274
- box-shadow: 0 14px 32px color-mix(in srgb, var(--market-primary) 28%, transparent);
1275
- }
1276
-
1277
- .market-orbit-core strong {
1278
- margin-top: 8px;
1279
- font-family: var(--market-headline);
1280
- font-size: 18px;
1281
- letter-spacing: -0.04em;
1282
- }
1283
-
1284
- .market-orbit-core small {
1285
- color: var(--market-muted);
1286
- font-size: 12px;
1287
- font-weight: 800;
1288
- }
1289
-
1290
- .market-orbit-node {
1291
- position: absolute;
1292
- z-index: 3;
1293
- display: inline-flex;
1294
- align-items: center;
1295
- gap: 8px;
1296
- min-width: 118px;
1297
- min-height: 54px;
1298
- padding: 10px 12px;
1299
- border: 1px solid color-mix(in srgb, var(--node-a, var(--market-primary)) 30%, var(--market-line));
1300
- border-radius: 20px;
1301
- color: var(--market-ink);
1302
- background:
1303
- linear-gradient(145deg, color-mix(in srgb, var(--market-panel-strong) 94%, transparent), var(--market-panel-muted)),
1304
- radial-gradient(circle at 15% 0%, color-mix(in srgb, var(--node-a, var(--market-primary)) 24%, transparent), transparent 64%);
1305
- box-shadow: 0 18px 44px color-mix(in srgb, var(--node-a, var(--market-primary)) 18%, transparent);
1306
- transform: translate3d(0, 0, 0) rotate(var(--tilt, 0deg));
1307
- animation: nodeFloat var(--speed, 6s) ease-in-out infinite;
1308
- }
1309
-
1310
- .market-orbit-node .material-symbols-outlined {
1311
- display: inline-flex;
1312
- align-items: center;
1313
- justify-content: center;
1314
- flex: 0 0 auto;
1315
- width: 32px;
1316
- height: 32px;
1317
- border-radius: 13px;
1318
- color: #fff;
1319
- background: linear-gradient(135deg, var(--node-a, var(--market-primary)), var(--node-b, var(--market-primary-2)));
1320
- font-size: 18px;
1321
- }
1322
-
1323
- .market-orbit-node span:last-child {
1324
- color: var(--market-ink);
1325
- font-size: 13px;
1326
- font-weight: 900;
1327
- white-space: nowrap;
1328
- }
1329
-
1330
- .market-orbit-node-cli {
1331
- --node-a: #6d5dfc;
1332
- --node-b: #b86bff;
1333
- --tilt: -8deg;
1334
- --speed: 6.5s;
1335
- left: 1%;
1336
- top: 18%;
1337
- }
1338
-
1339
- .market-orbit-node-cdk {
1340
- --node-a: #ff7a59;
1341
- --node-b: #ffd166;
1342
- --tilt: 7deg;
1343
- --speed: 7.5s;
1344
- right: 2%;
1345
- top: 9%;
1346
- animation-delay: -1.8s;
1347
- }
1348
-
1349
- .market-orbit-node-quota {
1350
- --node-a: #17c3b2;
1351
- --node-b: #5eead4;
1352
- --tilt: 8deg;
1353
- --speed: 8s;
1354
- right: 0;
1355
- bottom: 20%;
1356
- animation-delay: -3s;
1357
- }
1358
-
1359
- .market-orbit-node-sync {
1360
- --node-a: #111827;
1361
- --node-b: #6d5dfc;
1362
- --tilt: -7deg;
1363
- --speed: 7s;
1364
- left: 7%;
1365
- bottom: 8%;
1366
- animation-delay: -4.3s;
1367
- }
1368
-
1369
- .market-signal-line {
1370
- position: absolute;
1371
- left: 8%;
1372
- right: 8%;
1373
- top: 50%;
1374
- height: 1px;
1375
- background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--market-primary) 55%, transparent), transparent);
1376
- transform: rotate(-18deg);
1377
- opacity: 0.72;
1378
- overflow: hidden;
1379
- }
1380
-
1381
- .market-signal-line-alt {
1382
- transform: rotate(36deg);
1383
- opacity: 0.42;
1384
- }
1385
-
1386
- .market-signal-line::after {
1387
- content: "";
1388
- position: absolute;
1389
- inset: 0 auto 0 0;
1390
- width: 38%;
1391
- background: linear-gradient(90deg, transparent, #fff, transparent);
1392
- animation: signalSweep 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
1393
- }
1394
-
1395
- .market-signal-line-alt::after {
1396
- animation-delay: -1.1s;
1397
- }
1398
-
1399
1308
  .market-card-lab {
1400
1309
  min-height: 318px;
1401
1310
  padding: 0;
@@ -1837,16 +1746,6 @@ body.is-pointer-active .market-mouse-light {
1837
1746
  to { transform: rotate(360deg); }
1838
1747
  }
1839
1748
 
1840
- @keyframes nodeFloat {
1841
- 0%, 100% { transform: translate3d(0, 0, 0) rotate(var(--tilt)); }
1842
- 50% { transform: translate3d(0, -3px, 0) rotate(var(--tilt)); }
1843
- }
1844
-
1845
- @keyframes signalSweep {
1846
- 0% { transform: translateX(-120%); }
1847
- 100% { transform: translateX(360%); }
1848
- }
1849
-
1850
1749
  @keyframes cardShine {
1851
1750
  from { transform: translateX(-120%); }
1852
1751
  to { transform: translateX(120%); }
@@ -1909,14 +1808,6 @@ body.is-pointer-active .market-mouse-light {
1909
1808
  }
1910
1809
 
1911
1810
  @media (max-width: 980px) {
1912
- .market-orbit-stage {
1913
- position: relative;
1914
- inset: auto;
1915
- width: min(100%, 420px);
1916
- height: 300px;
1917
- margin: 28px auto 0;
1918
- }
1919
-
1920
1811
  .market-hero,
1921
1812
  .market-activation {
1922
1813
  grid-template-columns: 1fr;
@@ -1984,32 +1875,6 @@ body.is-pointer-active .market-mouse-light {
1984
1875
  min-height: 150px;
1985
1876
  }
1986
1877
 
1987
- .market-orbit-stage {
1988
- height: 240px;
1989
- }
1990
-
1991
- .market-orbit-core {
1992
- width: 104px;
1993
- height: 104px;
1994
- border-radius: 28px;
1995
- }
1996
-
1997
- .market-orbit-core strong {
1998
- font-size: 16px;
1999
- }
2000
-
2001
- .market-orbit-node {
2002
- min-width: 58px;
2003
- min-height: 58px;
2004
- padding: 8px;
2005
- border-radius: 20px;
2006
- justify-content: center;
2007
- }
2008
-
2009
- .market-orbit-node span:last-child {
2010
- display: none;
2011
- }
2012
-
2013
1878
  .market-mouse-light {
2014
1879
  display: none;
2015
1880
  }
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>配色方案测试 | FogIDC Activator</title>
6
+ <title>配色方案测试 | FogAct</title>
7
7
  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@600;700;800&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
8
8
  <script src="https://cdn.tailwindcss.com"></script>
9
9
  <script>
@@ -7,7 +7,7 @@
7
7
  <meta name="description" content="FogAct 提供用户中心、激活码管理、配额查看和多平台 CLI 接入入口。" />
8
8
  <script>
9
9
  ;(function () {
10
- var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || localStorage.getItem('yunyi_user_theme') || 'system';
10
+ var theme = localStorage.getItem('fogact_theme') || localStorage.getItem('admin_theme') || 'system';
11
11
  var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
12
12
  var isDark = theme === 'dark' || (theme === 'system' && prefersDark);
13
13
  document.documentElement.classList.toggle('dark', isDark);
@@ -73,31 +73,6 @@
73
73
  <span class="market-ambient-item"><span class="material-symbols-outlined">query_stats</span></span>
74
74
  </div>
75
75
 
76
- <div class="market-orbit-stage" aria-label="FogAct 服务流程拓扑">
77
- <div class="market-orbit-core">
78
- <span class="material-symbols-outlined">hub</span>
79
- <strong>FogAct</strong>
80
- <small>统一入口</small>
81
- </div>
82
- <span class="market-orbit-node market-orbit-node-cli">
83
- <span class="material-symbols-outlined">terminal</span>
84
- <span>CLI 接入</span>
85
- </span>
86
- <span class="market-orbit-node market-orbit-node-cdk">
87
- <span class="material-symbols-outlined">vpn_key</span>
88
- <span>CDK 校验</span>
89
- </span>
90
- <span class="market-orbit-node market-orbit-node-quota">
91
- <span class="material-symbols-outlined">monitoring</span>
92
- <span>配额监控</span>
93
- </span>
94
- <span class="market-orbit-node market-orbit-node-sync">
95
- <span class="material-symbols-outlined">cloud_sync</span>
96
- <span>上游同步</span>
97
- </span>
98
- <span class="market-signal-line market-signal-line-main"></span>
99
- <span class="market-signal-line market-signal-line-alt"></span>
100
- </div>
101
76
  </div>
102
77
 
103
78
  <aside class="market-hero-side" aria-label="服务状态概览">
@@ -128,19 +103,39 @@
128
103
  </div>
129
104
  </div>
130
105
 
131
- <div class="market-panel" style="border-radius: 26px; padding: 18px;">
132
- <div class="market-card-footer">
133
- <span class="market-tag">本地服务</span>
134
- <span class="market-status-pill"><span class="market-kicker-dot"></span> 34020</span>
106
+ <div class="market-service-card">
107
+ <div class="market-service-head">
108
+ <span class="market-service-icon material-symbols-outlined">conversion_path</span>
109
+ <div>
110
+ <p>本地服务</p>
111
+ <h3>选择要进入的工作区</h3>
112
+ </div>
113
+ <span class="market-port-badge"><span class="market-kicker-dot"></span> :34020</span>
135
114
  </div>
136
- <p class="market-mini-copy" style="margin-top: 14px; font-size: 14px; line-height: 1.7;">
137
- 本地 Web 服务默认运行在 34020 端口,提供首页、用户中心、管理中心和激活入口。
115
+ <p class="market-service-copy">
116
+ Web 控制台已按角色拆成独立入口,直接选择当前要处理的任务。
138
117
  </p>
139
- <div class="market-quick-links" aria-label="本地服务快捷入口">
140
- <a href="/">首页</a>
141
- <a href="/user/">用户中心</a>
142
- <a href="/admin/">管理中心</a>
143
- <a href="/activate.html">激活入口</a>
118
+ <div class="market-entry-grid" aria-label="本地服务快捷入口">
119
+ <a class="market-entry-card" href="/">
120
+ <span class="material-symbols-outlined">home</span>
121
+ <strong>首页</strong>
122
+ <small>查看入口总览</small>
123
+ </a>
124
+ <a class="market-entry-card" href="/user/">
125
+ <span class="material-symbols-outlined">person</span>
126
+ <strong>用户中心</strong>
127
+ <small>用量与配额</small>
128
+ </a>
129
+ <a class="market-entry-card" href="/admin/">
130
+ <span class="material-symbols-outlined">admin_panel_settings</span>
131
+ <strong>管理中心</strong>
132
+ <small>用户与 CDK</small>
133
+ </a>
134
+ <a class="market-entry-card" href="/activate.html">
135
+ <span class="material-symbols-outlined">bolt</span>
136
+ <strong>激活入口</strong>
137
+ <small>绑定服务</small>
138
+ </a>
144
139
  </div>
145
140
  </div>
146
141
  </aside>