comisai 1.0.16 → 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 (90) 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/dist/wizard/non-interactive.js +1 -0
  4. package/node_modules/@comis/cli/dist/wizard/steps/01-detect-existing.js +4 -0
  5. package/node_modules/@comis/cli/dist/wizard/steps/07-gateway.js +9 -0
  6. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +2 -0
  7. package/node_modules/@comis/cli/dist/wizard/steps/12-finish.js +5 -2
  8. package/node_modules/@comis/cli/dist/wizard/types.d.ts +1 -0
  9. package/node_modules/@comis/cli/package.json +1 -1
  10. package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +17 -2
  11. package/node_modules/@comis/core/dist/config/schema-gateway.js +11 -0
  12. package/node_modules/@comis/core/dist/config/schema.d.ts +60 -57
  13. package/node_modules/@comis/core/package.json +1 -1
  14. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +34 -6
  15. package/node_modules/@comis/daemon/package.json +1 -1
  16. package/node_modules/@comis/gateway/package.json +1 -1
  17. package/node_modules/@comis/infra/package.json +1 -1
  18. package/node_modules/@comis/memory/package.json +1 -1
  19. package/node_modules/@comis/scheduler/package.json +1 -1
  20. package/node_modules/@comis/shared/package.json +1 -1
  21. package/node_modules/@comis/skills/package.json +1 -1
  22. package/node_modules/@comis/web/dist/android-chrome-192x192.png +0 -0
  23. package/node_modules/@comis/web/dist/android-chrome-512x512.png +0 -0
  24. package/node_modules/@comis/web/dist/apple-touch-icon.png +0 -0
  25. package/node_modules/@comis/web/dist/assets/agent-detail-BG9MGWWj.js +615 -0
  26. package/node_modules/@comis/web/dist/assets/agent-editor-C26Q_xCs.js +2173 -0
  27. package/node_modules/@comis/web/dist/assets/agent-list-LHCJ4rw2.js +504 -0
  28. package/node_modules/@comis/web/dist/assets/approvals-q9VH_IKr.js +54 -0
  29. package/node_modules/@comis/web/dist/assets/billing-view-CtYvBqTE.js +375 -0
  30. package/node_modules/@comis/web/dist/assets/channel-detail-CaInesJM.js +681 -0
  31. package/node_modules/@comis/web/dist/assets/channel-list-B8dj3O9a.js +323 -0
  32. package/node_modules/@comis/web/dist/assets/chat-console-CNmzl0JW.js +943 -0
  33. package/node_modules/@comis/web/dist/assets/config-editor-DX4ITw6y.js +1374 -0
  34. package/node_modules/@comis/web/dist/assets/context-dag-browser-BwiaF5tf.js +393 -0
  35. package/node_modules/@comis/web/dist/assets/context-engine-BZ5Am6hA.js +393 -0
  36. package/node_modules/@comis/web/dist/assets/delivery-view-OfBZof-m.js +392 -0
  37. package/node_modules/@comis/web/dist/assets/diagnostics-view-YFwCxgr2.js +231 -0
  38. package/node_modules/@comis/web/dist/assets/directive-DoeGSK_T.js +1 -0
  39. package/node_modules/@comis/web/dist/assets/extract-variables-BM5qyK-s.js +149 -0
  40. package/node_modules/@comis/web/dist/assets/ic-array-editor-B7m6x7-S.js +118 -0
  41. package/node_modules/@comis/web/dist/assets/ic-breadcrumb-CUMpp3BL.js +75 -0
  42. package/node_modules/@comis/web/dist/assets/ic-budget-segment-bar-BtJ6x5mN.js +64 -0
  43. package/node_modules/@comis/web/dist/assets/ic-chat-message-CFyDJd0z.js +352 -0
  44. package/node_modules/@comis/web/dist/assets/ic-confirm-dialog-CCDbB04e.js +110 -0
  45. package/node_modules/@comis/web/dist/assets/ic-connection-dot-CnT1b8xr.js +54 -0
  46. package/node_modules/@comis/web/dist/assets/ic-data-table-CKUNTxHw.js +277 -0
  47. package/node_modules/@comis/web/dist/assets/ic-delivery-row-GP5Fkygs.js +67 -0
  48. package/node_modules/@comis/web/dist/assets/ic-detail-panel-BF83r-if.js +116 -0
  49. package/node_modules/@comis/web/dist/assets/ic-empty-state-60l2ePhd.js +52 -0
  50. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-C8FuSMe1.js +359 -0
  51. package/node_modules/@comis/web/dist/assets/ic-icon-xeGTVhVG.js +33 -0
  52. package/node_modules/@comis/web/dist/assets/ic-layer-waterfall-COvEYMg5.js +69 -0
  53. package/node_modules/@comis/web/dist/assets/ic-relative-time-3FqpjeAI.js +12 -0
  54. package/node_modules/@comis/web/dist/assets/ic-search-input-CSOxY9g7.js +92 -0
  55. package/node_modules/@comis/web/dist/assets/ic-select-Ce-Raudx.js +127 -0
  56. package/node_modules/@comis/web/dist/assets/ic-tabs-B7QtM_v8.js +95 -0
  57. package/node_modules/@comis/web/dist/assets/ic-tag-CPPUnDLF.js +33 -0
  58. package/node_modules/@comis/web/dist/assets/ic-time-range-picker-CypCT68y.js +93 -0
  59. package/node_modules/@comis/web/dist/assets/ic-tool-call-7MaXSsCW.js +146 -0
  60. package/node_modules/@comis/web/dist/assets/index-CEcM1R_C.js +2830 -0
  61. package/node_modules/@comis/web/dist/assets/index-CIJFuItj.css +1 -0
  62. package/node_modules/@comis/web/dist/assets/mcp-management-BNZPnpDn.js +582 -0
  63. package/node_modules/@comis/web/dist/assets/media-config-BBvTYxOX.js +314 -0
  64. package/node_modules/@comis/web/dist/assets/media-test-BkK3RCRK.js +496 -0
  65. package/node_modules/@comis/web/dist/assets/memory-inspector-1hDGCGat.js +1139 -0
  66. package/node_modules/@comis/web/dist/assets/message-center-CXefwsUu.js +785 -0
  67. package/node_modules/@comis/web/dist/assets/models-C1qcU_j3.js +894 -0
  68. package/node_modules/@comis/web/dist/assets/observability-types-D7jUtSde.js +1 -0
  69. package/node_modules/@comis/web/dist/assets/observe-view-C0VBhX4C.js +814 -0
  70. package/node_modules/@comis/web/dist/assets/pipeline-builder-DcUUIrm0.js +1496 -0
  71. package/node_modules/@comis/web/dist/assets/pipeline-history-DkfOQ6SW.js +317 -0
  72. package/node_modules/@comis/web/dist/assets/pipeline-history-detail-hyHgD0ai.js +287 -0
  73. package/node_modules/@comis/web/dist/assets/pipeline-list-BPW8hV-q.js +518 -0
  74. package/node_modules/@comis/web/dist/assets/pipeline-monitor-Bip16T7e.js +972 -0
  75. package/node_modules/@comis/web/dist/assets/scheduler-BGgwKd06.js +1182 -0
  76. package/node_modules/@comis/web/dist/assets/security-D15st4xx.js +1224 -0
  77. package/node_modules/@comis/web/dist/assets/session-detail-SGEYNJ0M.js +632 -0
  78. package/node_modules/@comis/web/dist/assets/session-key-parser-DPORMVyU.js +1 -0
  79. package/node_modules/@comis/web/dist/assets/session-list-6ybUTxbY.js +231 -0
  80. package/node_modules/@comis/web/dist/assets/setup-wizard-nT0tz9QP.js +853 -0
  81. package/node_modules/@comis/web/dist/assets/skills-D8yVfSUy.js +1051 -0
  82. package/node_modules/@comis/web/dist/assets/subagents-HHXMeHYo.js +193 -0
  83. package/node_modules/@comis/web/dist/assets/workspace-manager-BQlr10iH.js +785 -0
  84. package/node_modules/@comis/web/dist/comis-logo.png +0 -0
  85. package/node_modules/@comis/web/dist/favicon-16x16.png +0 -0
  86. package/node_modules/@comis/web/dist/favicon-32x32.png +0 -0
  87. package/node_modules/@comis/web/dist/favicon.ico +0 -0
  88. package/node_modules/@comis/web/dist/index.html +17 -0
  89. package/node_modules/@comis/web/package.json +29 -0
  90. package/package.json +15 -13
