@auto-ai/agent 2.1.120 → 2.1.122

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 (85) hide show
  1. package/.env.example +2 -1
  2. package/dist/404/index.html +1 -1
  3. package/dist/404.html +1 -1
  4. package/dist/_next/static/chunks/19aa69c07b3642d5.js +1 -0
  5. package/dist/_next/static/chunks/24459c7365a2b28b.js +1 -0
  6. package/dist/_next/static/chunks/{d3e2070a86378cfb.js → 33eeef286c328da0.js} +1 -1
  7. package/dist/_next/static/chunks/3407244006d6a98a.js +1 -0
  8. package/dist/_next/static/chunks/566e152e480b267a.js +1 -0
  9. package/dist/_next/static/chunks/6ad4268160f361a6.js +1 -0
  10. package/dist/_next/static/chunks/{d9a278a2a26e8ee5.js → 6f9a48a7f83e669a.js} +1 -1
  11. package/dist/_next/static/chunks/7658b5b9c2865eb1.js +1 -0
  12. package/dist/_next/static/chunks/7a5fd448b280dd64.js +1 -0
  13. package/dist/_next/static/chunks/{fa677aa06f1c0539.js → 98f0c5604e839ba2.js} +1 -1
  14. package/dist/_next/static/chunks/a38eccf0bb5ca1e9.js +1 -0
  15. package/dist/_next/static/chunks/b29a354245bfc377.css +1 -0
  16. package/dist/_next/static/chunks/b76778c5811ef7a1.js +1 -0
  17. package/dist/_next/static/chunks/c2bed9d5fa7be4bd.js +1 -0
  18. package/dist/_next/static/chunks/c5a4977aae6a008c.js +1 -0
  19. package/dist/_next/static/chunks/e7bd145455a541af.css +4 -0
  20. package/dist/_next/static/chunks/f2bb685629307d4d.js +1 -0
  21. package/dist/_next/static/chunks/f7e71ce1c236f806.js +1 -0
  22. package/dist/_next/static/chunks/{67acc15b8a448e1a.js → fc4be3bcf72559a0.js} +1 -1
  23. package/dist/index.html +1 -1
  24. package/dist/index.txt +16 -16
  25. package/dist/manage/about/index.html +2 -2
  26. package/dist/manage/about/index.txt +19 -19
  27. package/dist/manage/add-account/basic/index.html +2 -2
  28. package/dist/manage/add-account/basic/index.txt +23 -22
  29. package/dist/manage/add-account/index.html +2 -2
  30. package/dist/manage/add-account/index.txt +22 -23
  31. package/dist/manage/agent-teams/index.html +2 -2
  32. package/dist/manage/agent-teams/index.txt +21 -21
  33. package/dist/manage/env/index.html +2 -2
  34. package/dist/manage/env/index.txt +21 -21
  35. package/dist/manage/general/index.html +2 -2
  36. package/dist/manage/general/index.txt +19 -19
  37. package/dist/manage/index.html +1 -1
  38. package/dist/manage/index.txt +16 -16
  39. package/dist/manage/mcp/index.html +2 -2
  40. package/dist/manage/mcp/index.txt +21 -21
  41. package/dist/manage/permissions/index.html +2 -2
  42. package/dist/manage/permissions/index.txt +19 -19
  43. package/dist/manage/skills/index.html +2 -2
  44. package/dist/manage/skills/index.txt +21 -21
  45. package/dist/manage/task/index.html +2 -2
  46. package/dist/manage/task/index.txt +19 -19
  47. package/dist/manage/teams/index.html +2 -2
  48. package/dist/manage/teams/index.txt +19 -19
  49. package/dist/manage/tools/index.html +2 -2
  50. package/dist/manage/tools/index.txt +21 -21
  51. package/dist/ws-test.html +129 -191
  52. package/mcps-runtime/claude-geelib-channel/.mcp.json +18 -0
  53. package/mcps-runtime/claude-geelib-channel/server/boot.mjs +32 -0
  54. package/mcps-runtime/claude-geelib-channel/server/geelib-api.mjs +192 -0
  55. package/mcps-runtime/claude-geelib-channel/server/geelib-auth.mjs +147 -0
  56. package/mcps-runtime/claude-geelib-channel/server/geelib-client.mjs +63 -0
  57. package/mcps-runtime/claude-geelib-channel/server/index.mjs +451 -0
  58. package/mcps-runtime/claude-geelib-channel/server/poll.mjs +457 -0
  59. package/mcps-runtime/claude-geelib-channel/server/state.mjs +216 -0
  60. package/package.json +6 -6
  61. package/tools-runtime/code-tool/index.cjs +1 -0
  62. package/tools-runtime/code-tool/src/index.ts +7 -1
  63. package/tools-runtime/git-tool/index.cjs +69 -5
  64. package/tools-runtime/git-tool/src/workspace.ts +101 -4
  65. package/tools-runtime/git-tool/src/wsInit.ts +26 -3
  66. package/dist/_next/static/chunks/249606605eed1993.js +0 -1
  67. package/dist/_next/static/chunks/424d3f3f176d43d7.js +0 -1
  68. package/dist/_next/static/chunks/4302af16b34bf750.js +0 -1
  69. package/dist/_next/static/chunks/4a073924e062c459.css +0 -1
  70. package/dist/_next/static/chunks/6209b42cbfcf288a.js +0 -1
  71. package/dist/_next/static/chunks/83bf6e4bc0aad48b.css +0 -4
  72. package/dist/_next/static/chunks/8b34d657c6bbb8df.js +0 -1
  73. package/dist/_next/static/chunks/904ad158fd721117.js +0 -1
  74. package/dist/_next/static/chunks/99063f8d79783308.js +0 -1
  75. package/dist/_next/static/chunks/9cd912a1967f10df.js +0 -1
  76. package/dist/_next/static/chunks/c52dcbe269bb02d0.js +0 -1
  77. package/dist/_next/static/chunks/d01957b1055b357a.js +0 -1
  78. package/dist/_next/static/chunks/dacc94cf10289334.js +0 -1
  79. package/dist/_next/static/chunks/fff9d250e482f00e.js +0 -1
  80. package/skills-runtime/geelib/SKILL.md +0 -229
  81. package/skills-runtime/geelib/geelib-poller-state.json +0 -17
  82. package/skills-runtime/geelib/geelib.mjs +0 -762
  83. /package/dist/_next/static/{fg4nA8liSSLEgWV4WTZDt → pVB1xZbEW09ksdJlV12Zn}/_buildManifest.js +0 -0
  84. /package/dist/_next/static/{fg4nA8liSSLEgWV4WTZDt → pVB1xZbEW09ksdJlV12Zn}/_clientMiddlewareManifest.json +0 -0
  85. /package/dist/_next/static/{fg4nA8liSSLEgWV4WTZDt → pVB1xZbEW09ksdJlV12Zn}/_ssgManifest.js +0 -0
