comisai 1.0.24 → 1.0.25

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 (98) hide show
  1. package/node_modules/@comis/agent/package.json +1 -1
  2. package/node_modules/@comis/channels/package.json +1 -1
  3. package/node_modules/@comis/cli/package.json +1 -1
  4. package/node_modules/@comis/core/dist/bootstrap.js +5 -0
  5. package/node_modules/@comis/core/dist/config/env-layer.d.ts +31 -0
  6. package/node_modules/@comis/core/dist/config/env-layer.js +41 -0
  7. package/node_modules/@comis/core/dist/config/layered.d.ts +9 -0
  8. package/node_modules/@comis/core/dist/config/layered.js +11 -0
  9. package/node_modules/@comis/core/package.json +1 -1
  10. package/node_modules/@comis/daemon/dist/daemon.js +3 -0
  11. package/node_modules/@comis/daemon/package.json +1 -1
  12. package/node_modules/@comis/gateway/package.json +1 -1
  13. package/node_modules/@comis/infra/package.json +1 -1
  14. package/node_modules/@comis/memory/package.json +1 -1
  15. package/node_modules/@comis/scheduler/package.json +1 -1
  16. package/node_modules/@comis/shared/package.json +1 -1
  17. package/node_modules/@comis/skills/package.json +1 -1
  18. package/node_modules/@comis/web/dist/assets/{agent-detail-BG9MGWWj.js → agent-detail-ru-AhppM.js} +270 -270
  19. package/node_modules/@comis/web/dist/assets/agent-editor-hjwRuFVp.js +2173 -0
  20. package/node_modules/@comis/web/dist/assets/{agent-list-LHCJ4rw2.js → agent-list-6Uotjatr.js} +170 -170
  21. package/node_modules/@comis/web/dist/assets/{approvals-q9VH_IKr.js → approvals-C-K6hN2U.js} +13 -13
  22. package/node_modules/@comis/web/dist/assets/billing-view-CxysXH0p.js +375 -0
  23. package/node_modules/@comis/web/dist/assets/{channel-detail-CaInesJM.js → channel-detail-BBCKtmne.js} +265 -265
  24. package/node_modules/@comis/web/dist/assets/channel-list-FkfeOLBQ.js +323 -0
  25. package/node_modules/@comis/web/dist/assets/{chat-console-CNmzl0JW.js → chat-console-BumBaIgO.js} +243 -246
  26. package/node_modules/@comis/web/dist/assets/{config-editor-DX4ITw6y.js → config-editor-C9BSwHGy.js} +477 -477
  27. package/node_modules/@comis/web/dist/assets/{context-dag-browser-BwiaF5tf.js → context-dag-browser-BHm00mJD.js} +105 -105
  28. package/node_modules/@comis/web/dist/assets/{context-engine-BZ5Am6hA.js → context-engine-BENY3pWE.js} +136 -136
  29. package/node_modules/@comis/web/dist/assets/decorate-BvWYovGE.js +38 -0
  30. package/node_modules/@comis/web/dist/assets/{delivery-view-OfBZof-m.js → delivery-view-BCnkPsAp.js} +134 -134
  31. package/node_modules/@comis/web/dist/assets/{diagnostics-view-YFwCxgr2.js → diagnostics-view-C_jQFG2H.js} +82 -82
  32. package/node_modules/@comis/web/dist/assets/directive-BOYXJ-K-.js +1 -0
  33. package/node_modules/@comis/web/dist/assets/{extract-variables-BM5qyK-s.js → extract-variables-B7-Doo7l.js} +39 -39
  34. package/node_modules/@comis/web/dist/assets/{ic-array-editor-B7m6x7-S.js → ic-array-editor-BLoEyeLS.js} +29 -29
  35. package/node_modules/@comis/web/dist/assets/{ic-breadcrumb-CUMpp3BL.js → ic-breadcrumb-DqN6G3gc.js} +16 -16
  36. package/node_modules/@comis/web/dist/assets/{ic-budget-segment-bar-BtJ6x5mN.js → ic-budget-segment-bar-zLsMzjDO.js} +20 -20
  37. package/node_modules/@comis/web/dist/assets/ic-chat-message-FdQcZsSQ.js +352 -0
  38. package/node_modules/@comis/web/dist/assets/{ic-confirm-dialog-CCDbB04e.js → ic-confirm-dialog-DGlPbV1T.js} +26 -26
  39. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CnT1b8xr.js → ic-connection-dot-BgYiK2N4.js} +13 -13
  40. package/node_modules/@comis/web/dist/assets/ic-data-table-CKIvr-ag.js +277 -0
  41. package/node_modules/@comis/web/dist/assets/ic-delivery-row-B3YwjjuM.js +67 -0
  42. package/node_modules/@comis/web/dist/assets/{ic-detail-panel-BF83r-if.js → ic-detail-panel-DiCe4hLr.js} +27 -27
  43. package/node_modules/@comis/web/dist/assets/{ic-empty-state-60l2ePhd.js → ic-empty-state-CM3Wbj2f.js} +19 -19
  44. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-ByRjij68.js +359 -0
  45. package/node_modules/@comis/web/dist/assets/ic-icon-BGNCCPpZ.js +33 -0
  46. package/node_modules/@comis/web/dist/assets/{ic-layer-waterfall-COvEYMg5.js → ic-layer-waterfall-WkaFyu-l.js} +18 -18
  47. package/node_modules/@comis/web/dist/assets/ic-relative-time-B3UAnTqg.js +12 -0
  48. package/node_modules/@comis/web/dist/assets/{ic-search-input-CSOxY9g7.js → ic-search-input-B02AGw1i.js} +22 -22
  49. package/node_modules/@comis/web/dist/assets/{ic-select-Ce-Raudx.js → ic-select-BqfZISjw.js} +29 -29
  50. package/node_modules/@comis/web/dist/assets/ic-tabs-yBjkWKJH.js +95 -0
  51. package/node_modules/@comis/web/dist/assets/ic-tag-CvMVQFRR.js +33 -0
  52. package/node_modules/@comis/web/dist/assets/{ic-time-range-picker-CypCT68y.js → ic-time-range-picker-DXbYeBmY.js} +31 -31
  53. package/node_modules/@comis/web/dist/assets/{ic-tool-call-7MaXSsCW.js → ic-tool-call-DMPHsLyx.js} +51 -51
  54. package/node_modules/@comis/web/dist/assets/index-CVEaS9aY.css +2 -0
  55. package/node_modules/@comis/web/dist/assets/index-FLPhHz8p.js +2792 -0
  56. package/node_modules/@comis/web/dist/assets/{mcp-management-BNZPnpDn.js → mcp-management-5jyScQis.js} +209 -209
  57. package/node_modules/@comis/web/dist/assets/{media-config-BBvTYxOX.js → media-config-J9oT9PPs.js} +154 -154
  58. package/node_modules/@comis/web/dist/assets/{media-test-BkK3RCRK.js → media-test-DGTCtM8-.js} +259 -259
  59. package/node_modules/@comis/web/dist/assets/{memory-inspector-1hDGCGat.js → memory-inspector-D5Re9ptG.js} +450 -450
  60. package/node_modules/@comis/web/dist/assets/{message-center-CXefwsUu.js → message-center-cRLK6ZmG.js} +290 -290
  61. package/node_modules/@comis/web/dist/assets/{models-C1qcU_j3.js → models-D5vu07MR.js} +371 -371
  62. package/node_modules/@comis/web/dist/assets/observability-types-D0tkwElU.js +1 -0
  63. package/node_modules/@comis/web/dist/assets/{observe-view-C0VBhX4C.js → observe-view-CalNNEmd.js} +399 -399
  64. package/node_modules/@comis/web/dist/assets/pipeline-builder-DUYDGwZf.js +1495 -0
  65. package/node_modules/@comis/web/dist/assets/{pipeline-history-DkfOQ6SW.js → pipeline-history-BAO8brOe.js} +124 -124
  66. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-hyHgD0ai.js → pipeline-history-detail-DectIoQt.js} +65 -65
  67. package/node_modules/@comis/web/dist/assets/{pipeline-list-BPW8hV-q.js → pipeline-list-BHlaBKww.js} +227 -227
  68. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-Bip16T7e.js → pipeline-monitor-BhtpNEHf.js} +298 -298
  69. package/node_modules/@comis/web/dist/assets/{scheduler-BGgwKd06.js → scheduler-VafN_8xi.js} +486 -486
  70. package/node_modules/@comis/web/dist/assets/{security-D15st4xx.js → security-QQXMRTlo.js} +389 -389
  71. package/node_modules/@comis/web/dist/assets/{session-detail-SGEYNJ0M.js → session-detail-BpZ_8Yih.js} +294 -294
  72. package/node_modules/@comis/web/dist/assets/session-key-parser-Dkqcj2Ss.js +1 -0
  73. package/node_modules/@comis/web/dist/assets/session-list-DfCm8Cec.js +231 -0
  74. package/node_modules/@comis/web/dist/assets/{setup-wizard-nT0tz9QP.js → setup-wizard-C-z477CG.js} +486 -494
  75. package/node_modules/@comis/web/dist/assets/{skills-D8yVfSUy.js → skills-BCOGPf6s.js} +329 -329
  76. package/node_modules/@comis/web/dist/assets/{subagents-HHXMeHYo.js → subagents-l-auUraL.js} +74 -74
  77. package/node_modules/@comis/web/dist/assets/{workspace-manager-BQlr10iH.js → workspace-manager-DlvBixiq.js} +236 -236
  78. package/node_modules/@comis/web/dist/index.html +3 -2
  79. package/node_modules/@comis/web/package.json +1 -1
  80. package/package.json +15 -15
  81. package/node_modules/@comis/web/dist/assets/agent-editor-C26Q_xCs.js +0 -2173
  82. package/node_modules/@comis/web/dist/assets/billing-view-CtYvBqTE.js +0 -375
  83. package/node_modules/@comis/web/dist/assets/channel-list-B8dj3O9a.js +0 -323
  84. package/node_modules/@comis/web/dist/assets/directive-DoeGSK_T.js +0 -1
  85. package/node_modules/@comis/web/dist/assets/ic-chat-message-CFyDJd0z.js +0 -352
  86. package/node_modules/@comis/web/dist/assets/ic-data-table-CKUNTxHw.js +0 -277
  87. package/node_modules/@comis/web/dist/assets/ic-delivery-row-GP5Fkygs.js +0 -67
  88. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-C8FuSMe1.js +0 -359
  89. package/node_modules/@comis/web/dist/assets/ic-icon-xeGTVhVG.js +0 -33
  90. package/node_modules/@comis/web/dist/assets/ic-relative-time-3FqpjeAI.js +0 -12
  91. package/node_modules/@comis/web/dist/assets/ic-tabs-B7QtM_v8.js +0 -95
  92. package/node_modules/@comis/web/dist/assets/ic-tag-CPPUnDLF.js +0 -33
  93. package/node_modules/@comis/web/dist/assets/index-CEcM1R_C.js +0 -2830
  94. package/node_modules/@comis/web/dist/assets/index-CIJFuItj.css +0 -1
  95. package/node_modules/@comis/web/dist/assets/observability-types-D7jUtSde.js +0 -1
  96. package/node_modules/@comis/web/dist/assets/pipeline-builder-DcUUIrm0.js +0 -1496
  97. package/node_modules/@comis/web/dist/assets/session-key-parser-DPORMVyU.js +0 -1
  98. package/node_modules/@comis/web/dist/assets/session-list-6ybUTxbY.js +0 -231
