main
html 105 lines 4.62 KB
Raw
1 <html>
2 <head>
3 <title>Plugin Scanner</title>
4 <script type="module">
5 import { store } from "/plugins/_plugin_scan/webui/plugin-scan-store.js";
6 </script>
7 </head>
8 <body>
9 <div x-data>
10 <template x-if="$store.pluginScan">
11 <div x-create="$store.pluginScan.onOpen()" x-destroy="$store.pluginScan.cleanup()" class="plugin-scan">
12
13 <!-- Git URL -->
14 <div class="scan-field">
15 <label>Git Repository URL</label>
16 <input type="text" x-model="$store.pluginScan.gitUrl"
17 @input.debounce.300ms="$store.pluginScan.buildPrompt()"
18 placeholder="https://github.com/user/plugin-repo.git" />
19 </div>
20
21 <!-- Checks -->
22 <div class="scan-field">
23 <label>Security Checks</label>
24 <div class="scan-checks">
25 <template x-for="[key, meta] of Object.entries($store.pluginScan.checksMeta)" :key="key">
26 <label>
27 <input type="checkbox" x-model="$store.pluginScan.checks[key]"
28 @change="$store.pluginScan.buildPrompt()" />
29 <span x-text="meta.label"></span>
30 </label>
31 </template>
32 </div>
33 </div>
34
35 <!-- Prompt -->
36 <div class="scan-field">
37 <label>Agent Prompt <span style="font-weight:400; opacity:0.6">(editable)</span></label>
38 <textarea x-model="$store.pluginScan.prompt"></textarea>
39 </div>
40 <!-- Actions -->
41 <div class="scan-actions">
42 <button class="button" @click="$store.pluginScan.copyPrompt()">Copy Prompt</button>
43 <button class="button confirm" @click="$store.pluginScan.runScan()">
44 <span x-show="$store.pluginScan.scanning"><span class="scan-spinner"></span>Run Another Scan</span>
45 <span x-show="!$store.pluginScan.scanning">Run Scan</span>
46 </button>
47 <button class="button" @click="$store.pluginScan.openChatInNewWindow()"
48 x-show="$store.pluginScan.scanCtxId"
49 title="Open this scan's chat in a new tab">
50 Open in Chat ↗
51 </button>
52 </div>
53
54 <!-- Output -->
55 <div x-show="$store.pluginScan.output" class="scan-output">
56 <label style="font-size:0.85rem; font-weight:600; opacity:0.8;">Scan Results</label>
57 <div class="scan-output-html" x-html="$store.pluginScan.renderedOutput"></div>
58 </div>
59
60 </div>
61 </template>
62 </div>
63
64 <style>
65 .plugin-scan { display: flex; flex-direction: column; gap: 1rem; padding: 0.5rem; }
66
67 .scan-field { display: flex; flex-direction: column; gap: 0.35rem; }
68 .scan-field label { font-size: 0.85rem; font-weight: 600; opacity: 0.8; }
69 .scan-field input[type="text"],
70 .scan-field textarea {
71 width: 100%;
72 border: 1px solid var(--color-border);
73 border-radius: 6px;
74 padding: 0.5rem 0.75rem;
75 font-family: inherit;
76 font-size: 0.875rem;
77 background: var(--color-panel);
78 color: var(--color-text);
79 box-sizing: border-box;
80 }
81 .scan-field textarea { min-height: 15rem; resize: none; font-family: monospace; font-size: 0.8rem; }
82 .scan-field input:focus,
83 .scan-field textarea:focus { outline: none; border-color: var(--color-primary); }
84
85 .scan-checks { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
86 .scan-checks label { display: flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; cursor: pointer; user-select: none; }
87 .scan-checks input[type="checkbox"] { accent-color: var(--color-primary); }
88
89 .scan-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
90
91 .scan-output { border-top: 1px solid var(--color-border); padding-top: 1rem; }
92 .scan-output-html { line-height: 1.5; }
93 .scan-output-html table { border-collapse: collapse; width: 100%; margin: 0.75rem 0; }
94 .scan-output-html th,
95 .scan-output-html td { border: 1px solid var(--color-border); padding: 0.4rem 0.6rem; text-align: left; font-size: 0.85rem; }
96 .scan-output-html th { background: var(--color-panel); font-weight: 600; }
97 .scan-output-html hr { border: 1px solid var(--color-border); }
98 .scan-output-html pre { background: var(--color-panel); border: 1px solid var(--color-border); border-radius: 6px; padding: 0.75rem; overflow-x: auto; }
99 .scan-output-html code { font-size: 0.8rem; }
100 .scan-spinner { display: inline-block; width: 1em; height: 1em; border: 2px solid var(--color-border);
101 border-top-color: var(--color-primary); border-radius: 50%; animation: scan-spin 0.6s linear infinite; vertical-align: middle; margin-right: 0.4em; }
102 @keyframes scan-spin { to { transform: rotate(360deg); } }
103 </style>
104 </body>
105 </html>