agentworkshop 0.7.23 → 0.7.24

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.
Files changed (177) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/0jKrzLuM.js +19 -0
  3. package/.output/public/_nuxt/{Cor9siSf.js → 6PZPfFcO.js} +1 -1
  4. package/.output/public/_nuxt/BAfp6tmu.js +14 -0
  5. package/.output/public/_nuxt/{B-xskWta.js → BCJFMBQ6.js} +1 -1
  6. package/.output/public/_nuxt/{DNxVTfhe.js → BMb80_tm.js} +1 -1
  7. package/.output/public/_nuxt/{n3vMFfrv.js → Bc-_IsBP.js} +3 -3
  8. package/.output/public/_nuxt/BvNJUu3s.js +1 -0
  9. package/.output/public/_nuxt/C1CSiSBN.js +1 -0
  10. package/.output/public/_nuxt/CAGL7TNK.js +1 -0
  11. package/.output/public/_nuxt/{ed5qX-x5.js → CDLv-n51.js} +1 -1
  12. package/.output/public/_nuxt/CJviSvm-.js +1 -0
  13. package/.output/public/_nuxt/CLZWFhZC.js +1 -0
  14. package/.output/public/_nuxt/{Cr9DkD1d.js → CYzpZzB_.js} +1 -1
  15. package/.output/public/_nuxt/Cb3SnTM8.js +1 -0
  16. package/.output/public/_nuxt/CjXIpPMR.js +1 -0
  17. package/.output/public/_nuxt/CmHzfVc5.js +3 -0
  18. package/.output/public/_nuxt/Cn3J3NXR.js +23 -0
  19. package/.output/public/_nuxt/Coik560n.js +1 -0
  20. package/.output/public/_nuxt/{DA4lxCWC2.js → Ct68Z0232.js} +1 -1
  21. package/.output/public/_nuxt/CuVGPuP1.js +1 -0
  22. package/.output/public/_nuxt/CxY6LfeN.js +1 -0
  23. package/.output/public/_nuxt/{CfVAr2nf.js → Cz9gD2Yo.js} +1 -1
  24. package/.output/public/_nuxt/D6HDb-vN2.js +1 -0
  25. package/.output/public/_nuxt/{E88a-JCG.js → DGAOugLt.js} +1 -1
  26. package/.output/public/_nuxt/DKHcFE1i.js +1 -0
  27. package/.output/public/_nuxt/{BxtpDtzC.js → DNQF_TXX.js} +1 -1
  28. package/.output/public/_nuxt/DSa2O56y.js +1 -0
  29. package/.output/public/_nuxt/DUToq-k_.js +1 -0
  30. package/.output/public/_nuxt/Dfe8vXdG.js +1 -0
  31. package/.output/public/_nuxt/{CEHmSufQ.js → Djir5rSD.js} +1 -1
  32. package/.output/public/_nuxt/DjtE7AYt.js +1 -0
  33. package/.output/public/_nuxt/{BBwMH_hG.js → DoAlYsiF.js} +1 -1
  34. package/.output/public/_nuxt/{DWcEk1ur2.js → DvgKXPgu2.js} +1 -1
  35. package/.output/public/_nuxt/JOwsShod.js +2 -0
  36. package/.output/public/_nuxt/X6IraCTB.js +1 -0
  37. package/.output/public/_nuxt/{CYBq3kS7.js → b50gYVZl.js} +1 -1
  38. package/.output/public/_nuxt/builds/latest.json +1 -1
  39. package/.output/public/_nuxt/builds/meta/024de5f7-6a10-4f53-82ab-bc65f3ec9e35.json +1 -0
  40. package/.output/public/_nuxt/entry.AZM1Culo.css +1 -0
  41. package/.output/public/_nuxt/monitor.B--1dPzs.css +1 -0
  42. package/.output/public/_nuxt/permissions.B1pjGChZ.css +1 -0
  43. package/.output/public/_nuxt/plugins.DpCuwaJt.css +1 -0
  44. package/.output/public/_nuxt/tokens.xRb1fSPU.css +1 -0
  45. package/.output/public/_nuxt/users.DuAt_Zwf.css +1 -0
  46. package/.output/public/_nuxt/workshop.BJg84pOK.css +1 -0
  47. package/.output/server/chunks/_/nitro.mjs +793 -814
  48. package/.output/server/chunks/build/{OmpTerminalPanel-Ban3yJZ4.mjs → OmpTerminalPanel-Cw_Vw9oO.mjs} +3 -3
  49. package/.output/server/chunks/build/{OmpTerminalPanel-Ban3yJZ4.mjs.map → OmpTerminalPanel-Cw_Vw9oO.mjs.map} +1 -1
  50. package/.output/server/chunks/build/{_wsId_-C2O5zZsI.mjs → _wsId_-D38Vx6Ky.mjs} +8 -10
  51. package/.output/server/chunks/build/{_wsId_-C2O5zZsI.mjs.map → _wsId_-D38Vx6Ky.mjs.map} +1 -1
  52. package/.output/server/chunks/build/{agents--6bzGtES.mjs → agents-GnmUGZir.mjs} +6 -8
  53. package/.output/server/chunks/build/agents-GnmUGZir.mjs.map +1 -0
  54. package/.output/server/chunks/build/button-DEcZFcqN.mjs +1 -1
  55. package/.output/server/chunks/build/{card-CCPQoKlh.mjs → card-Dipvaykh.mjs} +4 -4
  56. package/.output/server/chunks/build/{card-CCPQoKlh.mjs.map → card-Dipvaykh.mjs.map} +1 -1
  57. package/.output/server/chunks/build/{channel-templates-C1Bb-U75.mjs → channel-templates-B4z6v8Z5.mjs} +4 -6
  58. package/.output/server/chunks/build/channel-templates-B4z6v8Z5.mjs.map +1 -0
  59. package/.output/server/chunks/build/{checkbox-Dv1kjaUZ.mjs → checkbox-dzcpU_Cd.mjs} +2 -2
  60. package/.output/server/chunks/build/{checkbox-Dv1kjaUZ.mjs.map → checkbox-dzcpU_Cd.mjs.map} +1 -1
  61. package/.output/server/chunks/build/{default-DdV642BY.mjs → default-CLf5m0NE.mjs} +2 -3
  62. package/.output/server/chunks/build/{default-DdV642BY.mjs.map → default-CLf5m0NE.mjs.map} +1 -1
  63. package/.output/server/chunks/build/dropdown-vhn1NPFs.mjs +1 -1
  64. package/.output/server/chunks/build/{input-number-CZ3ZrCsy.mjs → input-number-Bd55elNN.mjs} +3 -3
  65. package/.output/server/chunks/build/{input-number-CZ3ZrCsy.mjs.map → input-number-Bd55elNN.mjs.map} +1 -1
  66. package/.output/server/chunks/build/{input-DxDqeyQW.mjs → input-sf_BT6o6.mjs} +553 -5
  67. package/.output/server/chunks/build/input-sf_BT6o6.mjs.map +1 -0
  68. package/.output/server/chunks/build/menu-WCrlpYVh.mjs +2 -2
  69. package/.output/server/chunks/build/modal-yvUquPj5.mjs +2 -2
  70. package/.output/server/chunks/build/{monitor-miqq9xHB.mjs → monitor-Cp4V-H2n.mjs} +70 -192
  71. package/.output/server/chunks/build/monitor-Cp4V-H2n.mjs.map +1 -0
  72. package/.output/server/chunks/build/{pages-D9tOoJsf.mjs → pages-Dc2H1QFu.mjs} +2 -3
  73. package/.output/server/chunks/build/pages-Dc2H1QFu.mjs.map +1 -0
  74. package/.output/server/chunks/build/{permissions-CxEgXic0.mjs → permissions-BTRW2CVd.mjs} +288 -194
  75. package/.output/server/chunks/build/permissions-BTRW2CVd.mjs.map +1 -0
  76. package/.output/server/chunks/build/{plugins-wLIKHcIE.mjs → plugins-DZR0T4Mh.mjs} +17 -17
  77. package/.output/server/chunks/build/{plugins-wLIKHcIE.mjs.map → plugins-DZR0T4Mh.mjs.map} +1 -1
  78. package/.output/server/chunks/build/popconfirm-CRaHcz5O.mjs +1 -1
  79. package/.output/server/chunks/build/{segmented-ChmQZwz6.mjs → segmented-LPPREMtZ.mjs} +336 -5
  80. package/.output/server/chunks/build/{segmented-ChmQZwz6.mjs.map → segmented-LPPREMtZ.mjs.map} +1 -1
  81. package/.output/server/chunks/build/{settings-BPBll_7K.mjs → settings-UfGyDgM7.mjs} +6 -8
  82. package/.output/server/chunks/build/settings-UfGyDgM7.mjs.map +1 -0
  83. package/.output/server/chunks/build/space-CCBYAkXt.mjs +1 -1
  84. package/.output/server/chunks/build/switch-CelRXpcy.mjs +1 -1
  85. package/.output/server/chunks/build/{table-BtksyDlQ.mjs → table-Cswq-l2r.mjs} +5 -5
  86. package/.output/server/chunks/build/{table-BtksyDlQ.mjs.map → table-Cswq-l2r.mjs.map} +1 -1
  87. package/.output/server/chunks/build/{tabs-DQv-_-R6.mjs → tabs-BM3tAh_J.mjs} +2 -2
  88. package/.output/server/chunks/build/{tabs-DQv-_-R6.mjs.map → tabs-BM3tAh_J.mjs.map} +1 -1
  89. package/.output/server/chunks/build/{tag-A0tZ2Ouq.mjs → tag-NO9jEqKy.mjs} +3 -3
  90. package/.output/server/chunks/build/{tag-A0tZ2Ouq.mjs.map → tag-NO9jEqKy.mjs.map} +1 -1
  91. package/.output/server/chunks/build/{teams-DD8ZXTKL.mjs → teams-Cbg27MWW.mjs} +4 -6
  92. package/.output/server/chunks/build/teams-Cbg27MWW.mjs.map +1 -0
  93. package/.output/server/chunks/build/{tokens-Dxnuw96_.mjs → tokens-Bmm6rDfj.mjs} +296 -200
  94. package/.output/server/chunks/build/tokens-Bmm6rDfj.mjs.map +1 -0
  95. package/.output/server/chunks/build/{users-D6RNylrW.mjs → users-B50HHrfi.mjs} +12 -13
  96. package/.output/server/chunks/build/users-B50HHrfi.mjs.map +1 -0
  97. package/.output/server/chunks/build/{workshop-CTcYDq2i.mjs → workshop-81xhz368.mjs} +21 -22
  98. package/.output/server/chunks/build/workshop-81xhz368.mjs.map +1 -0
  99. package/.output/server/chunks/routes/renderer.mjs +2 -2
  100. package/.output/server/chunks/virtual/entry.mjs +40 -16
  101. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  102. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  103. package/.output/server/package.json +1 -1
  104. package/app/app.vue +7 -0
  105. package/app/assets/css/main.css +12 -1
  106. package/app/pages/monitor.vue +56 -68
  107. package/app/pages/permissions/index.vue +86 -82
  108. package/app/pages/plugins/index.vue +12 -7
  109. package/app/pages/tokens.vue +94 -96
  110. package/app/pages/users.vue +10 -18
  111. package/app/pages/workshop/index.vue +34 -5
  112. package/i18n/locales/en.ts +1 -1
  113. package/i18n/locales/zh-CN.ts +1 -1
  114. package/package.json +1 -1
  115. package/scripts/_dbg-logs-ui-e2e.py +3 -2
  116. package/scripts/_dbg-ui-survey.py +52 -0
  117. package/server/data/dcw-lines.json +7 -0
  118. package/server/data/dcw-products.json +7 -0
  119. package/server/data/dcw-recipes.json +22 -0
  120. package/server/data/dcw-rollback.json +73 -10
  121. package/server/data/dcw-runs.json +27 -27
  122. package/server/data/dcw-writes.json +24 -0
  123. package/server/data/dcws.json +244 -216
  124. package/.output/public/_nuxt/BJbhwS5o.js +0 -1
  125. package/.output/public/_nuxt/BWC4HQHQ.js +0 -1
  126. package/.output/public/_nuxt/BbZAzXjZ2.js +0 -1
  127. package/.output/public/_nuxt/BgOhoDTI.js +0 -1
  128. package/.output/public/_nuxt/Bo8t5fkJ.js +0 -1
  129. package/.output/public/_nuxt/BuiGDfMB.js +0 -1
  130. package/.output/public/_nuxt/BxPPAkGA.js +0 -3
  131. package/.output/public/_nuxt/C53drffV.js +0 -1
  132. package/.output/public/_nuxt/CcwJ2mrD2.js +0 -1
  133. package/.output/public/_nuxt/DTYBfjRY.js +0 -1
  134. package/.output/public/_nuxt/DVoWWlUW.js +0 -1
  135. package/.output/public/_nuxt/Dc32T41C.js +0 -1
  136. package/.output/public/_nuxt/Dhqra7NB.js +0 -1
  137. package/.output/public/_nuxt/DlRO_q5L.js +0 -1
  138. package/.output/public/_nuxt/DsUUYP292.js +0 -1
  139. package/.output/public/_nuxt/Dsdy4Ua-.js +0 -1
  140. package/.output/public/_nuxt/DtzZqC0z.js +0 -1
  141. package/.output/public/_nuxt/Ko9mMsJj.js +0 -14
  142. package/.output/public/_nuxt/RzXYI9FM.js +0 -23
  143. package/.output/public/_nuxt/UtviM1bg.js +0 -1
  144. package/.output/public/_nuxt/bAFueD6a.js +0 -1
  145. package/.output/public/_nuxt/builds/meta/1adc96e0-8bbd-4a79-ac7e-b6952556fef8.json +0 -1
  146. package/.output/public/_nuxt/dbi5bHkY.js +0 -2
  147. package/.output/public/_nuxt/eHYnGew0.js +0 -19
  148. package/.output/public/_nuxt/entry.OR_psZHp.css +0 -1
  149. package/.output/public/_nuxt/jyQyulh-.js +0 -1
  150. package/.output/public/_nuxt/monitor.CmwpEUCI.css +0 -1
  151. package/.output/public/_nuxt/permissions.DTRtZeTw.css +0 -1
  152. package/.output/public/_nuxt/plugins.BcSEwwGb.css +0 -1
  153. package/.output/public/_nuxt/tokens.BVXU1jOK.css +0 -1
  154. package/.output/public/_nuxt/users.D8lcLE62.css +0 -1
  155. package/.output/public/_nuxt/workshop.CbymC2LY.css +0 -1
  156. package/.output/public/_nuxt/zVkqCZ78.js +0 -1
  157. package/.output/server/chunks/build/Col-biaNnEPf.mjs +0 -338
  158. package/.output/server/chunks/build/Col-biaNnEPf.mjs.map +0 -1
  159. package/.output/server/chunks/build/agents--6bzGtES.mjs.map +0 -1
  160. package/.output/server/chunks/build/channel-templates-C1Bb-U75.mjs.map +0 -1
  161. package/.output/server/chunks/build/hasIn-vQ9LWt-J.mjs +0 -554
  162. package/.output/server/chunks/build/hasIn-vQ9LWt-J.mjs.map +0 -1
  163. package/.output/server/chunks/build/input-DxDqeyQW.mjs.map +0 -1
  164. package/.output/server/chunks/build/monitor-miqq9xHB.mjs.map +0 -1
  165. package/.output/server/chunks/build/pages-D9tOoJsf.mjs.map +0 -1
  166. package/.output/server/chunks/build/permissions-CxEgXic0.mjs.map +0 -1
  167. package/.output/server/chunks/build/settings-BPBll_7K.mjs.map +0 -1
  168. package/.output/server/chunks/build/teams-DD8ZXTKL.mjs.map +0 -1
  169. package/.output/server/chunks/build/tokens-Dxnuw96_.mjs.map +0 -1
  170. package/.output/server/chunks/build/useSiteConfig-DJe_KMVr.mjs +0 -27
  171. package/.output/server/chunks/build/useSiteConfig-DJe_KMVr.mjs.map +0 -1
  172. package/.output/server/chunks/build/users-D6RNylrW.mjs.map +0 -1
  173. package/.output/server/chunks/build/workshop-CTcYDq2i.mjs.map +0 -1
  174. /package/.output/public/_nuxt/{CNs_Ozdc.js → CNs_Ozdc2.js} +0 -0
  175. /package/.output/public/_nuxt/{Cno6kYiO.js → Cno6kYiO2.js} +0 -0
  176. /package/.output/public/_nuxt/{DAR70Lf5.js → DAR70Lf52.js} +0 -0
  177. /package/.output/public/_nuxt/{ORt9oDIy2.js → ORt9oDIy.js} +0 -0
