comisai 1.0.15 → 1.0.17

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 (124) hide show
  1. package/node_modules/@comis/agent/dist/bootstrap/types.d.ts +1 -1
  2. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +12 -11
  3. package/node_modules/@comis/agent/dist/context-engine/constants.d.ts +11 -0
  4. package/node_modules/@comis/agent/dist/context-engine/constants.js +11 -0
  5. package/node_modules/@comis/agent/dist/context-engine/index.d.ts +1 -1
  6. package/node_modules/@comis/agent/dist/context-engine/index.js +1 -1
  7. package/node_modules/@comis/agent/dist/context-engine/llm-compaction.js +32 -18
  8. package/node_modules/@comis/agent/dist/executor/cache-break-diff-writer.d.ts +2 -0
  9. package/node_modules/@comis/agent/dist/executor/cache-break-diff-writer.js +36 -0
  10. package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +12 -0
  11. package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +117 -27
  12. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.d.ts +1 -0
  13. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +16 -4
  14. package/node_modules/@comis/agent/dist/executor/executor-stream-setup.js +17 -1
  15. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +27 -1
  16. package/node_modules/@comis/agent/dist/executor/session-snapshot-cleanup.js +3 -1
  17. package/node_modules/@comis/agent/dist/executor/stream-wrappers/index.d.ts +2 -0
  18. package/node_modules/@comis/agent/dist/executor/stream-wrappers/index.js +2 -0
  19. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.d.ts +9 -0
  20. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +65 -3
  21. package/node_modules/@comis/agent/dist/executor/stream-wrappers/stub-filter-injector.d.ts +28 -0
  22. package/node_modules/@comis/agent/dist/executor/stream-wrappers/stub-filter-injector.js +63 -0
  23. package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +18 -1
  24. package/node_modules/@comis/agent/dist/executor/tool-deferral.js +275 -133
  25. package/node_modules/@comis/agent/dist/executor/ttl-guard.d.ts +6 -0
  26. package/node_modules/@comis/agent/dist/executor/ttl-guard.js +8 -0
  27. package/node_modules/@comis/agent/package.json +1 -1
  28. package/node_modules/@comis/channels/dist/shared/typing-controller.d.ts +7 -0
  29. package/node_modules/@comis/channels/dist/shared/typing-controller.js +33 -0
  30. package/node_modules/@comis/channels/package.json +1 -1
  31. package/node_modules/@comis/cli/dist/commands/daemon.js +116 -28
  32. package/node_modules/@comis/cli/dist/wizard/non-interactive.js +1 -0
  33. package/node_modules/@comis/cli/dist/wizard/steps/01-detect-existing.js +4 -0
  34. package/node_modules/@comis/cli/dist/wizard/steps/07-gateway.js +9 -0
  35. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +2 -0
  36. package/node_modules/@comis/cli/dist/wizard/steps/12-finish.js +5 -2
  37. package/node_modules/@comis/cli/dist/wizard/types.d.ts +1 -0
  38. package/node_modules/@comis/cli/package.json +1 -1
  39. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +10 -0
  40. package/node_modules/@comis/core/dist/config/schema-agent.js +8 -0
  41. package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +17 -2
  42. package/node_modules/@comis/core/dist/config/schema-gateway.js +11 -0
  43. package/node_modules/@comis/core/dist/config/schema-skills.d.ts +16 -2
  44. package/node_modules/@comis/core/dist/config/schema-skills.js +9 -2
  45. package/node_modules/@comis/core/dist/config/schema.d.ts +66 -60
  46. package/node_modules/@comis/core/package.json +1 -1
  47. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +34 -6
  48. package/node_modules/@comis/daemon/package.json +1 -1
  49. package/node_modules/@comis/gateway/package.json +1 -1
  50. package/node_modules/@comis/infra/package.json +1 -1
  51. package/node_modules/@comis/memory/package.json +1 -1
  52. package/node_modules/@comis/scheduler/package.json +1 -1
  53. package/node_modules/@comis/shared/package.json +1 -1
  54. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
  55. package/node_modules/@comis/skills/package.json +1 -1
  56. package/node_modules/@comis/web/dist/android-chrome-192x192.png +0 -0
  57. package/node_modules/@comis/web/dist/android-chrome-512x512.png +0 -0
  58. package/node_modules/@comis/web/dist/apple-touch-icon.png +0 -0
  59. package/node_modules/@comis/web/dist/assets/agent-detail-BG9MGWWj.js +615 -0
  60. package/node_modules/@comis/web/dist/assets/agent-editor-C26Q_xCs.js +2173 -0
  61. package/node_modules/@comis/web/dist/assets/agent-list-LHCJ4rw2.js +504 -0
  62. package/node_modules/@comis/web/dist/assets/approvals-q9VH_IKr.js +54 -0
  63. package/node_modules/@comis/web/dist/assets/billing-view-CtYvBqTE.js +375 -0
  64. package/node_modules/@comis/web/dist/assets/channel-detail-CaInesJM.js +681 -0
  65. package/node_modules/@comis/web/dist/assets/channel-list-B8dj3O9a.js +323 -0
  66. package/node_modules/@comis/web/dist/assets/chat-console-CNmzl0JW.js +943 -0
  67. package/node_modules/@comis/web/dist/assets/config-editor-DX4ITw6y.js +1374 -0
  68. package/node_modules/@comis/web/dist/assets/context-dag-browser-BwiaF5tf.js +393 -0
  69. package/node_modules/@comis/web/dist/assets/context-engine-BZ5Am6hA.js +393 -0
  70. package/node_modules/@comis/web/dist/assets/delivery-view-OfBZof-m.js +392 -0
  71. package/node_modules/@comis/web/dist/assets/diagnostics-view-YFwCxgr2.js +231 -0
  72. package/node_modules/@comis/web/dist/assets/directive-DoeGSK_T.js +1 -0
  73. package/node_modules/@comis/web/dist/assets/extract-variables-BM5qyK-s.js +149 -0
  74. package/node_modules/@comis/web/dist/assets/ic-array-editor-B7m6x7-S.js +118 -0
  75. package/node_modules/@comis/web/dist/assets/ic-breadcrumb-CUMpp3BL.js +75 -0
  76. package/node_modules/@comis/web/dist/assets/ic-budget-segment-bar-BtJ6x5mN.js +64 -0
  77. package/node_modules/@comis/web/dist/assets/ic-chat-message-CFyDJd0z.js +352 -0
  78. package/node_modules/@comis/web/dist/assets/ic-confirm-dialog-CCDbB04e.js +110 -0
  79. package/node_modules/@comis/web/dist/assets/ic-connection-dot-CnT1b8xr.js +54 -0
  80. package/node_modules/@comis/web/dist/assets/ic-data-table-CKUNTxHw.js +277 -0
  81. package/node_modules/@comis/web/dist/assets/ic-delivery-row-GP5Fkygs.js +67 -0
  82. package/node_modules/@comis/web/dist/assets/ic-detail-panel-BF83r-if.js +116 -0
  83. package/node_modules/@comis/web/dist/assets/ic-empty-state-60l2ePhd.js +52 -0
  84. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-C8FuSMe1.js +359 -0
  85. package/node_modules/@comis/web/dist/assets/ic-icon-xeGTVhVG.js +33 -0
  86. package/node_modules/@comis/web/dist/assets/ic-layer-waterfall-COvEYMg5.js +69 -0
  87. package/node_modules/@comis/web/dist/assets/ic-relative-time-3FqpjeAI.js +12 -0
  88. package/node_modules/@comis/web/dist/assets/ic-search-input-CSOxY9g7.js +92 -0
  89. package/node_modules/@comis/web/dist/assets/ic-select-Ce-Raudx.js +127 -0
  90. package/node_modules/@comis/web/dist/assets/ic-tabs-B7QtM_v8.js +95 -0
  91. package/node_modules/@comis/web/dist/assets/ic-tag-CPPUnDLF.js +33 -0
  92. package/node_modules/@comis/web/dist/assets/ic-time-range-picker-CypCT68y.js +93 -0
  93. package/node_modules/@comis/web/dist/assets/ic-tool-call-7MaXSsCW.js +146 -0
  94. package/node_modules/@comis/web/dist/assets/index-CEcM1R_C.js +2830 -0
  95. package/node_modules/@comis/web/dist/assets/index-CIJFuItj.css +1 -0
  96. package/node_modules/@comis/web/dist/assets/mcp-management-BNZPnpDn.js +582 -0
  97. package/node_modules/@comis/web/dist/assets/media-config-BBvTYxOX.js +314 -0
  98. package/node_modules/@comis/web/dist/assets/media-test-BkK3RCRK.js +496 -0
  99. package/node_modules/@comis/web/dist/assets/memory-inspector-1hDGCGat.js +1139 -0
  100. package/node_modules/@comis/web/dist/assets/message-center-CXefwsUu.js +785 -0
  101. package/node_modules/@comis/web/dist/assets/models-C1qcU_j3.js +894 -0
  102. package/node_modules/@comis/web/dist/assets/observability-types-D7jUtSde.js +1 -0
  103. package/node_modules/@comis/web/dist/assets/observe-view-C0VBhX4C.js +814 -0
  104. package/node_modules/@comis/web/dist/assets/pipeline-builder-DcUUIrm0.js +1496 -0
  105. package/node_modules/@comis/web/dist/assets/pipeline-history-DkfOQ6SW.js +317 -0
  106. package/node_modules/@comis/web/dist/assets/pipeline-history-detail-hyHgD0ai.js +287 -0
  107. package/node_modules/@comis/web/dist/assets/pipeline-list-BPW8hV-q.js +518 -0
  108. package/node_modules/@comis/web/dist/assets/pipeline-monitor-Bip16T7e.js +972 -0
  109. package/node_modules/@comis/web/dist/assets/scheduler-BGgwKd06.js +1182 -0
  110. package/node_modules/@comis/web/dist/assets/security-D15st4xx.js +1224 -0
  111. package/node_modules/@comis/web/dist/assets/session-detail-SGEYNJ0M.js +632 -0
  112. package/node_modules/@comis/web/dist/assets/session-key-parser-DPORMVyU.js +1 -0
  113. package/node_modules/@comis/web/dist/assets/session-list-6ybUTxbY.js +231 -0
  114. package/node_modules/@comis/web/dist/assets/setup-wizard-nT0tz9QP.js +853 -0
  115. package/node_modules/@comis/web/dist/assets/skills-D8yVfSUy.js +1051 -0
  116. package/node_modules/@comis/web/dist/assets/subagents-HHXMeHYo.js +193 -0
  117. package/node_modules/@comis/web/dist/assets/workspace-manager-BQlr10iH.js +785 -0
  118. package/node_modules/@comis/web/dist/comis-logo.png +0 -0
  119. package/node_modules/@comis/web/dist/favicon-16x16.png +0 -0
  120. package/node_modules/@comis/web/dist/favicon-32x32.png +0 -0
  121. package/node_modules/@comis/web/dist/favicon.ico +0 -0
  122. package/node_modules/@comis/web/dist/index.html +17 -0
  123. package/node_modules/@comis/web/package.json +29 -0
  124. package/package.json +15 -13