package/dist/ws-test.html CHANGED
@@ -2901,7 +2901,7 @@
2901
2901
  </button>
2902
2902
  </div>
2903
2903
  <p id="mcpItemConfigHint" class="tool-files-sub" style="margin: 0 1rem 0.5rem; line-height: 1.4">
2904
- 标准 mcp.json 单条 server 配置(与 Cursor mcp.json 相同):<code>{ "command": "...", "args": [...], "env": {...} }</code>。保存后写入 agent .mcp.json <code>mcpServers.&lt;serverName&gt;</code>。
2904
+ 标准 mcp.json 单条 server 配置(与 Cursor mcp.json 相同):<code>{ "command": "...", "args": [...], "env": {...} }</code>。runtime MCP 保存到当前包目录 <code>.mcp.json</code>;remote MCP 保存到 agent <code>.mcp.json</code>。
2905
2905
  </p>
2906
2906
  <textarea id="mcpItemConfigEditor" class="agent-md-editor" spellcheck="false" placeholder="加载中…"></textarea>
2907
2907
  <div class="agent-md-modal-foot">
@@ -3228,7 +3228,6 @@
3228
3228
  <div class="schedule-manage-toolbar">
3229
3229
  <button type="button" class="btn-system-settings" id="btnScheduleRefresh">刷新</button>
3230
3230
  <button type="button" class="btn-system-settings" id="btnScheduleCreateToggle">新建任务</button>
3231
- <button type="button" class="btn-system-settings" id="btnScheduleGeelibPreset">Geelib 巡检</button>
3232
3231
  </div>
3233
3232
  <div id="scheduleCreateForm" class="schedule-create-form" hidden>
3234
3233
  <div class="schedule-create-row">
@@ -3403,7 +3402,6 @@
3403
3402
  const btnScheduleManageModalClose = $('btnScheduleManageModalClose')
3404
3403
  const btnScheduleRefresh = $('btnScheduleRefresh')
3405
3404
  const btnScheduleCreateToggle = $('btnScheduleCreateToggle')
3406
- const btnScheduleGeelibPreset = $('btnScheduleGeelibPreset')
3407
3405
  const scheduleCreateForm = $('scheduleCreateForm')
3408
3406
  const scheduleSessionSelect = $('scheduleSessionSelect')
3409
3407
  const schedulePromptInput = $('schedulePromptInput')