@@ -270,17 +270,17 @@ useHead({ title: () => tt('titles.tokens') })
270
270
  </div>
271
271
 
272
272
  <template v-else>
273
- <div class="head">
273
+ <div class="aw-page-head">
274
274
  <div>
275
275
  <p class="aw-kicker">
276
276
  agentworkshop / api tokens
277
277
  </p>
278
- <h2>API Token</h2>
278
+ <h1>API Token</h1>
279
279
  <p class="sub">
280
280
  {{ userStore.user?.name }} · {{ $t('tokens.k1upppaw026') }}
281
281
  </p>
282
282
  </div>
283
- <a-space>
283
+ <a-space class="head-actions">
284
284
  <a-tag
285
285
  v-if="userStore.user?.tokenId"
286
286
  color="green"
@@ -297,95 +297,100 @@ useHead({ title: () => tt('titles.tokens') })
297
297
  </a-space>
298
298
  </div>
299
299
 
300
- <a-spin :spinning="loading">
301
- <a-table
302
- :columns="columns"
303
- :data-source="tokens"
304
- :pagination="false"
305
- row-key="id"
306
- >
307
- <template #bodyCell="{ column, record }">
308
- <template v-if="column.key === 'label'">
309
- <a-space>
310
- <span class="i-tabler-key text-primary" />
311
- <span class="font-medium">{{ record.label || $t('tokens.kj3mklm028') }}</span>
312
- <a-tag
313
- v-if="record.id === userStore.user?.tokenId"
314
- color="green"
315
- >
316
- {{ $t('tokens.k1defr98007') }}
317
- </a-tag>
318
- </a-space>
319
- </template>
320
- <template v-else-if="column.key === 'token'">
321
- <div class="tok-cell">
322
- <code
323
- class="tok-val"
324
- :class="{ revealed: isRevealed(record.id) }"
325
- :title="isRevealed(record.id) ? '已显示明文,点击眼睛遮回' : '掩码预览'"
326
- >{{ rowDisplay(record as TokenMeta) }}</code>
327
- <a-button
328
- v-if="record.hasPlain"
329
- type="text"
330
- size="small"
331
- class="tok-op"
332
- :loading="revealingId === record.id"
333
- :title="isRevealed(record.id) ? '遮回' : '查看明文'"
334
- @click="toggleRowReveal(record as TokenMeta)"
335
- >
336
- <span :class="isRevealed(record.id) ? 'i-tabler-eye-off' : 'i-tabler-eye'" />
337
- </a-button>
338
- <a-button
339
- v-if="record.hasPlain"
340
- type="text"
341
- size="small"
342
- class="tok-op"
343
- :class="{ ok: copyId === record.id }"
344
- :title="copyId === record.id ? '已复制' : '复制明文'"
345
- @click="copyRow(record as TokenMeta)"
346
- >
347
- <span :class="copyId === record.id ? 'i-tabler-check' : 'i-tabler-copy'" />
348
- </a-button>
349
- <!-- 0.7.10 起 token 只存哈希:无明文是常态,不再打「旧版不可见」标签 -->
350
- </div>
351
- </template>
352
- <template v-else-if="column.key === 'createdAt'">
353
- {{ fmt(record.createdAt) }}
354
- </template>
355
- <template v-else-if="column.key === 'lastUsedAt'">
356
- {{ fmt(record.lastUsedAt) }}
357
- </template>
358
- <template v-else-if="column.key === 'action'">
359
- <a-space>
360
- <a-button
361
- type="link"
362
- size="small"
363
- @click="openRename(record)"
364
- >
365
- <span class="i-tabler-edit" />
366
- {{ $t('tokens.k3vrpcs009') }}
367
- </a-button>
368
- <a-popconfirm
369
- :title="record.id === userStore.user?.tokenId ? '吊销当前会话 token 将退出登录' : '吊销后立即失效'"
370
- :ok-text="'吊销'"
371
- :cancel-text="'取消'"
372
- @confirm="doRevoke(record)"
373
- >
374
- <!-- 安静文本按钮:常态墨灰,悬停转红 —— 红色只留给真实确认瞬间,不再整行批发 -->
300
+ <a-card
301
+ :bordered="false"
302
+ class="table-card"
303
+ >
304
+ <a-spin :spinning="loading">
305
+ <a-table
306
+ :columns="columns"
307
+ :data-source="tokens"
308
+ :pagination="false"
309
+ row-key="id"
310
+ >
311
+ <template #bodyCell="{ column, record }">
312
+ <template v-if="column.key === 'label'">
313
+ <a-space>
314
+ <span class="i-tabler-key text-primary" />
315
+ <span class="font-medium">{{ record.label || $t('tokens.kj3mklm028') }}</span>
316
+ <a-tag
317
+ v-if="record.id === userStore.user?.tokenId"
318
+ color="green"
319
+ >
320
+ {{ $t('tokens.k1defr98007') }}
321
+ </a-tag>
322
+ </a-space>
323
+ </template>
324
+ <template v-else-if="column.key === 'token'">
325
+ <div class="tok-cell">
326
+ <code
327
+ class="tok-val"
328
+ :class="{ revealed: isRevealed(record.id) }"
329
+ :title="isRevealed(record.id) ? '已显示明文,点击眼睛遮回' : '掩码预览'"
330
+ >{{ rowDisplay(record as TokenMeta) }}</code>
331
+ <a-button
332
+ v-if="record.hasPlain"
333
+ type="text"
334
+ size="small"
335
+ class="tok-op"
336
+ :loading="revealingId === record.id"
337
+ :title="isRevealed(record.id) ? '遮回' : '查看明文'"
338
+ @click="toggleRowReveal(record as TokenMeta)"
339
+ >
340
+ <span :class="isRevealed(record.id) ? 'i-tabler-eye-off' : 'i-tabler-eye'" />
341
+ </a-button>
375
342
  <a-button
