comisai 1.0.24 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/dist/bootstrap.js +5 -0
- package/node_modules/@comis/core/dist/config/env-layer.d.ts +31 -0
- package/node_modules/@comis/core/dist/config/env-layer.js +41 -0
- package/node_modules/@comis/core/dist/config/layered.d.ts +9 -0
- package/node_modules/@comis/core/dist/config/layered.js +11 -0
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/dist/daemon.js +3 -0
- package/node_modules/@comis/daemon/package.json +1 -1
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/package.json +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-detail-BG9MGWWj.js → agent-detail-ru-AhppM.js} +270 -270
- package/node_modules/@comis/web/dist/assets/agent-editor-hjwRuFVp.js +2173 -0
- package/node_modules/@comis/web/dist/assets/{agent-list-LHCJ4rw2.js → agent-list-6Uotjatr.js} +170 -170
- package/node_modules/@comis/web/dist/assets/{approvals-q9VH_IKr.js → approvals-C-K6hN2U.js} +13 -13
- package/node_modules/@comis/web/dist/assets/billing-view-CxysXH0p.js +375 -0
- package/node_modules/@comis/web/dist/assets/{channel-detail-CaInesJM.js → channel-detail-BBCKtmne.js} +265 -265
- package/node_modules/@comis/web/dist/assets/channel-list-FkfeOLBQ.js +323 -0
- package/node_modules/@comis/web/dist/assets/{chat-console-CNmzl0JW.js → chat-console-BumBaIgO.js} +243 -246
- package/node_modules/@comis/web/dist/assets/{config-editor-DX4ITw6y.js → config-editor-C9BSwHGy.js} +477 -477
- package/node_modules/@comis/web/dist/assets/{context-dag-browser-BwiaF5tf.js → context-dag-browser-BHm00mJD.js} +105 -105
- package/node_modules/@comis/web/dist/assets/{context-engine-BZ5Am6hA.js → context-engine-BENY3pWE.js} +136 -136
- package/node_modules/@comis/web/dist/assets/decorate-BvWYovGE.js +38 -0
- package/node_modules/@comis/web/dist/assets/{delivery-view-OfBZof-m.js → delivery-view-BCnkPsAp.js} +134 -134
- package/node_modules/@comis/web/dist/assets/{diagnostics-view-YFwCxgr2.js → diagnostics-view-C_jQFG2H.js} +82 -82
- package/node_modules/@comis/web/dist/assets/directive-BOYXJ-K-.js +1 -0
- package/node_modules/@comis/web/dist/assets/{extract-variables-BM5qyK-s.js → extract-variables-B7-Doo7l.js} +39 -39
- package/node_modules/@comis/web/dist/assets/{ic-array-editor-B7m6x7-S.js → ic-array-editor-BLoEyeLS.js} +29 -29
- package/node_modules/@comis/web/dist/assets/{ic-breadcrumb-CUMpp3BL.js → ic-breadcrumb-DqN6G3gc.js} +16 -16
- package/node_modules/@comis/web/dist/assets/{ic-budget-segment-bar-BtJ6x5mN.js → ic-budget-segment-bar-zLsMzjDO.js} +20 -20
- package/node_modules/@comis/web/dist/assets/ic-chat-message-FdQcZsSQ.js +352 -0
- package/node_modules/@comis/web/dist/assets/{ic-confirm-dialog-CCDbB04e.js → ic-confirm-dialog-DGlPbV1T.js} +26 -26
- package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CnT1b8xr.js → ic-connection-dot-BgYiK2N4.js} +13 -13
- package/node_modules/@comis/web/dist/assets/ic-data-table-CKIvr-ag.js +277 -0
- package/node_modules/@comis/web/dist/assets/ic-delivery-row-B3YwjjuM.js +67 -0
- package/node_modules/@comis/web/dist/assets/{ic-detail-panel-BF83r-if.js → ic-detail-panel-DiCe4hLr.js} +27 -27
- package/node_modules/@comis/web/dist/assets/{ic-empty-state-60l2ePhd.js → ic-empty-state-CM3Wbj2f.js} +19 -19
- package/node_modules/@comis/web/dist/assets/ic-graph-canvas-ByRjij68.js +359 -0
- package/node_modules/@comis/web/dist/assets/ic-icon-BGNCCPpZ.js +33 -0
- package/node_modules/@comis/web/dist/assets/{ic-layer-waterfall-COvEYMg5.js → ic-layer-waterfall-WkaFyu-l.js} +18 -18
- package/node_modules/@comis/web/dist/assets/ic-relative-time-B3UAnTqg.js +12 -0
- package/node_modules/@comis/web/dist/assets/{ic-search-input-CSOxY9g7.js → ic-search-input-B02AGw1i.js} +22 -22
- package/node_modules/@comis/web/dist/assets/{ic-select-Ce-Raudx.js → ic-select-BqfZISjw.js} +29 -29
- package/node_modules/@comis/web/dist/assets/ic-tabs-yBjkWKJH.js +95 -0
- package/node_modules/@comis/web/dist/assets/ic-tag-CvMVQFRR.js +33 -0
- package/node_modules/@comis/web/dist/assets/{ic-time-range-picker-CypCT68y.js → ic-time-range-picker-DXbYeBmY.js} +31 -31
- package/node_modules/@comis/web/dist/assets/{ic-tool-call-7MaXSsCW.js → ic-tool-call-DMPHsLyx.js} +51 -51
- package/node_modules/@comis/web/dist/assets/index-CVEaS9aY.css +2 -0
- package/node_modules/@comis/web/dist/assets/index-FLPhHz8p.js +2792 -0
- package/node_modules/@comis/web/dist/assets/{mcp-management-BNZPnpDn.js → mcp-management-5jyScQis.js} +209 -209
- package/node_modules/@comis/web/dist/assets/{media-config-BBvTYxOX.js → media-config-J9oT9PPs.js} +154 -154
- package/node_modules/@comis/web/dist/assets/{media-test-BkK3RCRK.js → media-test-DGTCtM8-.js} +259 -259
- package/node_modules/@comis/web/dist/assets/{memory-inspector-1hDGCGat.js → memory-inspector-D5Re9ptG.js} +450 -450
- package/node_modules/@comis/web/dist/assets/{message-center-CXefwsUu.js → message-center-cRLK6ZmG.js} +290 -290
- package/node_modules/@comis/web/dist/assets/{models-C1qcU_j3.js → models-D5vu07MR.js} +371 -371
- package/node_modules/@comis/web/dist/assets/observability-types-D0tkwElU.js +1 -0
- package/node_modules/@comis/web/dist/assets/{observe-view-C0VBhX4C.js → observe-view-CalNNEmd.js} +399 -399
- package/node_modules/@comis/web/dist/assets/pipeline-builder-DUYDGwZf.js +1495 -0
- package/node_modules/@comis/web/dist/assets/{pipeline-history-DkfOQ6SW.js → pipeline-history-BAO8brOe.js} +124 -124
- package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-hyHgD0ai.js → pipeline-history-detail-DectIoQt.js} +65 -65
- package/node_modules/@comis/web/dist/assets/{pipeline-list-BPW8hV-q.js → pipeline-list-BHlaBKww.js} +227 -227
- package/node_modules/@comis/web/dist/assets/{pipeline-monitor-Bip16T7e.js → pipeline-monitor-BhtpNEHf.js} +298 -298
- package/node_modules/@comis/web/dist/assets/{scheduler-BGgwKd06.js → scheduler-VafN_8xi.js} +486 -486
- package/node_modules/@comis/web/dist/assets/{security-D15st4xx.js → security-QQXMRTlo.js} +389 -389
- package/node_modules/@comis/web/dist/assets/{session-detail-SGEYNJ0M.js → session-detail-BpZ_8Yih.js} +294 -294
- package/node_modules/@comis/web/dist/assets/session-key-parser-Dkqcj2Ss.js +1 -0
- package/node_modules/@comis/web/dist/assets/session-list-DfCm8Cec.js +231 -0
- package/node_modules/@comis/web/dist/assets/{setup-wizard-nT0tz9QP.js → setup-wizard-C-z477CG.js} +486 -494
- package/node_modules/@comis/web/dist/assets/{skills-D8yVfSUy.js → skills-BCOGPf6s.js} +329 -329
- package/node_modules/@comis/web/dist/assets/{subagents-HHXMeHYo.js → subagents-l-auUraL.js} +74 -74
- package/node_modules/@comis/web/dist/assets/{workspace-manager-BQlr10iH.js → workspace-manager-DlvBixiq.js} +236 -236
- package/node_modules/@comis/web/dist/index.html +3 -2
- package/node_modules/@comis/web/package.json +1 -1
- package/package.json +15 -15
- package/node_modules/@comis/web/dist/assets/agent-editor-C26Q_xCs.js +0 -2173
- package/node_modules/@comis/web/dist/assets/billing-view-CtYvBqTE.js +0 -375
- package/node_modules/@comis/web/dist/assets/channel-list-B8dj3O9a.js +0 -323
- package/node_modules/@comis/web/dist/assets/directive-DoeGSK_T.js +0 -1
- package/node_modules/@comis/web/dist/assets/ic-chat-message-CFyDJd0z.js +0 -352
- package/node_modules/@comis/web/dist/assets/ic-data-table-CKUNTxHw.js +0 -277
- package/node_modules/@comis/web/dist/assets/ic-delivery-row-GP5Fkygs.js +0 -67
- package/node_modules/@comis/web/dist/assets/ic-graph-canvas-C8FuSMe1.js +0 -359
- package/node_modules/@comis/web/dist/assets/ic-icon-xeGTVhVG.js +0 -33
- package/node_modules/@comis/web/dist/assets/ic-relative-time-3FqpjeAI.js +0 -12
- package/node_modules/@comis/web/dist/assets/ic-tabs-B7QtM_v8.js +0 -95
- package/node_modules/@comis/web/dist/assets/ic-tag-CPPUnDLF.js +0 -33
- package/node_modules/@comis/web/dist/assets/index-CEcM1R_C.js +0 -2830
- package/node_modules/@comis/web/dist/assets/index-CIJFuItj.css +0 -1
- package/node_modules/@comis/web/dist/assets/observability-types-D7jUtSde.js +0 -1
- package/node_modules/@comis/web/dist/assets/pipeline-builder-DcUUIrm0.js +0 -1496
- package/node_modules/@comis/web/dist/assets/session-key-parser-DPORMVyU.js +0 -1
- package/node_modules/@comis/web/dist/assets/session-list-6ybUTxbY.js +0 -231
package/node_modules/@comis/web/dist/assets/{config-editor-DX4ITw6y.js → config-editor-C9BSwHGy.js}
RENAMED
|
@@ -1,31 +1,6 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`),
|
|
3
|
-
`),
|
|
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`
|
|
1
|
+
import{c as e,f as t,h as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./decorate-BvWYovGE.js";import{a as u}from"./index-FLPhHz8p.js";import"./ic-tag-CvMVQFRR.js";import"./ic-confirm-dialog-DGlPbV1T.js";import"./ic-relative-time-B3UAnTqg.js";import"./ic-array-editor-BLoEyeLS.js";import"./ic-empty-state-CM3Wbj2f.js";import"./ic-tabs-yBjkWKJH.js";import"./ic-select-BqfZISjw.js";function d(e,t){let n=e.split(`
|
|
2
|
+
`),r=t.split(`
|
|
3
|
+
`),i=n.length,a=r.length,o=Array.from({length:i+1},()=>Array(a+1).fill(0));for(let e=1;e<=i;e++)for(let t=1;t<=a;t++)n[e-1]===r[t-1]?o[e][t]=o[e-1][t-1]+1:o[e][t]=Math.max(o[e-1][t],o[e][t-1]);let s=i,c=a,l=[],u=[];for(;s>0||c>0;)s>0&&c>0&&n[s-1]===r[c-1]?(l.push({text:n[s-1],status:`unchanged`}),u.push({text:r[c-1],status:`unchanged`}),s--,c--):c>0&&(s===0||o[s][c-1]>=o[s-1][c])?(u.push({text:r[c-1],status:`added`}),l.push({text:``,status:`unchanged`}),c--):(l.push({text:n[s-1],status:`removed`}),u.push({text:``,status:`unchanged`}),s--);return l.reverse(),u.reverse(),{oldLines:l,newLines:u}}var f=class extends r{constructor(...e){super(...e),this.oldText=``,this.newText=``,this.oldLabel=`Current`,this.newLabel=`Pending`,this._syncing=!1}static{this.styles=[o,i,n`
|
|
29
4
|
:host {
|
|
30
5
|
display: block;
|
|
31
6
|
}
|
|
@@ -107,156 +82,32 @@ 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}fro
|
|
|
107
82
|
font-size: var(--ic-text-sm);
|
|
108
83
|
grid-column: 1 / -1;
|
|
109
84
|
}
|
|
110
|
-
`]
|
|
111
|
-
|
|
112
|
-
|
|
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))}
|
|
85
|
+
`]}_handleScroll(e,t){if(this._syncing)return;this._syncing=!0;let n=e.target,r=this.shadowRoot?.querySelector(`.${t}`);r&&(r.scrollTop=n.scrollTop,r.scrollLeft=n.scrollLeft),requestAnimationFrame(()=>{this._syncing=!1})}_renderLines(e){return e.map(e=>{let n=`line`;return e.status===`removed`?n+=` line--removed`:e.status===`added`?n+=` line--added`:e.text===``&&(n+=` line--spacer`),t`<span class=${n}>${e.text||` `}</span>`})}render(){if(this.oldText===this.newText)return t`
|
|
86
|
+
<div class="diff-container">
|
|
87
|
+
<div class="no-changes">No changes detected</div>
|
|
161
88
|
</div>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
>\u00d7</button>
|
|
89
|
+
`;let{oldLines:e,newLines:n}=d(this.oldText,this.newText);return t`
|
|
90
|
+
<div class="diff-container">
|
|
91
|
+
<div class="diff-panel">
|
|
92
|
+
<div class="diff-header">${this.oldLabel}</div>
|
|
93
|
+
<div
|
|
94
|
+
class="diff-body diff-body--old"
|
|
95
|
+
@scroll=${e=>this._handleScroll(e,`diff-body--new`)}
|
|
96
|
+
>
|
|
97
|
+
<pre><code>${this._renderLines(e)}</code></pre>
|
|
98
|
+
</div>
|
|
173
99
|
</div>
|
|
174
|
-
<div class="
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
`})}
|
|
100
|
+
<div class="diff-panel">
|
|
101
|
+
<div class="diff-header">${this.newLabel}</div>
|
|
102
|
+
<div
|
|
103
|
+
class="diff-body diff-body--new"
|
|
104
|
+
@scroll=${e=>this._handleScroll(e,`diff-body--old`)}
|
|
105
|
+
>
|
|
106
|
+
<pre><code>${this._renderLines(n)}</code></pre>
|
|
107
|
+
</div>
|
|
230
108
|
</div>
|
|
231
109
|
</div>
|
|
232
|
-
`}
|
|
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`
|
|
110
|
+
`}};c([s()],f.prototype,`oldText`,void 0),c([s()],f.prototype,`newText`,void 0),c([s()],f.prototype,`oldLabel`,void 0),c([s()],f.prototype,`newLabel`,void 0),c([a()],f.prototype,`_syncing`,void 0),f=c([e(`ic-diff-viewer`)],f);var p=[`rpc`,`ws`,`admin`,`api`,`*`];function m(e){return e.replace(/([A-Z])/g,` $1`).replace(/^./,e=>e.toUpperCase()).trim()}function h(e,t){let n=t.split(`.`),r=e;for(let e of n){if(typeof r!=`object`||!r)return;r=r[e]}return r}function g(e,t,n){let r=t.split(`.`);if(r.length===1)return{...e,[r[0]]:n};let[i,...a]=r,o=e[i]??{};return{...e,[i]:g(o,a.join(`.`),n)}}var _=class extends r{constructor(...e){super(...e),this.schema={},this.config={},this.sectionKey=``,this._formState={},this._formErrors={},this._expandedFormPaths=new Set}static{this.styles=[o,i,n`
|
|
260
111
|
:host {
|
|
261
112
|
display: block;
|
|
262
113
|
}
|
|
@@ -460,318 +311,161 @@ 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}fro
|
|
|
460
311
|
outline: none;
|
|
461
312
|
border-color: var(--ic-accent);
|
|
462
313
|
}
|
|
463
|
-
`]
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
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
|
-
`}
|
|
314
|
+
`]}updated(e){e.has(`config`)&&(this._formState=structuredClone(this.config),this._formErrors={})}_onFormFieldChange(e,t){this._formState=g(this._formState,e,t);let n={...this._formErrors};delete n[e],this._formErrors=n,this.dispatchEvent(new CustomEvent(`field-change`,{detail:{path:e,value:t,formState:this._formState},bubbles:!0,composed:!0}))}_validateField(e,t,n){let r={...this._formErrors};if(n.type===`string`&&typeof t==`string`)if(n.minLength!==void 0&&t.length<n.minLength)r[e]=`Minimum length is ${n.minLength}`;else if(n.maxLength!==void 0&&t.length>n.maxLength)r[e]=`Maximum length is ${n.maxLength}`;else if(n.pattern)try{new RegExp(n.pattern).test(t)||(r[e]=`Must match pattern: ${n.pattern}`)}catch{}else delete r[e];else (n.type===`number`||n.type===`integer`)&&typeof t==`number`?n.minimum!==void 0&&t<n.minimum?r[e]=`Minimum value is ${n.minimum}`:n.maximum!==void 0&&t>n.maximum?r[e]=`Maximum value is ${n.maximum}`:delete r[e]:delete r[e];this._formErrors=r}_toggleFormFieldset(e){let t=new Set(this._expandedFormPaths);t.has(e)?t.delete(e):t.add(e),this._expandedFormPaths=t}_onArrayItemFieldChange(e,t,n,r){let i=(h(this._formState,e)??[]).map((e,i)=>i===t?{...e,[n]:r}:e);this._onFormFieldChange(e,i)}_renderStringField(e,n,r,i){let a=i.maxLength!==void 0&&i.maxLength>200||e.includes(`prompt`)||e.includes(`template`);return t`
|
|
315
|
+
<div class="form-field">
|
|
316
|
+
<label class="form-label">${n}</label>
|
|
317
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
318
|
+
${a?t`<textarea class="form-textarea" .value=${r}
|
|
319
|
+
@input=${t=>this._onFormFieldChange(e,t.target.value)}
|
|
320
|
+
@blur=${()=>this._validateField(e,r,i)}
|
|
321
|
+
></textarea>`:t`<input class="form-input" type="text" .value=${r}
|
|
322
|
+
@input=${t=>this._onFormFieldChange(e,t.target.value)}
|
|
323
|
+
@blur=${()=>this._validateField(e,r,i)}
|
|
324
|
+
/>`}
|
|
325
|
+
${this._formErrors[e]?t`<span class="form-error">${this._formErrors[e]}</span>`:l}
|
|
493
326
|
</div>
|
|
494
|
-
`}
|
|
495
|
-
<div
|
|
496
|
-
<
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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}
|
|
327
|
+
`}_renderNumberField(e,n,r,i){return t`
|
|
328
|
+
<div class="form-field">
|
|
329
|
+
<label class="form-label">${n}</label>
|
|
330
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
331
|
+
<input class="form-input" type="number" .value=${String(r)}
|
|
332
|
+
min=${i.minimum??l} max=${i.maximum??l}
|
|
333
|
+
@input=${t=>{let n=parseFloat(t.target.value);isNaN(n)||this._onFormFieldChange(e,n)}}
|
|
334
|
+
@blur=${()=>this._validateField(e,r,i)}
|
|
335
|
+
/>
|
|
336
|
+
${this._formErrors[e]?t`<span class="form-error">${this._formErrors[e]}</span>`:l}
|
|
513
337
|
</div>
|
|
514
|
-
`}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
<div class="schema-tree">
|
|
521
|
-
${Object.entries(e.properties).map(([r,i])=>this._renderSchemaTreeNode(r,i,r,0,t.includes(r)))}
|
|
338
|
+
`}_renderBooleanField(e,n,r,i){return t`
|
|
339
|
+
<div class="form-field">
|
|
340
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
341
|
+
<ic-toggle label=${n} .checked=${r}
|
|
342
|
+
@change=${t=>this._onFormFieldChange(e,t.detail)}
|
|
343
|
+
></ic-toggle>
|
|
522
344
|
</div>
|
|
523
|
-
`}
|
|
524
|
-
<div
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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>
|
|
345
|
+
`}_renderEnumField(e,n,r,i){let a=(i.enum??[]).map(e=>({value:String(e),label:String(e)}));return t`
|
|
346
|
+
<div class="form-field">
|
|
347
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
348
|
+
<ic-select label=${n} .value=${String(r??``)} .options=${a}
|
|
349
|
+
@change=${t=>this._onFormFieldChange(e,t.detail)}
|
|
350
|
+
></ic-select>
|
|
546
351
|
</div>
|
|
547
|
-
`}
|
|
548
|
-
<
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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))}
|
|
352
|
+
`}_renderArrayField(e,n,r,i){return i.items?.type===`string`?t`
|
|
353
|
+
<div class="form-field">
|
|
354
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
355
|
+
<ic-array-editor label=${n} .items=${(r??[]).map(String)} placeholder="Add item..."
|
|
356
|
+
@change=${t=>{this._onFormFieldChange(e,t.detail)}}
|
|
357
|
+
></ic-array-editor>
|
|
563
358
|
</div>
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
359
|
+
`:i.items?.type===`object`&&i.items.properties?this._renderArrayOfObjectsField(e,n,r,i):this._renderJsonFallback(e,n,r,i)}_renderArrayOfObjectsField(e,n,r,i){let a=r??[],o=i.items,s=o.properties??{},c=o.required??[],u=()=>{let e={};for(let[t,n]of Object.entries(s))n.default===void 0?n.type===`string`?e[t]=``:n.type===`number`||n.type===`integer`?e[t]=0:n.type===`boolean`?e[t]=!1:n.type===`array`?e[t]=[]:n.type===`object`&&(e[t]={}):e[t]=JSON.parse(JSON.stringify(n.default));return e};return t`
|
|
360
|
+
<div class="form-field">
|
|
361
|
+
<label class="form-label">${n}</label>
|
|
362
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
363
|
+
<div class="array-cards">
|
|
364
|
+
${a.map((t,n)=>this._renderArrayObjectCard(e,n,t,s,c))}
|
|
568
365
|
</div>
|
|
366
|
+
<button class="array-add-btn"
|
|
367
|
+
@click=${()=>{this._onFormFieldChange(e,[...a,u()])}}
|
|
368
|
+
>+ Add</button>
|
|
569
369
|
</div>
|
|
570
|
-
|
|
571
|
-
<div class="
|
|
572
|
-
<
|
|
573
|
-
class="
|
|
574
|
-
|
|
575
|
-
|
|
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>
|
|
370
|
+
`}_renderArrayObjectCard(e,n,r,i,a){return t`
|
|
371
|
+
<div class="array-card">
|
|
372
|
+
<div class="array-card-header">
|
|
373
|
+
<span class="array-card-index">#${n+1}</span>
|
|
374
|
+
<button class="array-card-remove" title="Remove"
|
|
375
|
+
@click=${()=>{let t=h(this._formState,e)??[];this._onFormFieldChange(e,t.filter((e,t)=>t!==n))}}
|
|
376
|
+
>\u00d7</button>
|
|
584
377
|
</div>
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
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>
|
|
378
|
+
<div class="array-card-fields">
|
|
379
|
+
${Object.entries(i).map(([i,o])=>{let s=`${m(i)}${a.includes(i)?` *`:``}`,c=r[i];if(i===`secret`)return t`
|
|
380
|
+
<div class="form-field">
|
|
381
|
+
<label class="form-label">${s}</label>
|
|
382
|
+
<input type="password" class="form-input"
|
|
383
|
+
.value=${typeof c==`string`?c:``}
|
|
384
|
+
placeholder="env:VAR_NAME or min 32 chars"
|
|
385
|
+
@input=${t=>{this._onArrayItemFieldChange(e,n,i,t.target.value)}}
|
|
386
|
+
/>
|
|
658
387
|
</div>
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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
|
-
`)}
|
|
388
|
+
`;if(o.type===`array`&&o.items?.type===`string`){if(i===`scopes`){let r=new Set((c??[]).map(String));return t`
|
|
389
|
+
<div class="form-field">
|
|
390
|
+
<label class="form-label">${s}</label>
|
|
391
|
+
<div class="scope-chips">
|
|
392
|
+
${p.map(a=>t`
|
|
393
|
+
<button class="scope-chip" ?data-active=${r.has(a)}
|
|
394
|
+
@click=${()=>{let t=new Set(r);t.has(a)?t.delete(a):t.add(a),this._onArrayItemFieldChange(e,n,i,[...t])}}
|
|
395
|
+
>${a}</button>
|
|
396
|
+
`)}
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
`}return t`
|
|
400
|
+
<div class="form-field">
|
|
401
|
+
<ic-array-editor label=${s} .items=${(c??[]).map(String)} placeholder="Add..."
|
|
402
|
+
@change=${t=>{this._onArrayItemFieldChange(e,n,i,t.detail)}}
|
|
403
|
+
></ic-array-editor>
|
|
732
404
|
</div>
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
</
|
|
764
|
-
|
|
765
|
-
<
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
405
|
+
`}return o.type===`string`?t`
|
|
406
|
+
<div class="form-field">
|
|
407
|
+
<label class="form-label">${s}</label>
|
|
408
|
+
<input type="text" class="form-input" .value=${String(c??``)}
|
|
409
|
+
@input=${t=>{this._onArrayItemFieldChange(e,n,i,t.target.value)}}
|
|
410
|
+
/>
|
|
411
|
+
</div>
|
|
412
|
+
`:o.type===`number`||o.type===`integer`?t`
|
|
413
|
+
<div class="form-field">
|
|
414
|
+
<label class="form-label">${s}</label>
|
|
415
|
+
<input type="number" class="form-input" .value=${String(c??0)}
|
|
416
|
+
@input=${t=>{this._onArrayItemFieldChange(e,n,i,Number(t.target.value))}}
|
|
417
|
+
/>
|
|
418
|
+
</div>
|
|
419
|
+
`:o.type===`boolean`?t`
|
|
420
|
+
<div class="form-field">
|
|
421
|
+
<label class="form-label">${s}</label>
|
|
422
|
+
<ic-toggle ?checked=${!!c}
|
|
423
|
+
@change=${t=>{this._onArrayItemFieldChange(e,n,i,t.detail)}}
|
|
424
|
+
></ic-toggle>
|
|
425
|
+
</div>
|
|
426
|
+
`:t`
|
|
427
|
+
<div class="form-field">
|
|
428
|
+
<label class="form-label">${s}</label>
|
|
429
|
+
<input type="text" class="form-input" .value=${JSON.stringify(c??``)}
|
|
430
|
+
@input=${t=>{try{this._onArrayItemFieldChange(e,n,i,JSON.parse(t.target.value))}catch{}}}
|
|
431
|
+
/>
|
|
432
|
+
</div>
|
|
433
|
+
`})}
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
`}_renderObjectField(e,n,r,i){let a=this._expandedFormPaths.has(e),o=i.properties??{},s=i.required??[];return t`
|
|
437
|
+
<fieldset class="form-fieldset">
|
|
438
|
+
<legend class="form-fieldset-legend" @click=${()=>this._toggleFormFieldset(e)}>
|
|
439
|
+
<span class="arrow" ?data-expanded=${a}>\u25B6</span>
|
|
440
|
+
${n}
|
|
441
|
+
</legend>
|
|
442
|
+
${a?t`
|
|
443
|
+
<div class="form-fieldset-content">
|
|
444
|
+
${Object.entries(o).map(([t,n])=>this._renderSchemaField(`${e}.${t}`,`${m(t)}${s.includes(t)?` *`:``}`,h(r??{},t),n))}
|
|
445
|
+
</div>
|
|
446
|
+
`:l}
|
|
447
|
+
</fieldset>
|
|
448
|
+
`}_renderJsonFallback(e,n,r,i){let a=JSON.stringify(r??null,null,2);return t`
|
|
449
|
+
<div class="form-field">
|
|
450
|
+
<label class="form-label">${n}</label>
|
|
451
|
+
${i.description?t`<span class="form-description">${i.description}</span>`:l}
|
|
452
|
+
<textarea class="json-fallback-textarea" .value=${a}
|
|
453
|
+
@input=${t=>{let n=t.target.value;try{let t=JSON.parse(n);this._onFormFieldChange(e,t);let r={...this._formErrors};delete r[e],this._formErrors=r}catch{this._formErrors={...this._formErrors,[e]:`Invalid JSON`}}}}
|
|
454
|
+
></textarea>
|
|
455
|
+
${this._formErrors[e]?t`<span class="form-error">${this._formErrors[e]}</span>`:l}
|
|
456
|
+
</div>
|
|
457
|
+
`}_renderSchemaField(e,t,n,r){if(r.enum&&r.enum.length>0)return this._renderEnumField(e,t,n,r);let i=r.anyOf??r.oneOf;if(i&&i.length>=2){let r=i.filter(e=>e.type!==`null`);if(r.length===1)return this._renderSchemaField(e,t,n,r[0]);if(n==null||typeof n==`string`){let i=r.find(e=>e.type===`string`);if(i)return this._renderStringField(e,t,String(n??``),i)}}if(r.anyOf||r.oneOf||r.allOf)return this._renderJsonFallback(e,t,n,r);switch(r.type){case`string`:return this._renderStringField(e,t,String(n??``),r);case`number`:case`integer`:return this._renderNumberField(e,t,Number(n??0),r);case`boolean`:return this._renderBooleanField(e,t,!!n,r);case`array`:return this._renderArrayField(e,t,n??[],r);case`object`:return this._renderObjectField(e,t,n??{},r);default:return this._renderJsonFallback(e,t,n,r)}}render(){let e=this.schema;if(e&&!e.properties&&e.additionalProperties&&typeof e.additionalProperties==`object`){let n=e.additionalProperties,r=Object.keys(this._formState);return r.length===0?t`<ic-empty-state icon="config" message="No entries" description="This section has no configured entries."></ic-empty-state>`:t`
|
|
458
|
+
${r.map(e=>{let t=this._formState[e]??{};return this._renderObjectField(e,m(e),t,n)})}
|
|
459
|
+
`}if(!e||!e.properties)return t`
|
|
460
|
+
${Object.entries(this._formState).map(([e,t])=>this._renderSchemaField(e,m(e),t,{type:typeof t==`boolean`?`boolean`:typeof t==`number`?`number`:`string`}))}
|
|
461
|
+
`;let n=e.properties,r=e.required??[];return t`
|
|
462
|
+
${Object.entries(n).map(([e,t])=>this._renderSchemaField(e,`${m(e)}${r.includes(e)?` *`:``}`,h(this._formState,e),t))}
|
|
463
|
+
`}};c([s({attribute:!1})],_.prototype,`schema`,void 0),c([s({attribute:!1})],_.prototype,`config`,void 0),c([s({type:String})],_.prototype,`sectionKey`,void 0),c([a()],_.prototype,`_formState`,void 0),c([a()],_.prototype,`_formErrors`,void 0),c([a()],_.prototype,`_expandedFormPaths`,void 0),_=c([e(`ic-schema-form`)],_);function v(e,t=0){let n=` `.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`[]`;let r=[];for(let i of e)if(typeof i==`object`&&i&&!Array.isArray(i)){let e=Object.entries(i);if(e.length>0){let[i,a]=e[0];r.push(`${n}- ${i}: ${v(a,0)}`);for(let i=1;i<e.length;i++){let[a,o]=e[i];r.push(`${n} ${a}: ${v(o,t+2)}`)}}else r.push(`${n}- {}`)}else r.push(`${n}- ${v(i,0)}`);return`
|
|
465
|
+
`+r.join(`
|
|
466
|
+
`)}if(typeof e==`object`){let r=Object.entries(e);if(r.length===0)return`{}`;let i=[];for(let[e,a]of r)typeof a==`object`&&a&&!Array.isArray(a)&&Object.keys(a).length>0?(i.push(`${n}${e}:`),i.push(v(a,t+1))):Array.isArray(a)&&a.length>0?i.push(`${n}${e}:${v(a,t+1)}`):i.push(`${n}${e}: ${v(a,0)}`);return i.join(`
|
|
467
|
+
`)}return String(e)}function y(e){try{return{data:S(e.split(`
|
|
468
|
+
`),0,0).value,error:null}}catch(e){return{data:null,error:e instanceof Error?e.message:`Parse error`}}}function b(e){let t=e.match(/^( *)/);return t?t[1].length:0}function x(e){let 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,`\\`);let n=Number(t);return!isNaN(n)&&t!==``?n:t}function S(e,t,n){let r=t;for(;r<e.length&&e[r].trim()===``;)r++;if(r>=e.length)return{value:null,nextLine:r};let i=e[r],a=b(i),o=i.trim();if(o.startsWith(`- `)){let t=[];for(;r<e.length;){let n=e[r];if(n.trim()===``){r++;continue}let i=b(n);if(i<a||i!==a||!n.trim().startsWith(`- `))break;let o=n.trim().slice(2),s=o.match(/^([^:]+):\s*(.*)/);if(s&&!o.startsWith(`"`)&&!o.startsWith(`'`)){let n={};n[s[1].trim()]=x(s[2]),r++;let i=a+2;for(;r<e.length;){let t=e[r];if(t.trim()===``){r++;continue}let a=b(t);if(a<i)break;if(a===i&&!t.trim().startsWith(`- `)){let a=t.trim().match(/^([^:]+):\s*(.*)/);if(a){let t=a[1].trim(),o=a[2];if(o===``||o===void 0){let a=S(e,r+1,i+2);n[t]=a.value,r=a.nextLine}else n[t]=x(o),r++}else break}else break}t.push(n)}else t.push(x(o)),r++}return{value:t,nextLine:r}}if(o.includes(`:`)){let t={};for(;r<e.length;){let n=e[r];if(n.trim()===``){r++;continue}let i=b(n);if(i<a||i!==a)break;let o=n.indexOf(`:`);if(o===-1)break;let s=n.slice(0,o).trim(),c=n.slice(o+1).trim();if(c===``||c===void 0){r++;let n=S(e,r,a+2);t[s]=n.value,r=n.nextLine}else t[s]=x(c),r++}return{value:t,nextLine:r}}return{value:x(o),nextLine:r+1}}var C=[{id:`editor`,label:`YAML Editor`},{id:`gateway`,label:`Gateway`},{id:`history`,label:`History`},{id:`wizard`,label:`Setup Wizard`}],w=v;function T(e,t,n){let r=t.split(`.`);if(r.length===1)return{...e,[r[0]]:n};let[i,...a]=r,o=e[i]??{};return{...e,[i]:T(o,a.join(`.`),n)}}var E=class extends r{constructor(...e){super(...e),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}static{this.styles=[o,i,n`
|
|
775
469
|
:host {
|
|
776
470
|
display: block;
|
|
777
471
|
}
|
|
@@ -1371,4 +1065,310 @@ 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}fro
|
|
|
1371
1065
|
.history-rollback-link:hover {
|
|
1372
1066
|
text-decoration: underline;
|
|
1373
1067
|
}
|
|
1374
|
-
`]
|
|
1068
|
+
`]}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),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{let 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(e=>{let t=e.schema;this._schemaData=t.properties??t}).catch(()=>{})}catch(e){this._error=e instanceof Error?e.message:`Failed to load configuration`,this._loadState=`error`}}}_loadSectionState(){let e=this._configData[this._selectedSection]??{};this._formState=structuredClone(e),this._yamlText=w(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=w(this._formState);else if(this._mode===`yaml`&&e===`form`&&this._yamlErrors.length===0){let e=y(this._yamlText);!e.error&&e.data&&typeof e.data==`object`&&(this._formState=e.data)}this._mode=e}}_renderFormMode(){return t`
|
|
1069
|
+
<ic-schema-form
|
|
1070
|
+
.schema=${this._schemaData[this._selectedSection]??{}}
|
|
1071
|
+
.config=${this._formState}
|
|
1072
|
+
.sectionKey=${this._selectedSection}
|
|
1073
|
+
@field-change=${e=>{let{path:t,value:n,formState:r}=e.detail;this._formState=r??T(this._formState,t,n),this._dirty=!0;let i={...this._formErrors};delete i[t],this._formErrors=i}}
|
|
1074
|
+
></ic-schema-form>
|
|
1075
|
+
`}_onYamlInput(e){this._yamlText=e.target.value,this._dirty=!0,this._yamlDebounceTimer!==null&&clearTimeout(this._yamlDebounceTimer),this._yamlDebounceTimer=setTimeout(()=>{this._validateYaml()},500)}_validateYaml(){let e=y(this._yamlText);e.error?this._yamlErrors=[e.error]:this._yamlErrors=[]}_renderYamlMode(){return t`
|
|
1076
|
+
<div class="yaml-editor">
|
|
1077
|
+
<textarea
|
|
1078
|
+
class="yaml-textarea"
|
|
1079
|
+
.value=${this._yamlText}
|
|
1080
|
+
@input=${e=>this._onYamlInput(e)}
|
|
1081
|
+
spellcheck="false"
|
|
1082
|
+
aria-label="YAML editor"
|
|
1083
|
+
></textarea>
|
|
1084
|
+
${this._yamlErrors.length>0?t`
|
|
1085
|
+
<div class="yaml-validation yaml-validation--error">
|
|
1086
|
+
${this._yamlErrors.map(e=>t`<div>${e}</div>`)}
|
|
1087
|
+
</div>
|
|
1088
|
+
`:t`
|
|
1089
|
+
<div class="yaml-validation yaml-validation--valid">
|
|
1090
|
+
Valid configuration
|
|
1091
|
+
</div>
|
|
1092
|
+
`}
|
|
1093
|
+
</div>
|
|
1094
|
+
`}_toggleSchemaPath(e){let t=new Set(this._expandedPaths);t.has(e)?t.delete(e):t.add(e),this._expandedPaths=t}_renderSchemaTreeNode(e,n,r,i,a){let o=n.type===`object`&&n.properties&&Object.keys(n.properties).length>0,s=this._expandedPaths.has(r),c=[];return a&&c.push(`required`),n.minimum!==void 0&&c.push(`min: ${n.minimum}`),n.maximum!==void 0&&c.push(`max: ${n.maximum}`),n.minLength!==void 0&&c.push(`minLen: ${n.minLength}`),n.maxLength!==void 0&&c.push(`maxLen: ${n.maxLength}`),n.enum&&c.push(`enum: [${n.enum.join(`, `)}]`),n.pattern&&c.push(`pattern: ${n.pattern}`),n.default!==void 0&&c.push(`default: ${JSON.stringify(n.default)}`),t`
|
|
1095
|
+
<div style="padding-left: ${i*1.5}rem">
|
|
1096
|
+
<div class="schema-row">
|
|
1097
|
+
<span
|
|
1098
|
+
class="schema-key"
|
|
1099
|
+
@click=${o?()=>this._toggleSchemaPath(r):l}
|
|
1100
|
+
>
|
|
1101
|
+
${o?t`<span class="arrow" ?data-expanded=${s}>\u25B6</span>`:l}
|
|
1102
|
+
${e}${a?t`<span class="required-marker">*</span>`:l}
|
|
1103
|
+
</span>
|
|
1104
|
+
<ic-tag variant="info">${n.type??`any`}</ic-tag>
|
|
1105
|
+
${n.description?t`<span class="schema-desc">${n.description}</span>`:l}
|
|
1106
|
+
${c.length>0?t`<span class="schema-constraints">${c.join(`, `)}</span>`:l}
|
|
1107
|
+
</div>
|
|
1108
|
+
${o&&s?t`
|
|
1109
|
+
<div class="schema-children">
|
|
1110
|
+
${Object.entries(n.properties).map(([e,t])=>this._renderSchemaTreeNode(e,t,`${r}.${e}`,i+1,(n.required??[]).includes(e)))}
|
|
1111
|
+
</div>
|
|
1112
|
+
`:l}
|
|
1113
|
+
</div>
|
|
1114
|
+
`}_renderSchemaMode(){let e=this._schemaData[this._selectedSection];if(e&&!e.properties&&e.additionalProperties&&typeof e.additionalProperties==`object`){let n=e.additionalProperties;if(!n.properties)return t`<ic-empty-state icon="config" message="No schema available" description="Schema definition not found for this section."></ic-empty-state>`;let r=n.required??[];return t`
|
|
1115
|
+
<div class="schema-tree">
|
|
1116
|
+
<div class="schema-note" style="padding:8px 0;opacity:0.7;font-style:italic">Record<string, entry> - each entry has:</div>
|
|
1117
|
+
${Object.entries(n.properties).map(([e,t])=>this._renderSchemaTreeNode(e,t,e,0,r.includes(e)))}
|
|
1118
|
+
</div>
|
|
1119
|
+
`}if(!e?.properties)return t`<ic-empty-state icon="config" message="No schema available" description="Schema definition not found for this section."></ic-empty-state>`;let n=e.required??[];return t`
|
|
1120
|
+
<div class="schema-tree">
|
|
1121
|
+
${Object.entries(e.properties).map(([e,t])=>this._renderSchemaTreeNode(e,t,e,0,n.includes(e)))}
|
|
1122
|
+
</div>
|
|
1123
|
+
`}async _onApply(){if(!this.rpcClient||!this._dirty)return;this._applying=!0;let e;if(this._mode===`yaml`){let t=y(this._yamlText);if(t.error){u.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}),u.show(`Configuration applied`,`success`),this._dirty=!1;let t=await this.rpcClient.call(`config.read`);this._configData=t.config,this._loadSectionState()}catch(e){let t=e instanceof Error?e.message:`Failed to apply configuration`;u.show(t,`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}),u.show(`Configuration rolled back`,`success`);let e=await this.rpcClient.call(`config.read`);this._configData=e.config,this._rollbackSnapshot=null,this._confirmRollback=!1,this._loadSectionState()}catch(e){let t=e instanceof Error?e.message:`Failed to rollback configuration`;u.show(t,`error`),this._confirmRollback=!1}}async _loadGatewayConfig(){if(this.rpcClient){this._gatewayLoading=!0,this._gatewayError=``;try{let 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,[e]:t},u.show(`Gateway updated`,`success`)}catch(e){let t=e instanceof Error?e.message:`Failed to update gateway`;u.show(t,`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{let 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{let t=await this.rpcClient.call(`config.diff`,{sha:e});this._diffText=t.diff}catch(e){this._diffText=``;let t=e instanceof Error?e.message:`Failed to load diff`;u.show(t,`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}),u.show(`Config rolled back. Daemon restarting...`,`success`),this._confirmRollbackSha=null}catch(e){let t=e instanceof Error?e.message:`Rollback failed`;u.show(t,`error`),this._confirmRollbackSha=null}}async _onGc(){if(!(!this.rpcClient||this._gcRunning)){this._gcRunning=!0;try{let e=(await this.rpcClient.call(`config.gc`)).squashed;u.show(e==null?`GC complete`:`GC complete: ${e} versions squashed`,`success`),this._loadHistory()}catch(e){let t=e instanceof Error?e.message:`GC failed`;u.show(t,`error`)}finally{this._gcRunning=!1}}}_renderDiffLine(e,n){let r=`diff-line--context`;return e.startsWith(`+`)?r=`diff-line--add`:e.startsWith(`-`)?r=`diff-line--remove`:e.startsWith(`@@`)&&(r=`diff-line--hunk`),t`<span class=${r}>${e}\n</span>`}_renderHistoryEntry(e,n){let r=e.sha===this._selectedSha,i=n===0,a=e.metadata.user||e.metadata.agent||`system`,o=new Date(e.timestamp).toLocaleString();return t`
|
|
1124
|
+
<div
|
|
1125
|
+
class="history-entry ${r?`history-entry--selected`:``}"
|
|
1126
|
+
@click=${()=>this._onSelectVersion(e.sha)}
|
|
1127
|
+
>
|
|
1128
|
+
<div class="history-entry-header">
|
|
1129
|
+
<ic-relative-time
|
|
1130
|
+
.timestamp=${new Date(e.timestamp).getTime()}
|
|
1131
|
+
title=${o}
|
|
1132
|
+
></ic-relative-time>
|
|
1133
|
+
<code class="history-sha">${e.sha.slice(0,7)}</code>
|
|
1134
|
+
</div>
|
|
1135
|
+
<div class="history-entry-summary" title=${e.metadata.summary}>
|
|
1136
|
+
${e.metadata.summary}
|
|
1137
|
+
</div>
|
|
1138
|
+
<div class="history-entry-meta">
|
|
1139
|
+
<ic-tag variant="default">${e.metadata.section}</ic-tag>
|
|
1140
|
+
<span class="history-author">${a}</span>
|
|
1141
|
+
${i?l:t`<button
|
|
1142
|
+
class="history-rollback-link"
|
|
1143
|
+
@click=${t=>{t.stopPropagation(),this._confirmRollbackSha=e.sha}}
|
|
1144
|
+
>Rollback</button>`}
|
|
1145
|
+
</div>
|
|
1146
|
+
</div>
|
|
1147
|
+
`}_renderHistoryTab(){return this._historyLoading?t`<div class="state-container"><ic-loading size="lg"></ic-loading></div>`:this._historyError?t`
|
|
1148
|
+
<ic-empty-state
|
|
1149
|
+
icon="config"
|
|
1150
|
+
message="Version history unavailable"
|
|
1151
|
+
description=${this._historyError}
|
|
1152
|
+
></ic-empty-state>
|
|
1153
|
+
`:this._historyEntries.length===0?t`
|
|
1154
|
+
<ic-empty-state
|
|
1155
|
+
icon="config"
|
|
1156
|
+
message="No version history"
|
|
1157
|
+
description="Config changes will appear here after the first edit."
|
|
1158
|
+
></ic-empty-state>
|
|
1159
|
+
`:t`
|
|
1160
|
+
<div class="history-layout">
|
|
1161
|
+
<div class="history-timeline">
|
|
1162
|
+
${this._historyEntries.map((e,t)=>this._renderHistoryEntry(e,t))}
|
|
1163
|
+
</div>
|
|
1164
|
+
|
|
1165
|
+
<div class="history-diff-panel">
|
|
1166
|
+
${this._diffLoading?t`<div class="state-container"><ic-loading size="lg"></ic-loading></div>`:this._selectedSha&&this._diffText?t`<pre class="diff-unified">${this._diffText.split(`
|
|
1167
|
+
`).map((e,t)=>this._renderDiffLine(e,t))}</pre>`:this._selectedSha&&!this._diffText?t`<ic-empty-state icon="config" message="No changes" description="No changes between this version and current."></ic-empty-state>`:t`<ic-empty-state icon="config" message="Select a version" description="Select a version to view changes."></ic-empty-state>`}
|
|
1168
|
+
</div>
|
|
1169
|
+
</div>
|
|
1170
|
+
|
|
1171
|
+
<div class="history-actions">
|
|
1172
|
+
<button
|
|
1173
|
+
class="secondary-btn"
|
|
1174
|
+
?disabled=${this._gcRunning}
|
|
1175
|
+
@click=${()=>this._onGc()}
|
|
1176
|
+
>
|
|
1177
|
+
${this._gcRunning?t`<span class="spinner"></span> Running GC...`:`Run GC`}
|
|
1178
|
+
</button>
|
|
1179
|
+
</div>
|
|
1180
|
+
`}_onExport(){let e=w(this._configData),t=new Blob([e],{type:`text/yaml`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`comis-config.yaml`,r.click(),URL.revokeObjectURL(n)}_onImportClick(){(this.shadowRoot?.querySelector(`.hidden-input`))?.click()}_onImportFile(e){let t=e.target,n=t.files?.[0];if(!n)return;let r=new FileReader;r.onload=()=>{let e=r.result,t=y(e);if(t.error){u.show(`Import failed: ${t.error}`,`error`);return}t.data&&typeof t.data==`object`&&!Array.isArray(t.data)?(this._configData=t.data,this._loadSectionState(),this._dirty=!0,u.show(`Configuration imported`,`info`)):u.show(`Import failed: expected a YAML object`,`error`)},r.readAsText(n),t.value=``}_renderModeContent(){switch(this._mode){case`form`:return this._renderFormMode();case`yaml`:return this._renderYamlMode();case`schema`:return this._renderSchemaMode();default:return l}}_renderEditorTab(){return this._loadState===`loading`?t`<ic-skeleton-view variant="editor"></ic-skeleton-view>`:this._loadState===`error`?t`
|
|
1181
|
+
<div class="error-container">
|
|
1182
|
+
<span class="error-message">${this._error}</span>
|
|
1183
|
+
<button class="retry-btn" @click=${()=>this._tryLoad()}>Retry</button>
|
|
1184
|
+
</div>
|
|
1185
|
+
`:t`
|
|
1186
|
+
<div class="editor-layout">
|
|
1187
|
+
<nav class="section-sidebar" role="navigation" aria-label="Config sections">
|
|
1188
|
+
${this._sections.map(e=>t`
|
|
1189
|
+
<div
|
|
1190
|
+
class="section-item"
|
|
1191
|
+
?data-selected=${e===this._selectedSection}
|
|
1192
|
+
@click=${()=>this._onSectionClick(e)}
|
|
1193
|
+
>
|
|
1194
|
+
${e.charAt(0).toUpperCase()+e.slice(1)}
|
|
1195
|
+
</div>
|
|
1196
|
+
`)}
|
|
1197
|
+
</nav>
|
|
1198
|
+
|
|
1199
|
+
<div class="content-area" role="main">
|
|
1200
|
+
<div class="toolbar">
|
|
1201
|
+
<div class="mode-tabs">
|
|
1202
|
+
<button
|
|
1203
|
+
class="mode-btn"
|
|
1204
|
+
?data-active=${this._mode===`form`}
|
|
1205
|
+
@click=${()=>this._onModeChange(`form`)}
|
|
1206
|
+
>Form</button>
|
|
1207
|
+
<button
|
|
1208
|
+
class="mode-btn"
|
|
1209
|
+
?data-active=${this._mode===`yaml`}
|
|
1210
|
+
@click=${()=>this._onModeChange(`yaml`)}
|
|
1211
|
+
>YAML</button>
|
|
1212
|
+
<button
|
|
1213
|
+
class="mode-btn"
|
|
1214
|
+
?data-active=${this._mode===`schema`}
|
|
1215
|
+
@click=${()=>this._onModeChange(`schema`)}
|
|
1216
|
+
>Schema</button>
|
|
1217
|
+
</div>
|
|
1218
|
+
|
|
1219
|
+
<div class="action-buttons">
|
|
1220
|
+
<button
|
|
1221
|
+
class="diff-btn"
|
|
1222
|
+
?data-active=${this._showDiff}
|
|
1223
|
+
@click=${()=>{this._showDiff=!this._showDiff}}
|
|
1224
|
+
>Show Diff</button>
|
|
1225
|
+
${this._rollbackSnapshot===null?l:t`<button
|
|
1226
|
+
class="rollback-btn"
|
|
1227
|
+
@click=${()=>{this._confirmRollback=!0}}
|
|
1228
|
+
>Rollback</button>`}
|
|
1229
|
+
<button
|
|
1230
|
+
class="secondary-btn"
|
|
1231
|
+
@click=${()=>this._onImportClick()}
|
|
1232
|
+
>Import</button>
|
|
1233
|
+
<button
|
|
1234
|
+
class="secondary-btn"
|
|
1235
|
+
@click=${()=>this._onExport()}
|
|
1236
|
+
>Export</button>
|
|
1237
|
+
<button
|
|
1238
|
+
class="apply-btn"
|
|
1239
|
+
?disabled=${!this._dirty||this._applying}
|
|
1240
|
+
@click=${()=>this._onApply()}
|
|
1241
|
+
>
|
|
1242
|
+
${this._applying?t`<span class="spinner"></span>`:l}
|
|
1243
|
+
Apply Changes
|
|
1244
|
+
</button>
|
|
1245
|
+
</div>
|
|
1246
|
+
</div>
|
|
1247
|
+
|
|
1248
|
+
${this._renderModeContent()}
|
|
1249
|
+
|
|
1250
|
+
${this._showDiff?t`
|
|
1251
|
+
<div class="diff-preview">
|
|
1252
|
+
<ic-diff-viewer
|
|
1253
|
+
.oldText=${this._savedYaml}
|
|
1254
|
+
.newText=${this._mode===`yaml`?this._yamlText:w(this._formState)}
|
|
1255
|
+
oldLabel="Current"
|
|
1256
|
+
newLabel="Pending Changes"
|
|
1257
|
+
></ic-diff-viewer>
|
|
1258
|
+
</div>
|
|
1259
|
+
`:l}
|
|
1260
|
+
</div>
|
|
1261
|
+
</div>
|
|
1262
|
+
|
|
1263
|
+
<input
|
|
1264
|
+
class="hidden-input"
|
|
1265
|
+
type="file"
|
|
1266
|
+
accept=".yaml,.yml"
|
|
1267
|
+
@change=${e=>this._onImportFile(e)}
|
|
1268
|
+
/>
|
|
1269
|
+
|
|
1270
|
+
<ic-confirm-dialog
|
|
1271
|
+
.open=${this._confirmRollback}
|
|
1272
|
+
title="Rollback Configuration"
|
|
1273
|
+
message="Restore previous configuration? This will revert all sections to the state before your last apply."
|
|
1274
|
+
confirmLabel="Rollback"
|
|
1275
|
+
@confirm=${()=>this._onRollback()}
|
|
1276
|
+
@cancel=${()=>{this._confirmRollback=!1}}
|
|
1277
|
+
></ic-confirm-dialog>
|
|
1278
|
+
`}_renderGatewayTab(){if(this._gatewayLoading)return t`<div class="state-container"><ic-loading size="lg"></ic-loading></div>`;if(this._gatewayError)return t`
|
|
1279
|
+
<div class="error-container">
|
|
1280
|
+
<span class="error-message">${this._gatewayError}</span>
|
|
1281
|
+
<button class="retry-btn" @click=${()=>this._loadGatewayConfig()}>Retry</button>
|
|
1282
|
+
</div>
|
|
1283
|
+
`;if(!this._gatewayConfig)return t`<ic-empty-state icon="config" message="No gateway configuration" description="Gateway config not available."></ic-empty-state>`;let e=this._gatewayConfig,n=e.cors?.origins??[],r=e.tokens??[];return t`
|
|
1284
|
+
<div class="gateway-form">
|
|
1285
|
+
<div class="gateway-field">
|
|
1286
|
+
<ic-toggle
|
|
1287
|
+
label="Gateway Enabled"
|
|
1288
|
+
.checked=${e.enabled??!1}
|
|
1289
|
+
@change=${e=>this._patchGateway(`enabled`,e.detail)}
|
|
1290
|
+
></ic-toggle>
|
|
1291
|
+
</div>
|
|
1292
|
+
|
|
1293
|
+
<div class="gateway-field">
|
|
1294
|
+
<label class="gateway-label">Host</label>
|
|
1295
|
+
<input
|
|
1296
|
+
class="gateway-input"
|
|
1297
|
+
type="text"
|
|
1298
|
+
.value=${e.host??`0.0.0.0`}
|
|
1299
|
+
@change=${e=>this._patchGateway(`host`,e.target.value)}
|
|
1300
|
+
/>
|
|
1301
|
+
</div>
|
|
1302
|
+
|
|
1303
|
+
<div class="gateway-field">
|
|
1304
|
+
<label class="gateway-label">Port</label>
|
|
1305
|
+
<input
|
|
1306
|
+
class="gateway-input"
|
|
1307
|
+
type="number"
|
|
1308
|
+
.value=${String(e.port??3e3)}
|
|
1309
|
+
@change=${e=>{let t=parseInt(e.target.value,10);isNaN(t)||this._patchGateway(`port`,t)}}
|
|
1310
|
+
/>
|
|
1311
|
+
</div>
|
|
1312
|
+
|
|
1313
|
+
<div class="gateway-field">
|
|
1314
|
+
<ic-array-editor
|
|
1315
|
+
label="CORS Origins"
|
|
1316
|
+
.items=${n.map(String)}
|
|
1317
|
+
placeholder="https://example.com"
|
|
1318
|
+
@change=${t=>this._patchGateway(`cors`,{...e.cors,origins:t.detail})}
|
|
1319
|
+
></ic-array-editor>
|
|
1320
|
+
</div>
|
|
1321
|
+
|
|
1322
|
+
<div class="gateway-tokens">
|
|
1323
|
+
<div class="gateway-tokens-label">API Tokens (${r.length})</div>
|
|
1324
|
+
${r.length>0?t`
|
|
1325
|
+
<div class="gateway-tokens-list">
|
|
1326
|
+
${r.map(e=>t`
|
|
1327
|
+
<div class="gateway-token-entry">
|
|
1328
|
+
<span class="gateway-token-id">${e.id}</span>
|
|
1329
|
+
${e.scopes&&e.scopes.length>0?e.scopes.map(e=>t`<ic-tag variant="info">${e}</ic-tag>`):t`<ic-tag variant="default">no scopes</ic-tag>`}
|
|
1330
|
+
</div>
|
|
1331
|
+
`)}
|
|
1332
|
+
</div>
|
|
1333
|
+
`:t`<div style="font-size:var(--ic-text-sm);color:var(--ic-text-dim)">No tokens configured</div>`}
|
|
1334
|
+
<a class="gateway-tokens-link" href="#security">Manage tokens in Security →</a>
|
|
1335
|
+
</div>
|
|
1336
|
+
</div>
|
|
1337
|
+
`}_renderWizardTab(){return t`
|
|
1338
|
+
<div class="wizard-content">
|
|
1339
|
+
<div class="wizard-description">
|
|
1340
|
+
The setup wizard guides you through initial Comis configuration
|
|
1341
|
+
including provider keys, agent creation, channel setup, and
|
|
1342
|
+
security settings.
|
|
1343
|
+
</div>
|
|
1344
|
+
<button
|
|
1345
|
+
class="wizard-btn"
|
|
1346
|
+
@click=${()=>{window.location.hash=`#setup`}}
|
|
1347
|
+
>Launch Setup Wizard</button>
|
|
1348
|
+
</div>
|
|
1349
|
+
`}render(){return t`
|
|
1350
|
+
<div class="view-header">
|
|
1351
|
+
<div class="view-title">Settings</div>
|
|
1352
|
+
</div>
|
|
1353
|
+
|
|
1354
|
+
<ic-tabs
|
|
1355
|
+
.tabs=${C}
|
|
1356
|
+
.activeTab=${this._activeTab}
|
|
1357
|
+
@tab-change=${this._onTabChange}
|
|
1358
|
+
>
|
|
1359
|
+
<div slot="editor">${this._renderEditorTab()}</div>
|
|
1360
|
+
<div slot="gateway">${this._renderGatewayTab()}</div>
|
|
1361
|
+
<div slot="history">${this._renderHistoryTab()}</div>
|
|
1362
|
+
<div slot="wizard">${this._renderWizardTab()}</div>
|
|
1363
|
+
</ic-tabs>
|
|
1364
|
+
|
|
1365
|
+
<ic-confirm-dialog
|
|
1366
|
+
.open=${this._confirmRollbackSha!==null}
|
|
1367
|
+
title="Rollback Configuration"
|
|
1368
|
+
message="Restore config to this version? The daemon will restart to apply changes."
|
|
1369
|
+
variant="danger"
|
|
1370
|
+
confirmLabel="Rollback"
|
|
1371
|
+
@confirm=${()=>this._onHistoryRollback()}
|
|
1372
|
+
@cancel=${()=>{this._confirmRollbackSha=null}}
|
|
1373
|
+
></ic-confirm-dialog>
|
|
1374
|
+
`}};c([s({attribute:!1})],E.prototype,`rpcClient`,void 0),c([a()],E.prototype,`_activeTab`,void 0),c([a()],E.prototype,`_loadState`,void 0),c([a()],E.prototype,`_error`,void 0),c([a()],E.prototype,`_sections`,void 0),c([a()],E.prototype,`_selectedSection`,void 0),c([a()],E.prototype,`_mode`,void 0),c([a()],E.prototype,`_configData`,void 0),c([a()],E.prototype,`_schemaData`,void 0),c([a()],E.prototype,`_yamlText`,void 0),c([a()],E.prototype,`_yamlErrors`,void 0),c([a()],E.prototype,`_formState`,void 0),c([a()],E.prototype,`_formErrors`,void 0),c([a()],E.prototype,`_dirty`,void 0),c([a()],E.prototype,`_applying`,void 0),c([a()],E.prototype,`_expandedPaths`,void 0),c([a()],E.prototype,`_showDiff`,void 0),c([a()],E.prototype,`_savedYaml`,void 0),c([a()],E.prototype,`_rollbackSnapshot`,void 0),c([a()],E.prototype,`_confirmRollback`,void 0),c([a()],E.prototype,`_gatewayConfig`,void 0),c([a()],E.prototype,`_gatewayLoading`,void 0),c([a()],E.prototype,`_gatewayError`,void 0),c([a()],E.prototype,`_historyEntries`,void 0),c([a()],E.prototype,`_historyLoading`,void 0),c([a()],E.prototype,`_historyError`,void 0),c([a()],E.prototype,`_selectedSha`,void 0),c([a()],E.prototype,`_diffText`,void 0),c([a()],E.prototype,`_diffLoading`,void 0),c([a()],E.prototype,`_confirmRollbackSha`,void 0),c([a()],E.prototype,`_gcRunning`,void 0),E=c([e(`ic-config-editor`)],E);export{E as IcConfigEditor,y as parseYaml,v as serializeToYaml};
|