@@ -3964,9 +3962,17 @@
3964
3962
  }
3965
3963
  const SHOW_TEAMMATE_EXIT_LIFECYCLE = true
3966
3964
  let renderScheduled = false
3965
+ /** HTTP 历史回放进行中:暂存实时 conversation.delta,避免与回放竞态写乱 transcript 下标 */
3966
+ let sessionReplayInProgress = false
3967
+ const pendingConversationDeltaEnvelopes = []
3967
3968
 
3968
3969
  function sourceAgentPayloadToText(payload) {
3969
3970
  if (!payload || typeof payload !== 'object') return ''
3971
+ if (payload.state === 'console') {
3972
+ const consoleLine =
3973
+ typeof payload.message === 'string' ? payload.message.trim() : ''
3974
+ if (consoleLine) return consoleLine
3975
+ }
3970
3976
  const t = typeof payload.type === 'string' ? payload.type : 'unknown'
3971
3977
  if (t === 'turn.terminal') {
3972
3978
  const resultText = typeof payload.resultText === 'string' ? payload.resultText : ''
@@ -4058,6 +4064,44 @@
4058
4064
  return buffer
4059
4065
  }
4060
4066
 
4067
+ /**
4068
+ * 业务语义:conversation.delta 的 index 是 transcript 全局下标(续聊时可能远大于当前 buffer 长度)。
4069
+ * 必须把槽位扩到 index 再写入,禁止把 index=206 的消息 push 到 buffer[0]。
4070
+ */
4071
+ function padRunBufferThroughIndex(runBuffer, index) {
4072
+ while (runBuffer.length <= index) {
4073
+ runBuffer.push(null)
4074
+ }
4075
+ }
4076
+
4077
+ function applyConversationDeltaToRunBuffer(runBuffer, action, index, runMessage) {
4078
+ if (index < 0) return
4079
+ if (action === 'message_removed') {
4080
+ if (index < runBuffer.length) {
4081
+ runBuffer.splice(index, 1)
4082
+ }
4083
+ return
4084
+ }
4085
+ if (action === 'message_added') {
4086
+ if (index <= runBuffer.length) {
4087
+ runBuffer.splice(index, 0, runMessage)
4088
+ } else {
4089
+ padRunBufferThroughIndex(runBuffer, index - 1)
4090
+ runBuffer.push(runMessage)
4091
+ }
4092
+ return
4093
+ }
4094
+ padRunBufferThroughIndex(runBuffer, index)
4095
+ runBuffer[index] = runMessage
4096
+ }
4097
+
4098
+ function flushPendingConversationDeltas() {
4099
+ const pending = pendingConversationDeltaEnvelopes.splice(0)
4100
+ for (let i = 0; i < pending.length; i++) {
4101
+ applyWsEnvelopeV3(pending[i])
4102
+ }
4103
+ }
4104
+
4061
4105
  function isNearBottom(el) {
4062
4106
  if (!el) return true
4063
4107
  const gap = el.scrollHeight - (el.scrollTop + el.clientHeight)
@@ -4298,12 +4342,20 @@
4298
4342
  if (t === 'user') {
4299
4343
  const body = extractMessageBody(m)
4300
4344
  if (!body.trim()) continue
4345
+ const isToolResult =
4346
+ Array.isArray(m.message && m.message.content) &&
4347
+ m.message.content.some(function (block) {
4348
+ return block && block.type === 'tool_result'
4349
+ })
4301
4350
  const div = document.createElement('div')
4302
4351
  div.className = 'chat-msg chat-msg-user'
4303
4352
  applyScheduledMsgClass(div, isScheduled)
4304
4353
  const lab = document.createElement('div')
4305
4354
  lab.className = 'chat-msg-label'
4306
- lab.textContent = formatScheduledLabel('User · agent=' + messageAgent, isScheduled)
4355
+ lab.textContent = formatScheduledLabel(
4356
+ (isToolResult ? 'Tool Result' : 'User') + ' · agent=' + messageAgent,
4357
+ isScheduled,
4358
+ )
4307
4359
  const bodyEl = document.createElement('div')
4308
4360
  bodyEl.className = 'chat-user-body'
4309
4361
  setMessageBodyEl(bodyEl, body)
@@ -4314,12 +4366,20 @@
4314
4366
  } else if (t === 'assistant') {
4315
4367
  const body = extractMessageBody(m)
4316
4368
  if (!body.trim()) continue
4369
+ const isToolCall =
4370
+ Array.isArray(m.message && m.message.content) &&
4371
+ m.message.content.some(function (block) {
4372
+ return block && block.type === 'tool_use'
4373
+ })
4317
4374
  const div = document.createElement('div')
4318
4375
  div.className = 'chat-msg chat-msg-assistant'
4319
4376
  applyScheduledMsgClass(div, isScheduled)
4320
4377
  const lab = document.createElement('div')
4321
4378
  lab.className = 'chat-msg-label'
4322
- lab.textContent = formatScheduledLabel('Assistant · agent=' + messageAgent, isScheduled)
4379
+ lab.textContent = formatScheduledLabel(
4380
+ (isToolCall ? 'Tool Call' : 'Assistant') + ' · agent=' + messageAgent,
4381
+ isScheduled,
4382
+ )
4323
4383
  const md = document.createElement('div')
4324
4384
  md.className = 'chat-md'
4325
4385
  md.innerHTML = renderMd(body)
@@ -4584,6 +4644,8 @@
4584
4644
  chatState.streamByRun.clear()
4585
4645
  chatState.sourceAgentMessages = []
4586
4646
  chatState.seenEventIds.clear()
4647
+ sessionReplayInProgress = false
4648
+ pendingConversationDeltaEnvelopes.length = 0
4587
4649
  autoScrollState.mode = 'STICKY_BOTTOM'
4588
4650
  if (logEl) logEl.textContent = ''
4589
4651
  requestRenderChat()
@@ -4665,13 +4727,17 @@
4665
4727
  function applyWsEnvelopeV3(data) {
4666
4728
  if (!data || typeof data !== 'object') return false
4667
4729
  if (data.protocolVersion !== 3) return false
4730
+ const runId = typeof data.runId === 'string' ? data.runId : 'main'
4731
+ const payload = data.data && typeof data.data === 'object' ? data.data : {}
4732
+ const type = typeof data.type === 'string' ? data.type : 'unknown'
4733
+ if (type === 'conversation.delta' && sessionReplayInProgress) {
4734
+ pendingConversationDeltaEnvelopes.push(data)
4735
+ return true
4736
+ }
4668
4737
  if (typeof data.eventId === 'string' && data.eventId) {
4669
4738
  if (chatState.seenEventIds.has(data.eventId)) return true
4670
4739
  chatState.seenEventIds.add(data.eventId)
4671
4740
  }
4672
- const runId = typeof data.runId === 'string' ? data.runId : 'main'
4673
- const payload = data.data && typeof data.data === 'object' ? data.data : {}
4674
- const type = typeof data.type === 'string' ? data.type : 'unknown'
4675
4741
  if (type === 'conversation.delta') {
4676
4742
  const action = typeof payload.action === 'string' ? payload.action : ''
4677
4743
  const index = Number.isInteger(payload.index) ? payload.index : -1
@@ -4688,32 +4754,7 @@
4688
4754
  : '',
4689
4755
  arrivalSeq: ++chatState.eventClock,
4690
4756
  }
4691
- if (action === 'message_removed') {
4692
- if (index >= 0 && index < runBuffer.length) {
4693
- runBuffer.splice(index, 1)
4694
- }
4695
- } else if (action === 'message_added') {
4696
- if (index >= 0) {
4697
- if (index >= runBuffer.length) {
4698
- runBuffer.push(runMessage)
4699
- } else {
4700
- runBuffer.splice(index, 0, runMessage)
4701
- }
4702
- }
4703
- } else if (
4704
- action === 'message_updated' ||
4705
- action === 'tool_call' ||
4706
- action === 'tool_result' ||
4707
- action === 'message_completed'
4708
- ) {
4709
- if (index >= 0) {
4710
- if (index >= runBuffer.length) {
4711
- runBuffer.push(runMessage)
4712
- } else {
4713
- runBuffer[index] = runMessage
4714
- }
4715
- }
4716
- }
4757
+ applyConversationDeltaToRunBuffer(runBuffer, action, index, runMessage)
4717
4758
  requestRenderChat()
4718
4759
  return true
4719
4760
  }
@@ -4814,8 +4855,14 @@
4814
4855
  if (typeof payload.sessionId === 'string' && payload.sessionId) {
4815
4856
  sessionIdInput.value = payload.sessionId
4816
4857
  sessionIdInput.placeholder = '留空下次新建'
4817
- if (window.__lastSessions) renderSessionList(window.__lastSessions)
4818
- else updateMainHeader()
4858
+ void loadSessions()
4859
+ if (pendingSessionOverrides) {
4860
+ void flushPendingSessionOverridesIfAny()
4861
+ } else {
4862
+ void loadSessionOverridesIntoComposer()
4863
+ }
4864
+ } else {
4865
+ updateMainHeader()
4819
4866
  }
4820
4867
  return true
4821
4868
  }
@@ -4827,6 +4874,8 @@
4827
4874
  const phase = typeof payload.phase === 'string' ? payload.phase : ''
4828
4875
  if (phase === 'idle') {
4829
4876
  if (serverReady) setStatus('已就绪。', 'ready')
4877
+ // 一轮 prompt 收尾后 transcript 已落盘,刷新列表以更新页签 firstPrompt/summary
4878
+ void loadSessions()
4830
4879
  } else if (phase) {
4831
4880
  setStatus('查询阶段: ' + phase + '…', '')
4832
4881
  }
@@ -5162,6 +5211,8 @@
5162
5211
  async function loadSessionReplayViaHttp(sessionId) {
5163
5212
  const sid = typeof sessionId === 'string' ? sessionId.trim() : ''
5164
5213
  if (!sid) return
5214
+ sessionReplayInProgress = true
5215
+ pendingConversationDeltaEnvelopes.length = 0
5165
5216
  try {
5166
5217
  const r = await fetch(buildSessionReplayUrl(sid))
5167
5218
  const data = await r.json()
@@ -5174,7 +5225,6 @@
5174
5225
  for (let i = 0; i < envelopes.length; i++) {
5175
5226
  applyWsEnvelopeV3(envelopes[i])
5176
5227
  }
5177
- requestRenderChat()
5178
5228
  logLine('session-replay-http', {
5179
5229
  sessionId: sid,
5180
5230
  messageCount: data.messageCount,
@@ -5183,6 +5233,10 @@
5183
5233
  } catch (e) {
5184
5234
  logLine('session-replay-http', String(e))
5185
5235
  setStatus('历史回放失败: ' + e, 'err')
5236
+ } finally {
5237
+ sessionReplayInProgress = false
5238
+ flushPendingConversationDeltas()
5239
+ requestRenderChat()
5186
5240
  }
5187
5241
  }
5188
5242
 
@@ -5254,20 +5308,6 @@
5254
5308
  }
5255
5309
  }
5256
5310
 
5257
- /** Geelib 定时巡检快捷模板:/geelib poll,每分钟循环 */
5258
- function applyGeelibSchedulePreset() {
5259
- if (scheduleCreateForm) scheduleCreateForm.hidden = false
5260
- populateScheduleSessionSelect()
5261
- if (schedulePromptInput) schedulePromptInput.value = '/geelib poll'
5262
- document.querySelectorAll('input[name="scheduleTriggerMode"]').forEach(function (el) {
5263
- el.checked = el.value === 'cron'
5264
- })
5265
- if (scheduleDelayRow) scheduleDelayRow.hidden = true
5266
- if (scheduleCronRow) scheduleCronRow.hidden = false
5267
- if (scheduleCronInput) scheduleCronInput.value = '* * * * *'
5268
- if (scheduleRecurringInput) scheduleRecurringInput.checked = true
5269
- }
5270
-
5271
5311
  /** 渲染定时任务表格 */
5272
5312
  function renderScheduleTaskTable(tasks, timezone) {
5273
5313
  if (!scheduleTaskTableBody || !scheduleManageEmpty) return
@@ -5536,12 +5576,6 @@
5536
5576
  return u.toString()
5537
5577
  }
5538
5578
 
5539
- function buildToolBaseListUrl() {
5540
- const u = new URL('/api/tools/base-list', httpOriginForApi() + '/')
5541
- u.searchParams.set('agent', currentAgentParam())
5542
- return u.toString()
5543
- }
5544
-
5545
5579
  function buildToolInstalledListUrl() {
5546
5580
  const u = new URL('/api/tools/installed-list', httpOriginForApi() + '/')
5547
5581
  u.searchParams.set('agent', currentAgentParam())
@@ -6781,19 +6815,6 @@
6781
6815
  runId: data.runId,
6782
6816
  seq: data.seq,
6783
6817
  })
6784
- if (
6785
- data.type === 'session.meta' &&
6786
- data.data &&
6787
- typeof data.data === 'object' &&
6788
- data.data.sessionId
6789
- ) {
6790
- void loadSessions()
6791
- if (pendingSessionOverrides) {
6792
- void flushPendingSessionOverridesIfAny()
6793
- } else {
6794
- void loadSessionOverridesIntoComposer()
6795
- }
6796
- }
6797
6818
  updateButtons()
6798
6819
  return
6799
6820
  }