343
+ v-if="record.hasPlain"
376
344
  type="text"
377
345
  size="small"
378
- class="tok-revoke"
346
+ class="tok-op"
347
+ :class="{ ok: copyId === record.id }"
348
+ :title="copyId === record.id ? '已复制' : '复制明文'"
349
+ @click="copyRow(record as TokenMeta)"
379
350
  >
380
- <span class="i-tabler-trash" />
381
- {{ $t('tokens.k3xmrz010') }}
351
+ <span :class="copyId === record.id ? 'i-tabler-check' : 'i-tabler-copy'" />
382
352
  </a-button>
383
- </a-popconfirm>
384
- </a-space>
353
+ <!-- 0.7.10 起 token 只存哈希:无明文是常态,不再打「旧版不可见」标签 -->
354
+ </div>
355
+ </template>
356
+ <template v-else-if="column.key === 'createdAt'">
357
+ {{ fmt(record.createdAt) }}
358
+ </template>
359
+ <template v-else-if="column.key === 'lastUsedAt'">
360
+ {{ fmt(record.lastUsedAt) }}
361
+ </template>
362
+ <template v-else-if="column.key === 'action'">
363
+ <a-space>
364
+ <a-button
365
+ type="link"
366
+ size="small"
367
+ @click="openRename(record)"
368
+ >
369
+ <span class="i-tabler-edit" />
370
+ {{ $t('tokens.k3vrpcs009') }}
371
+ </a-button>
372
+ <a-popconfirm
373
+ :title="record.id === userStore.user?.tokenId ? '吊销当前会话 token 将退出登录' : '吊销后立即失效'"
374
+ :ok-text="'吊销'"
375
+ :cancel-text="'取消'"
376
+ @confirm="doRevoke(record)"
377
+ >
378
+ <!-- 安静文本按钮:常态墨灰,悬停转红 —— 红色只留给真实确认瞬间,不再整行批发 -->
379
+ <a-button
380
+ type="text"
381
+ size="small"
382
+ class="tok-revoke"
383
+ >
384
+ <span class="i-tabler-trash" />
385
+ {{ $t('tokens.k3xmrz010') }}
386
+ </a-button>
387
+ </a-popconfirm>
388
+ </a-space>
389
+ </template>
385
390
  </template>
