agent-discover 1.3.8 → 1.4.0
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/CHANGELOG.md +44 -1
- package/README.md +34 -8
- package/agent-desk-plugin.json +10 -3
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +15 -0
- package/dist/context.js.map +1 -1
- package/dist/domain/log.d.ts +7 -3
- package/dist/domain/log.d.ts.map +1 -1
- package/dist/domain/log.js +15 -5
- package/dist/domain/log.js.map +1 -1
- package/dist/domain/presets.d.ts +30 -0
- package/dist/domain/presets.d.ts.map +1 -0
- package/dist/domain/presets.js +76 -0
- package/dist/domain/presets.js.map +1 -0
- package/dist/domain/proxy.d.ts +153 -0
- package/dist/domain/proxy.d.ts.map +1 -1
- package/dist/domain/proxy.js +396 -3
- package/dist/domain/proxy.js.map +1 -1
- package/dist/domain/sampling.d.ts +9 -0
- package/dist/domain/sampling.d.ts.map +1 -0
- package/dist/domain/sampling.js +68 -0
- package/dist/domain/sampling.js.map +1 -0
- package/dist/storage/database.js +21 -0
- package/dist/storage/database.js.map +1 -1
- package/dist/transport/rest.d.ts.map +1 -1
- package/dist/transport/rest.js +349 -0
- package/dist/transport/rest.js.map +1 -1
- package/dist/transport/ws.d.ts.map +1 -1
- package/dist/transport/ws.js +32 -0
- package/dist/transport/ws.js.map +1 -1
- package/dist/ui/app.js +16 -0
- package/dist/ui/index.html +3 -0
- package/dist/ui/markdown.js +102 -0
- package/dist/ui/schema-form.js +393 -0
- package/dist/ui/styles.css +724 -0
- package/dist/ui/tester-window.html +116 -0
- package/dist/ui/tester-window.js +153 -0
- package/dist/ui/tester.js +1412 -0
- package/package.json +1 -1
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
(function () {
|
|
3
|
+
'use strict';
|
|
4
|
+
var AD = (window.AD = window.AD || {});
|
|
5
|
+
|
|
6
|
+
function escHtml(s) {
|
|
7
|
+
return String(s == null ? '' : s)
|
|
8
|
+
.replace(/&/g, '&')
|
|
9
|
+
.replace(/</g, '<')
|
|
10
|
+
.replace(/>/g, '>')
|
|
11
|
+
.replace(/"/g, '"');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function typeOf(schema) {
|
|
15
|
+
if (!schema) return 'unknown';
|
|
16
|
+
if (Array.isArray(schema.type)) {
|
|
17
|
+
return (
|
|
18
|
+
schema.type.filter(function (t) {
|
|
19
|
+
return t !== 'null';
|
|
20
|
+
})[0] || 'string'
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
return schema.type || (schema.properties ? 'object' : 'string');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function fieldId(path) {
|
|
27
|
+
return 'fld-' + path.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function renderField(schema, path, required, value) {
|
|
31
|
+
if (!schema) schema = {};
|
|
32
|
+
var t = typeOf(schema);
|
|
33
|
+
var id = fieldId(path);
|
|
34
|
+
var label = path.split('.').pop() || path;
|
|
35
|
+
var desc = schema.description
|
|
36
|
+
? '<div class="sf-desc">' + escHtml(schema.description) + '</div>'
|
|
37
|
+
: '';
|
|
38
|
+
var req = required ? ' <span class="sf-req">*</span>' : '';
|
|
39
|
+
var defaultVal = value != null ? value : schema.default;
|
|
40
|
+
|
|
41
|
+
if (schema.enum) {
|
|
42
|
+
var opts = schema.enum
|
|
43
|
+
.map(function (v) {
|
|
44
|
+
var sel = String(defaultVal) === String(v) ? ' selected' : '';
|
|
45
|
+
return '<option value="' + escHtml(v) + '"' + sel + '>' + escHtml(v) + '</option>';
|
|
46
|
+
})
|
|
47
|
+
.join('');
|
|
48
|
+
var blank = required ? '' : '<option value=""></option>';
|
|
49
|
+
return (
|
|
50
|
+
'<div class="sf-field" data-path="' +
|
|
51
|
+
escHtml(path) +
|
|
52
|
+
'" data-type="enum">' +
|
|
53
|
+
'<label for="' +
|
|
54
|
+
id +
|
|
55
|
+
'">' +
|
|
56
|
+
escHtml(label) +
|
|
57
|
+
req +
|
|
58
|
+
'</label>' +
|
|
59
|
+
'<select id="' +
|
|
60
|
+
id +
|
|
61
|
+
'" class="sf-input" data-path="' +
|
|
62
|
+
escHtml(path) +
|
|
63
|
+
'">' +
|
|
64
|
+
blank +
|
|
65
|
+
opts +
|
|
66
|
+
'</select>' +
|
|
67
|
+
desc +
|
|
68
|
+
'</div>'
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (t === 'boolean') {
|
|
73
|
+
var checked = defaultVal === true ? ' checked' : '';
|
|
74
|
+
return (
|
|
75
|
+
'<div class="sf-field sf-field-bool" data-path="' +
|
|
76
|
+
escHtml(path) +
|
|
77
|
+
'" data-type="boolean">' +
|
|
78
|
+
'<label class="sf-bool-label"><input type="checkbox" id="' +
|
|
79
|
+
id +
|
|
80
|
+
'" class="sf-input" data-path="' +
|
|
81
|
+
escHtml(path) +
|
|
82
|
+
'"' +
|
|
83
|
+
checked +
|
|
84
|
+
'/> ' +
|
|
85
|
+
escHtml(label) +
|
|
86
|
+
req +
|
|
87
|
+
'</label>' +
|
|
88
|
+
desc +
|
|
89
|
+
'</div>'
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (t === 'integer' || t === 'number') {
|
|
94
|
+
var step = t === 'integer' ? '1' : 'any';
|
|
95
|
+
var v = defaultVal != null ? escHtml(defaultVal) : '';
|
|
96
|
+
return (
|
|
97
|
+
'<div class="sf-field" data-path="' +
|
|
98
|
+
escHtml(path) +
|
|
99
|
+
'" data-type="' +
|
|
100
|
+
t +
|
|
101
|
+
'">' +
|
|
102
|
+
'<label for="' +
|
|
103
|
+
id +
|
|
104
|
+
'">' +
|
|
105
|
+
escHtml(label) +
|
|
106
|
+
req +
|
|
107
|
+
'</label>' +
|
|
108
|
+
'<input type="number" step="' +
|
|
109
|
+
step +
|
|
110
|
+
'" id="' +
|
|
111
|
+
id +
|
|
112
|
+
'" class="sf-input" data-path="' +
|
|
113
|
+
escHtml(path) +
|
|
114
|
+
'" value="' +
|
|
115
|
+
v +
|
|
116
|
+
'"/>' +
|
|
117
|
+
desc +
|
|
118
|
+
'</div>'
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (t === 'array') {
|
|
123
|
+
var itemSchema = schema.items || {};
|
|
124
|
+
var arr = Array.isArray(defaultVal) ? defaultVal : [];
|
|
125
|
+
var rows = arr
|
|
126
|
+
.map(function (item, i) {
|
|
127
|
+
return renderArrayRow(path + '[' + i + ']', itemSchema, item);
|
|
128
|
+
})
|
|
129
|
+
.join('');
|
|
130
|
+
return (
|
|
131
|
+
'<div class="sf-field sf-field-array" data-path="' +
|
|
132
|
+
escHtml(path) +
|
|
133
|
+
'" data-type="array">' +
|
|
134
|
+
'<label>' +
|
|
135
|
+
escHtml(label) +
|
|
136
|
+
req +
|
|
137
|
+
'</label>' +
|
|
138
|
+
'<div class="sf-array-rows" data-array-path="' +
|
|
139
|
+
escHtml(path) +
|
|
140
|
+
'">' +
|
|
141
|
+
rows +
|
|
142
|
+
'</div>' +
|
|
143
|
+
'<button type="button" class="sf-array-add" data-array-path="' +
|
|
144
|
+
escHtml(path) +
|
|
145
|
+
'">+ Add</button>' +
|
|
146
|
+
desc +
|
|
147
|
+
'</div>'
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (t === 'object' && schema.properties) {
|
|
152
|
+
var inner = renderObject(schema, path, defaultVal || {});
|
|
153
|
+
return (
|
|
154
|
+
'<fieldset class="sf-field sf-field-object" data-path="' +
|
|
155
|
+
escHtml(path) +
|
|
156
|
+
'" data-type="object">' +
|
|
157
|
+
'<legend>' +
|
|
158
|
+
escHtml(label) +
|
|
159
|
+
req +
|
|
160
|
+
'</legend>' +
|
|
161
|
+
inner +
|
|
162
|
+
desc +
|
|
163
|
+
'</fieldset>'
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// oneOf / anyOf / complex: raw JSON textarea fallback
|
|
168
|
+
if (schema.oneOf || schema.anyOf || schema.allOf || schema.patternProperties) {
|
|
169
|
+
var txt = defaultVal != null ? JSON.stringify(defaultVal, null, 2) : '';
|
|
170
|
+
return (
|
|
171
|
+
'<div class="sf-field" data-path="' +
|
|
172
|
+
escHtml(path) +
|
|
173
|
+
'" data-type="json">' +
|
|
174
|
+
'<label for="' +
|
|
175
|
+
id +
|
|
176
|
+
'">' +
|
|
177
|
+
escHtml(label) +
|
|
178
|
+
req +
|
|
179
|
+
' <span class="sf-hint">(raw JSON)</span></label>' +
|
|
180
|
+
'<textarea id="' +
|
|
181
|
+
id +
|
|
182
|
+
'" class="sf-input sf-textarea" data-path="' +
|
|
183
|
+
escHtml(path) +
|
|
184
|
+
'" rows="3">' +
|
|
185
|
+
escHtml(txt) +
|
|
186
|
+
'</textarea>' +
|
|
187
|
+
desc +
|
|
188
|
+
'</div>'
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// string (default)
|
|
193
|
+
var sv = defaultVal != null ? escHtml(defaultVal) : '';
|
|
194
|
+
var inputType = 'text';
|
|
195
|
+
if (schema.format === 'date-time') inputType = 'datetime-local';
|
|
196
|
+
else if (schema.format === 'date') inputType = 'date';
|
|
197
|
+
else if (schema.format === 'email') inputType = 'email';
|
|
198
|
+
else if (schema.format === 'uri' || schema.format === 'url') inputType = 'url';
|
|
199
|
+
return (
|
|
200
|
+
'<div class="sf-field" data-path="' +
|
|
201
|
+
escHtml(path) +
|
|
202
|
+
'" data-type="string">' +
|
|
203
|
+
'<label for="' +
|
|
204
|
+
id +
|
|
205
|
+
'">' +
|
|
206
|
+
escHtml(label) +
|
|
207
|
+
req +
|
|
208
|
+
'</label>' +
|
|
209
|
+
'<input type="' +
|
|
210
|
+
inputType +
|
|
211
|
+
'" id="' +
|
|
212
|
+
id +
|
|
213
|
+
'" class="sf-input" data-path="' +
|
|
214
|
+
escHtml(path) +
|
|
215
|
+
'" value="' +
|
|
216
|
+
sv +
|
|
217
|
+
'" placeholder="' +
|
|
218
|
+
escHtml(schema.examples ? schema.examples[0] || '' : '') +
|
|
219
|
+
'"/>' +
|
|
220
|
+
desc +
|
|
221
|
+
'</div>'
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function renderArrayRow(path, itemSchema, value) {
|
|
226
|
+
return (
|
|
227
|
+
'<div class="sf-array-row" data-row-path="' +
|
|
228
|
+
escHtml(path) +
|
|
229
|
+
'">' +
|
|
230
|
+
renderField(itemSchema, path, false, value) +
|
|
231
|
+
'<button type="button" class="sf-array-remove" data-remove-path="' +
|
|
232
|
+
escHtml(path) +
|
|
233
|
+
'" title="Remove">×</button>' +
|
|
234
|
+
'</div>'
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function renderObject(schema, basePath, value) {
|
|
239
|
+
var props = schema.properties || {};
|
|
240
|
+
var required = schema.required || [];
|
|
241
|
+
var html = '';
|
|
242
|
+
Object.keys(props).forEach(function (key) {
|
|
243
|
+
var childPath = basePath ? basePath + '.' + key : key;
|
|
244
|
+
var childValue = value && value[key];
|
|
245
|
+
html += renderField(props[key], childPath, required.indexOf(key) >= 0, childValue);
|
|
246
|
+
});
|
|
247
|
+
return html;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
AD.renderSchemaForm = function (schema, container, initialValue) {
|
|
251
|
+
if (!schema || typeof schema !== 'object') {
|
|
252
|
+
container.innerHTML = '<div class="sf-empty">No input schema — call with empty args.</div>';
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (schema.type !== 'object' || !schema.properties) {
|
|
256
|
+
// root is not an object — fall back to JSON textarea
|
|
257
|
+
container.innerHTML =
|
|
258
|
+
'<div class="sf-field" data-path="__root__" data-type="json">' +
|
|
259
|
+
'<label>Arguments (raw JSON)</label>' +
|
|
260
|
+
'<textarea class="sf-input sf-textarea" data-path="__root__" rows="6">' +
|
|
261
|
+
escHtml(initialValue ? JSON.stringify(initialValue, null, 2) : '') +
|
|
262
|
+
'</textarea>' +
|
|
263
|
+
'</div>';
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
container.innerHTML =
|
|
267
|
+
'<div class="sf-form-root">' + renderObject(schema, '', initialValue || {}) + '</div>';
|
|
268
|
+
wireArrayButtons(container, schema);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
function wireArrayButtons(container, schema) {
|
|
272
|
+
container.addEventListener('click', function (ev) {
|
|
273
|
+
var add = ev.target.closest && ev.target.closest('.sf-array-add');
|
|
274
|
+
if (add) {
|
|
275
|
+
ev.preventDefault();
|
|
276
|
+
var path = add.getAttribute('data-array-path');
|
|
277
|
+
var rows = container.querySelector('.sf-array-rows[data-array-path="' + path + '"]');
|
|
278
|
+
if (!rows) return;
|
|
279
|
+
var itemSchema = resolveSchema(schema, path);
|
|
280
|
+
var n = rows.children.length;
|
|
281
|
+
rows.insertAdjacentHTML(
|
|
282
|
+
'beforeend',
|
|
283
|
+
renderArrayRow(
|
|
284
|
+
path + '[' + n + ']',
|
|
285
|
+
itemSchema && itemSchema.items ? itemSchema.items : {},
|
|
286
|
+
undefined,
|
|
287
|
+
),
|
|
288
|
+
);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
var rm = ev.target.closest && ev.target.closest('.sf-array-remove');
|
|
292
|
+
if (rm) {
|
|
293
|
+
ev.preventDefault();
|
|
294
|
+
var row = rm.closest('.sf-array-row');
|
|
295
|
+
if (row) row.remove();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function resolveSchema(rootSchema, path) {
|
|
302
|
+
var parts = path
|
|
303
|
+
.replace(/\[\d+\]/g, '')
|
|
304
|
+
.split('.')
|
|
305
|
+
.filter(Boolean);
|
|
306
|
+
var current = rootSchema;
|
|
307
|
+
for (var i = 0; i < parts.length && current; i++) {
|
|
308
|
+
current = current.properties && current.properties[parts[i]];
|
|
309
|
+
}
|
|
310
|
+
return current;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
AD.collectSchemaForm = function (container) {
|
|
314
|
+
var result = {};
|
|
315
|
+
var rootInput = container.querySelector('[data-path="__root__"]');
|
|
316
|
+
if (rootInput && rootInput.tagName === 'TEXTAREA') {
|
|
317
|
+
var raw = rootInput.value.trim();
|
|
318
|
+
if (!raw) return {};
|
|
319
|
+
try {
|
|
320
|
+
return JSON.parse(raw);
|
|
321
|
+
} catch (e) {
|
|
322
|
+
throw new Error('Arguments JSON is invalid: ' + e.message);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Walk every input/select/textarea in DOM order, respecting array indices.
|
|
326
|
+
var inputs = container.querySelectorAll('.sf-input[data-path]');
|
|
327
|
+
for (var i = 0; i < inputs.length; i++) {
|
|
328
|
+
var el = inputs[i];
|
|
329
|
+
var path = el.getAttribute('data-path');
|
|
330
|
+
if (!path || path === '__root__') continue;
|
|
331
|
+
var val = readValue(el);
|
|
332
|
+
if (val === undefined) continue;
|
|
333
|
+
setPath(result, path, val);
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
function readValue(el) {
|
|
339
|
+
var field = el.closest('.sf-field');
|
|
340
|
+
var t = field ? field.getAttribute('data-type') : 'string';
|
|
341
|
+
if (el.tagName === 'SELECT') {
|
|
342
|
+
var v = el.value;
|
|
343
|
+
if (v === '') return undefined;
|
|
344
|
+
return v;
|
|
345
|
+
}
|
|
346
|
+
if (t === 'boolean') return el.checked;
|
|
347
|
+
if (t === 'integer') {
|
|
348
|
+
if (el.value === '') return undefined;
|
|
349
|
+
var n = parseInt(el.value, 10);
|
|
350
|
+
return isNaN(n) ? undefined : n;
|
|
351
|
+
}
|
|
352
|
+
if (t === 'number') {
|
|
353
|
+
if (el.value === '') return undefined;
|
|
354
|
+
var f = parseFloat(el.value);
|
|
355
|
+
return isNaN(f) ? undefined : f;
|
|
356
|
+
}
|
|
357
|
+
if (t === 'json') {
|
|
358
|
+
var raw = el.value.trim();
|
|
359
|
+
if (!raw) return undefined;
|
|
360
|
+
try {
|
|
361
|
+
return JSON.parse(raw);
|
|
362
|
+
} catch (e) {
|
|
363
|
+
throw new Error('Invalid JSON at ' + el.getAttribute('data-path') + ': ' + e.message);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (el.value === '') return undefined;
|
|
367
|
+
return el.value;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function setPath(obj, path, value) {
|
|
371
|
+
var parts = path.split(/\.|(?=\[)/).filter(Boolean);
|
|
372
|
+
var cur = obj;
|
|
373
|
+
for (var i = 0; i < parts.length; i++) {
|
|
374
|
+
var p = parts[i];
|
|
375
|
+
var isLast = i === parts.length - 1;
|
|
376
|
+
if (p.charAt(0) === '[') {
|
|
377
|
+
var idx = parseInt(p.slice(1, -1), 10);
|
|
378
|
+
if (!Array.isArray(cur)) return;
|
|
379
|
+
if (isLast) cur[idx] = value;
|
|
380
|
+
else {
|
|
381
|
+
if (cur[idx] == null) cur[idx] = parts[i + 1].charAt(0) === '[' ? [] : {};
|
|
382
|
+
cur = cur[idx];
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
if (isLast) cur[p] = value;
|
|
386
|
+
else {
|
|
387
|
+
if (cur[p] == null) cur[p] = parts[i + 1] && parts[i + 1].charAt(0) === '[' ? [] : {};
|
|
388
|
+
cur = cur[p];
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
})();
|