main
html 240 lines 8.87 KB
Raw
1 <html>
2 <head>
3 <title>Slash Command</title>
4 <script type="module">
5 import { store } from "/plugins/_commands/webui/commands-store.js";
6 </script>
7 </head>
8 <body>
9 <div x-data>
10 <template x-if="$store.commandsManager">
11 <div class="commands-editor"
12 x-create="$el.closest('.modal')?.querySelector('.modal-title') && ($el.closest('.modal').querySelector('.modal-title').textContent = $store.commandsManager.editorTitle)">
13 <div class="commands-editor-header">
14 <div class="commands-editor-copy">
15 <div class="commands-editor-title" x-text="$store.commandsManager.editorTitle"></div>
16 <div class="commands-editor-subtitle">
17 Saving writes a <code>.command.yaml</code> config plus a template file in <span x-text="$store.commandsManager.selectedScopeLabel"></span>.
18 </div>
19 </div>
20 </div>
21
22 <div class="commands-editor-grid">
23 <label class="commands-field">
24 <span>Command name</span>
25 <input type="text"
26 x-model="$store.commandsManager.editor.name"
27 placeholder="explain-code"
28 autocomplete="off">
29 </label>
30
31 <label class="commands-field">
32 <span>Description</span>
33 <input type="text"
34 x-model="$store.commandsManager.editor.description"
35 placeholder="Explain code clearly with examples.">
36 </label>
37 </div>
38
39 <label class="commands-field">
40 <span>Argument hint or example</span>
41 <input type="text"
42 x-model="$store.commandsManager.editor.argumentHint"
43 placeholder="Optional free-form text after /command">
44 </label>
45
46 <div class="commands-editor-grid">
47 <label class="commands-field">
48 <span>Command type</span>
49 <select x-model="$store.commandsManager.editor.commandType"
50 @change="$store.commandsManager.setEditorType($store.commandsManager.editor.commandType)">
51 <option value="text">Text template (.txt)</option>
52 <option value="script">Python hook (.py)</option>
53 </select>
54 </label>
55
56 <template x-if="$store.commandsManager.editor.commandType === 'script'">
57 <label class="commands-field commands-field-checkbox">
58 <span>Script context</span>
59 <div class="commands-checkbox-inline">
60 <input type="checkbox" x-model="$store.commandsManager.editor.includeHistory">
61 <span>Include chat history payload</span>
62 </div>
63 </label>
64 </template>
65 </div>
66
67 <label class="commands-field commands-field-body">
68 <span x-text="$store.commandsManager.editorBodyLabel"></span>
69 <textarea x-model="$store.commandsManager.editor.body"
70 rows="14"
71 :placeholder="$store.commandsManager.editor.commandType === 'script'
72 ? 'Implement run(payload) and return { text, effects }.'
73 : 'Write reusable text. Use {raw}, {args.positional.0}, {args.flags.some_flag}.'"></textarea>
74 </label>
75
76 <template x-if="$store.commandsManager.editor.commandType === 'text'">
77 <div class="commands-editor-help">
78 <span class="commands-help-chip">{raw}</span>
79 <span class="commands-help-chip">{args.positional.0}</span>
80 <span class="commands-help-chip">{args.flags.git_url}</span>
81 <span class="commands-help-copy">
82 Trailing command input is parsed once and exposed to template placeholders and python payloads.
83 </span>
84 </div>
85 </template>
86
87 <template x-if="$store.commandsManager.editor.commandType === 'script'">
88 <div class="commands-editor-help">
89 <span class="commands-help-chip">run(payload)</span>
90 <span class="commands-help-chip">payload.arguments</span>
91 <span class="commands-help-chip">result.effects</span>
92 <span class="commands-help-copy">
93 Return a string or <code>{ text, effects }</code>. Effects support <code>replace_input</code>, <code>append_input</code>, and <code>toast</code>.
94 </span>
95 </div>
96 </template>
97
98 <template x-if="$store.commandsManager.editor.path">
99 <div class="commands-editor-path">
100 <x-icon name="description"></x-icon>
101 <span x-text="$store.commandsManager.editor.path"></span>
102 </div>
103 </template>
104 </div>
105 </template>
106 </div>
107
108 <div class="modal-footer" data-modal-footer>
109 <button class="btn btn-ok"
110 @click="$store.commandsManager.saveEditor()"
111 :disabled="$store.commandsManager.saving">
112 Save
113 </button>
114 <button class="btn btn-cancel" @click="$store.commandsManager.closeEditor()">
115 Cancel
116 </button>
117 </div>
118
119 <style>
120 .commands-editor {
121 display: flex;
122 flex-direction: column;
123 gap: 1rem;
124 padding: 1rem 1.1rem 1.2rem;
125 }
126
127 .commands-editor-header {
128 display: flex;
129 justify-content: space-between;
130 gap: 1rem;
131 align-items: flex-start;
132 }
133
134 .commands-editor-copy {
135 min-width: 0;
136 }
137
138 .commands-editor-title {
139 font-size: 1.02rem;
140 font-weight: 600;
141 }
142
143 .commands-editor-subtitle {
144 margin-top: 0.25rem;
145 color: var(--color-text-secondary);
146 font-size: 0.88rem;
147 line-height: 1.45;
148 }
149
150 .commands-editor-grid {
151 display: grid;
152 grid-template-columns: repeat(2, minmax(0, 1fr));
153 gap: 0.85rem;
154 }
155
156 .commands-field {
157 display: flex;
158 flex-direction: column;
159 gap: 0.4rem;
160 }
161
162 .commands-field span {
163 font-size: 0.82rem;
164 font-weight: 600;
165 color: var(--color-text-secondary);
166 }
167
168 .commands-field textarea,
169 .commands-field input {
170 width: 100%;
171 }
172
173 .commands-field select {
174 width: 100%;
175 }
176
177 .commands-field-checkbox {
178 justify-content: flex-end;
179 }
180
181 .commands-checkbox-inline {
182 display: inline-flex;
183 align-items: center;
184 gap: 0.45rem;
185 color: var(--color-text-primary);
186 font-size: 0.86rem;
187 font-weight: 500;
188 }
189
190 .commands-checkbox-inline input {
191 width: auto;
192 }
193
194 .commands-field-body textarea {
195 min-height: 18rem;
196 resize: vertical;
197 font-family: "Roboto Mono", monospace;
198 }
199
200 .commands-editor-help {
201 display: flex;
202 flex-wrap: wrap;
203 gap: 0.5rem;
204 align-items: center;
205 }
206
207 .commands-help-chip {
208 display: inline-flex;
209 align-items: center;
210 padding: 0.22rem 0.55rem;
211 border-radius: 999px;
212 background: color-mix(in srgb, var(--color-highlight) 12%, transparent);
213 border: 1px solid color-mix(in srgb, var(--color-highlight) 24%, transparent);
214 font-family: "Roboto Mono", monospace;
215 font-size: 0.8rem;
216 }
217
218 .commands-help-copy {
219 color: var(--color-text-secondary);
220 font-size: 0.85rem;
221 }
222
223 .commands-editor-path {
224 display: inline-flex;
225 align-items: center;
226 gap: 0.45rem;
227 color: var(--color-text-secondary);
228 font-family: "Roboto Mono", monospace;
229 font-size: 0.78rem;
230 word-break: break-all;
231 }
232
233 @media (max-width: 760px) {
234 .commands-editor-grid {
235 grid-template-columns: 1fr;
236 }
237 }
238 </style>
239 </body>
240 </html>