386
- </template>
387
- </a-table>
388
- </a-spin>
391
+ </a-table>
392
+ </a-spin>
393
+ </a-card>
389
394
 
390
395
  <!-- 创建 Token -->
391
396
  <a-modal
@@ -477,16 +482,9 @@ useHead({ title: () => tt('titles.tokens') })
477
482
 
478
483
  .auth-card { width: 460px; max-width: 92vw; }
479
484
  .auth-card h2 { margin: 0 0 8px; font-family: var(--font-display); }
480
- .sub { margin: 0 0 12px; font-size: 12px; opacity: 0.6; }
481
-
482
- .head {
483
- display: flex;
484
- align-items: center;
485
- justify-content: space-between;
486
- margin-bottom: 16px;
487
- }
488
-
489
- h2 { margin: 0 0 4px; font-family: var(--font-display); }
485
+ .sub { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-faint); }
486
+ .head-actions { padding-bottom: 4px; }
487
+ .table-card { margin-bottom: 16px; }
490
488
 
491
489
  .once-banner {
492
490
  display: flex;
@@ -116,9 +116,12 @@ useHead({ title: () => t('titles.users') })
116
116
 
117
117
  <template>
118
118
  <div class="page-wrap">
119
- <div class="page-head">
119
+ <div class="aw-page-head">
120
120
  <div>
121
- <h2 class="page-title">
121
+ <p class="aw-kicker">
122
+ agentworkshop / identity
123
+ </p>
124
+ <h1>
122
125
  {{ t('users.title') }}
123
126
  <a-tag
124
127
  color="volcano"
@@ -127,8 +130,8 @@ useHead({ title: () => t('titles.users') })
127
130
  <span class="i-tabler-shield-check" />
128
131
  admin
129
132
  </a-tag>
130
- </h2>
131
- <p class="page-sub">
133
+ </h1>
134
+ <p class="sub">
132
135
  {{ $t('users.k1flpho5002') }}
133
136
  </p>
134
137
  </div>
@@ -228,21 +231,10 @@ useHead({ title: () => t('titles.users') })
228
231
  max-width: 1080px;
229
232
  margin: 0 auto;
230
233
  }