@@ -7913,8 +7934,7 @@
7913
7934
 
7914
7935
  if (kind === 'tools') {
7915
7936
  const toolPickerState = {
7916
- activeTab: 'base',
7917
- baseRows: [],
7937
+ activeTab: 'installed',
7918
7938
  installedRows: [],
7919
7939
  cloudRows: [],
7920
7940
  cloudQuery: '',
@@ -7951,17 +7971,28 @@
7951
7971
  if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
7952
7972
  const tools = Array.isArray(x.b.tools) ? x.b.tools : []
7953
7973
  return tools.map(function (t) {
7954
- return { id: t.name, t: t }
7974
+ const pkg = t.packageName ? String(t.packageName) : ''
7975
+ const layer = t.layer === 'system' || t.layer === 'agent' ? t.layer : ''
7976
+ const layerTag = layer === 'system' ? ' [系统]' : layer === 'agent' ? ' [Agent]' : ''
7977
+ return {
7978
+ id: t.name,
7979
+ t: t,
7980
+ packageId: pkg,
7981
+ deletable: t.deletable === true,
7982
+ layerTag: layerTag,
7983
+ }
7955
7984
  })
7956
7985
  })
7957
7986
  }
7958
- const makeManageRow = function (row, canDelete) {
7987
+ const makeManageRow = function (row) {
7959
7988
  const id = row.id
7989
+ const canDelete = row.deletable === true
7990
+ const packageId = row.packageId || ''
7960
7991
  const div = document.createElement('div')
7961
7992
  div.className = 'agent-picker-item'
7962
7993
  const labelEl = document.createElement('div')
7963
7994
  labelEl.className = 'agent-picker-item-label'
7964
- labelEl.textContent = toolLabel(row)
7995
+ labelEl.textContent = toolLabel(row) + (row.layerTag || '')
7965
7996
  div.appendChild(labelEl)
7966
7997
  const actions = document.createElement('div')
7967
7998
  actions.className = 'agent-picker-actions'
@@ -7976,13 +8007,13 @@
7976
8007
  renderToolsRows()
7977
8008
  })