@@ -0,0 +1,1374 @@
1
+ import{s as N,f as P,i as I,n as x,r as p,a as j,b as o,t as M,A as g,I as y}from"./index-CEcM1R_C.js";import"./ic-empty-state-60l2ePhd.js";import"./ic-confirm-dialog-CCDbB04e.js";import"./ic-tag-CPPUnDLF.js";import"./ic-relative-time-3FqpjeAI.js";import"./ic-tabs-B7QtM_v8.js";import"./ic-select-Ce-Raudx.js";import"./ic-array-editor-B7m6x7-S.js";import"./ic-icon-xeGTVhVG.js";var V=Object.defineProperty,J=Object.getOwnPropertyDescriptor,S=(e,t,r,i)=>{for(var a=i>1?void 0:i?J(t,r):t,s=e.length-1,n;s>=0;s--)(n=e[s])&&(a=(i?n(t,r,a):n(a))||a);return i&&a&&V(t,r,a),a};function U(e,t){const r=e.split(`
2
+ `),i=t.split(`
3
+ `),a=r.length,s=i.length,n=Array.from({length:a+1},()=>new Array(s+1).fill(0));for(let u=1;u<=a;u++)for(let v=1;v<=s;v++)r[u-1]===i[v-1]?n[u][v]=n[u-1][v-1]+1:n[u][v]=Math.max(n[u-1][v],n[u][v-1]);let c=a,l=s;const d=[],m=[];for(;c>0||l>0;)c>0&&l>0&&r[c-1]===i[l-1]?(d.push({text:r[c-1],status:"unchanged"}),m.push({text:i[l-1],status:"unchanged"}),c--,l--):l>0&&(c===0||n[c][l-1]>=n[c-1][l])?(m.push({text:i[l-1],status:"added"}),d.push({text:"",status:"unchanged"}),l--):(d.push({text:r[c-1],status:"removed"}),m.push({text:"",status:"unchanged"}),c--);return d.reverse(),m.reverse(),{oldLines:d,newLines:m}}let _=class extends j{constructor(){super(...arguments),this.oldText="",this.newText="",this.oldLabel="Current",this.newLabel="Pending",this._syncing=!1}_handleScroll(e,t){if(this._syncing)return;this._syncing=!0;const r=e.target,i=this.shadowRoot?.querySelector(`.${t}`);i&&(i.scrollTop=r.scrollTop,i.scrollLeft=r.scrollLeft),requestAnimationFrame(()=>{this._syncing=!1})}_renderLines(e){return e.map(t=>{let r="line";return t.status==="removed"?r+=" line--removed":t.status==="added"?r+=" line--added":t.text===""&&(r+=" line--spacer"),o`<span class=${r}>${t.text||" "}</span>`})}render(){if(this.oldText===this.newText)return o`
4
+ <div class="diff-container">
5
+ <div class="no-changes">No changes detected</div>
6
+ </div>
7
+ `;const{oldLines:e,newLines:t}=U(this.oldText,this.newText);return o`
8
+ <div class="diff-container">
9
+ <div class="diff-panel">
10
+ <div class="diff-header">${this.oldLabel}</div>
11
+ <div
12
+ class="diff-body diff-body--old"
13
+ @scroll=${r=>this._handleScroll(r,"diff-body--new")}
14
+ >
15
+ <pre><code>${this._renderLines(e)}</code></pre>
16
+ </div>
17
+ </div>
18
+ <div class="diff-panel">
19
+ <div class="diff-header">${this.newLabel}</div>
20
+ <div
21
+ class="diff-body diff-body--new"
22
+ @scroll=${r=>this._handleScroll(r,"diff-body--old")}
23
+ >
24
+ <pre><code>${this._renderLines(t)}</code></pre>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ `}};_.styles=[N,P,I`
29
+ :host {
30
+ display: block;
31
+ }
32
+
33
+ .diff-container {
34
+ display: grid;
35
+ grid-template-columns: 1fr 1fr;
36
+ border: 1px solid var(--ic-border);
37
+ border-radius: var(--ic-radius-md);
38
+ overflow: hidden;
39
+ background: var(--ic-bg-card, var(--ic-surface));
40
+ }
41
+
42
+ .diff-panel {
43
+ display: flex;
44
+ flex-direction: column;
45
+ min-width: 0;
46
+ overflow: hidden;
47
+ }
48
+
49
+ .diff-panel + .diff-panel {
50
+ border-left: 1px solid var(--ic-border);
51
+ }
52
+
53
+ .diff-header {
54
+ padding: var(--ic-space-xs) var(--ic-space-md);
55
+ background: var(--ic-surface-2);
56
+ border-bottom: 1px solid var(--ic-border);
57
+ font-size: var(--ic-text-xs);
58
+ font-weight: 600;
59
+ color: var(--ic-text-muted);
60
+ text-transform: uppercase;
61
+ letter-spacing: 0.04em;
62
+ }
63
+
64
+ .diff-body {
65
+ overflow: auto;
66
+ max-height: 24rem;
67
+ }
68
+
69
+ pre {
70
+ margin: 0;
71
+ padding: 0;
72
+ }
73
+
74
+ code {
75
+ font-family: var(--ic-font-mono, ui-monospace, monospace);
76
+ font-size: var(--ic-text-sm);
77
+ line-height: 1.6;
78
+ white-space: pre;
79
+ tab-size: 2;
80
+ display: block;
81
+ }
82
+
83
+ .line {
84
+ display: block;
85
+ padding: 0 var(--ic-space-md);
86
+ min-height: 1.6em;
87
+ }
88
+
89
+ .line--removed {
90
+ background: color-mix(in srgb, var(--ic-error) 15%, transparent);
91
+ color: var(--ic-text);
92
+ }
93
+
94
+ .line--added {
95
+ background: color-mix(in srgb, var(--ic-success) 15%, transparent);
96
+ color: var(--ic-text);
97
+ }
98
+
99
+ .line--spacer {
100
+ opacity: 0.3;
101
+ }
102
+
103
+ .no-changes {
104
+ padding: var(--ic-space-lg);
105
+ text-align: center;
106
+ color: var(--ic-text-muted);
107
+ font-size: var(--ic-text-sm);
108
+ grid-column: 1 / -1;
109
+ }
110
+ `];S([x()],_.prototype,"oldText",2);S([x()],_.prototype,"newText",2);S([x()],_.prototype,"oldLabel",2);S([x()],_.prototype,"newLabel",2);S([p()],_.prototype,"_syncing",2);_=S([M("ic-diff-viewer")],_);var B=Object.defineProperty,K=Object.getOwnPropertyDescriptor,w=(e,t,r,i)=>{for(var a=i>1?void 0:i?K(t,r):t,s=e.length-1,n;s>=0;s--)(n=e[s])&&(a=(i?n(t,r,a):n(a))||a);return i&&a&&B(t,r,a),a};const Z=["rpc","ws","admin","api","*"];function C(e){return e.replace(/([A-Z])/g," $1").replace(/^./,t=>t.toUpperCase()).trim()}function T(e,t){const r=t.split(".");let i=e;for(const a of r){if(i==null||typeof i!="object")return;i=i[a]}return i}function W(e,t,r){const i=t.split(".");if(i.length===1)return{...e,[i[0]]:r};const[a,...s]=i,n=e[a]??{};return{...e,[a]:W(n,s.join("."),r)}}let b=class extends j{constructor(){super(...arguments),this.schema={},this.config={},this.sectionKey="",this._formState={},this._formErrors={},this._expandedFormPaths=new Set}updated(e){e.has("config")&&(this._formState=structuredClone(this.config),this._formErrors={})}_onFormFieldChange(e,t){this._formState=W(this._formState,e,t);const r={...this._formErrors};delete r[e],this._formErrors=r,this.dispatchEvent(new CustomEvent("field-change",{detail:{path:e,value:t,formState:this._formState},bubbles:!0,composed:!0}))}_validateField(e,t,r){const i={...this._formErrors};if(r.type==="string"&&typeof t=="string")if(r.minLength!==void 0&&t.length<r.minLength)i[e]=`Minimum length is ${r.minLength}`;else if(r.maxLength!==void 0&&t.length>r.maxLength)i[e]=`Maximum length is ${r.maxLength}`;else if(r.pattern)try{new RegExp(r.pattern).test(t)||(i[e]=`Must match pattern: ${r.pattern}`)}catch{}else delete i[e];else(r.type==="number"||r.type==="integer")&&typeof t=="number"?r.minimum!==void 0&&t<r.minimum?i[e]=`Minimum value is ${r.minimum}`:r.maximum!==void 0&&t>r.maximum?i[e]=`Maximum value is ${r.maximum}`:delete i[e]:delete i[e];this._formErrors=i}_toggleFormFieldset(e){const t=new Set(this._expandedFormPaths);t.has(e)?t.delete(e):t.add(e),this._expandedFormPaths=t}_onArrayItemFieldChange(e,t,r,i){const s=(T(this._formState,e)??[]).map((n,c)=>c!==t?n:{...n,[r]:i});this._onFormFieldChange(e,s)}_renderStringField(e,t,r,i){const a=i.maxLength!==void 0&&i.maxLength>200||e.includes("prompt")||e.includes("template");return o`
111
+ <div class="form-field">
112
+ <label class="form-label">${t}</label>
113
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
114
+ ${a?o`<textarea class="form-textarea" .value=${r}
115
+ @input=${s=>this._onFormFieldChange(e,s.target.value)}
116
+ @blur=${()=>this._validateField(e,r,i)}
117
+ ></textarea>`:o`<input class="form-input" type="text" .value=${r}
118
+ @input=${s=>this._onFormFieldChange(e,s.target.value)}
119
+ @blur=${()=>this._validateField(e,r,i)}
120
+ />`}
121
+ ${this._formErrors[e]?o`<span class="form-error">${this._formErrors[e]}</span>`:g}
122
+ </div>
123
+ `}_renderNumberField(e,t,r,i){return o`
124
+ <div class="form-field">
125
+ <label class="form-label">${t}</label>
126
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
127
+ <input class="form-input" type="number" .value=${String(r)}
128
+ min=${i.minimum??g} max=${i.maximum??g}
129
+ @input=${a=>{const s=parseFloat(a.target.value);isNaN(s)||this._onFormFieldChange(e,s)}}
130
+ @blur=${()=>this._validateField(e,r,i)}
131
+ />
132
+ ${this._formErrors[e]?o`<span class="form-error">${this._formErrors[e]}</span>`:g}
133
+ </div>
134
+ `}_renderBooleanField(e,t,r,i){return o`
135
+ <div class="form-field">
136
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
137
+ <ic-toggle label=${t} .checked=${r}
138
+ @change=${a=>this._onFormFieldChange(e,a.detail)}
139
+ ></ic-toggle>
140
+ </div>
141
+ `}_renderEnumField(e,t,r,i){const a=(i.enum??[]).map(s=>({value:String(s),label:String(s)}));return o`
142
+ <div class="form-field">
143
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
144
+ <ic-select label=${t} .value=${String(r??"")} .options=${a}
145
+ @change=${s=>this._onFormFieldChange(e,s.detail)}
146
+ ></ic-select>
147
+ </div>
148
+ `}_renderArrayField(e,t,r,i){return i.items?.type==="string"?o`
149
+ <div class="form-field">
150
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
151
+ <ic-array-editor label=${t} .items=${(r??[]).map(String)} placeholder="Add item..."
152
+ @change=${a=>{this._onFormFieldChange(e,a.detail)}}
153
+ ></ic-array-editor>
154
+ </div>
155
+ `:i.items?.type==="object"&&i.items.properties?this._renderArrayOfObjectsField(e,t,r,i):this._renderJsonFallback(e,t,r,i)}_renderArrayOfObjectsField(e,t,r,i){const a=r??[],s=i.items,n=s.properties??{},c=s.required??[],l=()=>{const d={};for(const[m,u]of Object.entries(n))u.default!==void 0?d[m]=JSON.parse(JSON.stringify(u.default)):u.type==="string"?d[m]="":u.type==="number"||u.type==="integer"?d[m]=0:u.type==="boolean"?d[m]=!1:u.type==="array"?d[m]=[]:u.type==="object"&&(d[m]={});return d};return o`
156
+ <div class="form-field">
157
+ <label class="form-label">${t}</label>
158
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
159
+ <div class="array-cards">
160
+ ${a.map((d,m)=>this._renderArrayObjectCard(e,m,d,n,c))}
161
+ </div>
162
+ <button class="array-add-btn"
163
+ @click=${()=>{this._onFormFieldChange(e,[...a,l()])}}
164
+ >+ Add</button>
165
+ </div>
166
+ `}_renderArrayObjectCard(e,t,r,i,a){return o`
167
+ <div class="array-card">
168
+ <div class="array-card-header">
169
+ <span class="array-card-index">#${t+1}</span>
170
+ <button class="array-card-remove" title="Remove"
171
+ @click=${()=>{const s=T(this._formState,e)??[];this._onFormFieldChange(e,s.filter((n,c)=>c!==t))}}
172
+ >\u00d7</button>
173
+ </div>
174
+ <div class="array-card-fields">
175
+ ${Object.entries(i).map(([s,n])=>{const c=`${C(s)}${a.includes(s)?" *":""}`,l=r[s];if(s==="secret")return o`
176
+ <div class="form-field">
177
+ <label class="form-label">${c}</label>
178
+ <input type="password" class="form-input"
179
+ .value=${typeof l=="string"?l:""}
180
+ placeholder="env:VAR_NAME or min 32 chars"
181
+ @input=${d=>{this._onArrayItemFieldChange(e,t,s,d.target.value)}}
182
+ />
183
+ </div>
184
+ `;if(n.type==="array"&&n.items?.type==="string"){if(s==="scopes"){const d=new Set((l??[]).map(String));return o`
185
+ <div class="form-field">
186
+ <label class="form-label">${c}</label>
187
+ <div class="scope-chips">
188
+ ${Z.map(m=>o`
189
+ <button class="scope-chip" ?data-active=${d.has(m)}
190
+ @click=${()=>{const u=new Set(d);u.has(m)?u.delete(m):u.add(m),this._onArrayItemFieldChange(e,t,s,[...u])}}
191
+ >${m}</button>
192
+ `)}
193
+ </div>
194
+ </div>
195
+ `}return o`
196
+ <div class="form-field">
197
+ <ic-array-editor label=${c} .items=${(l??[]).map(String)} placeholder="Add..."
198
+ @change=${d=>{this._onArrayItemFieldChange(e,t,s,d.detail)}}
199
+ ></ic-array-editor>
200
+ </div>
201
+ `}return n.type==="string"?o`
202
+ <div class="form-field">
203
+ <label class="form-label">${c}</label>
204
+ <input type="text" class="form-input" .value=${String(l??"")}
205
+ @input=${d=>{this._onArrayItemFieldChange(e,t,s,d.target.value)}}
206
+ />
207
+ </div>
208
+ `:n.type==="number"||n.type==="integer"?o`
209
+ <div class="form-field">
210
+ <label class="form-label">${c}</label>
211
+ <input type="number" class="form-input" .value=${String(l??0)}
212
+ @input=${d=>{this._onArrayItemFieldChange(e,t,s,Number(d.target.value))}}
213
+ />
214
+ </div>
215
+ `:n.type==="boolean"?o`
216
+ <div class="form-field">
217
+ <label class="form-label">${c}</label>
218
+ <ic-toggle ?checked=${!!l}
219
+ @change=${d=>{this._onArrayItemFieldChange(e,t,s,d.detail)}}
220
+ ></ic-toggle>
221
+ </div>
222
+ `:o`
223
+ <div class="form-field">
224
+ <label class="form-label">${c}</label>
225
+ <input type="text" class="form-input" .value=${JSON.stringify(l??"")}
226
+ @input=${d=>{try{this._onArrayItemFieldChange(e,t,s,JSON.parse(d.target.value))}catch{}}}
227
+ />
228
+ </div>
229
+ `})}
230
+ </div>
231
+ </div>
232
+ `}_renderObjectField(e,t,r,i){const a=this._expandedFormPaths.has(e),s=i.properties??{},n=i.required??[];return o`
233
+ <fieldset class="form-fieldset">
234
+ <legend class="form-fieldset-legend" @click=${()=>this._toggleFormFieldset(e)}>
235
+ <span class="arrow" ?data-expanded=${a}>\u25B6</span>
236
+ ${t}
237
+ </legend>
238
+ ${a?o`
239
+ <div class="form-fieldset-content">
240
+ ${Object.entries(s).map(([c,l])=>this._renderSchemaField(`${e}.${c}`,`${C(c)}${n.includes(c)?" *":""}`,T(r??{},c),l))}
241
+ </div>
242
+ `:g}
243
+ </fieldset>
244
+ `}_renderJsonFallback(e,t,r,i){const a=JSON.stringify(r??null,null,2);return o`
245
+ <div class="form-field">
246
+ <label class="form-label">${t}</label>
247
+ ${i.description?o`<span class="form-description">${i.description}</span>`:g}
248
+ <textarea class="json-fallback-textarea" .value=${a}
249
+ @input=${s=>{const n=s.target.value;try{const c=JSON.parse(n);this._onFormFieldChange(e,c);const l={...this._formErrors};delete l[e],this._formErrors=l}catch{this._formErrors={...this._formErrors,[e]:"Invalid JSON"}}}}
250
+ ></textarea>
251
+ ${this._formErrors[e]?o`<span class="form-error">${this._formErrors[e]}</span>`:g}
252
+ </div>
253
+ `}_renderSchemaField(e,t,r,i){if(i.enum&&i.enum.length>0)return this._renderEnumField(e,t,r,i);const a=i.anyOf??i.oneOf;if(a&&a.length>=2){const s=a.filter(n=>n.type!=="null");if(s.length===1)return this._renderSchemaField(e,t,r,s[0]);if(r==null||typeof r=="string"){const n=s.find(c=>c.type==="string");if(n)return this._renderStringField(e,t,String(r??""),n)}}if(i.anyOf||i.oneOf||i.allOf)return this._renderJsonFallback(e,t,r,i);switch(i.type){case"string":return this._renderStringField(e,t,String(r??""),i);case"number":case"integer":return this._renderNumberField(e,t,Number(r??0),i);case"boolean":return this._renderBooleanField(e,t,!!r,i);case"array":return this._renderArrayField(e,t,r??[],i);case"object":return this._renderObjectField(e,t,r??{},i);default:return this._renderJsonFallback(e,t,r,i)}}render(){const e=this.schema;if(e&&!e.properties&&e.additionalProperties&&typeof e.additionalProperties=="object"){const i=e.additionalProperties,a=Object.keys(this._formState);return a.length===0?o`<ic-empty-state icon="config" message="No entries" description="This section has no configured entries."></ic-empty-state>`:o`
254
+ ${a.map(s=>{const n=this._formState[s]??{};return this._renderObjectField(s,C(s),n,i)})}
255
+ `}if(!e||!e.properties)return o`
256
+ ${Object.entries(this._formState).map(([i,a])=>this._renderSchemaField(i,C(i),a,{type:typeof a=="boolean"?"boolean":typeof a=="number"?"number":"string"}))}
257
+ `;const t=e.properties,r=e.required??[];return o`
258
+ ${Object.entries(t).map(([i,a])=>this._renderSchemaField(i,`${C(i)}${r.includes(i)?" *":""}`,T(this._formState,i),a))}
259
+ `}};b.styles=[N,P,I`
260
+ :host {
261
+ display: block;
262
+ }
263
+
264
+ .form-field {
265
+ display: flex;
266
+ flex-direction: column;
267
+ gap: var(--ic-space-xs);
268
+ margin-bottom: var(--ic-space-sm);
269
+ }
270
+
271
+ .form-label {
272
+ font-size: var(--ic-text-sm);
273
+ font-weight: 500;
274
+ color: var(--ic-text-muted);
275
+ }
276
+
277
+ .form-description {
278
+ font-size: var(--ic-text-xs);
279
+ color: var(--ic-text-dim);
280
+ }
281
+
282
+ .form-input {
283
+ padding: 0.5rem 0.75rem;
284
+ background: var(--ic-surface-2);
285
+ border: 1px solid var(--ic-border);
286
+ border-radius: var(--ic-radius-md);
287
+ color: var(--ic-text);
288
+ font-family: inherit;
289
+ font-size: var(--ic-text-sm);
290
+ }
291
+
292
+ .form-input:focus {
293
+ outline: none;
294
+ border-color: var(--ic-accent);
295
+ }
296
+
297
+ .form-textarea {
298
+ width: 100%;
299
+ min-height: 100px;
300
+ padding: 0.5rem 0.75rem;
301
+ background: var(--ic-surface-2);
302
+ border: 1px solid var(--ic-border);
303
+ border-radius: var(--ic-radius-md);
304
+ color: var(--ic-text);
305
+ font-family: inherit;
306
+ font-size: var(--ic-text-sm);
307
+ resize: vertical;
308
+ }
309
+
310
+ .form-textarea:focus {
311
+ outline: none;
312
+ border-color: var(--ic-accent);
313
+ }
314
+
315
+ .form-error {
316
+ font-size: var(--ic-text-xs);
317
+ color: var(--ic-error);
318
+ }
319
+
320
+ .form-fieldset {
321
+ border: 1px solid var(--ic-border);
322
+ border-radius: var(--ic-radius-md);
323
+ padding: var(--ic-space-sm) var(--ic-space-md);
324
+ margin-bottom: var(--ic-space-sm);
325
+ }
326
+
327
+ .form-fieldset-legend {
328
+ cursor: pointer;
329
+ user-select: none;
330
+ font-weight: 600;
331
+ font-size: var(--ic-text-sm);
332
+ color: var(--ic-text);
333
+ display: flex;
334
+ align-items: center;
335
+ gap: var(--ic-space-xs);
336
+ }
337
+
338
+ .form-fieldset-content {
339
+ padding-top: var(--ic-space-sm);
340
+ }
341
+
342
+ .arrow {
343
+ font-size: var(--ic-text-xs);
344
+ transition: transform 0.15s;
345
+ display: inline-block;
346
+ }
347
+
348
+ .arrow[data-expanded] {
349
+ transform: rotate(90deg);
350
+ }
351
+
352
+ .array-cards {
353
+ display: flex;
354
+ flex-direction: column;
355
+ gap: var(--ic-space-sm);
356
+ }
357
+
358
+ .array-card {
359
+ background: var(--ic-surface);
360
+ border: 1px solid var(--ic-border);
361
+ border-radius: var(--ic-radius-md);
362
+ padding: var(--ic-space-sm) var(--ic-space-md);
363
+ }
364
+
365
+ .array-card-header {
366
+ display: flex;
367
+ justify-content: space-between;
368
+ align-items: center;
369
+ margin-bottom: var(--ic-space-xs);
370
+ }
371
+
372
+ .array-card-index {
373
+ font-size: var(--ic-text-xs);
374
+ font-weight: 600;
375
+ color: var(--ic-text-muted);
376
+ }
377
+
378
+ .array-card-remove {
379
+ background: none;
380
+ border: none;
381
+ cursor: pointer;
382
+ font-size: var(--ic-text-base);
383
+ color: var(--ic-text-dim);
384
+ padding: 0;
385
+ line-height: 1;
386
+ }
387
+
388
+ .array-card-remove:hover {
389
+ color: var(--ic-error);
390
+ }
391
+
392
+ .array-card-fields {
393
+ display: flex;
394
+ flex-direction: column;
395
+ gap: var(--ic-space-xs);
396
+ }
397
+
398
+ .array-add-btn {
399
+ align-self: flex-start;
400
+ padding: 0.4rem 1rem;
401
+ background: var(--ic-surface-2);
402
+ border: 1px dashed var(--ic-border);
403
+ border-radius: var(--ic-radius-md);
404
+ color: var(--ic-text-muted);
405
+ font-size: var(--ic-text-sm);
406
+ font-family: inherit;
407
+ cursor: pointer;
408
+ margin-top: var(--ic-space-xs);
409
+ }
410
+
411
+ .array-add-btn:hover {
412
+ border-color: var(--ic-accent);
413
+ color: var(--ic-accent);
414
+ }
415
+
416
+ .scope-chips {
417
+ display: flex;
418
+ flex-wrap: wrap;
419
+ gap: 0.4rem;
420
+ }
421
+
422
+ .scope-chip {
423
+ padding: 0.25rem 0.75rem;
424
+ border-radius: var(--ic-radius-md);
425
+ font-size: var(--ic-text-xs);
426
+ font-family: inherit;
427
+ font-weight: 500;
428
+ cursor: pointer;
429
+ transition: all var(--ic-transition);
430
+ border: 1px solid var(--ic-border);
431
+ background: var(--ic-surface-2);
432
+ color: var(--ic-text-dim);
433
+ }
434
+
435
+ .scope-chip:hover {
436
+ border-color: var(--ic-accent);
437
+ }
438
+
439
+ .scope-chip[data-active] {
440
+ background: var(--ic-accent);
441
+ border-color: var(--ic-accent);
442
+ color: #fff;
443
+ }
444
+
445
+ .json-fallback-textarea {
446
+ width: 100%;
447
+ min-height: 60px;
448
+ padding: 0.5rem 0.75rem;
449
+ background: var(--ic-surface-2);
450
+ border: 1px solid var(--ic-border);
451
+ border-radius: var(--ic-radius-md);
452
+ color: var(--ic-text);
453
+ font-family: var(--ic-font-mono, ui-monospace, monospace);
454
+ font-size: var(--ic-text-xs);
455
+ resize: vertical;
456
+ tab-size: 2;
457
+ }
458
+
459
+ .json-fallback-textarea:focus {
460
+ outline: none;
461
+ border-color: var(--ic-accent);
462
+ }
463
+ `];w([x({attribute:!1})],b.prototype,"schema",2);w([x({attribute:!1})],b.prototype,"config",2);w([x({type:String})],b.prototype,"sectionKey",2);w([p()],b.prototype,"_formState",2);w([p()],b.prototype,"_formErrors",2);w([p()],b.prototype,"_expandedFormPaths",2);b=w([M("ic-schema-form")],b);function $(e,t=0){const r=" ".repeat(t);if(e==null)return"null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number")return String(e);if(typeof e=="string")return e===""||e.includes(":")||e.includes("#")||e.includes(`
464
+ `)||e.includes('"')||e.includes("'")||e.startsWith(" ")||e.endsWith(" ")||e==="true"||e==="false"||e==="null"||/^\d+(\.\d+)?$/.test(e)?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:e;if(Array.isArray(e)){if(e.length===0)return"[]";const i=[];for(const a of e)if(typeof a=="object"&&a!==null&&!Array.isArray(a)){const s=Object.entries(a);if(s.length>0){const[n,c]=s[0];i.push(`${r}- ${n}: ${$(c,0)}`);for(let l=1;l<s.length;l++){const[d,m]=s[l];i.push(`${r} ${d}: ${$(m,t+2)}`)}}else i.push(`${r}- {}`)}else i.push(`${r}- ${$(a,0)}`);return`
465
+ `+i.join(`
466
+ `)}if(typeof e=="object"){const i=Object.entries(e);if(i.length===0)return"{}";const a=[];for(const[s,n]of i)typeof n=="object"&&n!==null&&!Array.isArray(n)&&Object.keys(n).length>0?(a.push(`${r}${s}:`),a.push($(n,t+1))):Array.isArray(n)&&n.length>0?a.push(`${r}${s}:${$(n,t+1)}`):a.push(`${r}${s}: ${$(n,0)}`);return a.join(`
467
+ `)}return String(e)}function L(e){try{const t=e.split(`
468
+ `);return{data:A(t,0,0).value,error:null}}catch(t){return{data:null,error:t instanceof Error?t.message:"Parse error"}}}function z(e){const t=e.match(/^( *)/);return t?t[1].length:0}function F(e){const t=e.trim();if(t===""||t==="null"||t==="~")return null;if(t==="true")return!0;if(t==="false")return!1;if(t==="[]")return[];if(t==="{}")return{};if(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))return t.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\");const r=Number(t);return!isNaN(r)&&t!==""?r:t}function A(e,t,r){let i=t;for(;i<e.length&&e[i].trim()==="";)i++;if(i>=e.length)return{value:null,nextLine:i};const a=e[i],s=z(a),n=a.trim();if(n.startsWith("- ")){const c=[];for(;i<e.length;){const l=e[i];if(l.trim()===""){i++;continue}const d=z(l);if(d<s||d!==s||!l.trim().startsWith("- "))break;const m=l.trim().slice(2),u=m.match(/^([^:]+):\s*(.*)/);if(u&&!m.startsWith('"')&&!m.startsWith("'")){const v={};v[u[1].trim()]=F(u[2]),i++;const k=s+2;for(;i<e.length;){const E=e[i];if(E.trim()===""){i++;continue}const G=z(E);if(G<k)break;if(G===k&&!E.trim().startsWith("- ")){const O=E.trim().match(/^([^:]+):\s*(.*)/);if(O){const H=O[1].trim(),D=O[2];if(D===""||D===void 0){const q=A(e,i+1);v[H]=q.value,i=q.nextLine}else v[H]=F(D),i++}else break}else break}c.push(v)}else c.push(F(m)),i++}return{value:c,nextLine:i}}if(n.includes(":")){const c={};for(;i<e.length;){const l=e[i];if(l.trim()===""){i++;continue}const d=z(l);if(d<s||d!==s)break;const m=l.indexOf(":");if(m===-1)break;const u=l.slice(0,m).trim(),v=l.slice(m+1).trim();if(v===""||v===void 0){i++;const k=A(e,i);c[u]=k.value,i=k.nextLine}else c[u]=F(v),i++}return{value:c,nextLine:i}}return{value:F(n),nextLine:i+1}}var Q=Object.defineProperty,X=Object.getOwnPropertyDescriptor,h=(e,t,r,i)=>{for(var a=i>1?void 0:i?X(t,r):t,s=e.length-1,n;s>=0;s--)(n=e[s])&&(a=(i?n(t,r,a):n(a))||a);return i&&a&&Q(t,r,a),a};const ee=[{id:"editor",label:"YAML Editor"},{id:"gateway",label:"Gateway"},{id:"history",label:"History"},{id:"wizard",label:"Setup Wizard"}],R=$;function Y(e,t,r){const i=t.split(".");if(i.length===1)return{...e,[i[0]]:r};const[a,...s]=i,n=e[a]??{};return{...e,[a]:Y(n,s.join("."),r)}}let f=class extends j{constructor(){super(...arguments),this.rpcClient=null,this._activeTab="editor",this._loadState="loading",this._error="",this._sections=[],this._selectedSection="",this._mode="form",this._configData={},this._schemaData={},this._yamlText="",this._yamlErrors=[],this._formState={},this._formErrors={},this._dirty=!1,this._applying=!1,this._expandedPaths=new Set,this._showDiff=!1,this._savedYaml="",this._rollbackSnapshot=null,this._confirmRollback=!1,this._gatewayConfig=null,this._gatewayLoading=!1,this._gatewayError="",this._historyEntries=[],this._historyLoading=!1,this._historyError="",this._selectedSha=null,this._diffText="",this._diffLoading=!1,this._confirmRollbackSha=null,this._gcRunning=!1,this._historyReloadTimer=null,this._yamlDebounceTimer=null,this._rpcStatusUnsub=null,this._dataLoaded=!1,this._configPatchedHandler=null}connectedCallback(){super.connectedCallback(),this._configPatchedHandler=()=>{this._dataLoaded&&!this._dirty&&this._tryLoad(),this._activeTab==="history"&&this._scheduleHistoryReload()},document.addEventListener("config:patched",this._configPatchedHandler)}_scheduleHistoryReload(){this._historyReloadTimer!==null&&clearTimeout(this._historyReloadTimer),this._historyReloadTimer=setTimeout(()=>{this._historyReloadTimer=null,this._loadHistory()},300)}disconnectedCallback(){super.disconnectedCallback(),this._yamlDebounceTimer!==null&&clearTimeout(this._yamlDebounceTimer),this._historyReloadTimer!==null&&clearTimeout(this._historyReloadTimer),this._rpcStatusUnsub?.(),this._rpcStatusUnsub=null,this._configPatchedHandler&&(document.removeEventListener("config:patched",this._configPatchedHandler),this._configPatchedHandler=null)}updated(e){e.has("rpcClient")&&this.rpcClient&&this._tryLoad()}_tryLoad(){this.rpcClient&&(this._rpcStatusUnsub?.(),this.rpcClient.status==="connected"?this._loadData():this._rpcStatusUnsub=this.rpcClient.onStatusChange(e=>{e==="connected"&&!this._dataLoaded&&this._loadData()}))}async _loadData(){if(this.rpcClient){this._loadState="loading",this._error="";try{const e=await this.rpcClient.call("config.read");this._sections=e.sections,this._configData=e.config,this._sections.length>0&&!this._selectedSection&&(this._selectedSection=this._sections[0],this._loadSectionState()),this._loadState="loaded",this._dataLoaded=!0,this.rpcClient.call("config.schema").then(t=>{const r=t.schema;this._schemaData=r.properties??r}).catch(()=>{})}catch(e){this._error=e instanceof Error?e.message:"Failed to load configuration",this._loadState="error"}}}_loadSectionState(){const e=this._configData[this._selectedSection]??{};this._formState=structuredClone(e),this._yamlText=R(e),this._savedYaml=this._yamlText,this._yamlErrors=[],this._formErrors={},this._dirty=!1,this._showDiff=!1,this._expandedPaths=new Set}_onSectionClick(e){e!==this._selectedSection&&(this._selectedSection=e,this._loadSectionState())}_onModeChange(e){if(e!==this._mode){if(this._mode==="form"&&e==="yaml")this._yamlText=R(this._formState);else if(this._mode==="yaml"&&e==="form"&&this._yamlErrors.length===0){const t=L(this._yamlText);!t.error&&t.data&&typeof t.data=="object"&&(this._formState=t.data)}this._mode=e}}_renderFormMode(){const e=this._schemaData[this._selectedSection]??{};return o`
469
+ <ic-schema-form
470
+ .schema=${e}
471
+ .config=${this._formState}
472
+ .sectionKey=${this._selectedSection}
473
+ @field-change=${t=>{const{path:r,value:i,formState:a}=t.detail;this._formState=a??Y(this._formState,r,i),this._dirty=!0;const s={...this._formErrors};delete s[r],this._formErrors=s}}
474
+ ></ic-schema-form>
475
+ `}_onYamlInput(e){this._yamlText=e.target.value,this._dirty=!0,this._yamlDebounceTimer!==null&&clearTimeout(this._yamlDebounceTimer),this._yamlDebounceTimer=setTimeout(()=>{this._validateYaml()},500)}_validateYaml(){const e=L(this._yamlText);e.error?this._yamlErrors=[e.error]:this._yamlErrors=[]}_renderYamlMode(){return o`
476
+ <div class="yaml-editor">
477
+ <textarea
478
+ class="yaml-textarea"
479
+ .value=${this._yamlText}
480
+ @input=${e=>this._onYamlInput(e)}
481
+ spellcheck="false"
482
+ aria-label="YAML editor"
483
+ ></textarea>
484
+ ${this._yamlErrors.length>0?o`
485
+ <div class="yaml-validation yaml-validation--error">
486
+ ${this._yamlErrors.map(e=>o`<div>${e}</div>`)}
487
+ </div>
488
+ `:o`
489
+ <div class="yaml-validation yaml-validation--valid">
490
+ Valid configuration
491
+ </div>
492
+ `}
493
+ </div>
494
+ `}_toggleSchemaPath(e){const t=new Set(this._expandedPaths);t.has(e)?t.delete(e):t.add(e),this._expandedPaths=t}_renderSchemaTreeNode(e,t,r,i,a){const s=t.type==="object"&&t.properties&&Object.keys(t.properties).length>0,n=this._expandedPaths.has(r),c=[];return a&&c.push("required"),t.minimum!==void 0&&c.push(`min: ${t.minimum}`),t.maximum!==void 0&&c.push(`max: ${t.maximum}`),t.minLength!==void 0&&c.push(`minLen: ${t.minLength}`),t.maxLength!==void 0&&c.push(`maxLen: ${t.maxLength}`),t.enum&&c.push(`enum: [${t.enum.join(", ")}]`),t.pattern&&c.push(`pattern: ${t.pattern}`),t.default!==void 0&&c.push(`default: ${JSON.stringify(t.default)}`),o`
495
+ <div style="padding-left: ${i*1.5}rem">
496
+ <div class="schema-row">
497
+ <span
498
+ class="schema-key"
499
+ @click=${s?()=>this._toggleSchemaPath(r):g}
500
+ >
501
+ ${s?o`<span class="arrow" ?data-expanded=${n}>\u25B6</span>`:g}
502
+ ${e}${a?o`<span class="required-marker">*</span>`:g}
503
+ </span>
504
+ <ic-tag variant="info">${t.type??"any"}</ic-tag>
505
+ ${t.description?o`<span class="schema-desc">${t.description}</span>`:g}
506
+ ${c.length>0?o`<span class="schema-constraints">${c.join(", ")}</span>`:g}
507
+ </div>
508
+ ${s&&n?o`
509
+ <div class="schema-children">
510
+ ${Object.entries(t.properties).map(([l,d])=>this._renderSchemaTreeNode(l,d,`${r}.${l}`,i+1,(t.required??[]).includes(l)))}
511
+ </div>
512
+ `:g}
513
+ </div>
514
+ `}_renderSchemaMode(){const e=this._schemaData[this._selectedSection];if(e&&!e.properties&&e.additionalProperties&&typeof e.additionalProperties=="object"){const r=e.additionalProperties;if(!r.properties)return o`<ic-empty-state icon="config" message="No schema available" description="Schema definition not found for this section."></ic-empty-state>`;const i=r.required??[];return o`
515
+ <div class="schema-tree">
516
+ <div class="schema-note" style="padding:8px 0;opacity:0.7;font-style:italic">Record&lt;string, entry&gt; - each entry has:</div>
517
+ ${Object.entries(r.properties).map(([a,s])=>this._renderSchemaTreeNode(a,s,a,0,i.includes(a)))}
518
+ </div>
519
+ `}if(!e?.properties)return o`<ic-empty-state icon="config" message="No schema available" description="Schema definition not found for this section."></ic-empty-state>`;const t=e.required??[];return o`
520
+ <div class="schema-tree">
521
+ ${Object.entries(e.properties).map(([r,i])=>this._renderSchemaTreeNode(r,i,r,0,t.includes(r)))}
522
+ </div>
523
+ `}async _onApply(){if(!this.rpcClient||!this._dirty)return;this._applying=!0;let e;if(this._mode==="yaml"){const t=L(this._yamlText);if(t.error){y.show(t.error,"error"),this._applying=!1;return}e=t.data}else e=this._formState;this._rollbackSnapshot=structuredClone(this._configData);try{await this.rpcClient.call("config.apply",{section:this._selectedSection,value:e}),y.show("Configuration applied","success"),this._dirty=!1;const t=await this.rpcClient.call("config.read");this._configData=t.config,this._loadSectionState()}catch(t){const r=t instanceof Error?t.message:"Failed to apply configuration";y.show(r,"error"),this._rollbackSnapshot=null}finally{this._applying=!1}}async _onRollback(){if(!(!this.rpcClient||!this._rollbackSnapshot))try{await this.rpcClient.call("config.apply",{config:this._rollbackSnapshot}),y.show("Configuration rolled back","success");const e=await this.rpcClient.call("config.read");this._configData=e.config,this._rollbackSnapshot=null,this._confirmRollback=!1,this._loadSectionState()}catch(e){const t=e instanceof Error?e.message:"Failed to rollback configuration";y.show(t,"error"),this._confirmRollback=!1}}async _loadGatewayConfig(){if(this.rpcClient){this._gatewayLoading=!0,this._gatewayError="";try{const e=await this.rpcClient.call("config.read",{section:"gateway"});this._gatewayConfig=e??{}}catch(e){this._gatewayError=e instanceof Error?e.message:"Failed to load gateway config"}finally{this._gatewayLoading=!1}}}async _patchGateway(e,t){if(this.rpcClient)try{await this.rpcClient.call("config.patch",{section:"gateway",key:e,value:t}),this._gatewayConfig&&(this._gatewayConfig={...this._gatewayConfig,[e]:t}),y.show("Gateway updated","success")}catch(r){const i=r instanceof Error?r.message:"Failed to update gateway";y.show(i,"error")}}_onTabChange(e){this._activeTab=e.detail,e.detail==="gateway"&&this._gatewayConfig===null&&this._loadGatewayConfig(),e.detail==="history"&&this._historyEntries.length===0&&!this._historyLoading&&this._loadHistory()}async _loadHistory(){if(this.rpcClient){this._historyLoading=!0,this._historyError="";try{const e=await this.rpcClient.call("config.history",{limit:50});e.error?(this._historyEntries=[],this._historyError=e.error):this._historyEntries=e.entries}catch(e){this._historyError=e instanceof Error?e.message:"Failed to load history"}finally{this._historyLoading=!1}}}async _loadDiff(e){if(this.rpcClient){this._diffLoading=!0;try{const t=await this.rpcClient.call("config.diff",{sha:e});this._diffText=t.diff}catch(t){this._diffText="";const r=t instanceof Error?t.message:"Failed to load diff";y.show(r,"error")}finally{this._diffLoading=!1}}}_onSelectVersion(e){if(e===this._selectedSha){this._selectedSha=null,this._diffText="";return}this._selectedSha=e,this._loadDiff(e)}async _onHistoryRollback(){if(!(!this.rpcClient||!this._confirmRollbackSha))try{await this.rpcClient.call("config.rollback",{sha:this._confirmRollbackSha}),y.show("Config rolled back. Daemon restarting...","success"),this._confirmRollbackSha=null}catch(e){const t=e instanceof Error?e.message:"Rollback failed";y.show(t,"error"),this._confirmRollbackSha=null}}async _onGc(){if(!(!this.rpcClient||this._gcRunning)){this._gcRunning=!0;try{const t=(await this.rpcClient.call("config.gc")).squashed;y.show(t!=null?`GC complete: ${t} versions squashed`:"GC complete","success"),this._loadHistory()}catch(e){const t=e instanceof Error?e.message:"GC failed";y.show(t,"error")}finally{this._gcRunning=!1}}}_renderDiffLine(e,t){let r="diff-line--context";return e.startsWith("+")?r="diff-line--add":e.startsWith("-")?r="diff-line--remove":e.startsWith("@@")&&(r="diff-line--hunk"),o`<span class=${r}>${e}\n</span>`}_renderHistoryEntry(e,t){const r=e.sha===this._selectedSha,i=t===0,a=e.metadata.user||e.metadata.agent||"system",s=new Date(e.timestamp).toLocaleString();return o`
524
+ <div
525
+ class="history-entry ${r?"history-entry--selected":""}"
526
+ @click=${()=>this._onSelectVersion(e.sha)}
527
+ >
528
+ <div class="history-entry-header">
529
+ <ic-relative-time
530
+ .timestamp=${new Date(e.timestamp).getTime()}
531
+ title=${s}
532
+ ></ic-relative-time>
533
+ <code class="history-sha">${e.sha.slice(0,7)}</code>
534
+ </div>
535
+ <div class="history-entry-summary" title=${e.metadata.summary}>
536
+ ${e.metadata.summary}
537
+ </div>
538
+ <div class="history-entry-meta">
539
+ <ic-tag variant="default">${e.metadata.section}</ic-tag>
540
+ <span class="history-author">${a}</span>
541
+ ${i?g:o`<button
542
+ class="history-rollback-link"
543
+ @click=${n=>{n.stopPropagation(),this._confirmRollbackSha=e.sha}}
544
+ >Rollback</button>`}
545
+ </div>
546
+ </div>
547
+ `}_renderHistoryTab(){return this._historyLoading?o`<div class="state-container"><ic-loading size="lg"></ic-loading></div>`:this._historyError?o`
548
+ <ic-empty-state
549
+ icon="config"
550
+ message="Version history unavailable"
551
+ description=${this._historyError}
552
+ ></ic-empty-state>
553
+ `:this._historyEntries.length===0?o`
554
+ <ic-empty-state
555
+ icon="config"
556
+ message="No version history"
557
+ description="Config changes will appear here after the first edit."
558
+ ></ic-empty-state>
559
+ `:o`
560
+ <div class="history-layout">
561
+ <div class="history-timeline">
562
+ ${this._historyEntries.map((e,t)=>this._renderHistoryEntry(e,t))}
563
+ </div>
564
+
565
+ <div class="history-diff-panel">
566
+ ${this._diffLoading?o`<div class="state-container"><ic-loading size="lg"></ic-loading></div>`:this._selectedSha&&this._diffText?o`<pre class="diff-unified">${this._diffText.split(`
567
+ `).map((e,t)=>this._renderDiffLine(e,t))}</pre>`:this._selectedSha&&!this._diffText?o`<ic-empty-state icon="config" message="No changes" description="No changes between this version and current."></ic-empty-state>`:o`<ic-empty-state icon="config" message="Select a version" description="Select a version to view changes."></ic-empty-state>`}
568
+ </div>
569
+ </div>
570
+
571
+ <div class="history-actions">
572
+ <button
573
+ class="secondary-btn"
574
+ ?disabled=${this._gcRunning}
575
+ @click=${()=>this._onGc()}
576
+ >
577
+ ${this._gcRunning?o`<span class="spinner"></span> Running GC...`:"Run GC"}
578
+ </button>
579
+ </div>
580
+ `}_onExport(){const e=R(this._configData),t=new Blob([e],{type:"text/yaml"}),r=URL.createObjectURL(t),i=document.createElement("a");i.href=r,i.download="comis-config.yaml",i.click(),URL.revokeObjectURL(r)}_onImportClick(){this.shadowRoot?.querySelector(".hidden-input")?.click()}_onImportFile(e){const t=e.target,r=t.files?.[0];if(!r)return;const i=new FileReader;i.onload=()=>{const a=i.result,s=L(a);if(s.error){y.show(`Import failed: ${s.error}`,"error");return}s.data&&typeof s.data=="object"&&!Array.isArray(s.data)?(this._configData=s.data,this._loadSectionState(),this._dirty=!0,y.show("Configuration imported","info")):y.show("Import failed: expected a YAML object","error")},i.readAsText(r),t.value=""}_renderModeContent(){switch(this._mode){case"form":return this._renderFormMode();case"yaml":return this._renderYamlMode();case"schema":return this._renderSchemaMode();default:return g}}_renderEditorTab(){return this._loadState==="loading"?o`<ic-skeleton-view variant="editor"></ic-skeleton-view>`:this._loadState==="error"?o`
581
+ <div class="error-container">
582
+ <span class="error-message">${this._error}</span>
583
+ <button class="retry-btn" @click=${()=>this._tryLoad()}>Retry</button>
584
+ </div>
585
+ `:o`
586
+ <div class="editor-layout">
587
+ <nav class="section-sidebar" role="navigation" aria-label="Config sections">
588
+ ${this._sections.map(e=>o`
589
+ <div
590
+ class="section-item"
591
+ ?data-selected=${e===this._selectedSection}
592
+ @click=${()=>this._onSectionClick(e)}
593
+ >
594
+ ${e.charAt(0).toUpperCase()+e.slice(1)}
595
+ </div>
596
+ `)}
597
+ </nav>
598
+
599
+ <div class="content-area" role="main">
600
+ <div class="toolbar">
601
+ <div class="mode-tabs">
602
+ <button
603
+ class="mode-btn"
604
+ ?data-active=${this._mode==="form"}
605
+ @click=${()=>this._onModeChange("form")}
606
+ >Form</button>
607
+ <button
608
+ class="mode-btn"
609
+ ?data-active=${this._mode==="yaml"}
610
+ @click=${()=>this._onModeChange("yaml")}
611
+ >YAML</button>
612
+ <button
613
+ class="mode-btn"
614
+ ?data-active=${this._mode==="schema"}
615
+ @click=${()=>this._onModeChange("schema")}
616
+ >Schema</button>
617
+ </div>
618
+
619
+ <div class="action-buttons">
620
+ <button
621
+ class="diff-btn"
622
+ ?data-active=${this._showDiff}
623
+ @click=${()=>{this._showDiff=!this._showDiff}}
624
+ >Show Diff</button>
625
+ ${this._rollbackSnapshot!==null?o`<button
626
+ class="rollback-btn"
627
+ @click=${()=>{this._confirmRollback=!0}}
628
+ >Rollback</button>`:g}
629
+ <button
630
+ class="secondary-btn"
631
+ @click=${()=>this._onImportClick()}
632
+ >Import</button>
633
+ <button
634
+ class="secondary-btn"
635
+ @click=${()=>this._onExport()}
636
+ >Export</button>
637
+ <button
638
+ class="apply-btn"
639
+ ?disabled=${!this._dirty||this._applying}
640
+ @click=${()=>this._onApply()}
641
+ >
642
+ ${this._applying?o`<span class="spinner"></span>`:g}
643
+ Apply Changes
644
+ </button>
645
+ </div>
646
+ </div>
647
+
648
+ ${this._renderModeContent()}
649
+
650
+ ${this._showDiff?o`
651
+ <div class="diff-preview">
652
+ <ic-diff-viewer
653
+ .oldText=${this._savedYaml}
654
+ .newText=${this._mode==="yaml"?this._yamlText:R(this._formState)}
655
+ oldLabel="Current"
656
+ newLabel="Pending Changes"
657
+ ></ic-diff-viewer>
658
+ </div>
659
+ `:g}
660
+ </div>
661
+ </div>
662
+
663
+ <input
664
+ class="hidden-input"
665
+ type="file"
666
+ accept=".yaml,.yml"
667
+ @change=${e=>this._onImportFile(e)}
668
+ />
669
+
670
+ <ic-confirm-dialog
671
+ .open=${this._confirmRollback}
672
+ title="Rollback Configuration"
673
+ message="Restore previous configuration? This will revert all sections to the state before your last apply."
674
+ confirmLabel="Rollback"
675
+ @confirm=${()=>this._onRollback()}
676
+ @cancel=${()=>{this._confirmRollback=!1}}
677
+ ></ic-confirm-dialog>
678
+ `}_renderGatewayTab(){if(this._gatewayLoading)return o`<div class="state-container"><ic-loading size="lg"></ic-loading></div>`;if(this._gatewayError)return o`
679
+ <div class="error-container">
680
+ <span class="error-message">${this._gatewayError}</span>
681
+ <button class="retry-btn" @click=${()=>this._loadGatewayConfig()}>Retry</button>
682
+ </div>
683
+ `;if(!this._gatewayConfig)return o`<ic-empty-state icon="config" message="No gateway configuration" description="Gateway config not available."></ic-empty-state>`;const e=this._gatewayConfig,t=e.cors?.origins??[],r=e.tokens??[];return o`
684
+ <div class="gateway-form">
685
+ <div class="gateway-field">
686
+ <ic-toggle
687
+ label="Gateway Enabled"
688
+ .checked=${e.enabled??!1}
689
+ @change=${i=>this._patchGateway("enabled",i.detail)}
690
+ ></ic-toggle>
691
+ </div>
692
+
693
+ <div class="gateway-field">
694
+ <label class="gateway-label">Host</label>
695
+ <input
696
+ class="gateway-input"
697
+ type="text"
698
+ .value=${e.host??"0.0.0.0"}
699
+ @change=${i=>this._patchGateway("host",i.target.value)}
700
+ />
701
+ </div>
702
+
703
+ <div class="gateway-field">
704
+ <label class="gateway-label">Port</label>
705
+ <input
706
+ class="gateway-input"
707
+ type="number"
708
+ .value=${String(e.port??3e3)}
709
+ @change=${i=>{const a=parseInt(i.target.value,10);isNaN(a)||this._patchGateway("port",a)}}
710
+ />
711
+ </div>
712
+
713
+ <div class="gateway-field">
714
+ <ic-array-editor
715
+ label="CORS Origins"
716
+ .items=${t.map(String)}
717
+ placeholder="https://example.com"
718
+ @change=${i=>this._patchGateway("cors",{...e.cors,origins:i.detail})}
719
+ ></ic-array-editor>
720
+ </div>
721
+
722
+ <div class="gateway-tokens">
723
+ <div class="gateway-tokens-label">API Tokens (${r.length})</div>
724
+ ${r.length>0?o`
725
+ <div class="gateway-tokens-list">
726
+ ${r.map(i=>o`
727
+ <div class="gateway-token-entry">
728
+ <span class="gateway-token-id">${i.id}</span>
729
+ ${i.scopes&&i.scopes.length>0?i.scopes.map(a=>o`<ic-tag variant="info">${a}</ic-tag>`):o`<ic-tag variant="default">no scopes</ic-tag>`}
730
+ </div>
731
+ `)}
732
+ </div>
733
+ `:o`<div style="font-size:var(--ic-text-sm);color:var(--ic-text-dim)">No tokens configured</div>`}
734
+ <a class="gateway-tokens-link" href="#security">Manage tokens in Security &rarr;</a>
735
+ </div>
736
+ </div>
737
+ `}_renderWizardTab(){return o`
738
+ <div class="wizard-content">
739
+ <div class="wizard-description">
740
+ The setup wizard guides you through initial Comis configuration
741
+ including provider keys, agent creation, channel setup, and
742
+ security settings.
743
+ </div>
744
+ <button
745
+ class="wizard-btn"
746
+ @click=${()=>{window.location.hash="#setup"}}
747
+ >Launch Setup Wizard</button>
748
+ </div>
749
+ `}render(){return o`
750
+ <div class="view-header">
751
+ <div class="view-title">Settings</div>
752
+ </div>
753
+
754
+ <ic-tabs
755
+ .tabs=${ee}
756
+ .activeTab=${this._activeTab}
757
+ @tab-change=${this._onTabChange}
758
+ >
759
+ <div slot="editor">${this._renderEditorTab()}</div>
760
+ <div slot="gateway">${this._renderGatewayTab()}</div>
761
+ <div slot="history">${this._renderHistoryTab()}</div>
762
+ <div slot="wizard">${this._renderWizardTab()}</div>
763
+ </ic-tabs>
764
+
765
+ <ic-confirm-dialog
766
+ .open=${this._confirmRollbackSha!==null}
767
+ title="Rollback Configuration"
768
+ message="Restore config to this version? The daemon will restart to apply changes."
769
+ variant="danger"
770
+ confirmLabel="Rollback"
771
+ @confirm=${()=>this._onHistoryRollback()}
772
+ @cancel=${()=>{this._confirmRollbackSha=null}}
773
+ ></ic-confirm-dialog>
774
+ `}};f.styles=[N,P,I`
775
+ :host {
776
+ display: block;
777
+ }
778
+
779
+ .view-header {
780
+ margin-bottom: var(--ic-space-lg);
781
+ }
782
+
783
+ .view-title {
784
+ font-size: 1.125rem;
785
+ font-weight: 600;
786
+ }
787
+
788
+ /* Loading & error states */
789
+ .state-container {
790
+ display: flex;
791
+ align-items: center;
792
+ justify-content: center;
793
+ padding: 3rem;
794
+ }
795
+
796
+ .error-container {
797
+ display: flex;
798
+ flex-direction: column;
799
+ align-items: center;
800
+ gap: 0.75rem;
801
+ padding: 3rem;
802
+ }
803
+
804
+ .error-message {
805
+ color: var(--ic-error);
806
+ font-size: var(--ic-text-sm);
807
+ }
808
+
809
+ .retry-btn {
810
+ padding: 0.5rem 1rem;
811
+ background: var(--ic-surface-2);
812
+ border: 1px solid var(--ic-border);
813
+ border-radius: var(--ic-radius-md);
814
+ color: var(--ic-text-muted);
815
+ font-size: var(--ic-text-sm);
816
+ cursor: pointer;
817
+ font-family: inherit;
818
+ }
819
+
820
+ .retry-btn:hover {
821
+ background: var(--ic-border);
822
+ }
823
+
824
+ /* Main layout: sidebar + content */
825
+ .editor-layout {
826
+ display: grid;
827
+ grid-template-columns: 220px 1fr;
828
+ gap: var(--ic-space-lg);
829
+ min-height: 500px;
830
+ }
831
+
832
+ /* Section sidebar */
833
+ .section-sidebar {
834
+ display: flex;
835
+ flex-direction: column;
836
+ gap: 2px;
837
+ background: var(--ic-surface);
838
+ border: 1px solid var(--ic-border);
839
+ border-radius: var(--ic-radius-md);
840
+ padding: var(--ic-space-xs);
841
+ overflow-y: auto;
842
+ max-height: 80vh;
843
+ }
844
+
845
+ .section-item {
846
+ padding: 0.5rem 1rem;
847
+ cursor: pointer;
848
+ border-left: 3px solid transparent;
849
+ border-radius: var(--ic-radius-sm);
850
+ font-size: var(--ic-text-sm);
851
+ color: var(--ic-text-muted);
852
+ transition: background var(--ic-transition, 0.15s), color var(--ic-transition, 0.15s);
853
+ }
854
+
855
+ .section-item:hover {
856
+ background: var(--ic-surface-2);
857
+ color: var(--ic-text);
858
+ }
859
+
860
+ .section-item[data-selected] {
861
+ border-left-color: var(--ic-accent);
862
+ background: var(--ic-surface-2);
863
+ color: var(--ic-text);
864
+ font-weight: 500;
865
+ }
866
+
867
+ /* Content area */
868
+ .content-area {
869
+ display: flex;
870
+ flex-direction: column;
871
+ gap: var(--ic-space-md);
872
+ min-width: 0;
873
+ }
874
+
875
+ /* Toolbar: mode tabs + action buttons */
876
+ .toolbar {
877
+ display: flex;
878
+ align-items: center;
879
+ justify-content: space-between;
880
+ gap: var(--ic-space-md);
881
+ flex-wrap: wrap;
882
+ }
883
+
884
+ .mode-tabs {
885
+ display: inline-flex;
886
+ gap: 2px;
887
+ background: var(--ic-surface);
888
+ border: 1px solid var(--ic-border);
889
+ border-radius: var(--ic-radius-md);
890
+ padding: 2px;
891
+ }
892
+
893
+ .mode-btn {
894
+ padding: 0.375rem 0.75rem;
895
+ border: none;
896
+ border-radius: var(--ic-radius-sm);
897
+ background: transparent;
898
+ color: var(--ic-text-muted);
899
+ font-size: var(--ic-text-sm);
900
+ font-family: inherit;
901
+ cursor: pointer;
902
+ transition: background var(--ic-transition, 0.15s), color var(--ic-transition, 0.15s);
903
+ }
904
+
905
+ .mode-btn:hover {
906
+ color: var(--ic-text);
907
+ }
908
+
909
+ .mode-btn[data-active] {
910
+ background: var(--ic-accent);
911
+ color: white;
912
+ }
913
+
914
+ .action-buttons {
915
+ display: flex;
916
+ align-items: center;
917
+ gap: var(--ic-space-sm);
918
+ }
919
+
920
+ .apply-btn {
921
+ padding: 0.5rem 1rem;
922
+ background: var(--ic-accent);
923
+ color: white;
924
+ border: none;
925
+ border-radius: var(--ic-radius-md);
926
+ font-size: var(--ic-text-sm);
927
+ font-family: inherit;
928
+ cursor: pointer;
929
+ display: inline-flex;
930
+ align-items: center;
931
+ gap: var(--ic-space-xs);
932
+ }
933
+
934
+ .apply-btn:hover {
935
+ opacity: 0.9;
936
+ }
937
+
938
+ .apply-btn:disabled {
939
+ opacity: 0.5;
940
+ cursor: not-allowed;
941
+ }
942
+
943
+ .secondary-btn {
944
+ padding: 0.5rem 1rem;
945
+ background: var(--ic-surface-2);
946
+ border: 1px solid var(--ic-border);
947
+ border-radius: var(--ic-radius-md);
948
+ color: var(--ic-text-muted);
949
+ font-size: var(--ic-text-sm);
950
+ font-family: inherit;
951
+ cursor: pointer;
952
+ }
953
+
954
+ .secondary-btn:hover {
955
+ background: var(--ic-border);
956
+ }
957
+
958
+ /* Form mode CSS extracted to ic-schema-form sub-component */
959
+
960
+ /* YAML mode */
961
+ .yaml-editor {
962
+ display: flex;
963
+ flex-direction: column;
964
+ gap: var(--ic-space-sm);
965
+ }
966
+
967
+ .yaml-textarea {
968
+ width: 100%;
969
+ min-height: 400px;
970
+ padding: 1rem;
971
+ background: var(--ic-surface-2);
972
+ border: 1px solid var(--ic-border);
973
+ border-radius: var(--ic-radius-md);
974
+ color: var(--ic-text);
975
+ font-family: var(--ic-font-mono, ui-monospace, monospace);
976
+ font-size: var(--ic-text-sm);
977
+ line-height: 1.5;
978
+ tab-size: 2;
979
+ white-space: pre;
980
+ resize: vertical;
981
+ }
982
+
983
+ .yaml-textarea:focus {
984
+ outline: none;
985
+ border-color: var(--ic-accent);
986
+ }
987
+
988
+ .yaml-validation {
989
+ padding: var(--ic-space-sm) var(--ic-space-md);
990
+ border-radius: var(--ic-radius-md);
991
+ font-size: var(--ic-text-sm);
992
+ }
993
+
994
+ .yaml-validation--valid {
995
+ background: color-mix(in srgb, var(--ic-success) 10%, transparent);
996
+ color: var(--ic-success);
997
+ border: 1px solid color-mix(in srgb, var(--ic-success) 30%, transparent);
998
+ }
999
+
1000
+ .yaml-validation--error {
1001
+ background: color-mix(in srgb, var(--ic-error) 10%, transparent);
1002
+ color: var(--ic-error);
1003
+ border: 1px solid color-mix(in srgb, var(--ic-error) 30%, transparent);
1004
+ }
1005
+
1006
+ /* Schema mode */
1007
+ .schema-tree {
1008
+ display: flex;
1009
+ flex-direction: column;
1010
+ gap: 2px;
1011
+ }
1012
+
1013
+ .schema-row {
1014
+ display: flex;
1015
+ align-items: baseline;
1016
+ gap: var(--ic-space-sm);
1017
+ padding: var(--ic-space-xs) 0;
1018
+ }
1019
+
1020
+ .schema-key {
1021
+ font-weight: 600;
1022
+ font-size: var(--ic-text-sm);
1023
+ color: var(--ic-text);
1024
+ cursor: pointer;
1025
+ display: flex;
1026
+ align-items: center;
1027
+ gap: var(--ic-space-xs);
1028
+ user-select: none;
1029
+ }
1030
+
1031
+ .schema-key .arrow {
1032
+ font-size: var(--ic-text-xs);
1033
+ transition: transform var(--ic-transition, 0.15s);
1034
+ display: inline-block;
1035
+ }
1036
+
1037
+ .schema-key .arrow[data-expanded] {
1038
+ transform: rotate(90deg);
1039
+ }
1040
+
1041
+ .schema-desc {
1042
+ font-size: var(--ic-text-xs);
1043
+ color: var(--ic-text-dim);
1044
+ }
1045
+
1046
+ .schema-constraints {
1047
+ font-size: var(--ic-text-xs);
1048
+ color: var(--ic-text-muted);
1049
+ font-style: italic;
1050
+ }
1051
+
1052
+ .schema-children {
1053
+ padding-left: 1.5rem;
1054
+ }
1055
+
1056
+ .required-marker {
1057
+ color: var(--ic-error);
1058
+ font-weight: 600;
1059
+ }
1060
+
1061
+ /* Hidden file input for import */
1062
+ .hidden-input {
1063
+ display: none;
1064
+ }
1065
+
1066
+ /* Spinner */
1067
+ .spinner {
1068
+ display: inline-block;
1069
+ width: 14px;
1070
+ height: 14px;
1071
+ border: 2px solid rgba(255, 255, 255, 0.3);
1072
+ border-top-color: white;
1073
+ border-radius: 50%;
1074
+ animation: spin 0.6s linear infinite;
1075
+ }
1076
+
1077
+ @keyframes spin {
1078
+ to { transform: rotate(360deg); }
1079
+ }
1080
+
1081
+ /* Diff preview toggle */
1082
+ .diff-btn {
1083
+ padding: 0.5rem 1rem;
1084
+ background: var(--ic-surface-2);
1085
+ border: 1px solid var(--ic-border);
1086
+ border-radius: var(--ic-radius-md);
1087
+ color: var(--ic-text-muted);
1088
+ font-size: var(--ic-text-sm);
1089
+ font-family: inherit;
1090
+ cursor: pointer;
1091
+ }
1092
+
1093
+ .diff-btn:hover {
1094
+ background: var(--ic-border);
1095
+ }
1096
+
1097
+ .diff-btn[data-active] {
1098
+ background: var(--ic-accent);
1099
+ color: #fff;
1100
+ border-color: var(--ic-accent);
1101
+ }
1102
+
1103
+ /* Rollback button */
1104
+ .rollback-btn {
1105
+ padding: 0.5rem 1rem;
1106
+ background: var(--ic-surface-2);
1107
+ border: 1px solid var(--ic-border);
1108
+ border-radius: var(--ic-radius-md);
1109
+ color: var(--ic-text-muted);
1110
+ font-size: var(--ic-text-sm);
1111
+ font-family: inherit;
1112
+ cursor: pointer;
1113
+ }
1114
+
1115
+ .rollback-btn:hover {
1116
+ border-color: var(--ic-error);
1117
+ color: var(--ic-error);
1118
+ }
1119
+
1120
+ /* Diff viewer container */
1121
+ .diff-preview {
1122
+ margin-top: var(--ic-space-md);
1123
+ }
1124
+
1125
+ /* Gateway tab */
1126
+ .gateway-form {
1127
+ display: flex;
1128
+ flex-direction: column;
1129
+ gap: var(--ic-space-lg);
1130
+ max-width: 36rem;
1131
+ padding: var(--ic-space-md) 0;
1132
+ }
1133
+
1134
+ .gateway-field {
1135
+ display: flex;
1136
+ flex-direction: column;
1137
+ gap: var(--ic-space-xs);
1138
+ }
1139
+
1140
+ .gateway-label {
1141
+ font-size: var(--ic-text-sm);
1142
+ font-weight: 500;
1143
+ color: var(--ic-text-muted);
1144
+ }
1145
+
1146
+ .gateway-input {
1147
+ padding: 0.5rem 0.75rem;
1148
+ background: var(--ic-surface-2);
1149
+ border: 1px solid var(--ic-border);
1150
+ border-radius: var(--ic-radius-md);
1151
+ color: var(--ic-text);
1152
+ font-family: inherit;
1153
+ font-size: var(--ic-text-sm);
1154
+ }
1155
+
1156
+ .gateway-input:focus {
1157
+ outline: none;
1158
+ border-color: var(--ic-accent);
1159
+ }
1160
+
1161
+ .gateway-tokens {
1162
+ padding: var(--ic-space-md);
1163
+ background: var(--ic-surface-2);
1164
+ border: 1px solid var(--ic-border);
1165
+ border-radius: var(--ic-radius-md);
1166
+ }
1167
+
1168
+ .gateway-tokens-label {
1169
+ font-size: var(--ic-text-sm);
1170
+ font-weight: 600;
1171
+ color: var(--ic-text);
1172
+ margin-bottom: var(--ic-space-sm);
1173
+ }
1174
+
1175
+ .gateway-tokens-list {
1176
+ display: flex;
1177
+ flex-direction: column;
1178
+ gap: var(--ic-space-xs);
1179
+ font-size: var(--ic-text-sm);
1180
+ color: var(--ic-text-muted);
1181
+ }
1182
+
1183
+ .gateway-token-entry {
1184
+ display: flex;
1185
+ align-items: center;
1186
+ gap: var(--ic-space-sm);
1187
+ }
1188
+
1189
+ .gateway-token-id {
1190
+ font-family: var(--ic-font-mono, ui-monospace, monospace);
1191
+ font-size: var(--ic-text-xs);
1192
+ }
1193
+
1194
+ .gateway-tokens-link {
1195
+ color: var(--ic-accent);
1196
+ font-size: var(--ic-text-sm);
1197
+ text-decoration: none;
1198
+ margin-top: var(--ic-space-sm);
1199
+ display: inline-block;
1200
+ cursor: pointer;
1201
+ }
1202
+
1203
+ .gateway-tokens-link:hover {
1204
+ text-decoration: underline;
1205
+ }
1206
+
1207
+ /* Setup wizard tab */
1208
+ .wizard-content {
1209
+ display: flex;
1210
+ flex-direction: column;
1211
+ align-items: center;
1212
+ gap: var(--ic-space-lg);
1213
+ padding: 3rem var(--ic-space-lg);
1214
+ text-align: center;
1215
+ }
1216
+
1217
+ .wizard-description {
1218
+ font-size: var(--ic-text-sm);
1219
+ color: var(--ic-text-muted);
1220
+ max-width: 32rem;
1221
+ line-height: 1.6;
1222
+ }
1223
+
1224
+ .wizard-btn {
1225
+ padding: 0.75rem 2rem;
1226
+ background: var(--ic-accent);
1227
+ color: #fff;
1228
+ border: none;
1229
+ border-radius: var(--ic-radius-md);
1230
+ font-size: var(--ic-text-sm);
1231
+ font-family: inherit;
1232
+ font-weight: 500;
1233
+ cursor: pointer;
1234
+ }
1235
+
1236
+ .wizard-btn:hover {
1237
+ filter: brightness(1.1);
1238
+ }
1239
+
1240
+ /* History tab */
1241
+ .history-layout {
1242
+ display: grid;
1243
+ grid-template-columns: 350px 1fr;
1244
+ gap: var(--ic-space-md);
1245
+ min-height: 400px;
1246
+ }
1247
+
1248
+ @media (max-width: 768px) {
1249
+ .history-layout {
1250
+ grid-template-columns: 1fr;
1251
+ }
1252
+ }
1253
+
1254
+ .history-timeline {
1255
+ overflow-y: auto;
1256
+ max-height: 70vh;
1257
+ border: 1px solid var(--ic-border);
1258
+ border-radius: var(--ic-radius-md);
1259
+ background: var(--ic-surface);
1260
+ }
1261
+
1262
+ .history-entry {
1263
+ padding: var(--ic-space-sm) var(--ic-space-md);
1264
+ border-bottom: 1px solid var(--ic-border);
1265
+ cursor: pointer;
1266
+ transition: background var(--ic-transition, 0.15s);
1267
+ border-left: 3px solid transparent;
1268
+ position: relative;
1269
+ }
1270
+
1271
+ .history-entry:hover {
1272
+ background: var(--ic-surface-2);
1273
+ }
1274
+
1275
+ .history-entry--selected {
1276
+ border-left: 3px solid var(--ic-accent);
1277
+ background: var(--ic-surface-2);
1278
+ }
1279
+
1280
+ .history-entry-header {
1281
+ display: flex;
1282
+ justify-content: space-between;
1283
+ align-items: center;
1284
+ margin-bottom: 2px;
1285
+ }
1286
+
1287
+ .history-sha {
1288
+ font-family: var(--ic-font-mono, ui-monospace, monospace);
1289
+ font-size: var(--ic-text-xs);
1290
+ color: var(--ic-text-dim);
1291
+ }
1292
+
1293
+ .history-entry-summary {
1294
+ font-size: var(--ic-text-sm);
1295
+ white-space: nowrap;
1296
+ overflow: hidden;
1297
+ text-overflow: ellipsis;
1298
+ color: var(--ic-text);
1299
+ margin-bottom: 4px;
1300
+ }
1301
+
1302
+ .history-entry-meta {
1303
+ display: flex;
1304
+ align-items: center;
1305
+ gap: 8px;
1306
+ font-size: var(--ic-text-xs);
1307
+ color: var(--ic-text-dim);
1308
+ }
1309
+
1310
+ .history-author {
1311
+ font-size: var(--ic-text-xs);
1312
+ color: var(--ic-text-dim);
1313
+ }
1314
+
1315
+ .history-diff-panel {
1316
+ display: flex;
1317
+ flex-direction: column;
1318
+ overflow: auto;
1319
+ }
1320
+
1321
+ .diff-unified {
1322
+ font-family: var(--ic-font-mono, ui-monospace, monospace);
1323
+ font-size: var(--ic-text-sm);
1324
+ overflow-x: auto;
1325
+ white-space: pre;
1326
+ padding: var(--ic-space-md);
1327
+ background: var(--ic-surface);
1328
+ border-radius: var(--ic-radius-md);
1329
+ border: 1px solid var(--ic-border);
1330
+ margin: 0;
1331
+ line-height: 1.5;
1332
+ }
1333
+
1334
+ .diff-line--add {
1335
+ background: rgba(34, 197, 94, 0.15);
1336
+ display: block;
1337
+ }
1338
+
1339
+ .diff-line--remove {
1340
+ background: rgba(239, 68, 68, 0.15);
1341
+ display: block;
1342
+ }
1343
+
1344
+ .diff-line--hunk {
1345
+ color: var(--ic-text-dim);
1346
+ font-style: italic;
1347
+ display: block;
1348
+ }
1349
+
1350
+ .diff-line--context {
1351
+ display: block;
1352
+ }
1353
+
1354
+ .history-actions {
1355
+ display: flex;
1356
+ align-items: center;
1357
+ gap: var(--ic-space-sm);
1358
+ padding-top: var(--ic-space-md);
1359
+ }
1360
+
1361
+ .history-rollback-link {
1362
+ font-size: var(--ic-text-xs);
1363
+ color: var(--ic-accent);
1364
+ cursor: pointer;
1365
+ background: none;
1366
+ border: none;
1367
+ font-family: inherit;
1368
+ padding: 0;
1369
+ }
1370
+
1371
+ .history-rollback-link:hover {
1372
+ text-decoration: underline;
1373
+ }
1374
+ `];h([x({attribute:!1})],f.prototype,"rpcClient",2);h([p()],f.prototype,"_activeTab",2);h([p()],f.prototype,"_loadState",2);h([p()],f.prototype,"_error",2);h([p()],f.prototype,"_sections",2);h([p()],f.prototype,"_selectedSection",2);h([p()],f.prototype,"_mode",2);h([p()],f.prototype,"_configData",2);h([p()],f.prototype,"_schemaData",2);h([p()],f.prototype,"_yamlText",2);h([p()],f.prototype,"_yamlErrors",2);h([p()],f.prototype,"_formState",2);h([p()],f.prototype,"_formErrors",2);h([p()],f.prototype,"_dirty",2);h([p()],f.prototype,"_applying",2);h([p()],f.prototype,"_expandedPaths",2);h([p()],f.prototype,"_showDiff",2);h([p()],f.prototype,"_savedYaml",2);h([p()],f.prototype,"_rollbackSnapshot",2);h([p()],f.prototype,"_confirmRollback",2);h([p()],f.prototype,"_gatewayConfig",2);h([p()],f.prototype,"_gatewayLoading",2);h([p()],f.prototype,"_gatewayError",2);h([p()],f.prototype,"_historyEntries",2);h([p()],f.prototype,"_historyLoading",2);h([p()],f.prototype,"_historyError",2);h([p()],f.prototype,"_selectedSha",2);h([p()],f.prototype,"_diffText",2);h([p()],f.prototype,"_diffLoading",2);h([p()],f.prototype,"_confirmRollbackSha",2);h([p()],f.prototype,"_gcRunning",2);f=h([M("ic-config-editor")],f);export{f as IcConfigEditor,L as parseYaml,$ as serializeToYaml};