231
- .page-head {
232
- display: flex;
233
- align-items: flex-end;
234
- justify-content: space-between;
235
- margin-bottom: 16px;
236
- }
237
- .page-title {
238
- display: flex;
239
- gap: 8px;
240
- align-items: center;
241
- margin: 0 0 4px;
242
- font-size: 24px;
234
+ .admin-tag {
235
+ transform: translateY(-3px);
243
236
  }
244
- .admin-tag { transform: translateY(-2px); }
245
- .page-sub { margin: 0; font-size: 12.5px; opacity: 0.55; }
237
+ .sub { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-faint); }
246
238
  .gate-card {
247
239
  display: flex;
248
240
  flex-direction: column;
@@ -413,16 +413,19 @@ useHead({ title: () => t('titles.workshop') })
413
413
  </div>
414
414
  </div>
415
415
 
416
- <div
416
+ <button
417
417
  v-if="wsStore.workspaces.length === 0 && ready"
418
- class="card placeholder aw-empty"
418
+ class="ws-empty"
419
419
  @click="createOpen = true"
420
420
  >
421
+ <span class="i-tabler-layout-2 ws-empty-ico" />
421
422
  <span class="aw-empty-title">从一条产线、一个 Agent 开始</span>
422
423
  <span class="aw-empty-sub">Workspace 是频道与任务的容器 —— 建立第一个工作区后,你的 Agent 团队即可上线作业。</span>
423
- <span class="i-tabler-plus big" />
424
- <span>新建第一个 Workspace</span>
425
- </div>
424
+ <span class="pill-btn ws-empty-cta">
425
+ <span class="i-tabler-plus" />
426
+ 新建第一个 Workspace
427
+ </span>
428
+ </button>
426
429
  </div>
427
430
  </a-spin>
428
431
 
@@ -560,6 +563,32 @@ useHead({ title: () => t('titles.workshop') })
560
563
  border-style: dashed;
561
564
  }