7978
8009
  actions.appendChild(toggleBtn)
7979
- if (canDelete) {
8010
+ if (canDelete && packageId) {
7980
8011
  const exportBtn = document.createElement('button')
7981
8012
  exportBtn.type = 'button'
7982
8013
  exportBtn.className = 'btn-picker-action'
7983
8014
  exportBtn.textContent = '导出'
7984
8015
  exportBtn.addEventListener('click', function () {
7985
- window.open(buildRuntimeToolExportUrl(id), '_blank', 'noopener')
8016
+ window.open(buildRuntimeToolExportUrl(packageId), '_blank', 'noopener')
7986
8017
  })
7987
8018
  actions.appendChild(exportBtn)
7988
8019
  }
@@ -7990,10 +8021,13 @@
7990
8021
  delBtn.type = 'button'
7991
8022
  delBtn.className = 'btn-picker-action is-delete'
7992
8023
  delBtn.textContent = '删除'
7993
- delBtn.disabled = !canDelete
8024
+ delBtn.disabled = !canDelete || !packageId
8025
+ if (!canDelete) {
8026
+ delBtn.title = '系统内置工具不可删除'
8027
+ }
7994
8028
  delBtn.addEventListener('click', function () {
7995
8029
  if (delBtn.disabled) return
7996
- fetch(buildRuntimeToolDeleteUrl(id), { method: 'DELETE' })
8030
+ fetch(buildRuntimeToolDeleteUrl(packageId), { method: 'DELETE' })
7997
8031
  .then(function (r) {
7998
8032
  return r.json().catch(function () { return {} }).then(function (b) { return { r: r, b: b } })
7999
8033
  })
@@ -8011,111 +8045,21 @@
8011
8045
  div.appendChild(actions)
8012
8046
  return div
8013
8047
  }
8014
- const loadCloudRows = function () { return Promise.resolve() }
8015
8048
  const renderToolsRows = function () {
8016
8049
  if (!agentPickerList) return
8017
8050
  agentPickerList.innerHTML = ''
8018
- renderPickerHeaderTabs(
8019
- [
8020
- { id: 'base', label: '基础工具' },
8021
- { id: 'installed', label: '已安装工具' },
8022
- ],
8023
- toolPickerState.activeTab,
8024
- function (id) {
8025
- toolPickerState.activeTab = id
8026
- renderToolsRows()
8027
- },
8028
- )
8029
- if (toolPickerState.activeTab === 'base') {
8030
- const rows = toolPickerState.baseRows
8031
- if (!rows.length) {
8032
- agentPickerList.appendChild(document.createTextNode('(暂无)'))
8033
- return
8034
- }
8035
- for (let i = 0; i < rows.length; i++) agentPickerList.appendChild(makeManageRow(rows[i], false))
8051
+ const rows = toolPickerState.installedRows
8052
+ if (!rows.length) {
8053
+ agentPickerList.appendChild(document.createTextNode('(暂无已安装工具)'))
8036
8054
  return
8037
8055
  }
8038
- if (toolPickerState.activeTab === 'installed') {
8039
- const rows = toolPickerState.installedRows
8040
- if (!rows.length) {
8041
- agentPickerList.appendChild(document.createTextNode('(暂无)'))
8042
- return
8043
- }
8044
- for (let i = 0; i < rows.length; i++) agentPickerList.appendChild(makeManageRow(rows[i], true))
8045
- return
8046
- }
8047
- const cloudSearch = document.createElement('input')
8048
- cloudSearch.type = 'search'
8049
- cloudSearch.className = 'agent-picker-cloud-search'
8050
- cloudSearch.placeholder = '搜索云端工具…'
8051
- cloudSearch.value = toolPickerState.cloudQuery
8052
- cloudSearch.oninput = function () {
8053
- toolPickerState.cloudQuery = cloudSearch.value.trim()
8054
- toolPickerState.cloudPage = 1
8055
- void loadCloudRows()
8056
- }
8057
- agentPickerList.appendChild(cloudSearch)
8058
- agentPickerList.appendChild(createCloudPager({
8059
- page: toolPickerState.cloudPage,
8060
- totalPages: toolPickerState.cloudTotalPages,
8061
- loading: toolPickerState.cloudLoading,
8062
- }, function (nextPage) {
8063
- toolPickerState.cloudPage = nextPage
8064
- void loadCloudRows()
8065
- }))
8066
- if (toolPickerState.cloudError) {
8067
- agentPickerList.appendChild(document.createTextNode('加载失败:' + toolPickerState.cloudError))
8068
- return
8069
- }
8070
- if (!toolPickerState.cloudRows.length) {
8071
- agentPickerList.appendChild(document.createTextNode(toolPickerState.cloudLoading ? '加载中…' : '(无匹配项)'))
8072
- return
8073
- }
8074
- for (let i = 0; i < toolPickerState.cloudRows.length; i++) {
8075
- const item = toolPickerState.cloudRows[i]
8076
- const row = document.createElement('div')
8077
- row.className = 'agent-picker-item'
8078
- const label = document.createElement('div')
8079
- label.className = 'agent-picker-item-label'
8080
- label.textContent = item.title + ' · ' + item.toolName + (item.description ? ' — ' + item.description : '')
8081
- row.appendChild(label)
8082
- const actions = document.createElement('div')
8083
- actions.className = 'agent-picker-actions'
8084
- const opBtn = document.createElement('button')
8085
- opBtn.type = 'button'
8086
- opBtn.className = 'btn-picker-action' + (item.installed ? ' is-delete' : '')
8087
- const running = !!toolPickerState.loadingMap[item.id]
8088
- opBtn.disabled = running
8089
- opBtn.textContent = running ? '处理中…' : item.installed ? '卸载' : '安装'
8090
- opBtn.addEventListener('click', function () {
8091
- if (opBtn.disabled) return
8092
- toolPickerState.loadingMap[item.id] = true
8093
- renderToolsRows()
8094
- const req = item.installed
8095
- ? fetch(buildRuntimeToolDeleteUrl(item.packageId), { method: 'DELETE' })
8096
- : Promise.reject(new Error('云端工具安装接口已下线'))
8097
- req
8098
- .then(function (r) { return r.json().catch(function () { return {} }).then(function (b) { return { r: r, b: b } }) })
8099
- .then(function (x) {
8100
- if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
8101
- restartCurrentSessionSubprocessWithReason(item.installed ? 'cloud-tool-uninstall' : 'cloud-tool-install')
8102
- return refreshToolPickerRows()
8103
- })
8104
- .catch(function (e) { window.alert((item.installed ? '卸载' : '安装') + '失败: ' + e) })
8105
- .finally(function () { delete toolPickerState.loadingMap[item.id]; renderToolsRows() })
8106
- })
8107
- actions.appendChild(opBtn)
8108
- row.appendChild(actions)
8109
- agentPickerList.appendChild(row)
8056
+ for (let i = 0; i < rows.length; i++) {
8057
+ agentPickerList.appendChild(makeManageRow(rows[i]))
8110
8058
  }
8111
8059
  }
8112
8060
  refreshToolPickerRows = function () {
8113
- return Promise.all([
8114
- fetchToolRows(buildToolBaseListUrl),
8115
- fetchToolRows(buildToolInstalledListUrl),
8116
- ]).then(function (allRows) {
8117
- toolPickerState.baseRows = allRows[0]
8118
- toolPickerState.installedRows = allRows[1]
8061
+ return fetchToolRows(buildToolInstalledListUrl).then(function (rows) {
8062
+ toolPickerState.installedRows = rows
8119
8063
  renderToolsRows()
8120
8064
  })
8121
8065
  }
@@ -9114,11 +9058,6 @@
9114
9058
  if (!scheduleCreateForm.hidden) populateScheduleSessionSelect()
9115
9059
  })
9116
9060
  }
9117
- if (btnScheduleGeelibPreset) {
9118
- btnScheduleGeelibPreset.addEventListener('click', function () {
9119
- applyGeelibSchedulePreset()
9120
- })
9121
- }
9122
9061
  if (btnScheduleCreateCancel && scheduleCreateForm) {
9123
9062
  btnScheduleCreateCancel.addEventListener('click', function () {
9124
9063
  scheduleCreateForm.hidden = true
@@ -9331,16 +9270,15 @@
9331
9270
  agentEnvSessionTabStrip.setAttribute('aria-label', '环境变量、编辑 agent.md、设置')
9332
9271
  agentEnvSessionTabStrip.removeAttribute('hidden')
9333
9272
  }
9334
- if (!agentEnvSchema.length) {
9335
- void loadProjectEnvDefaults().then(function () {
9336
- const latestEnvObj =
9337
- agentConfigState.env && typeof agentConfigState.env === 'object'
9338
- ? agentConfigState.env
9339
- : {}
9340
- agentEnvFieldValues = buildAgentEnvFieldValues(latestEnvObj)
9341
- renderAgentEnvList()
9342
- })
9343
- }
9273
+ /** 每次打开设置弹窗都拉最新 schema,避免后端新增字段后页面仍用旧缓存。 */
9274
+ void loadProjectEnvDefaults().then(function () {
9275
+ const latestEnvObj =
9276
+ agentConfigState.env && typeof agentConfigState.env === 'object'
9277
+ ? agentConfigState.env
9278
+ : {}
9279
+ agentEnvFieldValues = buildAgentEnvFieldValues(latestEnvObj)
9280
+ renderAgentEnvList()
9281
+ })
9344
9282
  renderAgentEnvHeaderTabs()
9345
9283
  syncAgentEnvTabPanels()
9346
9284
  agentEnvModal.classList.add('is-open')
@@ -0,0 +1,18 @@
1
+ {
2
+ "mcpServers": {
3
+ "geelib": {
4
+ "command": "node",
5
+ "args": [
6
+ "${CLAUDE_PLUGIN_ROOT}/server/boot.mjs"
7
+ ],
8
+ "env": {
9
+ "GEELIB_USER": "${GEELIB_USER}",
10
+ "GEELIB_PASSWD": "${GEELIB_PASSWD}",
11
+ "GEELIB_BASE_URL": "${GEELIB_BASE_URL:-https://geelib.qihoo.net}",
12
+ "GEELIB_SUB_ID": "${GEELIB_SUB_ID}",
13
+ "GEELIB_STATE_DIR": "${WS_AGENTS_ROOT}/mcps-runtime/claude-geelib-channel/.state",
14
+ "GEELIB_POLL_INTERVAL_MS": "${GEELIB_POLL_INTERVAL_MS:-60000}"
15
+ }
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,32 @@
1
+ import { mkdirSync, appendFileSync } from 'node:fs'
2
+ import { dirname, join } from 'node:path'
3
+ import { homedir } from 'node:os'
4
+
5
+ const stateDir =
6
+ process.env.GEELIB_STATE_DIR ||
7
+ join(homedir(), '.claude', 'channels', 'geelib')
8
+ const bootLog = join(stateDir, 'boot.log')
9
+ mkdirSync(dirname(bootLog), { recursive: true })
10
+
11
+ function log(line) {
12
+ appendFileSync(bootLog, `${new Date().toISOString()} ${line}\n`, {
13
+ encoding: 'utf8',
14
+ mode: 0o600,
15
+ flag: 'a',
16
+ })
17
+ }
18
+
19
+ log(`[BOOT] geelib-channel boot.mjs start pid=${process.pid}`)
20
+ log(
21
+ `[BOOT] env GEELIB_STATE_DIR=${process.env.GEELIB_STATE_DIR || ''} GEELIB_POLL_INTERVAL_MS=${process.env.GEELIB_POLL_INTERVAL_MS || ''} GEELIB_SUB_ID=${process.env.GEELIB_SUB_ID || ''}`,
22
+ )
23
+
24
+ process.on('uncaughtException', err => {
25
+ log(`[BOOT] uncaughtException ${err?.stack || err}`)
26
+ })
27
+ process.on('unhandledRejection', err => {
28
+ log(`[BOOT] unhandledRejection ${err?.stack || err}`)
29
+ })
30
+
31
+ await import('./index.mjs')
32
+ log('[BOOT] imported index.mjs successfully')