@@ -0,0 +1,1224 @@
1
+ import{s as _,f as S,i as w,n as d,r as l,a as x,A as p,b as s,t as $,I as n,S as B}from"./index-CEcM1R_C.js";import"./ic-tabs-B7QtM_v8.js";import"./ic-empty-state-60l2ePhd.js";import"./ic-tag-CPPUnDLF.js";import"./ic-relative-time-3FqpjeAI.js";import"./ic-connection-dot-CnT1b8xr.js";import"./ic-select-Ce-Raudx.js";import"./ic-array-editor-B7m6x7-S.js";import"./ic-icon-xeGTVhVG.js";var j=Object.defineProperty,F=Object.getOwnPropertyDescriptor,T=(e,t,i,a)=>{for(var r=a>1?void 0:a?F(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&j(t,i,r),r};let g=class extends x{constructor(){super(...arguments),this.label="",this.value="",this.placeholder="env:SECRET_NAME or file:/path",this.disabled=!1,this._visible=!1}_onInput(e){const t=e.target.value;this.dispatchEvent(new CustomEvent("change",{detail:t,bubbles:!0,composed:!0}))}_toggleVisibility(){this._visible=!this._visible}render(){return s`
2
+ <div class="field-wrapper">
3
+ ${this.label?s`<label>${this.label}</label>`:p}
4
+ <div class="input-row">
5
+ <input
6
+ type=${this._visible?"text":"password"}
7
+ .value=${this.value}
8
+ placeholder=${this.placeholder}
9
+ ?disabled=${this.disabled}
10
+ @input=${this._onInput}
11
+ />
12
+ <button
13
+ class="toggle-btn"
14
+ type="button"
15
+ aria-label=${this._visible?"Hide value":"Show value"}
16
+ @click=${this._toggleVisibility}
17
+ >${this._visible?"🙈":"👁"}</button>
18
+ </div>
19
+ <span class="hint">Format: env:VAR_NAME or file:/path/to/secret</span>
20
+ </div>
21
+ `}};g.styles=[_,S,w`
22
+ :host {
23
+ display: block;
24
+ }
25
+
26
+ .field-wrapper {
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: var(--ic-space-xs);
30
+ }
31
+
32
+ label {
33
+ font-size: var(--ic-text-sm);
34
+ font-weight: 500;
35
+ color: var(--ic-text-muted);
36
+ }
37
+
38
+ .input-row {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: var(--ic-space-xs);
42
+ }
43
+
44
+ input {
45
+ flex: 1;
46
+ padding: 0.5rem 0.75rem;
47
+ background: var(--ic-surface-2);
48
+ border: 1px solid var(--ic-border);
49
+ border-radius: var(--ic-radius-md);
50
+ color: var(--ic-text);
51
+ font-family: inherit;
52
+ font-size: var(--ic-text-sm);
53
+ transition: border-color var(--ic-transition);
54
+ }
55
+
56
+ input:focus {
57
+ outline: none;
58
+ border-color: var(--ic-accent);
59
+ }
60
+
61
+ input::placeholder {
62
+ color: var(--ic-text-dim);
63
+ }
64
+
65
+ input:disabled {
66
+ opacity: 0.5;
67
+ cursor: not-allowed;
68
+ }
69
+
70
+ .toggle-btn {
71
+ background: var(--ic-surface-2);
72
+ border: 1px solid var(--ic-border);
73
+ border-radius: var(--ic-radius-md);
74
+ color: var(--ic-text-dim);
75
+ cursor: pointer;
76
+ padding: 0.5rem;
77
+ font-size: var(--ic-text-sm);
78
+ line-height: 1;
79
+ flex-shrink: 0;
80
+ }
81
+
82
+ .toggle-btn:hover {
83
+ color: var(--ic-text);
84
+ }
85
+
86
+ .hint {
87
+ font-size: var(--ic-text-xs);
88
+ color: var(--ic-text-dim);
89
+ font-style: italic;
90
+ }
91
+ `];T([d()],g.prototype,"label",2);T([d()],g.prototype,"value",2);T([d()],g.prototype,"placeholder",2);T([d({type:Boolean})],g.prototype,"disabled",2);T([l()],g.prototype,"_visible",2);g=T([$("ic-secret-input")],g);var L=Object.defineProperty,G=Object.getOwnPropertyDescriptor,R=(e,t,i,a)=>{for(var r=a>1?void 0:a?G(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&L(t,i,r),r};let y=class extends x{constructor(){super(...arguments),this._tokens=[],this._newTokenScopes=[],this._newSecretDisplay=null}connectedCallback(){super.connectedCallback()}updated(e){e.has("rpc")&&this.rpc&&this._loadTokens()}async _loadTokens(){if(this.rpc)try{const e=await this.rpc.call("tokens.list");this._tokens=e.tokens??[]}catch{}}async _revokeToken(e){if(this.rpc)try{await this.rpc.call("tokens.revoke",{id:e}),this._tokens=this._tokens.filter(t=>t.id!==e),n.show(`Token "${e}" revoked`,"success"),this.dispatchEvent(new CustomEvent("tokens-changed",{bubbles:!0,composed:!0}))}catch(t){const i=t instanceof Error?t.message:"Failed to revoke token";n.show(i,"error")}}async _rotateToken(e){if(this.rpc)try{const t=await this.rpc.call("tokens.rotate",{id:e});this._newSecretDisplay=t.secret,n.show(`Token "${e}" rotated -- new secret shown below`,"success"),this.dispatchEvent(new CustomEvent("tokens-changed",{bubbles:!0,composed:!0}))}catch(t){const i=t instanceof Error?t.message:"Failed to rotate token";n.show(i,"error")}}_onScopeToggle(e,t){t?this._newTokenScopes=[...this._newTokenScopes,e]:this._newTokenScopes=this._newTokenScopes.filter(i=>i!==e)}async _generateToken(){if(this.rpc)try{const e=await this.rpc.call("tokens.create",{scopes:[...this._newTokenScopes]});this._tokens=[...this._tokens,{id:e.id,scopes:e.scopes}],this._newSecretDisplay=e.secret,this._newTokenScopes=[],n.show("Token created -- secret shown below","success"),this.dispatchEvent(new CustomEvent("tokens-changed",{bubbles:!0,composed:!0}))}catch(e){const t=e instanceof Error?e.message:"Failed to create token";n.show(t,"error")}}_renderTokenRow(e){return s`
92
+ <div class="data-cell" role="cell">${e.id}</div>
93
+ <div class="data-cell scopes-cell" role="cell">
94
+ ${e.scopes.map(t=>s`<ic-tag variant="info">${t}</ic-tag>`)}
95
+ </div>
96
+ <div class="data-cell" role="cell">
97
+ <div class="token-actions">
98
+ <button class="rotate-btn" @click=${()=>this._rotateToken(e.id)}>Rotate</button>
99
+ <button class="revoke-btn" @click=${()=>this._revokeToken(e.id)}>Revoke</button>
100
+ </div>
101
+ </div>
102
+ `}render(){return s`
103
+ <div class="grid-table grid-table--tokens" role="table" aria-label="API tokens">
104
+ <div class="header-cell" role="columnheader">Token ID</div>
105
+ <div class="header-cell" role="columnheader">Scopes</div>
106
+ <div class="header-cell" role="columnheader">Actions</div>
107
+ ${this._tokens.map(e=>this._renderTokenRow(e))}
108
+ </div>
109
+
110
+ ${this._newSecretDisplay?s`
111
+ <div class="new-secret-banner">
112
+ <div class="secret-label">New Token Secret</div>
113
+ <div class="secret-value">${this._newSecretDisplay}</div>
114
+ <div class="secret-warning">Copy this secret now. It will not be shown again.</div>
115
+ </div>
116
+ `:p}
117
+
118
+ <div class="create-form">
119
+ <div class="create-form-title">Create Token</div>
120
+ <div class="form-field">
121
+ <label class="form-label">Scopes</label>
122
+ <div class="checkbox-row">
123
+ <input type="checkbox" id="scope-rpc"
124
+ .checked=${this._newTokenScopes.includes("rpc")}
125
+ @change=${e=>this._onScopeToggle("rpc",e.target.checked)}
126
+ /><label for="scope-rpc">rpc</label>
127
+ </div>
128
+ <div class="checkbox-row">
129
+ <input type="checkbox" id="scope-ws"
130
+ .checked=${this._newTokenScopes.includes("ws")}
131
+ @change=${e=>this._onScopeToggle("ws",e.target.checked)}
132
+ /><label for="scope-ws">ws</label>
133
+ </div>
134
+ <div class="checkbox-row">
135
+ <input type="checkbox" id="scope-admin"
136
+ .checked=${this._newTokenScopes.includes("admin")}
137
+ @change=${e=>this._onScopeToggle("admin",e.target.checked)}
138
+ /><label for="scope-admin">admin</label>
139
+ </div>
140
+ <div class="checkbox-row">
141
+ <input type="checkbox" id="scope-api"
142
+ .checked=${this._newTokenScopes.includes("api")}
143
+ @change=${e=>this._onScopeToggle("api",e.target.checked)}
144
+ /><label for="scope-api">api</label>
145
+ </div>
146
+ <div class="checkbox-row">
147
+ <input type="checkbox" id="scope-all"
148
+ .checked=${this._newTokenScopes.includes("*")}
149
+ @change=${e=>this._onScopeToggle("*",e.target.checked)}
150
+ /><label for="scope-all">* (all)</label>
151
+ </div>
152
+ </div>
153
+ <button class="generate-btn" @click=${()=>this._generateToken()}>Generate</button>
154
+ </div>
155
+ `}};y.styles=[_,S,w`
156
+ :host {
157
+ display: block;
158
+ }
159
+
160
+ .grid-table {
161
+ display: grid;
162
+ width: 100%;
163
+ }
164
+
165
+ .grid-table--tokens {
166
+ grid-template-columns: 1fr 1fr 10rem;
167
+ }
168
+
169
+ .grid-table .header-cell {
170
+ padding: var(--ic-space-xs) var(--ic-space-sm);
171
+ font-size: var(--ic-text-xs);
172
+ font-weight: 600;
173
+ color: var(--ic-text-muted);
174
+ text-transform: uppercase;
175
+ letter-spacing: 0.05em;
176
+ border-bottom: 2px solid var(--ic-border);
177
+ background: var(--ic-surface);
178
+ }
179
+
180
+ .grid-table .data-cell {
181
+ padding: var(--ic-space-xs) var(--ic-space-sm);
182
+ font-size: var(--ic-text-sm);
183
+ color: var(--ic-text);
184
+ display: flex;
185
+ align-items: center;
186
+ border-bottom: 1px solid var(--ic-border);
187
+ min-height: 2.25rem;
188
+ }
189
+
190
+ .scopes-cell {
191
+ display: flex;
192
+ gap: var(--ic-space-xs);
193
+ flex-wrap: wrap;
194
+ }
195
+
196
+ .create-form {
197
+ background: var(--ic-surface);
198
+ border: 1px solid var(--ic-border);
199
+ border-radius: var(--ic-radius-md);
200
+ padding: var(--ic-space-md);
201
+ margin-top: var(--ic-space-lg);
202
+ max-width: 32rem;
203
+ }
204
+
205
+ .create-form-title {
206
+ font-size: var(--ic-text-sm);
207
+ font-weight: 600;
208
+ color: var(--ic-text-muted);
209
+ margin-bottom: var(--ic-space-sm);
210
+ }
211
+
212
+ .form-field {
213
+ display: flex;
214
+ flex-direction: column;
215
+ gap: var(--ic-space-xs);
216
+ margin-bottom: var(--ic-space-sm);
217
+ }
218
+
219
+ .form-label {
220
+ font-size: var(--ic-text-sm);
221
+ font-weight: 500;
222
+ color: var(--ic-text-muted);
223
+ }
224
+
225
+ .checkbox-row {
226
+ display: flex;
227
+ align-items: center;
228
+ gap: var(--ic-space-sm);
229
+ margin-bottom: var(--ic-space-xs);
230
+ }
231
+
232
+ .checkbox-row input[type="checkbox"] {
233
+ accent-color: var(--ic-accent);
234
+ }
235
+
236
+ .checkbox-row label {
237
+ font-size: var(--ic-text-sm);
238
+ color: var(--ic-text);
239
+ cursor: pointer;
240
+ }
241
+
242
+ .generate-btn {
243
+ padding: 0.5rem 1rem;
244
+ background: var(--ic-accent);
245
+ color: white;
246
+ border: none;
247
+ border-radius: var(--ic-radius-md);
248
+ font-size: var(--ic-text-sm);
249
+ cursor: pointer;
250
+ font-family: inherit;
251
+ }
252
+
253
+ .generate-btn:hover {
254
+ opacity: 0.9;
255
+ }
256
+
257
+ .revoke-btn {
258
+ padding: 0.25rem 0.5rem;
259
+ background: none;
260
+ border: 1px solid var(--ic-error);
261
+ border-radius: var(--ic-radius-md);
262
+ color: var(--ic-error);
263
+ font-size: var(--ic-text-xs);
264
+ cursor: pointer;
265
+ font-family: inherit;
266
+ }
267
+
268
+ .revoke-btn:hover {
269
+ background: color-mix(in srgb, var(--ic-error) 10%, transparent);
270
+ }
271
+
272
+ .rotate-btn {
273
+ padding: 0.25rem 0.5rem;
274
+ background: none;
275
+ border: 1px solid var(--ic-accent);
276
+ border-radius: var(--ic-radius-md);
277
+ color: var(--ic-accent);
278
+ font-size: var(--ic-text-xs);
279
+ cursor: pointer;
280
+ font-family: inherit;
281
+ }
282
+
283
+ .rotate-btn:hover {
284
+ background: color-mix(in srgb, var(--ic-accent) 10%, transparent);
285
+ }
286
+
287
+ .token-actions {
288
+ display: flex;
289
+ gap: var(--ic-space-xs);
290
+ }
291
+
292
+ .new-secret-banner {
293
+ background: color-mix(in srgb, var(--ic-success) 10%, transparent);
294
+ border: 1px solid var(--ic-success);
295
+ border-radius: var(--ic-radius-md);
296
+ padding: var(--ic-space-sm) var(--ic-space-md);
297
+ margin-top: var(--ic-space-md);
298
+ max-width: 32rem;
299
+ }
300
+
301
+ .new-secret-banner .secret-label {
302
+ font-size: var(--ic-text-xs);
303
+ font-weight: 600;
304
+ color: var(--ic-success);
305
+ margin-bottom: var(--ic-space-xs);
306
+ }
307
+
308
+ .new-secret-banner .secret-value {
309
+ font-family: ui-monospace, monospace;
310
+ font-size: var(--ic-text-sm);
311
+ color: var(--ic-text);
312
+ word-break: break-all;
313
+ }
314
+
315
+ .new-secret-banner .secret-warning {
316
+ font-size: var(--ic-text-xs);
317
+ color: var(--ic-text-dim);
318
+ margin-top: var(--ic-space-xs);
319
+ }
320
+ `];R([d({attribute:!1})],y.prototype,"rpc",2);R([l()],y.prototype,"_tokens",2);R([l()],y.prototype,"_newTokenScopes",2);R([l()],y.prototype,"_newSecretDisplay",2);y=R([$("ic-token-manager")],y);var V=Object.defineProperty,K=Object.getOwnPropertyDescriptor,I=(e,t,i,a)=>{for(var r=a>1?void 0:a?K(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&V(t,i,r),r};const U={low:"success",medium:"warning",high:"error",critical:"error"},J={low:"var(--ic-success)",medium:"var(--ic-warning)",high:"var(--ic-error)",critical:"var(--ic-error)"};let C=class extends x{constructor(){super(...arguments),this.approval=null,this._reason="",this._expanded=!1}_onApprove(){this.approval&&this.dispatchEvent(new CustomEvent("approve",{detail:{id:this.approval.id,reason:this._reason},bubbles:!0,composed:!0}))}_onDeny(){this.approval&&this.dispatchEvent(new CustomEvent("deny",{detail:{id:this.approval.id,reason:this._reason},bubbles:!0,composed:!0}))}render(){if(!this.approval)return p;const e=this.approval,t=U[e.classification]??"default",i=J[e.classification]??"var(--ic-border)";return s`
321
+ <div
322
+ class="card"
323
+ role="article"
324
+ aria-label="${e.agentId} ${e.action} approval request"
325
+ style="border-left-color: ${i};"
326
+ >
327
+ <div class="card-header">
328
+ <span class="agent-id">${e.agentId}</span>
329
+ <span class="action-name">${e.action}</span>
330
+ <ic-tag variant=${t}>${e.classification}</ic-tag>
331
+ </div>
332
+ <div class="timestamp">
333
+ <ic-relative-time .timestamp=${e.requestedAt}></ic-relative-time>
334
+ </div>
335
+ ${e.user?s`<div class="user-row"><span class="user-label">Requested by:</span> ${e.user}</div>`:p}
336
+ <button
337
+ class="context-toggle"
338
+ @click=${()=>{this._expanded=!this._expanded}}
339
+ >${this._expanded?"Hide details":"Show details"}</button>
340
+ ${this._expanded?s`<div class="context-details">${e.context}</div>`:p}
341
+ <input
342
+ class="reason-input"
343
+ type="text"
344
+ placeholder="Reason (optional)"
345
+ aria-label="Decision reason"
346
+ .value=${this._reason}
347
+ @input=${a=>{this._reason=a.target.value}}
348
+ />
349
+ <div class="action-buttons">
350
+ <button class="approve-btn" @click=${()=>this._onApprove()}>Approve</button>
351
+ <button class="deny-btn" @click=${()=>this._onDeny()}>Deny</button>
352
+ </div>
353
+ </div>
354
+ `}};C.styles=[_,S,w`
355
+ :host {
356
+ display: block;
357
+ width: 100%;
358
+ }
359
+
360
+ .card {
361
+ background: var(--ic-surface);
362
+ border: 1px solid var(--ic-border);
363
+ border-radius: var(--ic-radius-lg);
364
+ padding: var(--ic-space-md);
365
+ border-left: 3px solid var(--ic-border);
366
+ }
367
+
368
+ .card-header {
369
+ display: flex;
370
+ align-items: center;
371
+ gap: var(--ic-space-sm);
372
+ flex-wrap: wrap;
373
+ margin-bottom: var(--ic-space-xs);
374
+ }
375
+
376
+ .agent-id {
377
+ font-weight: 600;
378
+ font-size: var(--ic-text-sm);
379
+ color: var(--ic-text);
380
+ }
381
+
382
+ .action-name {
383
+ font-size: var(--ic-text-sm);
384
+ color: var(--ic-text-muted);
385
+ font-family: ui-monospace, monospace;
386
+ }
387
+
388
+ .timestamp {
389
+ font-size: var(--ic-text-xs);
390
+ color: var(--ic-text-dim);
391
+ margin-bottom: var(--ic-space-sm);
392
+ }
393
+
394
+ .user-row {
395
+ font-size: var(--ic-text-xs);
396
+ color: var(--ic-text-dim);
397
+ margin-bottom: var(--ic-space-sm);
398
+ }
399
+
400
+ .user-label {
401
+ color: var(--ic-text-muted);
402
+ }
403
+
404
+ .context-toggle {
405
+ background: none;
406
+ border: none;
407
+ color: var(--ic-accent);
408
+ font-size: var(--ic-text-xs);
409
+ cursor: pointer;
410
+ padding: 0;
411
+ font-family: inherit;
412
+ margin-bottom: var(--ic-space-sm);
413
+ }
414
+
415
+ .context-toggle:hover {
416
+ text-decoration: underline;
417
+ }
418
+
419
+ .context-details {
420
+ background: var(--ic-surface-2);
421
+ border: 1px solid var(--ic-border);
422
+ border-radius: var(--ic-radius-md);
423
+ padding: var(--ic-space-sm);
424
+ font-size: var(--ic-text-xs);
425
+ color: var(--ic-text-muted);
426
+ white-space: pre-wrap;
427
+ word-break: break-word;
428
+ margin-bottom: var(--ic-space-sm);
429
+ }
430
+
431
+ .reason-input {
432
+ width: 100%;
433
+ padding: 0.5rem 0.75rem;
434
+ background: var(--ic-surface-2);
435
+ border: 1px solid var(--ic-border);
436
+ border-radius: var(--ic-radius-md);
437
+ color: var(--ic-text);
438
+ font-family: inherit;
439
+ font-size: var(--ic-text-sm);
440
+ margin-bottom: var(--ic-space-sm);
441
+ box-sizing: border-box;
442
+ }
443
+
444
+ .reason-input:focus {
445
+ outline: none;
446
+ border-color: var(--ic-accent);
447
+ }
448
+
449
+ .action-buttons {
450
+ display: flex;
451
+ gap: var(--ic-space-sm);
452
+ flex-wrap: wrap;
453
+ }
454
+
455
+ .approve-btn {
456
+ padding: 0.375rem 0.75rem;
457
+ background: color-mix(in srgb, var(--ic-success) 15%, transparent);
458
+ border: 1px solid var(--ic-success);
459
+ border-radius: var(--ic-radius-md);
460
+ color: var(--ic-success);
461
+ font-size: var(--ic-text-sm);
462
+ cursor: pointer;
463
+ font-family: inherit;
464
+ font-weight: 500;
465
+ }
466
+
467
+ .approve-btn:hover {
468
+ background: color-mix(in srgb, var(--ic-success) 25%, transparent);
469
+ }
470
+
471
+ .deny-btn {
472
+ padding: 0.375rem 0.75rem;
473
+ background: color-mix(in srgb, var(--ic-error) 15%, transparent);
474
+ border: 1px solid var(--ic-error);
475
+ border-radius: var(--ic-radius-md);
476
+ color: var(--ic-error);
477
+ font-size: var(--ic-text-sm);
478
+ cursor: pointer;
479
+ font-family: inherit;
480
+ font-weight: 500;
481
+ }
482
+
483
+ .deny-btn:hover {
484
+ background: color-mix(in srgb, var(--ic-error) 25%, transparent);
485
+ }
486
+ `];I([d({type:Object})],C.prototype,"approval",2);I([l()],C.prototype,"_reason",2);I([l()],C.prototype,"_expanded",2);C=I([$("ic-approval-card")],C);var Q=Object.defineProperty,Y=Object.getOwnPropertyDescriptor,k=(e,t,i,a)=>{for(var r=a>1?void 0:a?Y(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&Q(t,i,r),r};function M(e){return{id:e.requestId,agentId:e.agentId,action:e.action||e.toolName,classification:e.trustLevel==="admin"?"low":e.trustLevel==="user"?"medium":"high",context:JSON.stringify(e.params,null,2),requestedAt:e.createdAt}}const q="ic:approval-history",H=10080*60*1e3;function X(){try{const e=localStorage.getItem(q);if(!e)return[];const t=JSON.parse(e),i=Date.now()-H;return t.filter(a=>a.resolvedAt>i)}catch{return[]}}function P(e){try{const t=Date.now()-H,i=e.filter(a=>a.resolvedAt>t);localStorage.setItem(q,JSON.stringify(i))}catch{}}let m=class extends x{constructor(){super(...arguments),this.securityConfig={},this.activeSubTab="pending",this._pendingApprovals=[],this._resolvedApprovals=[],this._approvalRules={defaultMode:"manual",timeoutMs:0}}connectedCallback(){super.connectedCallback(),this._resolvedApprovals=X()}updated(e){e.has("rpc")&&this.rpc&&this._loadApprovals(),e.has("securityConfig")&&(this._approvalRules=this.securityConfig.approvalRules??{defaultMode:"manual",timeoutMs:0})}async _loadApprovals(){if(this.rpc)try{const e=await this.rpc.call("admin.approval.pending");this._pendingApprovals=(e.requests??[]).map(M)}catch{}}onApprovalPending(e){const t=e;t?.requestId&&(this._pendingApprovals=[M(t),...this._pendingApprovals])}onApprovalResolved(e){const t=e,i=t?.requestId;if(!i)return;this._pendingApprovals=this._pendingApprovals.filter(o=>o.id!==i);const r={...M(t),outcome:t.approved?"approved":"denied",reason:t.reason??"",resolvedAt:t.resolvedAt??Date.now(),resolvedBy:t.approvedBy??"system"};this._resolvedApprovals=[r,...this._resolvedApprovals],P(this._resolvedApprovals)}async _handleApprove(e){if(!this.rpc)return;const{id:t,reason:i}=e.detail;try{await this.rpc.call("admin.approval.resolve",{requestId:t,approved:!0,approvedBy:"operator",reason:i});const a=this._pendingApprovals.find(r=>r.id===t);if(this._pendingApprovals=this._pendingApprovals.filter(r=>r.id!==t),a){const r={...a,outcome:"approved",reason:i,resolvedAt:Date.now(),resolvedBy:"operator"};this._resolvedApprovals=[r,...this._resolvedApprovals],P(this._resolvedApprovals)}n.show("Approval granted","success"),this.dispatchEvent(new CustomEvent("approvals-changed",{bubbles:!0,composed:!0}))}catch(a){n.show(a instanceof Error?a.message:"Failed to approve request","error")}}async _handleDeny(e){if(!this.rpc)return;const{id:t,reason:i}=e.detail;try{await this.rpc.call("admin.approval.resolve",{requestId:t,approved:!1,approvedBy:"operator",reason:i});const a=this._pendingApprovals.find(r=>r.id===t);if(this._pendingApprovals=this._pendingApprovals.filter(r=>r.id!==t),a){const r={...a,outcome:"denied",reason:i,resolvedAt:Date.now(),resolvedBy:"operator"};this._resolvedApprovals=[r,...this._resolvedApprovals],P(this._resolvedApprovals)}n.show("Approval denied","success"),this.dispatchEvent(new CustomEvent("approvals-changed",{bubbles:!0,composed:!0}))}catch(a){n.show(a instanceof Error?a.message:"Failed to deny request","error")}}async _handleResolveAll(e){if(!(!this.rpc||this._pendingApprovals.length===0))try{const t=await this.rpc.call("admin.approval.resolveAll",{approved:e,approvedBy:"operator",reason:e?"Bulk approved by operator":"Bulk denied by operator"});for(const i of this._pendingApprovals){const a={...i,outcome:e?"approved":"denied",reason:e?"Bulk approved by operator":"Bulk denied by operator",resolvedAt:Date.now(),resolvedBy:"operator"};this._resolvedApprovals=[a,...this._resolvedApprovals]}this._pendingApprovals=[],P(this._resolvedApprovals),n.show(`${t.resolved} approval(s) ${e?"approved":"denied"}`,"success"),this.dispatchEvent(new CustomEvent("approvals-changed",{bubbles:!0,composed:!0}))}catch(t){n.show(t instanceof Error?t.message:"Bulk operation failed","error")}}async _handleClearDenialCache(){if(this.rpc)try{await this.rpc.call("admin.approval.clearDenialCache",{}),n.show("Denial cache cleared","success")}catch(e){n.show(e instanceof Error?e.message:"Failed to clear denial cache","error")}}async _patchConfig(e,t){if(!this.rpc)return!1;try{const i=e.indexOf("."),a=i>0?e.slice(0,i):e,r=i>0?e.slice(i+1):void 0;return await this.rpc.call("config.patch",{section:a,key:r,value:t}),n.show("Configuration updated","success"),!0}catch(i){return n.show(i instanceof Error?i.message:"Failed to update configuration","error"),!1}}async _onActionConfirmationChange(e,t){const i={...this.securityConfig.actionConfirmation,[e]:t};await this._patchConfig("security.actionConfirmation",i)}async _onAgentToAgentEnabledChange(e){const t={...this.securityConfig.agentToAgent,enabled:e};await this._patchConfig("security.agentToAgent",t)}async _onAgentToAgentAllowChange(e){const t={...this.securityConfig.agentToAgent,allowAgents:e};await this._patchConfig("security.agentToAgent",t)}async _onPermissionToggleChange(e){const t={...this.securityConfig.permission,enableNodePermissions:e};await this._patchConfig("security.permission",t)}async _onPermissionPathsChange(e,t){const i={...this.securityConfig.permission,[e]:t};await this._patchConfig("security.permission",i)}async _saveApprovalRules(){if(this.rpc)try{await this.rpc.call("config.patch",{section:"security",key:"approvalRules",value:this._approvalRules}),n.show("Approval rules updated","success")}catch(e){n.show(e instanceof Error?e.message:"Failed to update approval rules","error")}}_renderHistoryRow(e){const t=e.outcome==="approved"?"success":"error",i={low:"success",medium:"warning",high:"error",critical:"error"}[e.classification]??"default";return s`
487
+ <div class="data-cell" role="cell">${e.agentId}</div>
488
+ <div class="data-cell" role="cell">${e.action}</div>
489
+ <div class="data-cell" role="cell"><ic-tag variant=${i}>${e.classification}</ic-tag></div>
490
+ <div class="data-cell" role="cell"><ic-tag variant=${t}>${e.outcome}</ic-tag></div>
491
+ <div class="data-cell data-cell--muted" role="cell">${e.reason||"---"}</div>
492
+ <div class="data-cell data-cell--muted" role="cell"><ic-relative-time .timestamp=${e.resolvedAt}></ic-relative-time></div>
493
+ <div class="data-cell data-cell--muted" role="cell">${e.resolvedBy}</div>
494
+ `}_renderRulesContent(){const e=this.securityConfig.actionConfirmation??{},t=this.securityConfig.agentToAgent??{},i=this.securityConfig.permission??{},a=[{value:"manual",label:"Manual (all require approval)"},{value:"auto-low",label:"Auto-approve low risk"},{value:"auto-medium",label:"Auto-approve low + medium risk"},{value:"auto-all",label:"Auto-approve all (no approvals)"}];return s`
495
+ <div class="policy-section">
496
+ <div class="section-header">Action Confirmation</div>
497
+ <ic-toggle label="Require for destructive actions"
498
+ .checked=${e.requireForDestructive??!0}
499
+ @change=${r=>this._onActionConfirmationChange("requireForDestructive",r.detail)}
500
+ ></ic-toggle>
501
+ <div style="margin-top: var(--ic-space-sm);">
502
+ <ic-toggle label="Require for sensitive actions"
503
+ .checked=${e.requireForSensitive??!1}
504
+ @change=${r=>this._onActionConfirmationChange("requireForSensitive",r.detail)}
505
+ ></ic-toggle>
506
+ </div>
507
+ <div style="margin-top: var(--ic-space-md);">
508
+ <ic-array-editor label="Auto-approve list" .items=${e.autoApprove??[]} placeholder="Action name to auto-approve"
509
+ @change=${r=>this._onActionConfirmationChange("autoApprove",r.detail)}
510
+ ></ic-array-editor>
511
+ </div>
512
+ </div>
513
+
514
+ <div class="policy-section">
515
+ <div class="section-header">Agent-to-Agent Policy</div>
516
+ <ic-toggle label="Enable cross-agent messaging"
517
+ .checked=${t.enabled??!0}
518
+ @change=${r=>this._onAgentToAgentEnabledChange(r.detail)}
519
+ ></ic-toggle>
520
+ <div style="margin-top: var(--ic-space-md);">
521
+ <ic-array-editor label="Allowed agents" .items=${t.allowAgents??[]} placeholder="Agent ID"
522
+ @change=${r=>this._onAgentToAgentAllowChange(r.detail)}
523
+ ></ic-array-editor>
524
+ </div>
525
+ </div>
526
+
527
+ <div class="policy-section">
528
+ <div class="section-header">Permissions</div>
529
+ <ic-toggle label="Enable Node.js permission model"
530
+ .checked=${i.enableNodePermissions??!1}
531
+ @change=${r=>this._onPermissionToggleChange(r.detail)}
532
+ ></ic-toggle>
533
+ <div style="margin-top: var(--ic-space-md);">
534
+ <ic-array-editor label="Allowed filesystem paths" .items=${i.allowedFsPaths??[]} placeholder="/path/to/allow"
535
+ @change=${r=>this._onPermissionPathsChange("allowedFsPaths",r.detail)}
536
+ ></ic-array-editor>
537
+ </div>
538
+ <div style="margin-top: var(--ic-space-md);">
539
+ <ic-array-editor label="Allowed network hosts" .items=${i.allowedNetHosts??[]} placeholder="hostname or IP"
540
+ @change=${r=>this._onPermissionPathsChange("allowedNetHosts",r.detail)}
541
+ ></ic-array-editor>
542
+ </div>
543
+ </div>
544
+
545
+ <div class="policy-section">
546
+ <div class="section-header">Approval Mode</div>
547
+ <div class="rules-form">
548
+ <ic-select label="Default Mode" .value=${this._approvalRules.defaultMode} .options=${a}
549
+ @change=${r=>{this._approvalRules={...this._approvalRules,defaultMode:r.detail}}}
550
+ ></ic-select>
551
+ <div class="form-field">
552
+ <label class="form-label">Timeout (seconds)</label>
553
+ <input class="number-input" type="number" min="0"
554
+ .value=${String(Math.round(this._approvalRules.timeoutMs/1e3))}
555
+ @change=${r=>{const o=parseInt(r.target.value,10);!isNaN(o)&&o>=0&&(this._approvalRules={...this._approvalRules,timeoutMs:o*1e3})}}
556
+ />
557
+ <span class="form-hint">0 = no timeout (request waits indefinitely)</span>
558
+ </div>
559
+ <button class="save-btn" @click=${()=>this._saveApprovalRules()}>Save Rules</button>
560
+ </div>
561
+ </div>
562
+ `}_renderPendingContent(){const e=[...this._pendingApprovals].sort((t,i)=>i.requestedAt-t.requestedAt);return s`
563
+ <div class="queue-header">
564
+ <span>Pending</span>
565
+ <span class="queue-count">${this._pendingApprovals.length}</span>
566
+ </div>
567
+ <div class="bulk-actions">
568
+ <button class="action-btn action-btn--success" ?disabled=${this._pendingApprovals.length===0}
569
+ @click=${()=>this._handleResolveAll(!0)}>Approve All (${this._pendingApprovals.length})</button>
570
+ <button class="action-btn action-btn--danger" ?disabled=${this._pendingApprovals.length===0}
571
+ @click=${()=>this._handleResolveAll(!1)}>Deny All (${this._pendingApprovals.length})</button>
572
+ <button class="action-btn" @click=${()=>this._handleClearDenialCache()}>Clear Denial Cache</button>
573
+ </div>
574
+ ${e.length===0?s`<ic-empty-state icon="security" message="No pending approvals" description="Approval requests will appear here as they arrive."></ic-empty-state>`:s`
575
+ <div class="queue-list">
576
+ ${e.map(t=>s`
577
+ <ic-approval-card .approval=${t}
578
+ @approve=${i=>this._handleApprove(i)}
579
+ @deny=${i=>this._handleDeny(i)}
580
+ ></ic-approval-card>
581
+ `)}
582
+ </div>
583
+ `}
584
+
585
+ <div class="history-divider">Recent History</div>
586
+ ${this._resolvedApprovals.length===0?s`<p style="font-size: var(--ic-text-sm); color: var(--ic-text-dim); font-style: italic;">No resolved approvals in the last 7 days.</p>`:s`
587
+ <div class="history-grid" role="table" aria-label="Resolved approvals">
588
+ <div class="header-cell" role="columnheader">Agent</div>
589
+ <div class="header-cell" role="columnheader">Action</div>
590
+ <div class="header-cell" role="columnheader">Risk</div>
591
+ <div class="header-cell" role="columnheader">Outcome</div>
592
+ <div class="header-cell" role="columnheader">Reason</div>
593
+ <div class="header-cell" role="columnheader">Resolved At</div>
594
+ <div class="header-cell" role="columnheader">Resolved By</div>
595
+ ${this._resolvedApprovals.map(t=>this._renderHistoryRow(t))}
596
+ </div>
597
+ `}
598
+ `}render(){return this.activeSubTab==="rules"?this._renderRulesContent():this._renderPendingContent()}};m.styles=[_,S,w`
599
+ :host {
600
+ display: block;
601
+ }
602
+
603
+ .section-header {
604
+ font-size: var(--ic-text-base);
605
+ font-weight: 600;
606
+ color: var(--ic-text);
607
+ margin-top: var(--ic-space-lg);
608
+ margin-bottom: var(--ic-space-sm);
609
+ }
610
+
611
+ .section-header:first-child {
612
+ margin-top: 0;
613
+ }
614
+
615
+ .policy-section {
616
+ margin-bottom: var(--ic-space-xl);
617
+ max-width: 40rem;
618
+ }
619
+
620
+ .queue-header {
621
+ display: flex;
622
+ align-items: center;
623
+ gap: var(--ic-space-sm);
624
+ margin-bottom: var(--ic-space-md);
625
+ }
626
+
627
+ .queue-count {
628
+ background: var(--ic-accent);
629
+ color: white;
630
+ font-size: var(--ic-text-xs);
631
+ font-weight: 600;
632
+ padding: 0.125rem 0.5rem;
633
+ border-radius: var(--ic-radius-md);
634
+ min-width: 1.25rem;
635
+ text-align: center;
636
+ }
637
+
638
+ .queue-list {
639
+ display: flex;
640
+ flex-direction: column;
641
+ gap: var(--ic-space-md);
642
+ }
643
+
644
+ .history-divider {
645
+ display: flex;
646
+ align-items: center;
647
+ gap: var(--ic-space-sm);
648
+ margin: var(--ic-space-xl) 0 var(--ic-space-md);
649
+ color: var(--ic-text-muted);
650
+ font-size: var(--ic-text-sm);
651
+ font-weight: 600;
652
+ }
653
+
654
+ .history-divider::after {
655
+ content: "";
656
+ flex: 1;
657
+ height: 1px;
658
+ background: var(--ic-border);
659
+ }
660
+
661
+ .history-grid {
662
+ display: grid;
663
+ grid-template-columns: 7rem 8rem 6rem 5rem 1fr 8rem 6rem;
664
+ width: 100%;
665
+ }
666
+
667
+ .history-grid .header-cell {
668
+ padding: var(--ic-space-xs) var(--ic-space-sm);
669
+ font-size: var(--ic-text-xs);
670
+ font-weight: 600;
671
+ color: var(--ic-text-muted);
672
+ text-transform: uppercase;
673
+ letter-spacing: 0.05em;
674
+ border-bottom: 2px solid var(--ic-border);
675
+ background: var(--ic-surface);
676
+ }
677
+
678
+ .history-grid .data-cell {
679
+ padding: var(--ic-space-xs) var(--ic-space-sm);
680
+ font-size: var(--ic-text-sm);
681
+ color: var(--ic-text);
682
+ display: flex;
683
+ align-items: center;
684
+ border-bottom: 1px solid var(--ic-border);
685
+ min-height: 2.25rem;
686
+ }
687
+
688
+ .history-grid .data-cell--muted {
689
+ color: var(--ic-text-muted);
690
+ }
691
+
692
+ .rules-form {
693
+ max-width: 32rem;
694
+ display: flex;
695
+ flex-direction: column;
696
+ gap: var(--ic-space-md);
697
+ }
698
+
699
+ .save-btn,
700
+ .action-btn {
701
+ padding: 0.5rem 1rem;
702
+ background: var(--ic-accent);
703
+ color: white;
704
+ border: none;
705
+ border-radius: var(--ic-radius-md);
706
+ font-size: var(--ic-text-sm);
707
+ cursor: pointer;
708
+ font-family: inherit;
709
+ align-self: flex-start;
710
+ }
711
+
712
+ .save-btn:hover,
713
+ .action-btn:hover {
714
+ opacity: 0.9;
715
+ }
716
+
717
+ .form-field {
718
+ display: flex;
719
+ flex-direction: column;
720
+ gap: var(--ic-space-xs);
721
+ margin-bottom: var(--ic-space-sm);
722
+ }
723
+
724
+ .form-label {
725
+ font-size: var(--ic-text-sm);
726
+ font-weight: 500;
727
+ color: var(--ic-text-muted);
728
+ }
729
+
730
+ .form-hint {
731
+ font-size: var(--ic-text-xs);
732
+ color: var(--ic-text-dim);
733
+ }
734
+
735
+ .number-input {
736
+ width: 8rem;
737
+ padding: 0.5rem 0.75rem;
738
+ background: var(--ic-surface-2);
739
+ border: 1px solid var(--ic-border);
740
+ border-radius: var(--ic-radius-md);
741
+ color: var(--ic-text);
742
+ font-family: inherit;
743
+ font-size: var(--ic-text-sm);
744
+ }
745
+
746
+ .number-input:focus {
747
+ outline: none;
748
+ border-color: var(--ic-accent);
749
+ }
750
+
751
+ .bulk-actions {
752
+ display: flex;
753
+ flex-direction: row;
754
+ gap: var(--ic-space-sm);
755
+ margin-bottom: var(--ic-space-md);
756
+ flex-wrap: wrap;
757
+ }
758
+
759
+ .action-btn--success {
760
+ background: var(--ic-success, #22c55e);
761
+ color: white;
762
+ }
763
+
764
+ .action-btn--danger {
765
+ background: var(--ic-error, #ef4444);
766
+ color: white;
767
+ }
768
+
769
+ .action-btn:disabled,
770
+ .action-btn--success:disabled,
771
+ .action-btn--danger:disabled {
772
+ opacity: 0.5;
773
+ cursor: not-allowed;
774
+ }
775
+ `];k([d({attribute:!1})],m.prototype,"rpc",2);k([d({attribute:!1})],m.prototype,"securityConfig",2);k([d({type:String})],m.prototype,"activeSubTab",2);k([l()],m.prototype,"_pendingApprovals",2);k([l()],m.prototype,"_resolvedApprovals",2);k([l()],m.prototype,"_approvalRules",2);m=k([$("ic-approval-queue")],m);var W=Object.defineProperty,Z=Object.getOwnPropertyDescriptor,N=(e,t,i,a)=>{for(var r=a>1?void 0:a?Z(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&W(t,i,r),r};const ee={low:"success",medium:"warning",high:"error",critical:"error"};let z=class extends x{constructor(){super(...arguments),this.event=null}render(){if(!this.event)return s`
776
+ <div class="cell cell--muted" role="cell">---</div>
777
+ <div class="cell cell--muted" role="cell">---</div>
778
+ <div class="cell cell--muted" role="cell">---</div>
779
+ <div class="cell cell--muted" role="cell">---</div>
780
+ <div class="cell cell--muted" role="cell">---</div>
781
+ `;const e=this.event,t=ee[e.classification]??"default";return s`
782
+ <div class="cell cell--muted" role="cell">
783
+ <ic-relative-time .timestamp=${e.timestamp}></ic-relative-time>
784
+ </div>
785
+ <div class="cell" role="cell">${e.agentId||"---"}</div>
786
+ <div class="cell" role="cell">${e.action||"---"}</div>
787
+ <div class="cell" role="cell">
788
+ <ic-tag variant=${t}>${e.classification||"unknown"}</ic-tag>
789
+ </div>
790
+ <div class="cell cell--muted" role="cell">${e.user||"---"}</div>
791
+ ${e.details?s`<div class="cell cell--details" role="cell" style="grid-column: 1 / -1;">${e.details}</div>`:p}
792
+ `}};z.styles=[_,w`
793
+ :host {
794
+ display: contents;
795
+ }
796
+
797
+ .cell {
798
+ padding: var(--ic-space-xs) var(--ic-space-sm);
799
+ font-size: var(--ic-text-sm);
800
+ color: var(--ic-text);
801
+ display: flex;
802
+ align-items: center;
803
+ border-bottom: 1px solid var(--ic-border);
804
+ min-height: 2.25rem;
805
+ }
806
+
807
+ .cell--muted {
808
+ color: var(--ic-text-muted);
809
+ }
810
+
811
+ .cell--details {
812
+ color: var(--ic-text-dim);
813
+ font-size: var(--ic-text-xs);
814
+ }
815
+ `];N([d({type:Object})],z.prototype,"event",2);z=N([$("ic-audit-row")],z);var te=Object.defineProperty,ie=Object.getOwnPropertyDescriptor,E=(e,t,i,a)=>{for(var r=a>1?void 0:a?ie(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&te(t,i,r),r};let f=class extends x{constructor(){super(...arguments),this.activeSubTab="events",this.securityEvents=[],this.inputGuardSummary={blockedAttempts:0,patternsTriggered:[],period:"session"},this._auditEntries=[],this._paused=!1,this._pauseBuffer=[],this._expandedEvents=new Set}onAuditEvent(e){const t=e;if(t){if(this._paused){this._pauseBuffer=[...this._pauseBuffer.slice(-199),t];return}this._auditEntries=[...this._auditEntries.slice(-199),t]}}get auditEntries(){return this._auditEntries}get paused(){return this._paused}get pauseBuffer(){return this._pauseBuffer}_severityVariant(e){switch(e){case"critical":case"high":return"error";case"medium":return"warning";default:return"info"}}_toggleEventDetails(e){this._expandedEvents.has(e)?this._expandedEvents.delete(e):this._expandedEvents.add(e),this.requestUpdate()}_togglePause(){if(this._paused){const e=[...this._auditEntries,...this._pauseBuffer].slice(-200);this._auditEntries=e,this._pauseBuffer=[]}this._paused=!this._paused}_renderEventsContent(){return s`
816
+ <div class="guard-summary">
817
+ <span style="font-size: var(--ic-text-sm); font-weight: 500; color: var(--ic-text-muted);">Input Guard</span>
818
+ <ic-tag variant="error">${this.inputGuardSummary.blockedAttempts} blocked</ic-tag>
819
+ ${this.inputGuardSummary.patternsTriggered.length>0?s`<ic-tag variant="warning">${this.inputGuardSummary.patternsTriggered.join(", ")}</ic-tag>`:p}
820
+ </div>
821
+ ${this.securityEvents.length===0?s`<ic-empty-state icon="security" message="No security events" description="Security events will appear here in real-time as they are detected."></ic-empty-state>`:s`
822
+ <div role="list" aria-label="Security events">
823
+ ${this.securityEvents.map(e=>s`
824
+ <div class="event-row" role="listitem">
825
+ <ic-tag variant=${this._severityVariant(e.severity)}>${e.severity}</ic-tag>
826
+ <ic-tag variant="default">${e.type}</ic-tag>
827
+ <span class="event-message">${e.message}</span>
828
+ ${e.agentId?s`<ic-tag variant="info">${e.agentId}</ic-tag>`:p}
829
+ <ic-relative-time .timestamp=${e.timestamp}></ic-relative-time>
830
+ <button class="event-details-toggle"
831
+ @click=${()=>this._toggleEventDetails(e.id)}
832
+ >${this._expandedEvents.has(e.id)?"hide":"details"}</button>
833
+ </div>
834
+ ${this._expandedEvents.has(e.id)?s`<pre class="event-details">${JSON.stringify(e.details,null,2)}</pre>`:p}
835
+ `)}
836
+ </div>
837
+ `}
838
+ `}_renderAuditContent(){return s`
839
+ <div class="audit-controls">
840
+ <button class="pause-btn" ?data-active=${this._paused}
841
+ @click=${()=>this._togglePause()}
842
+ >${this._paused?"Resume":"Pause"}</button>
843
+ ${this._paused?s`<span style="font-size: var(--ic-text-xs); color: var(--ic-text-dim);">${this._pauseBuffer.length} buffered</span>`:p}
844
+ </div>
845
+ ${this._auditEntries.length===0?s`<ic-empty-state icon="security" message="No audit events" description="Events will appear here as they occur."></ic-empty-state>`:s`
846
+ <div class="audit-grid" role="table" aria-label="Audit log">
847
+ <div class="header-cell" role="columnheader">Time</div>
848
+ <div class="header-cell" role="columnheader">Agent</div>
849
+ <div class="header-cell" role="columnheader">Action</div>
850
+ <div class="header-cell" role="columnheader">Risk</div>
851
+ <div class="header-cell" role="columnheader">User</div>
852
+ ${this._auditEntries.map(e=>s`<ic-audit-row .event=${e} role="row"></ic-audit-row>`)}
853
+ </div>
854
+ `}
855
+ `}render(){return this.activeSubTab==="audit"?this._renderAuditContent():this._renderEventsContent()}};f.styles=[_,S,w`
856
+ :host {
857
+ display: block;
858
+ }
859
+
860
+ .guard-summary {
861
+ display: flex;
862
+ gap: var(--ic-space-sm);
863
+ padding: var(--ic-space-sm) var(--ic-space-md);
864
+ background: var(--ic-surface-alt, var(--ic-surface-2));
865
+ border-radius: var(--ic-radius-md);
866
+ margin-bottom: var(--ic-space-md);
867
+ align-items: center;
868
+ flex-wrap: wrap;
869
+ }
870
+
871
+ .event-row {
872
+ display: flex;
873
+ gap: var(--ic-space-sm);
874
+ padding: var(--ic-space-sm) var(--ic-space-sm);
875
+ border-bottom: 1px solid var(--ic-border);
876
+ align-items: center;
877
+ }
878
+
879
+ .event-message {
880
+ flex: 1;
881
+ font-size: var(--ic-text-sm);
882
+ }
883
+
884
+ .event-details {
885
+ font-family: ui-monospace, monospace;
886
+ font-size: var(--ic-text-xs);
887
+ background: var(--ic-surface-alt, var(--ic-surface-2));
888
+ padding: var(--ic-space-sm);
889
+ border-radius: var(--ic-radius-md);
890
+ max-height: 200px;
891
+ overflow: auto;
892
+ white-space: pre-wrap;
893
+ margin-top: var(--ic-space-xs);
894
+ }
895
+
896
+ .event-details-toggle {
897
+ cursor: pointer;
898
+ font-size: var(--ic-text-xs);
899
+ color: var(--ic-text-dim);
900
+ background: none;
901
+ border: none;
902
+ font-family: inherit;
903
+ padding: 0;
904
+ }
905
+
906
+ .event-details-toggle:hover {
907
+ color: var(--ic-text-muted);
908
+ }
909
+
910
+ .audit-controls {
911
+ display: flex;
912
+ align-items: center;
913
+ gap: var(--ic-space-sm);
914
+ margin-bottom: var(--ic-space-md);
915
+ }
916
+
917
+ .pause-btn {
918
+ padding: 0.375rem 0.75rem;
919
+ background: var(--ic-surface-2);
920
+ border: 1px solid var(--ic-border);
921
+ border-radius: var(--ic-radius-md);
922
+ color: var(--ic-text-muted);
923
+ font-size: var(--ic-text-sm);
924
+ cursor: pointer;
925
+ font-family: inherit;
926
+ }
927
+
928
+ .pause-btn[data-active] {
929
+ background: var(--ic-warning);
930
+ color: var(--ic-bg);
931
+ border-color: var(--ic-warning);
932
+ }
933
+
934
+ .audit-grid {
935
+ display: grid;
936
+ grid-template-columns: 8rem 7rem 1fr 6rem 6rem;
937
+ overflow-y: auto;
938
+ max-height: 600px;
939
+ }
940
+
941
+ .audit-grid .header-cell {
942
+ padding: var(--ic-space-xs) var(--ic-space-sm);
943
+ font-size: var(--ic-text-xs);
944
+ font-weight: 600;
945
+ color: var(--ic-text-muted);
946
+ text-transform: uppercase;
947
+ letter-spacing: 0.05em;
948
+ border-bottom: 2px solid var(--ic-border);
949
+ background: var(--ic-surface);
950
+ position: sticky;
951
+ top: 0;
952
+ z-index: 1;
953
+ }
954
+ `];E([d({type:String})],f.prototype,"activeSubTab",2);E([d({attribute:!1})],f.prototype,"securityEvents",2);E([d({attribute:!1})],f.prototype,"inputGuardSummary",2);E([l()],f.prototype,"_auditEntries",2);E([l()],f.prototype,"_paused",2);f=E([$("ic-security-event-feed")],f);var re=Object.defineProperty,ae=Object.getOwnPropertyDescriptor,u=(e,t,i,a)=>{for(var r=a>1?void 0:a?ae(t,i):t,o=e.length-1,c;o>=0;o--)(c=e[o])&&(r=(a?c(t,i,r):c(r))||r);return a&&r&&re(t,i,r),r};const b=200,O=100,se=[{id:"events",label:"Security Events"},{id:"audit",label:"Audit Log"},{id:"tokens",label:"API Tokens"},{id:"secrets",label:"Secrets"},{id:"rules",label:"Approval Rules"},{id:"pending",label:"Pending Approvals"},{id:"health",label:"Provider Health"}];let v=class extends x{constructor(){super(...arguments),this.rpcClient=null,this.apiClient=null,this.eventDispatcher=null,this._sse=null,this._loadState="loading",this._error="",this._activeTab="events",this._securityEvents=[],this._inputGuardSummary={blockedAttempts:0,patternsTriggered:[],period:"session"},this._securityConfig={},this._providerHealth=[],this._failoverLog=[],this._authCooldowns=[],this._healthReloadDebounce=null}_scheduleHealthReload(e=300){this._healthReloadDebounce!==null&&clearTimeout(this._healthReloadDebounce),this._healthReloadDebounce=setTimeout(()=>{this._healthReloadDebounce=null,this._loadProviderHealth()},e)}connectedCallback(){super.connectedCallback(),this._initSse()}disconnectedCallback(){super.disconnectedCallback(),this._healthReloadDebounce!==null&&(clearTimeout(this._healthReloadDebounce),this._healthReloadDebounce=null)}updated(e){e.has("rpcClient")&&this.rpcClient&&this._loadData(),e.has("eventDispatcher")&&this.eventDispatcher&&!this._sse&&this._initSse()}get _eventFeed(){return this.shadowRoot?.querySelector("ic-security-event-feed")??null}get _approvalQueue(){return this.shadowRoot?.querySelector("ic-approval-queue")??null}_initSse(){!this.eventDispatcher||this._sse||(this._sse=new B(this,this.eventDispatcher,{"audit:event":e=>{this._eventFeed?.onAuditEvent(e);const t=e;if(t.actionType==="output_guard"){const i=t.metadata??{},a=i.action,r=a==="redacted"?"high":"medium",o=i.findingCount??0,c={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"output_guard",severity:r,message:`Output guard ${a??"scan"}: ${o} finding(s)`,details:{findingTypes:i.findingTypes,severities:i.severities,action:i.action,context:i.context},timestamp:t.timestamp??Date.now(),agentId:t.agentId};this._securityEvents=[c,...this._securityEvents].slice(0,b)}},"approval:requested":e=>{this._approvalQueue?.onApprovalPending(e)},"approval:resolved":e=>{this._approvalQueue?.onApprovalResolved(e)},"security:injection_detected":e=>{const t=e,i=t.riskLevel??"medium",r={high:"high",medium:"medium",low:"low"}[i]??"medium",o=t.source??"unknown",c=t.patterns??[],D={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"injection",severity:r,message:`Injection detected from ${o}`,details:{patterns:c,source:o,sessionKey:t.sessionKey},timestamp:Date.now(),agentId:t.agentId};this._securityEvents=[D,...this._securityEvents].slice(0,b);const A=[...new Set([...this._inputGuardSummary.patternsTriggered,...c])];this._inputGuardSummary={...this._inputGuardSummary,blockedAttempts:this._inputGuardSummary.blockedAttempts+1,patternsTriggered:A}},"security:injection_rate_exceeded":e=>{const t=e,i=t.count??0,a=t.threshold??0,r=t.action??"block",o={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"input_guard",severity:"critical",message:`Rate limit exceeded: ${i}/${a} (action: ${r})`,details:{sessionKey:t.sessionKey,count:i,threshold:a,action:r},timestamp:Date.now()};this._securityEvents=[o,...this._securityEvents].slice(0,b)},"security:memory_tainted":e=>{const t=e,i=t.blocked??!1,a=t.originalTrustLevel??"unknown",r=t.adjustedTrustLevel??"unknown",o={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"memory_tainted",severity:i?"high":"medium",message:`Memory tainted for ${t.agentId??"unknown"}: ${a} -> ${r}`,details:{patterns:t.patterns,blocked:i,originalTrustLevel:a,adjustedTrustLevel:r},timestamp:Date.now(),agentId:t.agentId};this._securityEvents=[o,...this._securityEvents].slice(0,b)},"security:warn":e=>{const t=e,i={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"warn",severity:"medium",message:t.message??"Security warning",details:{category:t.category},timestamp:Date.now(),agentId:t.agentId};this._securityEvents=[i,...this._securityEvents].slice(0,b)},"secret:accessed":e=>{const t=e,i=t.outcome??"unknown",r={denied:"high",not_found:"medium",success:"low"}[i]??"medium",o=t.secretName??"unknown",c={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"secret_access",severity:r,message:`Secret '${o}' ${i} by ${t.agentId??"unknown"}`,details:{secretName:o,outcome:i},timestamp:Date.now(),agentId:t.agentId};this._securityEvents=[c,...this._securityEvents].slice(0,b)},"secret:modified":e=>{const t=e,i=t.secretName??"unknown",a=t.action??"modified",r={id:`sec-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:"secret_access",severity:"medium",message:`Secret '${i}' ${a}`,details:{secretName:i,action:a},timestamp:Date.now()};this._securityEvents=[r,...this._securityEvents].slice(0,b)},"provider:degraded":e=>{const i=e.provider??"";this._providerHealth=this._providerHealth.map(a=>a.providerId===i?{...a,status:"degraded"}:a),this._scheduleHealthReload()},"provider:recovered":e=>{const i=e.provider??"";this._providerHealth=this._providerHealth.map(a=>a.providerId===i?{...a,status:"healthy"}:a),this._scheduleHealthReload()},"model:auth_cooldown":e=>{const t=e,i={keyName:t.keyName,provider:t.provider,cooldownMs:t.cooldownMs,failureCount:t.failureCount,timestamp:t.timestamp};this._authCooldowns=[i,...this._authCooldowns].slice(0,50),this._scheduleHealthReload(500)},"model:fallback_attempt":e=>{const t=e,i={fromProvider:t.fromProvider,fromModel:t.fromModel,toProvider:t.toProvider,toModel:t.toModel,error:t.error,attemptNumber:t.attemptNumber,timestamp:t.timestamp};this._failoverLog=[i,...this._failoverLog].slice(0,O),this._scheduleHealthReload()},"model:fallback_exhausted":e=>{const t=e,i={provider:t.provider,model:t.model,totalAttempts:t.totalAttempts,timestamp:t.timestamp,exhausted:!0};this._failoverLog=[i,...this._failoverLog].slice(0,O),this._scheduleHealthReload()},"observability:token_usage":()=>{this._scheduleHealthReload(500)}}))}async _loadProviderHealth(){if(this.rpcClient)try{const e=await this.rpcClient.call("agent.cacheStats"),t=Date.now(),i=t-300*1e3,a=(e.providers??[]).map(r=>{const o=this._failoverLog.filter(h=>h.fromProvider===r.provider||h.provider===r.provider),c=o.length>0?Math.max(...o.map(h=>h.timestamp)):void 0;let D="healthy";const A=this._authCooldowns.find(h=>h.provider===r.provider&&h.timestamp+h.cooldownMs>t);return A&&(D="degraded"),this._failoverLog.find(h=>h.exhausted===!0&&h.provider===r.provider&&h.timestamp>i)&&(D="down"),{providerId:r.provider,name:r.provider,status:D,cacheHitRate:r.cacheHitRate,failoverCount:o.length,lastFailover:c,authCooldownUntil:A?A.timestamp+A.cooldownMs:void 0}});this._providerHealth=a}catch{}}async _loadData(){if(this.rpcClient){this._loadState="loading",this._error="";try{const e=await this.rpcClient.call("config.read");this._securityConfig=e.config.security??{},this._loadState="loaded",this._loadProviderHealth()}catch(e){this._error=e instanceof Error?e.message:"Failed to load security configuration",this._loadState="error"}}}async _patchConfig(e,t){if(!this.rpcClient)return!1;try{const i=e.indexOf("."),a=i>0?e.slice(0,i):e,r=i>0?e.slice(i+1):void 0;return await this.rpcClient.call("config.patch",{section:a,key:r,value:t}),n.show("Configuration updated","success"),!0}catch(i){const a=i instanceof Error?i.message:"Failed to update configuration";return n.show(a,"error"),!1}}async _onSecretsEnabledChange(e){const t={...this._securityConfig.secrets,enabled:e};await this._patchConfig("security.secrets",t)&&(this._securityConfig={...this._securityConfig,secrets:t})}_renderSecretsTab(){const e=this._securityConfig.secrets??{};return s`
955
+ <div class="policy-section">
956
+ <div class="section-header">Encrypted Secrets Store</div>
957
+ <ic-toggle
958
+ label="Enabled"
959
+ .checked=${e.enabled??!1}
960
+ @change=${t=>this._onSecretsEnabledChange(t.detail)}
961
+ ></ic-toggle>
962
+ <div style="margin-top: var(--ic-space-md);">
963
+ <div class="tls-row">
964
+ <span class="tls-label">DB Path</span>
965
+ <span class="tls-value">${e.dbPath??"secrets.db"}</span>
966
+ </div>
967
+ </div>
968
+ </div>
969
+ `}_statusToDotStatus(e){switch(e){case"healthy":return"connected";case"degraded":return"reconnecting";case"down":return"disconnected";default:return"disconnected"}}_renderHealthTab(){const e=Date.now(),t=this._authCooldowns.filter(i=>i.timestamp+i.cooldownMs>e);return s`
970
+ <div class="section-header">Provider Status</div>
971
+ ${this._providerHealth.length===0?s`<ic-empty-state icon="cloud" message="No provider data" description="Provider health data will appear after LLM calls are made."></ic-empty-state>`:s`
972
+ <div class="health-grid">
973
+ ${this._providerHealth.map(i=>s`
974
+ <div class="health-card">
975
+ <div class="health-card-header">
976
+ <strong>${i.name}</strong>
977
+ <ic-connection-dot
978
+ status=${this._statusToDotStatus(i.status)}
979
+ size="8px"
980
+ ></ic-connection-dot>
981
+ </div>
982
+ <ic-progress-bar
983
+ .value=${Math.round(i.cacheHitRate*100)}
984
+ label="Cache Hit Rate"
985
+ .thresholds=${{green:101,yellow:102}}
986
+ ></ic-progress-bar>
987
+ <div class="health-card-stat">
988
+ Failovers: ${i.failoverCount}
989
+ ${i.lastFailover?s` &mdash; last <ic-relative-time .timestamp=${i.lastFailover}></ic-relative-time>`:p}
990
+ </div>
991
+ ${i.authCooldownUntil&&i.authCooldownUntil>e?s`
992
+ <div class="health-card-stat">
993
+ <ic-tag variant="warning">Auth cooldown</ic-tag>
994
+ ${Math.ceil((i.authCooldownUntil-e)/1e3)}s remaining
995
+ </div>
996
+ `:p}
997
+ </div>
998
+ `)}
999
+ </div>
1000
+ `}
1001
+
1002
+ <div class="section-header" style="margin-top: var(--ic-space-xl);">Failover Event Log</div>
1003
+ ${this._failoverLog.length===0?s`<p style="font-size: var(--ic-text-sm); color: var(--ic-text-dim); font-style: italic;">No failover events recorded</p>`:s`
1004
+ <div class="failover-log">
1005
+ ${this._failoverLog.map(i=>s`
1006
+ <div class="failover-entry">
1007
+ <ic-relative-time .timestamp=${i.timestamp}></ic-relative-time>
1008
+ ${i.exhausted?s`
1009
+ <span>${i.provider??"unknown"} exhausted after ${i.totalAttempts??"?"} attempts</span>
1010
+ <ic-tag variant="error">EXHAUSTED</ic-tag>
1011
+ `:s`
1012
+ <span>${i.fromProvider??"?"}/${i.fromModel??"?"} &rarr; ${i.toProvider??"?"}/${i.toModel??"?"}</span>
1013
+ ${i.attemptNumber!=null?s`<ic-tag variant="info">#${i.attemptNumber}</ic-tag>`:p}
1014
+ ${i.error?s`<span style="color: var(--ic-text-dim);">${i.error}</span>`:p}
1015
+ `}
1016
+ </div>
1017
+ `)}
1018
+ </div>
1019
+ `}
1020
+
1021
+ <div class="section-header" style="margin-top: var(--ic-space-xl);">Auth Cooldowns</div>
1022
+ ${t.length===0?s`<p style="font-size: var(--ic-text-sm); color: var(--ic-text-dim); font-style: italic;">No active cooldowns</p>`:s`
1023
+ <div class="cooldown-list">
1024
+ ${t.map(i=>s`
1025
+ <div class="cooldown-entry">
1026
+ <ic-tag variant="warning">${i.provider}</ic-tag>
1027
+ <span>${i.keyName}</span>
1028
+ <span style="color: var(--ic-text-dim);">${i.failureCount} failures</span>
1029
+ <span>${Math.ceil((i.timestamp+i.cooldownMs-e)/1e3)}s remaining</span>
1030
+ </div>
1031
+ `)}
1032
+ </div>
1033
+ `}
1034
+ `}_renderTabContent(){switch(this._activeTab){case"events":return s`<ic-security-event-feed
1035
+ activeSubTab="events"
1036
+ .securityEvents=${this._securityEvents}
1037
+ .inputGuardSummary=${this._inputGuardSummary}
1038
+ ></ic-security-event-feed>`;case"audit":return s`<ic-security-event-feed
1039
+ activeSubTab="audit"
1040
+ .securityEvents=${this._securityEvents}
1041
+ .inputGuardSummary=${this._inputGuardSummary}
1042
+ ></ic-security-event-feed>`;case"tokens":return s`<ic-token-manager .rpc=${this.rpcClient}></ic-token-manager>`;case"secrets":return this._renderSecretsTab();case"rules":return s`<ic-approval-queue
1043
+ activeSubTab="rules"
1044
+ .rpc=${this.rpcClient}
1045
+ .securityConfig=${this._securityConfig}
1046
+ ></ic-approval-queue>`;case"pending":return s`<ic-approval-queue
1047
+ activeSubTab="pending"
1048
+ .rpc=${this.rpcClient}
1049
+ .securityConfig=${this._securityConfig}
1050
+ ></ic-approval-queue>`;case"health":return this._renderHealthTab();default:return p}}render(){return this._loadState==="loading"?s`<ic-skeleton-view variant="list"></ic-skeleton-view>`:this._loadState==="error"?s`
1051
+ <div class="error-container">
1052
+ <span class="error-message">${this._error}</span>
1053
+ <button class="retry-btn" @click=${()=>this._loadData()}>Retry</button>
1054
+ </div>
1055
+ `:s`
1056
+ <div class="view-header">
1057
+ <div class="view-title">Security</div>
1058
+ </div>
1059
+ <ic-tabs
1060
+ .tabs=${se}
1061
+ .activeTab=${this._activeTab}
1062
+ @tab-change=${e=>{this._activeTab=e.detail}}
1063
+ ></ic-tabs>
1064
+ <div class="tab-content">
1065
+ ${this._renderTabContent()}
1066
+ </div>
1067
+ `}};v.styles=[_,S,w`
1068
+ :host {
1069
+ display: block;
1070
+ }
1071
+
1072
+ .view-header {
1073
+ margin-bottom: var(--ic-space-lg);
1074
+ }
1075
+
1076
+ .view-title {
1077
+ font-size: 1.125rem;
1078
+ font-weight: 600;
1079
+ }
1080
+
1081
+ .state-container {
1082
+ display: flex;
1083
+ align-items: center;
1084
+ justify-content: center;
1085
+ padding: 3rem;
1086
+ }
1087
+
1088
+ .error-container {
1089
+ display: flex;
1090
+ flex-direction: column;
1091
+ align-items: center;
1092
+ gap: 0.75rem;
1093
+ padding: 3rem;
1094
+ }
1095
+
1096
+ .error-message {
1097
+ color: var(--ic-error);
1098
+ font-size: var(--ic-text-sm);
1099
+ }
1100
+
1101
+ .retry-btn {
1102
+ padding: 0.5rem 1rem;
1103
+ background: var(--ic-surface-2);
1104
+ border: 1px solid var(--ic-border);
1105
+ border-radius: var(--ic-radius-md);
1106
+ color: var(--ic-text-muted);
1107
+ font-size: var(--ic-text-sm);
1108
+ cursor: pointer;
1109
+ font-family: inherit;
1110
+ }
1111
+
1112
+ .retry-btn:hover {
1113
+ background: var(--ic-border);
1114
+ }
1115
+
1116
+ .tab-content {
1117
+ margin-top: var(--ic-space-md);
1118
+ }
1119
+
1120
+ .section-header {
1121
+ font-size: var(--ic-text-base);
1122
+ font-weight: 600;
1123
+ color: var(--ic-text);
1124
+ margin-top: var(--ic-space-lg);
1125
+ margin-bottom: var(--ic-space-sm);
1126
+ }
1127
+
1128
+ .section-header:first-child {
1129
+ margin-top: 0;
1130
+ }
1131
+
1132
+ /* Secrets tab styles */
1133
+ .policy-section {
1134
+ margin-bottom: var(--ic-space-xl);
1135
+ max-width: 40rem;
1136
+ }
1137
+
1138
+ .tls-row {
1139
+ display: flex;
1140
+ align-items: center;
1141
+ gap: var(--ic-space-sm);
1142
+ font-size: var(--ic-text-sm);
1143
+ }
1144
+
1145
+ .tls-label {
1146
+ font-weight: 500;
1147
+ color: var(--ic-text-muted);
1148
+ min-width: 6rem;
1149
+ }
1150
+
1151
+ .tls-value {
1152
+ font-family: ui-monospace, monospace;
1153
+ color: var(--ic-text);
1154
+ font-size: var(--ic-text-xs);
1155
+ }
1156
+
1157
+ /* Provider Health tab */
1158
+ .health-grid {
1159
+ display: grid;
1160
+ grid-template-columns: 1fr;
1161
+ gap: var(--ic-space-md);
1162
+ }
1163
+
1164
+ @media (min-width: 768px) {
1165
+ .health-grid {
1166
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1167
+ }
1168
+ }
1169
+
1170
+ .health-card {
1171
+ background: var(--ic-surface);
1172
+ border: 1px solid var(--ic-border);
1173
+ border-radius: var(--ic-radius-md);
1174
+ padding: var(--ic-space-md);
1175
+ }
1176
+
1177
+ .health-card-header {
1178
+ display: flex;
1179
+ justify-content: space-between;
1180
+ align-items: center;
1181
+ margin-bottom: var(--ic-space-sm);
1182
+ }
1183
+
1184
+ .health-card-header strong {
1185
+ font-size: var(--ic-text-sm);
1186
+ }
1187
+
1188
+ .health-card-stat {
1189
+ font-size: var(--ic-text-sm);
1190
+ color: var(--ic-text-muted);
1191
+ margin-top: var(--ic-space-xs);
1192
+ }
1193
+
1194
+ .failover-log {
1195
+ max-height: 300px;
1196
+ overflow-y: auto;
1197
+ margin-top: var(--ic-space-md);
1198
+ }
1199
+
1200
+ .failover-entry {
1201
+ display: flex;
1202
+ flex-direction: row;
1203
+ gap: var(--ic-space-sm);
1204
+ padding: var(--ic-space-sm);
1205
+ border-bottom: 1px solid var(--ic-border);
1206
+ font-size: var(--ic-text-sm);
1207
+ align-items: center;
1208
+ flex-wrap: wrap;
1209
+ }
1210
+
1211
+ .cooldown-list {
1212
+ display: flex;
1213
+ flex-direction: column;
1214
+ gap: var(--ic-space-sm);
1215
+ margin-top: var(--ic-space-md);
1216
+ }
1217
+
1218
+ .cooldown-entry {
1219
+ display: flex;
1220
+ gap: var(--ic-space-sm);
1221
+ align-items: center;
1222
+ font-size: var(--ic-text-sm);
1223
+ }
1224
+ `];u([d({attribute:!1})],v.prototype,"rpcClient",2);u([d({attribute:!1})],v.prototype,"apiClient",2);u([d({attribute:!1})],v.prototype,"eventDispatcher",2);u([l()],v.prototype,"_loadState",2);u([l()],v.prototype,"_error",2);u([l()],v.prototype,"_activeTab",2);u([l()],v.prototype,"_securityEvents",2);u([l()],v.prototype,"_inputGuardSummary",2);u([l()],v.prototype,"_securityConfig",2);u([l()],v.prototype,"_providerHealth",2);u([l()],v.prototype,"_failoverLog",2);u([l()],v.prototype,"_authCooldowns",2);v=u([$("ic-security-view")],v);export{v as IcSecurityView};