562
565
 
566
+ /* 空态:整幅居中构图(跨全部网格列,代替左上角一张小幽灵卡) */
567
+ .ws-empty {
568
+ grid-column: 1 / -1;
569
+ display: flex;
570
+ flex-direction: column;
571
+ gap: 12px;
572
+ align-items: center;
573
+ justify-content: center;
574
+ min-height: min(480px, calc(100vh - 320px));
575
+ padding: 40px 24px;
576
+ text-align: center;
577
+ cursor: pointer;
578
+ background: transparent;
579
+ border: 1px dashed var(--line-strong);
580
+ border-radius: var(--radius-panel);
581
+ transition: background var(--transition-fast), border-color var(--transition-fast);
582
+ }
583
+ .ws-empty:hover {
584
+ background: var(--hover-tint);
585
+ border-color: var(--ink-fainter);
586
+ }
587
+ .ws-empty-ico { font-size: 34px; color: var(--ink-fainter); }
588
+ .aw-empty-title { font-size: 16px; font-weight: 600; color: var(--ink); }
589
+ .aw-empty-sub { max-width: 420px; font-size: 12.5px; line-height: 1.7; color: var(--ink-faint); }
590
+ .ws-empty-cta { margin-top: 6px; pointer-events: none; }
591
+
563
592
  .big { font-size: 28px; }
564
593
 
