@mainwp/control 1.0.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/LICENSE +674 -0
- package/README.md +583 -0
- package/bin/_exit.js +12 -0
- package/bin/dev.js +7 -0
- package/bin/run.js +7 -0
- package/dist/chat/chat-engine.d.ts +213 -0
- package/dist/chat/chat-engine.d.ts.map +1 -0
- package/dist/chat/chat-engine.js +636 -0
- package/dist/chat/chat-engine.js.map +1 -0
- package/dist/chat/index.d.ts +10 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +14 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/providers/anthropic.d.ts +52 -0
- package/dist/chat/providers/anthropic.d.ts.map +1 -0
- package/dist/chat/providers/anthropic.js +292 -0
- package/dist/chat/providers/anthropic.js.map +1 -0
- package/dist/chat/providers/gemini.d.ts +52 -0
- package/dist/chat/providers/gemini.d.ts.map +1 -0
- package/dist/chat/providers/gemini.js +284 -0
- package/dist/chat/providers/gemini.js.map +1 -0
- package/dist/chat/providers/index.d.ts +19 -0
- package/dist/chat/providers/index.d.ts.map +1 -0
- package/dist/chat/providers/index.js +23 -0
- package/dist/chat/providers/index.js.map +1 -0
- package/dist/chat/providers/local.d.ts +37 -0
- package/dist/chat/providers/local.d.ts.map +1 -0
- package/dist/chat/providers/local.js +130 -0
- package/dist/chat/providers/local.js.map +1 -0
- package/dist/chat/providers/openai-compatible.d.ts +155 -0
- package/dist/chat/providers/openai-compatible.d.ts.map +1 -0
- package/dist/chat/providers/openai-compatible.js +264 -0
- package/dist/chat/providers/openai-compatible.js.map +1 -0
- package/dist/chat/providers/openai.d.ts +24 -0
- package/dist/chat/providers/openai.d.ts.map +1 -0
- package/dist/chat/providers/openai.js +62 -0
- package/dist/chat/providers/openai.js.map +1 -0
- package/dist/chat/providers/openrouter.d.ts +26 -0
- package/dist/chat/providers/openrouter.d.ts.map +1 -0
- package/dist/chat/providers/openrouter.js +65 -0
- package/dist/chat/providers/openrouter.js.map +1 -0
- package/dist/chat/providers/provider-fetch.d.ts +15 -0
- package/dist/chat/providers/provider-fetch.d.ts.map +1 -0
- package/dist/chat/providers/provider-fetch.js +35 -0
- package/dist/chat/providers/provider-fetch.js.map +1 -0
- package/dist/chat/providers/provider.d.ts +214 -0
- package/dist/chat/providers/provider.d.ts.map +1 -0
- package/dist/chat/providers/provider.js +166 -0
- package/dist/chat/providers/provider.js.map +1 -0
- package/dist/chat/providers/sse-reader.d.ts +21 -0
- package/dist/chat/providers/sse-reader.d.ts.map +1 -0
- package/dist/chat/providers/sse-reader.js +48 -0
- package/dist/chat/providers/sse-reader.js.map +1 -0
- package/dist/chat/system-prompt.d.ts +33 -0
- package/dist/chat/system-prompt.d.ts.map +1 -0
- package/dist/chat/system-prompt.js +166 -0
- package/dist/chat/system-prompt.js.map +1 -0
- package/dist/chat/tool-envelope.d.ts +72 -0
- package/dist/chat/tool-envelope.d.ts.map +1 -0
- package/dist/chat/tool-envelope.js +263 -0
- package/dist/chat/tool-envelope.js.map +1 -0
- package/dist/commands/abilities/info.d.ts +21 -0
- package/dist/commands/abilities/info.d.ts.map +1 -0
- package/dist/commands/abilities/info.js +80 -0
- package/dist/commands/abilities/info.js.map +1 -0
- package/dist/commands/abilities/list.d.ts +19 -0
- package/dist/commands/abilities/list.d.ts.map +1 -0
- package/dist/commands/abilities/list.js +98 -0
- package/dist/commands/abilities/list.js.map +1 -0
- package/dist/commands/abilities/run.d.ts +75 -0
- package/dist/commands/abilities/run.d.ts.map +1 -0
- package/dist/commands/abilities/run.js +468 -0
- package/dist/commands/abilities/run.js.map +1 -0
- package/dist/commands/chat.d.ts +54 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +384 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config/show.d.ts +54 -0
- package/dist/commands/config/show.d.ts.map +1 -0
- package/dist/commands/config/show.js +324 -0
- package/dist/commands/config/show.js.map +1 -0
- package/dist/commands/doctor.d.ts +77 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +412 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/jobs/watch.d.ts +50 -0
- package/dist/commands/jobs/watch.d.ts.map +1 -0
- package/dist/commands/jobs/watch.js +269 -0
- package/dist/commands/jobs/watch.js.map +1 -0
- package/dist/commands/login.d.ts +25 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +165 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/profile/delete.d.ts +22 -0
- package/dist/commands/profile/delete.d.ts.map +1 -0
- package/dist/commands/profile/delete.js +57 -0
- package/dist/commands/profile/delete.js.map +1 -0
- package/dist/commands/profile/list.d.ts +19 -0
- package/dist/commands/profile/list.d.ts.map +1 -0
- package/dist/commands/profile/list.js +53 -0
- package/dist/commands/profile/list.js.map +1 -0
- package/dist/commands/profile/use.d.ts +22 -0
- package/dist/commands/profile/use.d.ts.map +1 -0
- package/dist/commands/profile/use.js +46 -0
- package/dist/commands/profile/use.js.map +1 -0
- package/dist/config/fs-utils.d.ts +14 -0
- package/dist/config/fs-utils.d.ts.map +1 -0
- package/dist/config/fs-utils.js +31 -0
- package/dist/config/fs-utils.js.map +1 -0
- package/dist/config/keychain.d.ts +53 -0
- package/dist/config/keychain.d.ts.map +1 -0
- package/dist/config/keychain.js +175 -0
- package/dist/config/keychain.js.map +1 -0
- package/dist/config/profile-store.d.ts +85 -0
- package/dist/config/profile-store.d.ts.map +1 -0
- package/dist/config/profile-store.js +228 -0
- package/dist/config/profile-store.js.map +1 -0
- package/dist/config/settings.d.ts +71 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +151 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/core/abilities-executor.d.ts +126 -0
- package/dist/core/abilities-executor.d.ts.map +1 -0
- package/dist/core/abilities-executor.js +264 -0
- package/dist/core/abilities-executor.js.map +1 -0
- package/dist/core/batch-manager.d.ts +113 -0
- package/dist/core/batch-manager.d.ts.map +1 -0
- package/dist/core/batch-manager.js +244 -0
- package/dist/core/batch-manager.js.map +1 -0
- package/dist/core/http-client.d.ts +111 -0
- package/dist/core/http-client.d.ts.map +1 -0
- package/dist/core/http-client.js +329 -0
- package/dist/core/http-client.js.map +1 -0
- package/dist/core/safety-controller.d.ts +114 -0
- package/dist/core/safety-controller.d.ts.map +1 -0
- package/dist/core/safety-controller.js +229 -0
- package/dist/core/safety-controller.js.map +1 -0
- package/dist/hooks/command-not-found.d.ts +12 -0
- package/dist/hooks/command-not-found.d.ts.map +1 -0
- package/dist/hooks/command-not-found.js +58 -0
- package/dist/hooks/command-not-found.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/base-command.d.ts +123 -0
- package/dist/lib/base-command.d.ts.map +1 -0
- package/dist/lib/base-command.js +285 -0
- package/dist/lib/base-command.js.map +1 -0
- package/dist/output/formatter.d.ts +48 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +138 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/json-envelope.d.ts +43 -0
- package/dist/output/json-envelope.d.ts.map +1 -0
- package/dist/output/json-envelope.js +73 -0
- package/dist/output/json-envelope.js.map +1 -0
- package/dist/utils/audit-logger.d.ts +97 -0
- package/dist/utils/audit-logger.d.ts.map +1 -0
- package/dist/utils/audit-logger.js +169 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/colors.d.ts +29 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +36 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/errors.d.ts +107 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +149 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +21 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +20 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/format.d.ts +64 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +69 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/prompt.d.ts +34 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +132 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/retry.d.ts +59 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +96 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/terminal-sanitizer.d.ts +60 -0
- package/dist/utils/terminal-sanitizer.d.ts.map +1 -0
- package/dist/utils/terminal-sanitizer.js +166 -0
- package/dist/utils/terminal-sanitizer.js.map +1 -0
- package/dist/validation/input-sanitizer.d.ts +76 -0
- package/dist/validation/input-sanitizer.d.ts.map +1 -0
- package/dist/validation/input-sanitizer.js +199 -0
- package/dist/validation/input-sanitizer.js.map +1 -0
- package/dist/validation/schema-validator.d.ts +75 -0
- package/dist/validation/schema-validator.d.ts.map +1 -0
- package/dist/validation/schema-validator.js +147 -0
- package/dist/validation/schema-validator.js.map +1 -0
- package/oclif.manifest.json +857 -0
- package/package.json +101 -0
- package/scripts/completions/README.md +221 -0
- package/scripts/completions/mainwpcontrol.bash +193 -0
- package/scripts/completions/mainwpcontrol.zsh +267 -0
- package/scripts/completions/profile-completer.sh +35 -0
- package/scripts/completions/regenerate.sh +78 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile store for mainwpcontrol
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple Dashboard connection profiles.
|
|
5
|
+
*/
|
|
6
|
+
import { promises as fs } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { ConfigError } from '../utils/errors.js';
|
|
9
|
+
import { getConfigDir } from './settings.js';
|
|
10
|
+
import { atomicWriteFile } from './fs-utils.js';
|
|
11
|
+
/**
|
|
12
|
+
* Get the profiles file path
|
|
13
|
+
*/
|
|
14
|
+
function getProfilesPath() {
|
|
15
|
+
return join(getConfigDir(), 'profiles.json');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Load profiles from file
|
|
19
|
+
*/
|
|
20
|
+
async function loadProfilesFile() {
|
|
21
|
+
const path = getProfilesPath();
|
|
22
|
+
try {
|
|
23
|
+
const content = await fs.readFile(path, 'utf-8');
|
|
24
|
+
return JSON.parse(content);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error.code === 'ENOENT') {
|
|
28
|
+
return { profiles: [] };
|
|
29
|
+
}
|
|
30
|
+
throw new ConfigError(`Failed to load profiles: ${error.message}`, undefined, 'Check file permissions for ~/.config/mainwpcontrol/profiles.json');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Save profiles to file
|
|
35
|
+
*
|
|
36
|
+
* SECURITY: Uses atomic write (tmp + rename) and restricted permissions.
|
|
37
|
+
*/
|
|
38
|
+
async function saveProfilesFile(data) {
|
|
39
|
+
const path = getProfilesPath();
|
|
40
|
+
await atomicWriteFile(path, JSON.stringify(data, null, 2));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Profile store class
|
|
44
|
+
*/
|
|
45
|
+
export class ProfileStore {
|
|
46
|
+
data = null;
|
|
47
|
+
/**
|
|
48
|
+
* Validate a URL format and protocol
|
|
49
|
+
*/
|
|
50
|
+
validateUrl(url) {
|
|
51
|
+
let parsed;
|
|
52
|
+
try {
|
|
53
|
+
parsed = new URL(url);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
throw new ConfigError(`Invalid Dashboard URL format: ${url}`, undefined, 'URL must include protocol (http:// or https://) and hostname');
|
|
57
|
+
}
|
|
58
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
59
|
+
throw new ConfigError(`Invalid URL protocol: ${parsed.protocol}. Must be http or https`, undefined, 'Only HTTP and HTTPS protocols are supported');
|
|
60
|
+
}
|
|
61
|
+
// HTTP warning is emitted at login time via formatWarning, not here
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate a profile's required fields and URL format
|
|
65
|
+
*/
|
|
66
|
+
validateProfile(profile) {
|
|
67
|
+
const validationHint = 'Run `mainwpcontrol login` to create a valid profile';
|
|
68
|
+
if (!profile.name || profile.name.trim().length === 0) {
|
|
69
|
+
throw new ConfigError('Profile validation failed: name is required', undefined, validationHint);
|
|
70
|
+
}
|
|
71
|
+
if (!profile.dashboardUrl || profile.dashboardUrl.trim().length === 0) {
|
|
72
|
+
throw new ConfigError('Profile validation failed: dashboardUrl is required', undefined, validationHint);
|
|
73
|
+
}
|
|
74
|
+
if (!profile.username || profile.username.trim().length === 0) {
|
|
75
|
+
throw new ConfigError('Profile validation failed: username is required', undefined, validationHint);
|
|
76
|
+
}
|
|
77
|
+
if (!profile.createdAt || profile.createdAt.trim().length === 0) {
|
|
78
|
+
throw new ConfigError('Profile validation failed: createdAt is required', undefined, validationHint);
|
|
79
|
+
}
|
|
80
|
+
this.validateUrl(profile.dashboardUrl);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate entire profiles file structure
|
|
84
|
+
*/
|
|
85
|
+
validateProfilesFile(data) {
|
|
86
|
+
for (const profile of data.profiles) {
|
|
87
|
+
try {
|
|
88
|
+
this.validateProfile(profile);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// Preserve hint from the original ConfigError when rewrapping
|
|
92
|
+
const hint = error instanceof ConfigError ? error.hint : undefined;
|
|
93
|
+
throw new ConfigError(`Invalid profile "${profile.name || 'unnamed'}": ${error.message}`, undefined, hint);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Validate activeProfile references an existing profile
|
|
97
|
+
if (data.activeProfile &&
|
|
98
|
+
!data.profiles.some((p) => p.name === data.activeProfile)) {
|
|
99
|
+
data.activeProfile = data.profiles[0]?.name;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Ensure data is loaded
|
|
104
|
+
*/
|
|
105
|
+
async ensureLoaded() {
|
|
106
|
+
if (!this.data) {
|
|
107
|
+
const data = await loadProfilesFile();
|
|
108
|
+
this.validateProfilesFile(data);
|
|
109
|
+
this.data = data;
|
|
110
|
+
}
|
|
111
|
+
return this.data;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* List all profiles
|
|
115
|
+
*/
|
|
116
|
+
async list() {
|
|
117
|
+
const data = await this.ensureLoaded();
|
|
118
|
+
return data.profiles;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the active profile
|
|
122
|
+
*/
|
|
123
|
+
async getActive() {
|
|
124
|
+
const data = await this.ensureLoaded();
|
|
125
|
+
if (!data.activeProfile) {
|
|
126
|
+
// Return first profile if no active set
|
|
127
|
+
return data.profiles[0];
|
|
128
|
+
}
|
|
129
|
+
return data.profiles.find((p) => p.name === data.activeProfile);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get the active profile name
|
|
133
|
+
*/
|
|
134
|
+
async getActiveName() {
|
|
135
|
+
const data = await this.ensureLoaded();
|
|
136
|
+
return data.activeProfile ?? data.profiles[0]?.name;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Set the active profile
|
|
140
|
+
*/
|
|
141
|
+
async setActive(name) {
|
|
142
|
+
const data = await this.ensureLoaded();
|
|
143
|
+
const profile = data.profiles.find((p) => p.name === name);
|
|
144
|
+
if (!profile) {
|
|
145
|
+
throw new ConfigError(`Profile not found: ${name}`, undefined, 'List available profiles with `mainwpcontrol profile list`');
|
|
146
|
+
}
|
|
147
|
+
data.activeProfile = name;
|
|
148
|
+
profile.lastUsedAt = new Date().toISOString();
|
|
149
|
+
await saveProfilesFile(data);
|
|
150
|
+
this.data = data;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get a profile by name
|
|
154
|
+
*/
|
|
155
|
+
async get(name) {
|
|
156
|
+
const data = await this.ensureLoaded();
|
|
157
|
+
return data.profiles.find((p) => p.name === name);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Save a profile (create or update)
|
|
161
|
+
*/
|
|
162
|
+
async save(profile) {
|
|
163
|
+
// Validate profile before saving
|
|
164
|
+
this.validateProfile(profile);
|
|
165
|
+
const data = await this.ensureLoaded();
|
|
166
|
+
const existingIndex = data.profiles.findIndex((p) => p.name === profile.name);
|
|
167
|
+
if (existingIndex >= 0) {
|
|
168
|
+
// Update existing
|
|
169
|
+
data.profiles[existingIndex] = profile;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Add new
|
|
173
|
+
data.profiles.push(profile);
|
|
174
|
+
}
|
|
175
|
+
// Set as active if it's the first profile
|
|
176
|
+
if (data.profiles.length === 1) {
|
|
177
|
+
data.activeProfile = profile.name;
|
|
178
|
+
}
|
|
179
|
+
await saveProfilesFile(data);
|
|
180
|
+
this.data = data;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Remove a profile
|
|
184
|
+
*/
|
|
185
|
+
async remove(name) {
|
|
186
|
+
const data = await this.ensureLoaded();
|
|
187
|
+
const index = data.profiles.findIndex((p) => p.name === name);
|
|
188
|
+
if (index < 0) {
|
|
189
|
+
throw new ConfigError(`Profile not found: ${name}`, undefined, 'List available profiles with `mainwpcontrol profile list`');
|
|
190
|
+
}
|
|
191
|
+
data.profiles.splice(index, 1);
|
|
192
|
+
// Clear active if we removed the active profile
|
|
193
|
+
if (data.activeProfile === name) {
|
|
194
|
+
data.activeProfile = data.profiles[0]?.name;
|
|
195
|
+
}
|
|
196
|
+
await saveProfilesFile(data);
|
|
197
|
+
this.data = data;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if a profile exists
|
|
201
|
+
*/
|
|
202
|
+
async exists(name) {
|
|
203
|
+
const data = await this.ensureLoaded();
|
|
204
|
+
return data.profiles.some((p) => p.name === name);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Reload profiles from disk
|
|
208
|
+
*/
|
|
209
|
+
async reload() {
|
|
210
|
+
const data = await loadProfilesFile();
|
|
211
|
+
this.validateProfilesFile(data);
|
|
212
|
+
this.data = data;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Singleton instance
|
|
217
|
+
*/
|
|
218
|
+
let profileStoreInstance = null;
|
|
219
|
+
/**
|
|
220
|
+
* Get the profile store instance
|
|
221
|
+
*/
|
|
222
|
+
export function getProfileStore() {
|
|
223
|
+
if (!profileStoreInstance) {
|
|
224
|
+
profileStoreInstance = new ProfileStore();
|
|
225
|
+
}
|
|
226
|
+
return profileStoreInstance;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=profile-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-store.js","sourceRoot":"","sources":["../../src/config/profile-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings file support for mainwpcontrol
|
|
3
|
+
*/
|
|
4
|
+
import { type ProviderName } from '../chat/providers/provider.js';
|
|
5
|
+
/**
|
|
6
|
+
* Settings structure
|
|
7
|
+
*/
|
|
8
|
+
export interface Settings {
|
|
9
|
+
/** Default output format (true = JSON, false = human-readable) */
|
|
10
|
+
defaultJsonOutput?: boolean;
|
|
11
|
+
/** Default LLM provider */
|
|
12
|
+
llmProvider?: string;
|
|
13
|
+
/** Default timeout for HTTP requests (ms) */
|
|
14
|
+
timeout?: number;
|
|
15
|
+
/** Skip SSL verification (not recommended) */
|
|
16
|
+
skipSSLVerification?: boolean;
|
|
17
|
+
/** Enable debug output */
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
/** Maximum messages to keep in chat context (default: 20, 0 = unlimited) */
|
|
20
|
+
chatContextMessages?: number;
|
|
21
|
+
/** Maximum estimated tokens in chat context (reserved for future use) */
|
|
22
|
+
chatContextTokens?: number;
|
|
23
|
+
/** Allow insecure HTTP connections (not recommended) */
|
|
24
|
+
allowInsecureHttp?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ResolvedSettings {
|
|
27
|
+
defaultJsonOutput: boolean;
|
|
28
|
+
llmProvider?: ProviderName;
|
|
29
|
+
timeout: number;
|
|
30
|
+
skipSSLVerification: boolean;
|
|
31
|
+
debug: boolean;
|
|
32
|
+
chatContextMessages: number;
|
|
33
|
+
chatContextTokens?: number;
|
|
34
|
+
allowInsecureHttp: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface SettingsResolution {
|
|
37
|
+
settings: ResolvedSettings;
|
|
38
|
+
warnings: string[];
|
|
39
|
+
}
|
|
40
|
+
export declare const SETTINGS_DEFAULTS: ResolvedSettings;
|
|
41
|
+
/**
|
|
42
|
+
* Get the config directory path
|
|
43
|
+
*/
|
|
44
|
+
export declare function getConfigDir(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Get the settings file path
|
|
47
|
+
*/
|
|
48
|
+
export declare function getSettingsPath(): string;
|
|
49
|
+
/**
|
|
50
|
+
* Load settings from file (cached after first read)
|
|
51
|
+
*/
|
|
52
|
+
export declare function loadSettings(): Promise<Settings>;
|
|
53
|
+
/**
|
|
54
|
+
* Validate and normalize settings with safe fallbacks.
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveSettings(raw: Settings): SettingsResolution;
|
|
57
|
+
/**
|
|
58
|
+
* Clear the settings cache (forces re-read on next loadSettings call)
|
|
59
|
+
*/
|
|
60
|
+
export declare function clearSettingsCache(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Save settings to file
|
|
63
|
+
*
|
|
64
|
+
* SECURITY: Uses atomic write (tmp + rename) and restricted permissions.
|
|
65
|
+
*/
|
|
66
|
+
export declare function saveSettings(settings: Settings): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Update specific settings
|
|
69
|
+
*/
|
|
70
|
+
export declare function updateSettings(updates: Partial<Settings>): Promise<Settings>;
|
|
71
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/config/settings.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,+BAA+B,CAAC;AAGvC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8CAA8C;IAC9C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,0BAA0B;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,EAAE,gBAO/B,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAUD;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAyBtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,kBAAkB,CA4DjE;AAoBD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAKlF"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings file support for mainwpcontrol
|
|
3
|
+
*/
|
|
4
|
+
import { promises as fs } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { isSupportedProviderName, SUPPORTED_PROVIDER_NAMES, } from '../chat/providers/provider.js';
|
|
8
|
+
import { atomicWriteFile } from './fs-utils.js';
|
|
9
|
+
export const SETTINGS_DEFAULTS = {
|
|
10
|
+
defaultJsonOutput: false,
|
|
11
|
+
timeout: 30000,
|
|
12
|
+
skipSSLVerification: false,
|
|
13
|
+
debug: false,
|
|
14
|
+
chatContextMessages: 20,
|
|
15
|
+
allowInsecureHttp: false,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Get the config directory path
|
|
19
|
+
*/
|
|
20
|
+
export function getConfigDir() {
|
|
21
|
+
const xdgConfig = process.env['XDG_CONFIG_HOME'];
|
|
22
|
+
if (xdgConfig) {
|
|
23
|
+
return join(xdgConfig, 'mainwpcontrol');
|
|
24
|
+
}
|
|
25
|
+
return join(homedir(), '.config', 'mainwpcontrol');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get the settings file path
|
|
29
|
+
*/
|
|
30
|
+
export function getSettingsPath() {
|
|
31
|
+
return join(getConfigDir(), 'settings.json');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Cached settings (cleared on explicit reload).
|
|
35
|
+
* No TTL needed: mainwpcontrol is a short-lived CLI process — settings are read
|
|
36
|
+
* once per invocation. clearSettingsCache() handles explicit invalidation
|
|
37
|
+
* (e.g. after saveSettings).
|
|
38
|
+
*/
|
|
39
|
+
let cachedSettings = null;
|
|
40
|
+
/**
|
|
41
|
+
* Load settings from file (cached after first read)
|
|
42
|
+
*/
|
|
43
|
+
export async function loadSettings() {
|
|
44
|
+
if (cachedSettings) {
|
|
45
|
+
return cachedSettings;
|
|
46
|
+
}
|
|
47
|
+
const path = getSettingsPath();
|
|
48
|
+
try {
|
|
49
|
+
const content = await fs.readFile(path, 'utf-8');
|
|
50
|
+
cachedSettings = JSON.parse(content);
|
|
51
|
+
return cachedSettings;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error.code === 'ENOENT') {
|
|
55
|
+
cachedSettings = {};
|
|
56
|
+
return cachedSettings;
|
|
57
|
+
}
|
|
58
|
+
if (error instanceof SyntaxError) {
|
|
59
|
+
// Corrupted/malformed JSON — warn but don't crash
|
|
60
|
+
console.error(`Warning: Failed to parse settings file at ${path}. Using defaults.`);
|
|
61
|
+
cachedSettings = {};
|
|
62
|
+
return cachedSettings;
|
|
63
|
+
}
|
|
64
|
+
// Permission or other I/O error — surface it
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validate and normalize settings with safe fallbacks.
|
|
70
|
+
*/
|
|
71
|
+
export function resolveSettings(raw) {
|
|
72
|
+
const warnings = [];
|
|
73
|
+
const settings = { ...SETTINGS_DEFAULTS };
|
|
74
|
+
settings.defaultJsonOutput = readBooleanSetting(raw.defaultJsonOutput, 'defaultJsonOutput', SETTINGS_DEFAULTS.defaultJsonOutput, warnings);
|
|
75
|
+
settings.debug = readBooleanSetting(raw.debug, 'debug', SETTINGS_DEFAULTS.debug, warnings);
|
|
76
|
+
settings.skipSSLVerification = readBooleanSetting(raw.skipSSLVerification, 'skipSSLVerification', SETTINGS_DEFAULTS.skipSSLVerification, warnings);
|
|
77
|
+
settings.allowInsecureHttp = readBooleanSetting(raw.allowInsecureHttp, 'allowInsecureHttp', SETTINGS_DEFAULTS.allowInsecureHttp, warnings);
|
|
78
|
+
if (raw.timeout === undefined) {
|
|
79
|
+
settings.timeout = SETTINGS_DEFAULTS.timeout;
|
|
80
|
+
}
|
|
81
|
+
else if (Number.isInteger(raw.timeout) && raw.timeout > 0) {
|
|
82
|
+
settings.timeout = raw.timeout;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
warnings.push('Ignoring invalid settings.timeout; expected a positive integer in milliseconds.');
|
|
86
|
+
}
|
|
87
|
+
if (raw.chatContextMessages === undefined) {
|
|
88
|
+
settings.chatContextMessages = SETTINGS_DEFAULTS.chatContextMessages;
|
|
89
|
+
}
|
|
90
|
+
else if (Number.isInteger(raw.chatContextMessages) && raw.chatContextMessages >= 0) {
|
|
91
|
+
settings.chatContextMessages = raw.chatContextMessages;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
warnings.push('Ignoring invalid settings.chatContextMessages; expected an integer greater than or equal to 0.');
|
|
95
|
+
}
|
|
96
|
+
if (raw.chatContextTokens !== undefined) {
|
|
97
|
+
if (Number.isInteger(raw.chatContextTokens) && raw.chatContextTokens > 0) {
|
|
98
|
+
settings.chatContextTokens = raw.chatContextTokens;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
warnings.push('Ignoring invalid settings.chatContextTokens; expected a positive integer.');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (raw.llmProvider) {
|
|
105
|
+
const normalized = raw.llmProvider.trim().toLowerCase();
|
|
106
|
+
if (isSupportedProviderName(normalized)) {
|
|
107
|
+
settings.llmProvider = normalized;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
warnings.push(`Ignoring invalid settings.llmProvider "${raw.llmProvider}". Available: ${SUPPORTED_PROVIDER_NAMES.join(', ')}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return { settings, warnings };
|
|
114
|
+
}
|
|
115
|
+
function readBooleanSetting(value, key, fallback, warnings) {
|
|
116
|
+
if (value === undefined) {
|
|
117
|
+
return fallback;
|
|
118
|
+
}
|
|
119
|
+
if (typeof value === 'boolean') {
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
warnings.push(`Ignoring invalid settings.${key}; expected a boolean.`);
|
|
123
|
+
return fallback;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Clear the settings cache (forces re-read on next loadSettings call)
|
|
127
|
+
*/
|
|
128
|
+
export function clearSettingsCache() {
|
|
129
|
+
cachedSettings = null;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Save settings to file
|
|
133
|
+
*
|
|
134
|
+
* SECURITY: Uses atomic write (tmp + rename) and restricted permissions.
|
|
135
|
+
*/
|
|
136
|
+
export async function saveSettings(settings) {
|
|
137
|
+
const path = getSettingsPath();
|
|
138
|
+
await atomicWriteFile(path, JSON.stringify(settings, null, 2));
|
|
139
|
+
// Update cache with freshly saved settings
|
|
140
|
+
cachedSettings = settings;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Update specific settings
|
|
144
|
+
*/
|
|
145
|
+
export async function updateSettings(updates) {
|
|
146
|
+
const current = await loadSettings();
|
|
147
|
+
const merged = { ...current, ...updates };
|
|
148
|
+
await saveSettings(merged);
|
|
149
|
+
return merged;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/config/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abilities Executor for mainwpcontrol
|
|
3
|
+
*
|
|
4
|
+
* Single execution pathway for all ability calls.
|
|
5
|
+
* INVARIANT: Both commands and chat route through this module.
|
|
6
|
+
*/
|
|
7
|
+
import { type HttpClientConfig } from './http-client.js';
|
|
8
|
+
/**
|
|
9
|
+
* Ability annotation metadata
|
|
10
|
+
*/
|
|
11
|
+
export interface AbilityAnnotations {
|
|
12
|
+
readonly: boolean;
|
|
13
|
+
destructive: boolean;
|
|
14
|
+
idempotent: boolean;
|
|
15
|
+
instructions?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Ability definition from the API
|
|
19
|
+
*/
|
|
20
|
+
export interface Ability {
|
|
21
|
+
name: string;
|
|
22
|
+
label: string;
|
|
23
|
+
description: string;
|
|
24
|
+
category: string;
|
|
25
|
+
input_schema?: Record<string, unknown>;
|
|
26
|
+
output_schema?: Record<string, unknown>;
|
|
27
|
+
meta?: {
|
|
28
|
+
annotations?: AbilityAnnotations;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Execution options
|
|
33
|
+
*/
|
|
34
|
+
export interface ExecutionOptions {
|
|
35
|
+
dryRun?: boolean | undefined;
|
|
36
|
+
confirm?: boolean | undefined;
|
|
37
|
+
signal?: AbortSignal | undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execution result
|
|
41
|
+
*/
|
|
42
|
+
export interface ExecutionResult<T = unknown> {
|
|
43
|
+
success: boolean;
|
|
44
|
+
data?: T;
|
|
45
|
+
error?: {
|
|
46
|
+
code: string;
|
|
47
|
+
message: string;
|
|
48
|
+
details?: unknown;
|
|
49
|
+
hint?: string;
|
|
50
|
+
};
|
|
51
|
+
jobId?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Abilities Executor class
|
|
55
|
+
*/
|
|
56
|
+
export declare class AbilitiesExecutor {
|
|
57
|
+
private readonly httpClient;
|
|
58
|
+
private readonly baseEndpoint;
|
|
59
|
+
private abilitiesCache;
|
|
60
|
+
private cacheExpiry;
|
|
61
|
+
private readonly cacheTTL;
|
|
62
|
+
constructor(config: HttpClientConfig);
|
|
63
|
+
/**
|
|
64
|
+
* List all available abilities
|
|
65
|
+
*/
|
|
66
|
+
listAbilities(): Promise<Ability[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Get a single ability by name
|
|
69
|
+
*/
|
|
70
|
+
getAbility(name: string): Promise<Ability | undefined>;
|
|
71
|
+
/**
|
|
72
|
+
* Execute an ability
|
|
73
|
+
*
|
|
74
|
+
* @param abilityName - The ability name (e.g., "list-sites-v1" or "mainwp/list-sites-v1")
|
|
75
|
+
* @param input - The input parameters
|
|
76
|
+
* @param options - Execution options (dryRun, confirm)
|
|
77
|
+
*/
|
|
78
|
+
execute<T = unknown>(abilityName: string, input?: Record<string, unknown>, options?: ExecutionOptions): Promise<ExecutionResult<T>>;
|
|
79
|
+
/**
|
|
80
|
+
* Get ability categories
|
|
81
|
+
*/
|
|
82
|
+
getCategories(): Promise<string[]>;
|
|
83
|
+
/**
|
|
84
|
+
* List abilities by category
|
|
85
|
+
*/
|
|
86
|
+
listByCategory(category: string): Promise<Ability[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Ensure abilities cache is populated
|
|
89
|
+
*/
|
|
90
|
+
private ensureCache;
|
|
91
|
+
/**
|
|
92
|
+
* Normalize ability name (handle with/without namespace)
|
|
93
|
+
*/
|
|
94
|
+
private normalizeName;
|
|
95
|
+
/**
|
|
96
|
+
* Get short name from full ability name
|
|
97
|
+
*/
|
|
98
|
+
private getShortName;
|
|
99
|
+
/**
|
|
100
|
+
* Build request body with execution options.
|
|
101
|
+
* The WP Abilities API expects: { input: { ...userInput, dry_run?, confirm? } }
|
|
102
|
+
*/
|
|
103
|
+
private buildRequestBody;
|
|
104
|
+
/**
|
|
105
|
+
* Determine HTTP method based on ability annotations
|
|
106
|
+
*/
|
|
107
|
+
private getHttpMethod;
|
|
108
|
+
/**
|
|
109
|
+
* Build query string for GET/DELETE requests with WordPress-style nesting.
|
|
110
|
+
* User input goes under input[key]=value; control flags stay top-level.
|
|
111
|
+
*/
|
|
112
|
+
private buildGetQueryString;
|
|
113
|
+
/**
|
|
114
|
+
* Normalize API response to ExecutionResult
|
|
115
|
+
*/
|
|
116
|
+
private normalizeResponse;
|
|
117
|
+
/**
|
|
118
|
+
* Clear the abilities cache
|
|
119
|
+
*/
|
|
120
|
+
clearCache(): void;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create an abilities executor from config
|
|
124
|
+
*/
|
|
125
|
+
export declare function createAbilitiesExecutor(config: HttpClientConfig): AbilitiesExecutor;
|
|
126
|
+
//# sourceMappingURL=abilities-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abilities-executor.d.ts","sourceRoot":"","sources":["../../src/core/abilities-executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,KAAK,gBAAgB,EAAoB,MAAM,kBAAkB,CAAC;AAIvF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE;QACL,WAAW,CAAC,EAAE,kBAAkB,CAAC;KAClC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8B;IAC3D,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;gBAE9B,MAAM,EAAE,gBAAgB;IAIpC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAQzC;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAK5D;;;;;;OAMG;IACG,OAAO,CAAC,CAAC,GAAG,OAAO,EACvB,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAiE9B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAMxC;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAK1D;;OAEG;YACW,WAAW;IAyCzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAwBxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,UAAU,IAAI,IAAI;CAInB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CAEnF"}
|