@@ -1,267 +1,4 @@
1
- import{a as b,S as y,I as h,b as t,A as u,s as _,f as x,i as k,n as m,r as c,t as $}from"./index-CEcM1R_C.js";import"./ic-breadcrumb-CUMpp3BL.js";import"./ic-tabs-B7QtM_v8.js";import"./ic-icon-xeGTVhVG.js";import"./ic-connection-dot-CnT1b8xr.js";import"./ic-relative-time-3FqpjeAI.js";import"./ic-tag-CPPUnDLF.js";import"./ic-empty-state-60l2ePhd.js";var w=Object.defineProperty,T=Object.getOwnPropertyDescriptor,r=(e,i,a,n)=>{for(var l=n>1?void 0:n?T(i,a):i,o=e.length-1,d;o>=0;o--)(d=e[o])&&(l=(n?d(i,a,l):d(l))||l);return n&&l&&w(i,a,l),l};const f=[{key:"transcribeAudio",label:"Voice Transcription",description:"Transcribe inbound audio/voice attachments to text (STT)"},{key:"analyzeImages",label:"Image Analysis",description:"Analyze inbound images using vision AI"},{key:"describeVideos",label:"Video Description",description:"Generate text descriptions of inbound video attachments"},{key:"extractDocuments",label:"Document Extraction",description:"Extract text from PDF, CSV, and other document attachments"},{key:"understandLinks",label:"Link Understanding",description:"Fetch and inject content from URLs in message text"}],A={telegram:[{key:"botToken",label:"Bot Token",type:"secret"},{key:"webhookUrl",label:"Webhook URL",type:"text",placeholder:"https://..."},{key:"ackReaction.enabled",label:"Ack Reaction",type:"toggle"},{key:"ackReaction.emoji",label:"Ack Emoji",type:"text",placeholder:"👀"}],discord:[{key:"botToken",label:"Bot Token",type:"secret"},{key:"guildId",label:"Guild ID",type:"text"}],slack:[{key:"botToken",label:"Bot Token",type:"secret"},{key:"appToken",label:"App Token",type:"secret"},{key:"signingSecret",label:"Signing Secret",type:"secret"},{key:"mode",label:"Mode",type:"select",options:["socket","http"]}],whatsapp:[{key:"authDir",label:"Auth Directory",type:"text"},{key:"printQR",label:"Print QR Code",type:"toggle"}],line:[{key:"channelSecret",label:"Channel Secret",type:"secret"},{key:"webhookPath",label:"Webhook Path",type:"text",placeholder:"/webhooks/line"}],signal:[{key:"baseUrl",label:"Base URL",type:"text",placeholder:"http://127.0.0.1:8080"},{key:"account",label:"Account",type:"text"},{key:"cliPath",label:"CLI Path",type:"text"}],irc:[{key:"host",label:"Host",type:"text"},{key:"port",label:"Port",type:"text"},{key:"nick",label:"Nick",type:"text"},{key:"tls",label:"TLS",type:"toggle"},{key:"nickservPassword",label:"NickServ Password",type:"secret"},{key:"channels",label:"Channels",type:"list"}],imessage:[{key:"binaryPath",label:"Binary Path",type:"text"},{key:"account",label:"Account",type:"text"}]};function g(e){return e?e.charAt(0).toUpperCase()+e.slice(1):""}function D(e,i){return i.split(".").reduce((a,n)=>a!=null&&typeof a=="object"?a[n]:void 0,e)}let s=class extends b{constructor(){super(...arguments),this.apiClient=null,this.rpcClient=null,this.eventDispatcher=null,this.channelType="",this._loadState="loading",this._error="",this._config={},this._enabled=!1,this._status="disconnected",this._deliveryTrace=[],this._activityData=[],this._channelLastActiveAt=0,this._channelMessagesSent=0,this._channelMessagesReceived=0,this._connectionMode="",this._lastError="",this._actionPending=!1,this._queueStatus=null,this._capabilities=null,this._mediaProcessing={transcribeAudio:!0,analyzeImages:!0,describeVideos:!0,extractDocuments:!0,understandLinks:!0},this._sse=null,this._reloadDebounce=null,this._hasLoaded=!1,this._previousChannelType=""}connectedCallback(){super.connectedCallback(),this._initSse()}disconnectedCallback(){super.disconnectedCallback(),this._reloadDebounce!==null&&(clearTimeout(this._reloadDebounce),this._reloadDebounce=null)}updated(e){e.has("channelType")&&this.channelType&&this.channelType!==this._previousChannelType?(this._previousChannelType=this.channelType,this._hasLoaded=!1,this._loadData()):(e.has("rpcClient")||e.has("apiClient"))&&this.rpcClient&&this.channelType&&!this._hasLoaded&&this._loadData(),e.has("eventDispatcher")&&this.eventDispatcher&&!this._sse&&this._initSse()}_initSse(){!this.eventDispatcher||this._sse||(this._sse=new y(this,this.eventDispatcher,{"diagnostic:channel_health":()=>{this._scheduleReload(500)}}))}_scheduleReload(e=300){this._reloadDebounce!==null&&clearTimeout(this._reloadDebounce),this._reloadDebounce=setTimeout(()=>{this._reloadDebounce=null,this._loadData()},e)}async _loadData(){if(!(!this.rpcClient||!this.channelType)){this._loadState="loading",this._error="";try{const e=await this.rpcClient.call("channels.get",{channel_type:this.channelType});this._config=e??{};const i=this._config.status??"";this._enabled=this._config.enabled??(i==="running"||i==="connected"),this._status=this._config.status??"disconnected",this._connectionMode=this._config.connectionMode??"",this._lastError=this._config.lastError??"";const[a,n,l,o,d]=await Promise.allSettled([this.rpcClient.call("config.read",{section:"channels"}),this.rpcClient.call("obs.delivery.recent",{type:this.channelType,limit:10}),this.rpcClient.call("obs.channels.get",{channelId:this.channelType}),this.rpcClient.call("delivery.queue.status",{channel_type:this.channelType}),this.rpcClient.call("channels.capabilities",{channel_type:this.channelType})]);if(a.status==="fulfilled"){const v=a.value?.[this.channelType]?.mediaProcessing;v&&(this._mediaProcessing={transcribeAudio:v.transcribeAudio!==!1,analyzeImages:v.analyzeImages!==!1,describeVideos:v.describeVideos!==!1,extractDocuments:v.extractDocuments!==!1,understandLinks:v.understandLinks!==!1})}if(n.status==="fulfilled"){const p=n.value;this._deliveryTrace=p?.deliveries??p?.entries??[]}else this._deliveryTrace=[];if(l.status==="fulfilled"&&l.value?.channel){const p=l.value.channel;this._channelLastActiveAt=p.lastActiveAt??0,this._channelMessagesSent=p.messagesSent??0,this._channelMessagesReceived=p.messagesReceived??0}o.status==="fulfilled"&&o.value?this._queueStatus=o.value:this._queueStatus=null,d.status==="fulfilled"&&d.value?.features?this._capabilities=d.value.features:this._capabilities=null,this._activityData=this._deriveActivityFromTraces(this._deliveryTrace),this._loadState="loaded",this._hasLoaded=!0}catch(e){this._error=e instanceof Error?e.message:"Failed to load channel configuration",this._loadState="error"}}}async _handleRestart(){if(this.rpcClient){this._actionPending=!0;try{await this.rpcClient.call("channels.restart",{channel_type:this.channelType}),h.show(`${g(this.channelType)} restarted`,"success"),await this._loadData()}catch{h.show(`Failed to restart ${this.channelType}`,"error")}finally{this._actionPending=!1}}}async _handleToggleEnabled(){if(this.rpcClient){this._actionPending=!0;try{this._enabled?(await this.rpcClient.call("channels.disable",{channel_type:this.channelType}),this._enabled=!1,h.show(`${g(this.channelType)} disabled`,"success")):(await this.rpcClient.call("channels.enable",{channel_type:this.channelType}),this._enabled=!0,h.show(`${g(this.channelType)} enabled`,"success")),await this._loadData()}catch{h.show(`Failed to ${this._enabled?"disable":"enable"} ${this.channelType}`,"error")}finally{this._actionPending=!1}}}async _handleMediaToggle(e,i){if(this.rpcClient){this._mediaProcessing={...this._mediaProcessing,[e]:i};try{await this.rpcClient.call("config.patch",{section:"channels",key:`${this.channelType}.mediaProcessing.${e}`,value:i});const a=f.find(n=>n.key===e)?.label??e;h.show(`${a} ${i?"enabled":"disabled"}`,"success")}catch{this._mediaProcessing={...this._mediaProcessing,[e]:!i},h.show("Failed to update media processing","error")}}}_renderMediaProcessing(){return t`
2
- <div class="section">
3
- <h3 class="section-title">Media Processing</h3>
4
- <div class="media-toggle-list">
5
- ${f.map(e=>t`
6
- <div class="media-toggle-item">
7
- <div class="media-toggle-info">
8
- <span class="media-toggle-label">${e.label}</span>
9
- <span class="media-toggle-desc">${e.description}</span>
10
- </div>
11
- <label class="toggle-switch">
12
- <input
13
- type="checkbox"
14
- .checked=${this._mediaProcessing[e.key]??!0}
15
- ?disabled=${this._actionPending}
16
- @change=${i=>{const a=i.target.checked;this._handleMediaToggle(e.key,a)}}
17
- />
18
- <span class="toggle-slider"></span>
19
- </label>
20
- </div>
21
- `)}
22
- </div>
23
- </div>
24
- `}_renderField(e){const i=D(this._config,e.key);switch(e.type){case"secret":return t`
25
- <div class="field">
26
- <label>${e.label}</label>
27
- <div class="field-value secret">${i?"••••••••":"Not set"}</div>
28
- </div>
29
- `;case"toggle":return t`
30
- <div class="field">
31
- <label>${e.label}</label>
32
- <div class="field-value">${i?"Enabled":"Disabled"}</div>
33
- </div>
34
- `;case"list":{const a=Array.isArray(i)?i:[];return t`
35
- <div class="field">
36
- <label>${e.label}</label>
37
- <div class="field-value list">${a.length>0?a.join(", "):"None"}</div>
38
- </div>
39
- `}default:return t`
40
- <div class="field">
41
- <label>${e.label}</label>
42
- <div class="field-value">${i!=null&&i!==""?String(i):"—"}</div>
43
- </div>
44
- `}}_renderPlatformFields(){const e=A[this.channelType];return!e||e.length===0?t`
45
- <div class="section">
46
- <h3 class="section-title">Platform Configuration</h3>
47
- <p class="section-hint">No platform-specific fields defined for ${g(this.channelType)}</p>
48
- </div>
49
- `:t`
50
- <div class="section">
51
- <h3 class="section-title">${g(this.channelType)} Configuration</h3>
52
- <div class="fields-grid">
53
- ${e.map(i=>this._renderField(i))}
54
- </div>
55
- </div>
56
- `}_renderAllowFrom(){const e=Array.isArray(this._config.allowFrom)?this._config.allowFrom:[];return t`
57
- <div class="section">
58
- <h3 class="section-title">Allow From</h3>
59
- ${e.length===0?t`<p class="section-hint">No restrictions \u2014 all senders allowed</p>`:t`
60
- <ul class="allow-list">
61
- ${e.map(i=>t`
62
- <li class="allow-item">
63
- <ic-icon name="user" size="14px"></ic-icon>
64
- ${i}
65
- </li>
66
- `)}
67
- </ul>
68
- `}
69
- </div>
70
- `}_renderStreamingConfig(){const e=this._config.streaming;return t`
71
- <div class="section">
72
- <h3 class="section-title">Streaming</h3>
73
- ${e?t`
74
- <div class="config-grid">
75
- <div class="config-item">
76
- <span class="config-label">Chunk Mode</span>
77
- <span class="config-value">${e.chunkMode||"—"}</span>
78
- </div>
79
- <div class="config-item">
80
- <span class="config-label">Pacing</span>
81
- <span class="config-value">${e.pacingMs?`${e.pacingMs}ms`:"—"}</span>
82
- </div>
83
- <div class="config-item">
84
- <span class="config-label">Typing Indicator</span>
85
- <span class="config-value">${e.typingMode||"—"}</span>
86
- </div>
87
- </div>
88
- `:t`<p class="section-hint">Default settings</p>`}
89
- </div>
90
- `}_renderAutoReply(){const e=this._config.autoReply;return t`
91
- <div class="section">
92
- <h3 class="section-title">Auto-Reply</h3>
93
- ${e?t`
94
- <div class="config-grid">
95
- <div class="config-item">
96
- <span class="config-label">Group Activation</span>
97
- <span class="config-value">${e.groupActivation||"—"}</span>
98
- </div>
99
- <div class="config-item">
100
- <span class="config-label">Cooldown</span>
101
- <span class="config-value">${e.cooldownMs?`${e.cooldownMs}ms`:"—"}</span>
102
- </div>
103
- </div>
104
- `:t`<p class="section-hint">Not configured</p>`}
105
- </div>
106
- `}_renderSendPolicy(){const e=this._config.sendPolicy,i=Array.isArray(e?.rules)?e.rules:[];return t`
107
- <div class="section">
108
- <h3 class="section-title">Send Policy</h3>
109
- ${i.length===0?t`<p class="section-hint">No send policy rules</p>`:t`
110
- <ul class="policy-list">
111
- ${i.map(a=>t`<li class="policy-item">${String(a)}</li>`)}
112
- </ul>
113
- `}
114
- </div>
115
- `}_formatTimeAgo(e){if(e<=0)return"unknown";const i=Date.now()-e,a=Math.floor(i/1e3);if(a<60)return"just now";const n=Math.floor(a/60);if(n<60)return`${n}m ago`;const l=Math.floor(n/60);return l<24?`${l}h ago`:`${Math.floor(l/24)}d ago`}_deriveActivityFromTraces(e){if(e.length===0)return[];const i=Date.now(),a=new Array(24).fill(0);for(const n of e){const l=n.timestamp??n.deliveredAt??0,o=Math.floor((i-l)/36e5);o>=0&&o<24&&a[23-o]++}return a}_renderDeliveryQueuePanel(){if(!this._queueStatus)return u;const e=this._queueStatus;return t`
116
- <div class="section">
117
- <h3 class="section-title">Delivery Queue</h3>
118
- <div class="config-grid">
119
- <div class="config-item">
120
- <span class="config-label">Pending</span>
121
- <span class="config-value" style="${e.pending>0?"color: var(--ic-warning)":""}">${e.pending}</span>
122
- </div>
123
- <div class="config-item">
124
- <span class="config-label">In Flight</span>
125
- <span class="config-value">${e.inFlight}</span>
126
- </div>
127
- <div class="config-item">
128
- <span class="config-label">Failed</span>
129
- <span class="config-value" style="${e.failed>0?"color: var(--ic-error)":""}">${e.failed}</span>
130
- </div>
131
- <div class="config-item">
132
- <span class="config-label">Delivered</span>
133
- <span class="config-value">${e.delivered}</span>
134
- </div>
135
- </div>
136
- </div>
137
- `}_renderCapabilitiesMatrix(){if(!this._capabilities)return u;const e=this._capabilities,i=[{label:"Reactions",supported:e.reactions},{label:"Edit Messages",supported:e.editMessages},{label:"Delete Messages",supported:e.deleteMessages},{label:"Fetch History",supported:e.fetchHistory},{label:"Attachments",supported:e.attachments},{label:"Threads",supported:e.threads},{label:"Mentions",supported:e.mentions},{label:"Buttons",supported:e.buttons},{label:"Cards",supported:e.cards},{label:"Effects",supported:e.effects}];return t`
138
- <div class="section">
139
- <h3 class="section-title">Platform Capabilities</h3>
140
- <div class="config-grid">
141
- ${i.map(a=>t`
142
- <div class="capability-row">
143
- <span class="config-label">${a.label}</span>
144
- <ic-icon
145
- name=${a.supported?"check":"x"}
146
- size="16px"
147
- color=${a.supported?"var(--ic-success)":"var(--ic-text-dim)"}
148
- ></ic-icon>
149
- </div>
150
- `)}
151
- </div>
152
- </div>
153
- `}_renderDeliveryTrace(){return t`
154
- <div class="section">
155
- <h3 class="section-title">Recent Deliveries</h3>
156
- ${this._deliveryTrace.length===0?t`<p class="section-hint">No recent deliveries</p>`:t`
157
- <div class="trace-grid" role="table" aria-label="Recent deliveries">
158
- <div role="row" style="display:contents">
159
- <div role="columnheader">Time</div>
160
- <div role="columnheader">Status</div>
161
- <div role="columnheader">Latency</div>
162
- </div>
163
- ${this._deliveryTrace.map((e,i)=>t`
164
- <div role="row" class="${i%2===1?"trace-row-even":""}" style="display:contents">
165
- <div role="cell"><ic-relative-time .timestamp=${e.timestamp??e.deliveredAt??0}></ic-relative-time></div>
166
- <div role="cell"><ic-tag variant=${e.success??e.status==="delivered"?"success":"error"}>${e.success!==void 0?e.success?"delivered":"failed":e.status??"unknown"}</ic-tag></div>
167
- <div role="cell">${e.latencyMs}ms</div>
168
- </div>
169
- `)}
170
- </div>
171
- `}
172
- </div>
173
- `}_renderActivitySparkline(){const e=Math.max(...this._activityData,1);return t`
174
- <div class="section">
175
- <h3 class="section-title">Message Activity (24h)</h3>
176
- ${this._activityData.length===0?t`<p class="section-hint">No activity data available</p>`:t`
177
- <div class="sparkline">
178
- ${this._activityData.map(i=>t`
179
- <div
180
- class="spark-bar"
181
- style="height: ${i/e*100}%"
182
- title="${i} messages"
183
- ></div>
184
- `)}
185
- </div>
186
- `}
187
- </div>
188
- `}render(){return this._loadState==="loading"?t`
189
- <div class="loading-container">
190
- <ic-loading size="lg"></ic-loading>
191
- </div>
192
- `:this._loadState==="error"?t`
193
- <div class="error-container">
194
- <div class="error-message">${this._error}</div>
195
- <button class="retry-btn" @click=${()=>{this._loadData()}}>Retry</button>
196
- </div>
197
- `:t`
198
- <div class="channel-detail">
199
- <ic-breadcrumb
200
- .items=${[{label:"Channels",route:"channels"},{label:g(this.channelType)}]}
201
- @navigate=${e=>{this.dispatchEvent(new CustomEvent("navigate",{detail:e.detail,bubbles:!1,composed:!1}))}}
202
- ></ic-breadcrumb>
203
-
204
- <div class="header-row">
205
- <div class="header-left">
206
- <ic-icon name=${this.channelType} size="32px"></ic-icon>
207
- <h1 class="page-title">${g(this.channelType)}</h1>
208
- <ic-connection-dot status=${this._status} size="10px" showLabel></ic-connection-dot>
209
- ${this._connectionMode?t`<span class="connection-mode-badge">${this._connectionMode}</span>`:u}
210
- </div>
211
- <div class="header-actions">
212
- <button class="btn btn-warning" @click=${()=>{this._handleRestart()}} ?disabled=${this._actionPending}>
213
- Restart
214
- </button>
215
- <button
216
- class="btn ${this._enabled?"btn-danger":"btn-primary"}"
217
- @click=${()=>{this._handleToggleEnabled()}}
218
- ?disabled=${this._actionPending}
219
- >
220
- ${this._enabled?"Disable":"Enable"}
221
- </button>
222
- </div>
223
- </div>
224
-
225
- ${this._lastError?t`
226
- <div class="error-banner">
227
- <ic-icon name="alert-circle" size="16px" color="var(--ic-error)"></ic-icon>
228
- <span>${this._lastError}</span>
229
- </div>
230
- `:u}
231
-
232
- ${this._channelLastActiveAt>0?t`
233
- <div class="last-message-row">
234
- <ic-icon name="message-circle" size="14px"></ic-icon>
235
- <span>Last message:</span>
236
- <span
237
- class="last-message-time"
238
- title=${new Date(this._channelLastActiveAt).toISOString()}
239
- >${this._formatTimeAgo(this._channelLastActiveAt)}</span>
240
- </div>
241
- `:u}
242
-
243
- <ic-tabs
244
- .tabs=${[{id:"config",label:"Configuration"},{id:"streaming",label:"Streaming"},{id:"activity",label:"Activity"}]}
245
- >
246
- <div data-tab="config">
247
- ${this._renderPlatformFields()}
248
- ${this._renderAllowFrom()}
249
- ${this._renderMediaProcessing()}
250
- </div>
251
- <div data-tab="streaming">
252
- ${this._renderStreamingConfig()}
253
- ${this._renderAutoReply()}
254
- ${this._renderSendPolicy()}
255
- </div>
256
- <div data-tab="activity">
257
- ${this._renderDeliveryQueuePanel()}
258
- ${this._renderCapabilitiesMatrix()}
259
- ${this._renderDeliveryTrace()}
260
- ${this._renderActivitySparkline()}
261
- </div>
262
- </ic-tabs>
263
- </div>
264
- `}};s.styles=[_,x,k`
1
+ import{c as e,f as t,h as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./decorate-BvWYovGE.js";import{a as u,i as d}from"./index-FLPhHz8p.js";import"./ic-breadcrumb-DqN6G3gc.js";import"./ic-tag-CvMVQFRR.js";import"./ic-relative-time-B3UAnTqg.js";import"./ic-icon-BGNCCPpZ.js";import"./ic-empty-state-CM3Wbj2f.js";import"./ic-tabs-yBjkWKJH.js";import"./ic-connection-dot-BgYiK2N4.js";var f=[{key:`transcribeAudio`,label:`Voice Transcription`,description:`Transcribe inbound audio/voice attachments to text (STT)`},{key:`analyzeImages`,label:`Image Analysis`,description:`Analyze inbound images using vision AI`},{key:`describeVideos`,label:`Video Description`,description:`Generate text descriptions of inbound video attachments`},{key:`extractDocuments`,label:`Document Extraction`,description:`Extract text from PDF, CSV, and other document attachments`},{key:`understandLinks`,label:`Link Understanding`,description:`Fetch and inject content from URLs in message text`}],p={telegram:[{key:`botToken`,label:`Bot Token`,type:`secret`},{key:`webhookUrl`,label:`Webhook URL`,type:`text`,placeholder:`https://...`},{key:`ackReaction.enabled`,label:`Ack Reaction`,type:`toggle`},{key:`ackReaction.emoji`,label:`Ack Emoji`,type:`text`,placeholder:`👀`}],discord:[{key:`botToken`,label:`Bot Token`,type:`secret`},{key:`guildId`,label:`Guild ID`,type:`text`}],slack:[{key:`botToken`,label:`Bot Token`,type:`secret`},{key:`appToken`,label:`App Token`,type:`secret`},{key:`signingSecret`,label:`Signing Secret`,type:`secret`},{key:`mode`,label:`Mode`,type:`select`,options:[`socket`,`http`]}],whatsapp:[{key:`authDir`,label:`Auth Directory`,type:`text`},{key:`printQR`,label:`Print QR Code`,type:`toggle`}],line:[{key:`channelSecret`,label:`Channel Secret`,type:`secret`},{key:`webhookPath`,label:`Webhook Path`,type:`text`,placeholder:`/webhooks/line`}],signal:[{key:`baseUrl`,label:`Base URL`,type:`text`,placeholder:`http://127.0.0.1:8080`},{key:`account`,label:`Account`,type:`text`},{key:`cliPath`,label:`CLI Path`,type:`text`}],irc:[{key:`host`,label:`Host`,type:`text`},{key:`port`,label:`Port`,type:`text`},{key:`nick`,label:`Nick`,type:`text`},{key:`tls`,label:`TLS`,type:`toggle`},{key:`nickservPassword`,label:`NickServ Password`,type:`secret`},{key:`channels`,label:`Channels`,type:`list`}],imessage:[{key:`binaryPath`,label:`Binary Path`,type:`text`},{key:`account`,label:`Account`,type:`text`}]};function m(e){return e?e.charAt(0).toUpperCase()+e.slice(1):``}function h(e,t){return t.split(`.`).reduce((e,t)=>typeof e==`object`&&e?e[t]:void 0,e)}var g=class extends r{constructor(...e){super(...e),this.apiClient=null,this.rpcClient=null,this.eventDispatcher=null,this.channelType=``,this._loadState=`loading`,this._error=``,this._config={},this._enabled=!1,this._status=`disconnected`,this._deliveryTrace=[],this._activityData=[],this._channelLastActiveAt=0,this._channelMessagesSent=0,this._channelMessagesReceived=0,this._connectionMode=``,this._lastError=``,this._actionPending=!1,this._queueStatus=null,this._capabilities=null,this._mediaProcessing={transcribeAudio:!0,analyzeImages:!0,describeVideos:!0,extractDocuments:!0,understandLinks:!0},this._sse=null,this._reloadDebounce=null,this._hasLoaded=!1,this._previousChannelType=``}static{this.styles=[o,i,n`
265
2
  :host {
266
3
  display: block;
267
4
  }
@@ -678,4 +415,267 @@ import{a as b,S as y,I as h,b as t,A as u,s as _,f as x,i as k,n as m,r as c,t a
678
415
  opacity: 0.5;
679
416
  cursor: not-allowed;
680
417
  }
681
- `];r([m({attribute:!1})],s.prototype,"apiClient",2);r([m({attribute:!1})],s.prototype,"rpcClient",2);r([m({attribute:!1})],s.prototype,"eventDispatcher",2);r([m()],s.prototype,"channelType",2);r([c()],s.prototype,"_loadState",2);r([c()],s.prototype,"_error",2);r([c()],s.prototype,"_config",2);r([c()],s.prototype,"_enabled",2);r([c()],s.prototype,"_status",2);r([c()],s.prototype,"_deliveryTrace",2);r([c()],s.prototype,"_activityData",2);r([c()],s.prototype,"_channelLastActiveAt",2);r([c()],s.prototype,"_channelMessagesSent",2);r([c()],s.prototype,"_channelMessagesReceived",2);r([c()],s.prototype,"_connectionMode",2);r([c()],s.prototype,"_lastError",2);r([c()],s.prototype,"_actionPending",2);r([c()],s.prototype,"_queueStatus",2);r([c()],s.prototype,"_capabilities",2);r([c()],s.prototype,"_mediaProcessing",2);s=r([$("ic-channel-detail")],s);export{s as IcChannelDetail};
418
+ `]}connectedCallback(){super.connectedCallback(),this._initSse()}disconnectedCallback(){super.disconnectedCallback(),this._reloadDebounce!==null&&(clearTimeout(this._reloadDebounce),this._reloadDebounce=null)}updated(e){e.has(`channelType`)&&this.channelType&&this.channelType!==this._previousChannelType?(this._previousChannelType=this.channelType,this._hasLoaded=!1,this._loadData()):(e.has(`rpcClient`)||e.has(`apiClient`))&&this.rpcClient&&this.channelType&&!this._hasLoaded&&this._loadData(),e.has(`eventDispatcher`)&&this.eventDispatcher&&!this._sse&&this._initSse()}_initSse(){!this.eventDispatcher||this._sse||(this._sse=new d(this,this.eventDispatcher,{"diagnostic:channel_health":()=>{this._scheduleReload(500)}}))}_scheduleReload(e=300){this._reloadDebounce!==null&&clearTimeout(this._reloadDebounce),this._reloadDebounce=setTimeout(()=>{this._reloadDebounce=null,this._loadData()},e)}async _loadData(){if(!(!this.rpcClient||!this.channelType)){this._loadState=`loading`,this._error=``;try{let e=await this.rpcClient.call(`channels.get`,{channel_type:this.channelType});this._config=e??{};let t=this._config.status??``;this._enabled=this._config.enabled??(t===`running`||t===`connected`),this._status=this._config.status??`disconnected`,this._connectionMode=this._config.connectionMode??``,this._lastError=this._config.lastError??``;let[n,r,i,a,o]=await Promise.allSettled([this.rpcClient.call(`config.read`,{section:`channels`}),this.rpcClient.call(`obs.delivery.recent`,{type:this.channelType,limit:10}),this.rpcClient.call(`obs.channels.get`,{channelId:this.channelType}),this.rpcClient.call(`delivery.queue.status`,{channel_type:this.channelType}),this.rpcClient.call(`channels.capabilities`,{channel_type:this.channelType})]);if(n.status===`fulfilled`){let e=n.value?.[this.channelType]?.mediaProcessing;e&&(this._mediaProcessing={transcribeAudio:e.transcribeAudio!==!1,analyzeImages:e.analyzeImages!==!1,describeVideos:e.describeVideos!==!1,extractDocuments:e.extractDocuments!==!1,understandLinks:e.understandLinks!==!1})}if(r.status===`fulfilled`){let e=r.value;this._deliveryTrace=e?.deliveries??e?.entries??[]}else this._deliveryTrace=[];if(i.status===`fulfilled`&&i.value?.channel){let e=i.value.channel;this._channelLastActiveAt=e.lastActiveAt??0,this._channelMessagesSent=e.messagesSent??0,this._channelMessagesReceived=e.messagesReceived??0}a.status===`fulfilled`&&a.value?this._queueStatus=a.value:this._queueStatus=null,o.status===`fulfilled`&&o.value?.features?this._capabilities=o.value.features:this._capabilities=null,this._activityData=this._deriveActivityFromTraces(this._deliveryTrace),this._loadState=`loaded`,this._hasLoaded=!0}catch(e){this._error=e instanceof Error?e.message:`Failed to load channel configuration`,this._loadState=`error`}}}async _handleRestart(){if(this.rpcClient){this._actionPending=!0;try{await this.rpcClient.call(`channels.restart`,{channel_type:this.channelType}),u.show(`${m(this.channelType)} restarted`,`success`),await this._loadData()}catch{u.show(`Failed to restart ${this.channelType}`,`error`)}finally{this._actionPending=!1}}}async _handleToggleEnabled(){if(this.rpcClient){this._actionPending=!0;try{this._enabled?(await this.rpcClient.call(`channels.disable`,{channel_type:this.channelType}),this._enabled=!1,u.show(`${m(this.channelType)} disabled`,`success`)):(await this.rpcClient.call(`channels.enable`,{channel_type:this.channelType}),this._enabled=!0,u.show(`${m(this.channelType)} enabled`,`success`)),await this._loadData()}catch{u.show(`Failed to ${this._enabled?`disable`:`enable`} ${this.channelType}`,`error`)}finally{this._actionPending=!1}}}async _handleMediaToggle(e,t){if(this.rpcClient){this._mediaProcessing={...this._mediaProcessing,[e]:t};try{await this.rpcClient.call(`config.patch`,{section:`channels`,key:`${this.channelType}.mediaProcessing.${e}`,value:t});let n=f.find(t=>t.key===e)?.label??e;u.show(`${n} ${t?`enabled`:`disabled`}`,`success`)}catch{this._mediaProcessing={...this._mediaProcessing,[e]:!t},u.show(`Failed to update media processing`,`error`)}}}_renderMediaProcessing(){return t`
419
+ <div class="section">
420
+ <h3 class="section-title">Media Processing</h3>
421
+ <div class="media-toggle-list">
422
+ ${f.map(e=>t`
423
+ <div class="media-toggle-item">
424
+ <div class="media-toggle-info">
425
+ <span class="media-toggle-label">${e.label}</span>
426
+ <span class="media-toggle-desc">${e.description}</span>
427
+ </div>
428
+ <label class="toggle-switch">
429
+ <input
430
+ type="checkbox"
431
+ .checked=${this._mediaProcessing[e.key]??!0}
432
+ ?disabled=${this._actionPending}
433
+ @change=${t=>{let n=t.target.checked;this._handleMediaToggle(e.key,n)}}
434
+ />
435
+ <span class="toggle-slider"></span>
436
+ </label>
437
+ </div>
438
+ `)}
439
+ </div>
440
+ </div>
441
+ `}_renderField(e){let n=h(this._config,e.key);switch(e.type){case`secret`:return t`
442
+ <div class="field">
443
+ <label>${e.label}</label>
444
+ <div class="field-value secret">${n?`••••••••`:`Not set`}</div>
445
+ </div>
446
+ `;case`toggle`:return t`
447
+ <div class="field">
448
+ <label>${e.label}</label>
449
+ <div class="field-value">${n?`Enabled`:`Disabled`}</div>
450
+ </div>
451
+ `;case`list`:{let r=Array.isArray(n)?n:[];return t`
452
+ <div class="field">
453
+ <label>${e.label}</label>
454
+ <div class="field-value list">${r.length>0?r.join(`, `):`None`}</div>
455
+ </div>
456
+ `}default:return t`
457
+ <div class="field">
458
+ <label>${e.label}</label>
459
+ <div class="field-value">${n!=null&&n!==``?String(n):`—`}</div>
460
+ </div>
461
+ `}}_renderPlatformFields(){let e=p[this.channelType];return!e||e.length===0?t`
462
+ <div class="section">
463
+ <h3 class="section-title">Platform Configuration</h3>
464
+ <p class="section-hint">No platform-specific fields defined for ${m(this.channelType)}</p>
465
+ </div>
466
+ `:t`
467
+ <div class="section">
468
+ <h3 class="section-title">${m(this.channelType)} Configuration</h3>
469
+ <div class="fields-grid">
470
+ ${e.map(e=>this._renderField(e))}
471
+ </div>
472
+ </div>
473
+ `}_renderAllowFrom(){let e=Array.isArray(this._config.allowFrom)?this._config.allowFrom:[];return t`
474
+ <div class="section">
475
+ <h3 class="section-title">Allow From</h3>
476
+ ${e.length===0?t`<p class="section-hint">No restrictions \u2014 all senders allowed</p>`:t`
477
+ <ul class="allow-list">
478
+ ${e.map(e=>t`
479
+ <li class="allow-item">
480
+ <ic-icon name="user" size="14px"></ic-icon>
481
+ ${e}
482
+ </li>
483
+ `)}
484
+ </ul>
485
+ `}
486
+ </div>
487
+ `}_renderStreamingConfig(){let e=this._config.streaming;return t`
488
+ <div class="section">
489
+ <h3 class="section-title">Streaming</h3>
490
+ ${e?t`
491
+ <div class="config-grid">
492
+ <div class="config-item">
493
+ <span class="config-label">Chunk Mode</span>
494
+ <span class="config-value">${e.chunkMode||`—`}</span>
495
+ </div>
496
+ <div class="config-item">
497
+ <span class="config-label">Pacing</span>
498
+ <span class="config-value">${e.pacingMs?`${e.pacingMs}ms`:`—`}</span>
499
+ </div>
500
+ <div class="config-item">
501
+ <span class="config-label">Typing Indicator</span>
502
+ <span class="config-value">${e.typingMode||`—`}</span>
503
+ </div>
504
+ </div>
505
+ `:t`<p class="section-hint">Default settings</p>`}
506
+ </div>
507
+ `}_renderAutoReply(){let e=this._config.autoReply;return t`
508
+ <div class="section">
509
+ <h3 class="section-title">Auto-Reply</h3>
510
+ ${e?t`
511
+ <div class="config-grid">
512
+ <div class="config-item">
513
+ <span class="config-label">Group Activation</span>
514
+ <span class="config-value">${e.groupActivation||`—`}</span>
515
+ </div>
516
+ <div class="config-item">
517
+ <span class="config-label">Cooldown</span>
518
+ <span class="config-value">${e.cooldownMs?`${e.cooldownMs}ms`:`—`}</span>
519
+ </div>
520
+ </div>
521
+ `:t`<p class="section-hint">Not configured</p>`}
522
+ </div>
523
+ `}_renderSendPolicy(){let e=this._config.sendPolicy,n=Array.isArray(e?.rules)?e.rules:[];return t`
524
+ <div class="section">
525
+ <h3 class="section-title">Send Policy</h3>
526
+ ${n.length===0?t`<p class="section-hint">No send policy rules</p>`:t`
527
+ <ul class="policy-list">
528
+ ${n.map(e=>t`<li class="policy-item">${String(e)}</li>`)}
529
+ </ul>
530
+ `}
531
+ </div>
532
+ `}_formatTimeAgo(e){if(e<=0)return`unknown`;let t=Date.now()-e,n=Math.floor(t/1e3);if(n<60)return`just now`;let r=Math.floor(n/60);if(r<60)return`${r}m ago`;let i=Math.floor(r/60);return i<24?`${i}h ago`:`${Math.floor(i/24)}d ago`}_deriveActivityFromTraces(e){if(e.length===0)return[];let t=Date.now(),n=Array(24).fill(0);for(let r of e){let e=r.timestamp??r.deliveredAt??0,i=Math.floor((t-e)/36e5);i>=0&&i<24&&n[23-i]++}return n}_renderDeliveryQueuePanel(){if(!this._queueStatus)return l;let e=this._queueStatus;return t`
533
+ <div class="section">
534
+ <h3 class="section-title">Delivery Queue</h3>
535
+ <div class="config-grid">
536
+ <div class="config-item">
537
+ <span class="config-label">Pending</span>
538
+ <span class="config-value" style="${e.pending>0?`color: var(--ic-warning)`:``}">${e.pending}</span>
539
+ </div>
540
+ <div class="config-item">
541
+ <span class="config-label">In Flight</span>
542
+ <span class="config-value">${e.inFlight}</span>
543
+ </div>
544
+ <div class="config-item">
545
+ <span class="config-label">Failed</span>
546
+ <span class="config-value" style="${e.failed>0?`color: var(--ic-error)`:``}">${e.failed}</span>
547
+ </div>
548
+ <div class="config-item">
549
+ <span class="config-label">Delivered</span>
550
+ <span class="config-value">${e.delivered}</span>
551
+ </div>
552
+ </div>
553
+ </div>
554
+ `}_renderCapabilitiesMatrix(){if(!this._capabilities)return l;let e=this._capabilities;return t`
555
+ <div class="section">
556
+ <h3 class="section-title">Platform Capabilities</h3>
557
+ <div class="config-grid">
558
+ ${[{label:`Reactions`,supported:e.reactions},{label:`Edit Messages`,supported:e.editMessages},{label:`Delete Messages`,supported:e.deleteMessages},{label:`Fetch History`,supported:e.fetchHistory},{label:`Attachments`,supported:e.attachments},{label:`Threads`,supported:e.threads},{label:`Mentions`,supported:e.mentions},{label:`Buttons`,supported:e.buttons},{label:`Cards`,supported:e.cards},{label:`Effects`,supported:e.effects}].map(e=>t`
559
+ <div class="capability-row">
560
+ <span class="config-label">${e.label}</span>
561
+ <ic-icon
562
+ name=${e.supported?`check`:`x`}
563
+ size="16px"
564
+ color=${e.supported?`var(--ic-success)`:`var(--ic-text-dim)`}
565
+ ></ic-icon>
566
+ </div>
567
+ `)}
568
+ </div>
569
+ </div>
570
+ `}_renderDeliveryTrace(){return t`
571
+ <div class="section">
572
+ <h3 class="section-title">Recent Deliveries</h3>
573
+ ${this._deliveryTrace.length===0?t`<p class="section-hint">No recent deliveries</p>`:t`
574
+ <div class="trace-grid" role="table" aria-label="Recent deliveries">
575
+ <div role="row" style="display:contents">
576
+ <div role="columnheader">Time</div>
577
+ <div role="columnheader">Status</div>
578
+ <div role="columnheader">Latency</div>
579
+ </div>
580
+ ${this._deliveryTrace.map((e,n)=>t`
581
+ <div role="row" class="${n%2==1?`trace-row-even`:``}" style="display:contents">
582
+ <div role="cell"><ic-relative-time .timestamp=${e.timestamp??e.deliveredAt??0}></ic-relative-time></div>
583
+ <div role="cell"><ic-tag variant=${e.success??e.status===`delivered`?`success`:`error`}>${e.success===void 0?e.status??`unknown`:e.success?`delivered`:`failed`}</ic-tag></div>
584
+ <div role="cell">${e.latencyMs}ms</div>
585
+ </div>
586
+ `)}
587
+ </div>
588
+ `}
589
+ </div>
590
+ `}_renderActivitySparkline(){let e=Math.max(...this._activityData,1);return t`
591
+ <div class="section">
592
+ <h3 class="section-title">Message Activity (24h)</h3>
593
+ ${this._activityData.length===0?t`<p class="section-hint">No activity data available</p>`:t`
594
+ <div class="sparkline">
595
+ ${this._activityData.map(n=>t`
596
+ <div
597
+ class="spark-bar"
598
+ style="height: ${n/e*100}%"
599
+ title="${n} messages"
600
+ ></div>
601
+ `)}
602
+ </div>
603
+ `}
604
+ </div>
605
+ `}render(){return this._loadState===`loading`?t`
606
+ <div class="loading-container">
607
+ <ic-loading size="lg"></ic-loading>
608
+ </div>
609
+ `:this._loadState===`error`?t`
610
+ <div class="error-container">
611
+ <div class="error-message">${this._error}</div>
612
+ <button class="retry-btn" @click=${()=>void this._loadData()}>Retry</button>
613
+ </div>
614
+ `:t`
615
+ <div class="channel-detail">
616
+ <ic-breadcrumb
617
+ .items=${[{label:`Channels`,route:`channels`},{label:m(this.channelType)}]}
618
+ @navigate=${e=>{this.dispatchEvent(new CustomEvent(`navigate`,{detail:e.detail,bubbles:!1,composed:!1}))}}
619
+ ></ic-breadcrumb>
620
+
621
+ <div class="header-row">
622
+ <div class="header-left">
623
+ <ic-icon name=${this.channelType} size="32px"></ic-icon>
624
+ <h1 class="page-title">${m(this.channelType)}</h1>
625
+ <ic-connection-dot status=${this._status} size="10px" showLabel></ic-connection-dot>
626
+ ${this._connectionMode?t`<span class="connection-mode-badge">${this._connectionMode}</span>`:l}
627
+ </div>
628
+ <div class="header-actions">
629
+ <button class="btn btn-warning" @click=${()=>void this._handleRestart()} ?disabled=${this._actionPending}>
630
+ Restart
631
+ </button>
632
+ <button
633
+ class="btn ${this._enabled?`btn-danger`:`btn-primary`}"
634
+ @click=${()=>void this._handleToggleEnabled()}
635
+ ?disabled=${this._actionPending}
636
+ >
637
+ ${this._enabled?`Disable`:`Enable`}
638
+ </button>
639
+ </div>
640
+ </div>
641
+
642
+ ${this._lastError?t`
643
+ <div class="error-banner">
644
+ <ic-icon name="alert-circle" size="16px" color="var(--ic-error)"></ic-icon>
645
+ <span>${this._lastError}</span>
646
+ </div>
647
+ `:l}
648
+
649
+ ${this._channelLastActiveAt>0?t`
650
+ <div class="last-message-row">
651
+ <ic-icon name="message-circle" size="14px"></ic-icon>
652
+ <span>Last message:</span>
653
+ <span
654
+ class="last-message-time"
655
+ title=${new Date(this._channelLastActiveAt).toISOString()}
656
+ >${this._formatTimeAgo(this._channelLastActiveAt)}</span>
657
+ </div>
658
+ `:l}
659
+
660
+ <ic-tabs
661
+ .tabs=${[{id:`config`,label:`Configuration`},{id:`streaming`,label:`Streaming`},{id:`activity`,label:`Activity`}]}
662
+ >
663
+ <div data-tab="config">
664
+ ${this._renderPlatformFields()}
665
+ ${this._renderAllowFrom()}
666
+ ${this._renderMediaProcessing()}
667
+ </div>
668
+ <div data-tab="streaming">
669
+ ${this._renderStreamingConfig()}
670
+ ${this._renderAutoReply()}
671
+ ${this._renderSendPolicy()}
672
+ </div>
673
+ <div data-tab="activity">
674
+ ${this._renderDeliveryQueuePanel()}
675
+ ${this._renderCapabilitiesMatrix()}
676
+ ${this._renderDeliveryTrace()}
677
+ ${this._renderActivitySparkline()}
678
+ </div>
679
+ </ic-tabs>
680
+ </div>
681
+ `}};c([s({attribute:!1})],g.prototype,`apiClient`,void 0),c([s({attribute:!1})],g.prototype,`rpcClient`,void 0),c([s({attribute:!1})],g.prototype,`eventDispatcher`,void 0),c([s()],g.prototype,`channelType`,void 0),c([a()],g.prototype,`_loadState`,void 0),c([a()],g.prototype,`_error`,void 0),c([a()],g.prototype,`_config`,void 0),c([a()],g.prototype,`_enabled`,void 0),c([a()],g.prototype,`_status`,void 0),c([a()],g.prototype,`_deliveryTrace`,void 0),c([a()],g.prototype,`_activityData`,void 0),c([a()],g.prototype,`_channelLastActiveAt`,void 0),c([a()],g.prototype,`_channelMessagesSent`,void 0),c([a()],g.prototype,`_channelMessagesReceived`,void 0),c([a()],g.prototype,`_connectionMode`,void 0),c([a()],g.prototype,`_lastError`,void 0),c([a()],g.prototype,`_actionPending`,void 0),c([a()],g.prototype,`_queueStatus`,void 0),c([a()],g.prototype,`_capabilities`,void 0),c([a()],g.prototype,`_mediaProcessing`,void 0),g=c([e(`ic-channel-detail`)],g);export{g as IcChannelDetail};