565
594
  .card-head {
@@ -1921,7 +1921,7 @@ export default {
1921
1921
  loadFail: 'Failed to load plugin list',
1922
1922
  hasClient: 'Client enhancer',
1923
1923
  routes: 'API routes',
1924
- empty: 'No plugins yet — aw plugin create <name>, or aw plugin enable to turn on examples',
1924
+ empty: 'No plugins yet — run aw plugin create my-plugin, or aw plugin enable to turn on examples',
1925
1925
  failures: 'Load failures',
1926
1926
  loadFailures: '{n} plugin(s) failed to load, see server startup log',
1927
1927
  enableFail: 'Toggle failed',
@@ -1922,7 +1922,7 @@ export default {
1922
1922
  loadFail: '插件列表加载失败',
1923
1923
  hasClient: '浏览器增强',
1924
1924
  routes: 'API 路由',
1925
- empty: '暂无插件 —— aw plugin create <name> 创建,或 aw plugin enable 开启示例',
1925
+ empty: '暂无插件 —— 执行 aw plugin create my-plugin 创建,或 aw plugin enable 开启内置示例',
1926
1926
  failures: '装载失败',
1927
1927
  loadFailures: '{n} 个插件装载失败,详情见服务启动日志',
1928
1928
  enableFail: '启停操作失败',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentworkshop",
3
- "version": "0.7.23",
3
+ "version": "0.7.24",
4
4
  "type": "module",
5
5
  "description": "AgentWorkShop 软件开发系统 - 基于 Nuxt 4 的配置驱动运行范式",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
@@ -4,11 +4,12 @@
4
4
  # 3) 页头 aw-page-head 规范(标题30px + 描述间距)
5
5
  # 附带:daq/dcw 页按钮抽查截图。产物 → .e2e-shots/
6
6
  import json
7
+ import os
7
8
  import sys
8
9
  from playwright.sync_api import sync_playwright
9
10
 
10
- BASE = 'http://127.0.0.1:3000'
11
- SHOT = '.e2e-shots'
11
+ BASE = os.environ.get('BASE', 'http://127.0.0.1:3000')
12
+ SHOT = os.environ.get('SHOT_PREFIX', '') or '.e2e-shots'
12
13
  passed = 0
13
14
  failed = 0
14
15
 
@@ -0,0 +1,52 @@
1
+ # 全站 UI 普查:登录后逐页截图,供美化前诊断(BASE/OUT/THEME 可参)
2
+ import os
3
+ import sys
4
+ from playwright.sync_api import sync_playwright
5
+
6
+ BASE = os.environ.get('BASE', 'http://127.0.0.1:3000')
7
+ OUT = os.environ.get('OUT', '.e2e-shots/survey')
8
+ PAGES = ['/', '/workshop', '/daq', '/dcw', '/logs', '/users', '/permissions', '/plugins', '/monitor', '/settings', '/tokens', '/town']
9
+
10
+ os.makedirs(OUT, exist_ok=True)
11
+ with sync_playwright() as p:
12
+ b = p.chromium.launch(headless=True)
13
+ pg = b.new_page(viewport={'width': 1600, 'height': 1000})
14
+ pg.set_default_timeout(30000)
15
+ pg.goto(BASE + '/workshop', wait_until='domcontentloaded', timeout=90000)
16
+ try:
17
+ pg.wait_for_selector('input[placeholder="邮箱 / 用户名"]', timeout=20000)
18
+ except Exception:
19
+ pg.goto(BASE + '/workshop', wait_until='domcontentloaded', timeout=60000)
20
+ pg.wait_for_selector('input[placeholder="邮箱 / 用户名"]', timeout=60000)
21
+ for attempt in range(3):
22
+ pg.wait_for_timeout(2500 + attempt * 2000)
23
+ pg.fill('input[placeholder="邮箱 / 用户名"]', 'admin')
24
+ pg.fill('.ant-input-password input', 'admin123')
25
+ try:
26
+ with pg.expect_response(lambda r: '/api/users/login' in r.url, timeout=15000):
27
+ pg.locator('.ant-input-password input').first.press('Enter')
28
+ except Exception:
29
+ pass
30
+ inp = pg.locator('input[placeholder="邮箱 / 用户名"]')
31
+ if inp.count() == 0 or not inp.first.is_visible():
32
+ break
33
+ print('logged in, theme:', pg.evaluate('document.documentElement.className'))
34
+
35
+ # 主题:dark 需要时点主题钮(runtime 插件可能按服务端设置强制 light)
36
+ want = os.environ.get('THEME', 'dark')
37
+ is_dark = 'dark' in (pg.evaluate('document.documentElement.className') or '')
38
+ if (want == 'dark') != is_dark:
39
+ btn = pg.locator('button.icon-btn', has=pg.locator('.i-tabler-sun-high, .i-tabler-moon-stars')).first
40
+ if btn.count():
41
+ btn.click()
42
+ pg.wait_for_timeout(1200)
43
+ print('toggled theme →', pg.evaluate('document.documentElement.className'))
44
+
45
+ for path in PAGES:
46
+ pg.goto(BASE + path, wait_until='domcontentloaded', timeout=60000)
47
+ pg.wait_for_timeout(3200)
48
+ name = path.strip('/').replace('/', '-') or 'home'
49
+ pg.screenshot(path=f'{OUT}/{name}.png')
50
+ print('shot', path)
51
+ b.close()
52
+ print('done →', OUT)
@@ -1468,5 +1468,12 @@
1468
1468
  "color": "#ff8a5c",
1469
1469
  "description": "",
1470
1470
  "createdAt": "2026-09-07T10:18:16.098+08:00"
1471
+ },
1472
+ {
1473
+ "id": "ln-34dedb0b",
1474
+ "name": "opsline-oltcvd",
1475
+ "color": "#3aa0ff",
1476
+ "description": "",
1477
+ "createdAt": "2026-09-07T12:04:05.866+08:00"
1471
1478
  }
1472
1479
  ]
@@ -1468,5 +1468,12 @@
1468
1468
  "name": "mh-prod-mhqc88",
1469
1469
  "description": "",
1470
1470
  "createdAt": "2026-09-07T01:17:49.528+08:00"
1471
+ },
1472
+ {
1473
+ "id": "pd-7daab995",
1474
+ "lineId": "ln-34dedb0b",
1475
+ "name": "opsproduct-oltcvd",
1476
+ "description": "",
1477
+ "createdAt": "2026-09-07T12:04:05.905+08:00"
1471
1478
  }
1472
1479
  ]
@@ -3756,5 +3756,27 @@
3756
3756
  "lastGoodRunId": "rr-38d2742c",
3757
3757
  "createdAt": "2026-09-07T01:17:49.548+08:00",
3758
3758
  "updatedAt": "2026-09-07T01:19:07.844+08:00"
3759
+ },
3760
+ {
3761
+ "id": "rc-74bc88da",
3762
+ "productId": "pd-7daab995",
3763
+ "lineId": "ln-34dedb0b",
3764
+ "name": "opsrecipe-oltcvd",
3765
+ "description": "",
3766
+ "params": [
3767
+ {
3768
+ "nodeId": "dw-7110d946",
3769
+ "templateRef": "temp-sp",
3770
+ "value": 42,
3771
+ "min": 0,
3772
+ "max": 100
3773
+ }
3774
+ ],
3775
+ "daqWindows": [],
3776
+ "version": 1,
3777
+ "paramsHistory": [],
3778
+ "lastGoodRunId": null,
3779
+ "createdAt": "2026-09-07T12:04:05.938+08:00",
3780
+ "updatedAt": "2026-09-07T12:04:05.938+08:00"
3759
3781
  }
3760
3782
  ]
@@ -5568,6 +5568,30 @@
5568
5568
  "recipeRunId": "rr-77310ee4",
5569
5569
  "id": "anc-4f735fd7",
5570
5570
  "at": "2026-09-07T10:34:38.491+08:00"
5571
+ },
5572
+ {
5573
+ "lineId": "ln-34dedb0b",
5574
+ "nodeId": "dw-7110d946",
5575
+ "prevValue": null,
5576
+ "newValue": 42,
5577
+ "source": "recipe",
5578
+ "actor": "recipe",
5579
+ "recipeRunId": "rr-e977a22f",
5580
+ "id": "anc-fc8a1a9b",
5581
+ "at": "2026-09-07T12:04:06.060+08:00"
5582
+ },
5583
+ {
5584
+ "lineId": "ln-34dedb0b",
5585
+ "nodeId": "dw-7110d946",
5586
+ "prevValue": 42,
5587
+ "newValue": 55,
5588
+ "source": "agent",
5589
+ "actor": "59c552c7-803d-42cf-ac16-42b9345a9c64",
5590
+ "recipeRunId": null,
5591
+ "taskId": "e2e-opslog",
5592
+ "id": "anc-55d9cdd0",
5593
+ "at": "2026-09-07T12:04:06.569+08:00",
5594
+ "recordId": "opt-32fb7eaa"
5571
5595
  }
5572
5596
  ],
5573
5597
  "records": [
@@ -5959,7 +5983,7 @@
5959
5983
  "channels": [],
5960
5984
  "degraded": true
5961
5985
  },
5962
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
5986
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
5963
5987
  "windowAgg": {
5964
5988
  "at": "2026-08-31T16:25:17.398Z",
5965
5989
  "fromMs": 1788193396897,
@@ -12408,7 +12432,7 @@
12408
12432
  }
12409
12433
  ]
12410
12434
  },
12411
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12435
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12412
12436
  "windowAgg": {
12413
12437
  "at": "2026-09-05T02:07:03.383Z",
12414
12438
  "fromMs": 1788573903195,
@@ -12469,7 +12493,7 @@
12469
12493
  }
12470
12494
  ]
12471
12495
  },
12472
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12496
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12473
12497
  "windowAgg": {
12474
12498
  "at": "2026-09-05T02:44:52.815Z",
12475
12499
  "fromMs": 1788576172595,
@@ -12529,7 +12553,7 @@
12529
12553
  }
12530
12554
  ]
12531
12555
  },
12532
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12556
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12533
12557
  "windowAgg": {
12534
12558
  "at": "2026-09-05T03:09:49.742Z",
12535
12559
  "fromMs": 1788577669697,
@@ -12589,7 +12613,7 @@
12589
12613
  }
12590
12614
  ]
12591
12615
  },
12592
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12616
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12593
12617
  "windowAgg": {
12594
12618
  "at": "2026-09-05T03:34:32.268Z",
12595
12619
  "fromMs": 1788579151974,
@@ -12638,7 +12662,7 @@
12638
12662
  "channels": [],
12639
12663
  "degraded": true
12640
12664
  },
12641
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12665
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12642
12666
  "windowAgg": {
12643
12667
  "at": "2026-09-05T09:01:07.414Z",
12644
12668
  "fromMs": 1788598747074,
@@ -12677,7 +12701,7 @@
12677
12701
  "channels": [],
12678
12702
  "degraded": true
12679
12703
  },
12680
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12704
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12681
12705
  "windowAgg": {
12682
12706
  "at": "2026-09-06T21:04:02.391+08:00",
12683
12707
  "fromMs": 1788699722063,
@@ -12716,7 +12740,7 @@
12716
12740
  "channels": [],
12717
12741
  "degraded": true
12718
12742
  },
12719
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12743
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12720
12744
  "windowAgg": {
12721
12745
  "at": "2026-09-06T21:18:40.623+08:00",
12722
12746
  "fromMs": 1788700600508,
@@ -12755,7 +12779,7 @@
12755
12779
  "channels": [],
12756
12780
  "degraded": true
12757
12781
  },
12758
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
12782
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
12759
12783
  "windowAgg": {
12760
12784
  "at": "2026-09-06T21:27:40.730+08:00",
12761
12785
  "fromMs": 1788701140666,
@@ -13804,7 +13828,7 @@
13804
13828
  }
13805
13829
  ]
13806
13830
  },
13807
- "evaluatedAt": "2026-09-07T11:22:31.954+08:00",
13831
+ "evaluatedAt": "2026-09-07T13:05:20.354+08:00",
13808
13832
  "windowAgg": {
13809
13833
  "at": "2026-09-07T01:35:04.592+08:00",
13810
13834
  "fromMs": 1788715984468,
@@ -14323,6 +14347,45 @@
14323
14347
  }
14324
14348
  ]
14325
14349
  }
14350
+ },
14351
+ {
14352
+ "lineId": "ln-34dedb0b",
14353
+ "nodeId": "dw-7110d946",
14354
+ "nodeName": "opsnode-oltcvd",
14355
+ "recipeId": null,
14356
+ "agentId": "59c552c7-803d-42cf-ac16-42b9345a9c64",
14357
+ "taskId": "e2e-opslog",
14358
+ "hypothesis": "",
14359
+ "params": [
14360
+ {
14361
+ "nodeId": "dw-7110d946",
14362
+ "templateRef": "temp-sp",
14363
+ "from": 42,
14364
+ "to": 55
14365
+ }
14366
+ ],
14367
+ "setAt": "2026-09-07T12:04:06.569+08:00",
14368
+ "status": "open",
14369
+ "judge": null,
14370
+ "anchorId": "anc-55d9cdd0",
14371
+ "policy": "auto_rollback",
14372
+ "id": "opt-32fb7eaa",
14373
+ "createdAt": "2026-09-07T12:04:06.569+08:00",
14374
+ "baseline": {
14375
+ "at": "2026-09-07T12:04:06.573+08:00",
14376
+ "fromMs": 1788753246569,
14377
+ "toMs": 1788753846569,
14378
+ "channels": [],
14379
+ "degraded": true
14380
+ },
14381
+ "evaluatedAt": "2026-09-07T13:05:16.260+08:00",
14382
+ "windowAgg": {
14383
+ "at": "2026-09-07T12:06:06.978+08:00",
14384
+ "fromMs": 1788753846569,
14385
+ "toMs": 1788753966978,
14386
+ "channels": [],
14387
+ "degraded": true
14388
+ }
14326
14389
  }
14327
14390
  ]
14328
14391
  }