@oxlayer/cli 0.0.1 → 0.0.2
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/README.md +2 -2
- package/dist/cli.js +1 -1327
- package/package.json +12 -10
- package/dist/api.service-CDPTVMJM.js +0 -17
- package/dist/api.service-CDPTVMJM.js.map +0 -1
- package/dist/chunk-DOYXC6AO.js +0 -93
- package/dist/chunk-DOYXC6AO.js.map +0 -1
- package/dist/chunk-HOFSFUN5.js +0 -108
- package/dist/chunk-HOFSFUN5.js.map +0 -1
- package/dist/chunk-HQST7GVM.js +0 -26
- package/dist/chunk-HQST7GVM.js.map +0 -1
- package/dist/chunk-M3AAB53U.js +0 -105
- package/dist/chunk-M3AAB53U.js.map +0 -1
- package/dist/chunk-QERPYPW4.js +0 -284
- package/dist/chunk-QERPYPW4.js.map +0 -1
- package/dist/cli-VUBGPXL3.js +0 -30
- package/dist/cli-VUBGPXL3.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/device-auth.service-CMNCNKYX.js +0 -42
- package/dist/device-auth.service-CMNCNKYX.js.map +0 -1
- package/dist/package.service-XK5PPZVF.js +0 -24
- package/dist/package.service-XK5PPZVF.js.map +0 -1
package/dist/chunk-QERPYPW4.js
DELETED
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__esm,
|
|
3
|
-
init_esm_shims
|
|
4
|
-
} from "./chunk-HQST7GVM.js";
|
|
5
|
-
|
|
6
|
-
// src/services/device-auth.service.ts
|
|
7
|
-
import { promises as fs } from "fs";
|
|
8
|
-
import { join } from "path";
|
|
9
|
-
import { homedir } from "os";
|
|
10
|
-
import { randomBytes } from "crypto";
|
|
11
|
-
async function getDeviceId() {
|
|
12
|
-
try {
|
|
13
|
-
const registry = await loadDeviceRegistry();
|
|
14
|
-
const hostname = await getHostname();
|
|
15
|
-
let device = registry.devices.find((d) => d.deviceName === hostname);
|
|
16
|
-
if (!device) {
|
|
17
|
-
device = {
|
|
18
|
-
deviceId: generateDeviceId(),
|
|
19
|
-
deviceName: hostname,
|
|
20
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21
|
-
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22
|
-
};
|
|
23
|
-
registry.devices.push(device);
|
|
24
|
-
await saveDeviceRegistry(registry);
|
|
25
|
-
} else {
|
|
26
|
-
device.lastSeenAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
27
|
-
await saveDeviceRegistry(registry);
|
|
28
|
-
}
|
|
29
|
-
return device.deviceId;
|
|
30
|
-
} catch {
|
|
31
|
-
return generateDeviceId();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
async function getDeviceName() {
|
|
35
|
-
return getHostname();
|
|
36
|
-
}
|
|
37
|
-
function generateDeviceId() {
|
|
38
|
-
return `oxl_dev_${randomBytes(16).toString("hex")}`;
|
|
39
|
-
}
|
|
40
|
-
async function getHostname() {
|
|
41
|
-
const os = await import("os");
|
|
42
|
-
return os.hostname();
|
|
43
|
-
}
|
|
44
|
-
async function loadDeviceRegistry() {
|
|
45
|
-
try {
|
|
46
|
-
const content = await fs.readFile(DEVICES_FILE, "utf-8");
|
|
47
|
-
return JSON.parse(content);
|
|
48
|
-
} catch {
|
|
49
|
-
return { devices: [] };
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
async function saveDeviceRegistry(registry) {
|
|
53
|
-
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
54
|
-
await fs.writeFile(DEVICES_FILE, JSON.stringify(registry, null, 2));
|
|
55
|
-
}
|
|
56
|
-
async function initiateDeviceAuth(environment = "development", apiEndpoint) {
|
|
57
|
-
const deviceId = await getDeviceId();
|
|
58
|
-
const deviceName = await getDeviceName();
|
|
59
|
-
const endpoint = apiEndpoint || DEFAULT_API_ENDPOINT;
|
|
60
|
-
const response = await fetch(`${endpoint}/v1/cli/device/code`, {
|
|
61
|
-
method: "POST",
|
|
62
|
-
headers: { "Content-Type": "application/json" },
|
|
63
|
-
body: JSON.stringify({
|
|
64
|
-
deviceId,
|
|
65
|
-
deviceName,
|
|
66
|
-
environment
|
|
67
|
-
})
|
|
68
|
-
});
|
|
69
|
-
if (!response.ok) {
|
|
70
|
-
const error = await response.text();
|
|
71
|
-
throw new Error(`Failed to initiate device auth: ${error}`);
|
|
72
|
-
}
|
|
73
|
-
return response.json();
|
|
74
|
-
}
|
|
75
|
-
async function pollForToken(pollEndpoint, deviceCode, options = {}) {
|
|
76
|
-
const interval = options.interval || DEFAULT_POLL_INTERVAL;
|
|
77
|
-
const maxAttempts = options.maxAttempts || MAX_POLL_ATTEMPTS;
|
|
78
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
79
|
-
options.onProgress?.(attempt, maxAttempts);
|
|
80
|
-
const response = await fetch(pollEndpoint, {
|
|
81
|
-
method: "POST",
|
|
82
|
-
headers: { "Content-Type": "application/json" },
|
|
83
|
-
body: JSON.stringify({ deviceCode })
|
|
84
|
-
});
|
|
85
|
-
if (!response.ok) {
|
|
86
|
-
throw new Error(`Poll request failed: ${response.statusText}`);
|
|
87
|
-
}
|
|
88
|
-
const result = await response.json();
|
|
89
|
-
if (!result.pending) {
|
|
90
|
-
if (result.error) {
|
|
91
|
-
throw new Error(`Authorization failed: ${result.error}`);
|
|
92
|
-
}
|
|
93
|
-
return { ...result, success: true };
|
|
94
|
-
}
|
|
95
|
-
await sleep(interval * 1e3);
|
|
96
|
-
}
|
|
97
|
-
throw new Error("Authorization timed out. Please try again.");
|
|
98
|
-
}
|
|
99
|
-
function sleep(ms) {
|
|
100
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
101
|
-
}
|
|
102
|
-
async function saveConfig(config) {
|
|
103
|
-
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
104
|
-
await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), {
|
|
105
|
-
mode: 384
|
|
106
|
-
// Read/write for owner only
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
async function loadConfig() {
|
|
110
|
-
try {
|
|
111
|
-
const content = await fs.readFile(CONFIG_FILE, "utf-8");
|
|
112
|
-
return JSON.parse(content);
|
|
113
|
-
} catch {
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
async function removeConfig() {
|
|
118
|
-
try {
|
|
119
|
-
await fs.unlink(CONFIG_FILE);
|
|
120
|
-
} catch {
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async function getAccessToken() {
|
|
124
|
-
const envToken = process.env.OXLAYER_TOKEN;
|
|
125
|
-
if (envToken) {
|
|
126
|
-
return envToken;
|
|
127
|
-
}
|
|
128
|
-
const config = await loadConfig();
|
|
129
|
-
return config?.token ?? null;
|
|
130
|
-
}
|
|
131
|
-
function validateToken(token) {
|
|
132
|
-
const MIN_TOKEN_LENGTH = 32;
|
|
133
|
-
const isJwt = token.startsWith("eyJ");
|
|
134
|
-
const isScopedToken = token.startsWith("oxl_cli_");
|
|
135
|
-
return typeof token === "string" && (isJwt || isScopedToken) && token.length >= MIN_TOKEN_LENGTH;
|
|
136
|
-
}
|
|
137
|
-
function isTokenExpired(config) {
|
|
138
|
-
const expiresAt = new Date(config.tokenInfo.expiresAt);
|
|
139
|
-
return expiresAt < /* @__PURE__ */ new Date();
|
|
140
|
-
}
|
|
141
|
-
async function refreshManifest(config, apiEndpoint) {
|
|
142
|
-
const endpoint = apiEndpoint || config.apiEndpoint || DEFAULT_API_ENDPOINT;
|
|
143
|
-
const response = await fetch(`${endpoint}/v1/cli/manifest`, {
|
|
144
|
-
headers: {
|
|
145
|
-
"Content-Type": "application/json",
|
|
146
|
-
"Authorization": `Bearer ${config.token}`
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
if (!response.ok) {
|
|
150
|
-
return {
|
|
151
|
-
...config,
|
|
152
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
const manifest = await response.json();
|
|
156
|
-
return {
|
|
157
|
-
...config,
|
|
158
|
-
manifest,
|
|
159
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
async function getManifest(apiEndpoint) {
|
|
163
|
-
const config = await loadConfig();
|
|
164
|
-
if (!config) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
if (config.manifest) {
|
|
168
|
-
const expiresAt = new Date(config.manifest.expiresAt);
|
|
169
|
-
if (expiresAt > /* @__PURE__ */ new Date()) {
|
|
170
|
-
return config.manifest;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
const updated = await refreshManifest(config, apiEndpoint);
|
|
174
|
-
await saveConfig(updated);
|
|
175
|
-
return updated.manifest || null;
|
|
176
|
-
}
|
|
177
|
-
async function isAuthenticated() {
|
|
178
|
-
const config = await loadConfig();
|
|
179
|
-
if (!config) {
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
if (isTokenExpired(config)) {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
async function getAuthInfo() {
|
|
188
|
-
const config = await loadConfig();
|
|
189
|
-
if (!config) {
|
|
190
|
-
return { authenticated: false };
|
|
191
|
-
}
|
|
192
|
-
return {
|
|
193
|
-
authenticated: !isTokenExpired(config),
|
|
194
|
-
deviceId: config.tokenInfo.deviceId,
|
|
195
|
-
organizationId: config.organizationId,
|
|
196
|
-
expiresAt: config.tokenInfo.expiresAt,
|
|
197
|
-
scopes: config.tokenInfo.scopes
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function buildVerificationUrl(baseUrl, deviceCode) {
|
|
201
|
-
const url = new URL(baseUrl);
|
|
202
|
-
url.searchParams.set("device_code", deviceCode);
|
|
203
|
-
return url.toString();
|
|
204
|
-
}
|
|
205
|
-
async function openBrowser(url) {
|
|
206
|
-
const { exec } = await import("child_process");
|
|
207
|
-
const platform = process.platform;
|
|
208
|
-
let command;
|
|
209
|
-
switch (platform) {
|
|
210
|
-
case "darwin":
|
|
211
|
-
command = `open "${url}"`;
|
|
212
|
-
break;
|
|
213
|
-
case "win32":
|
|
214
|
-
command = `start "" "${url}"`;
|
|
215
|
-
break;
|
|
216
|
-
default:
|
|
217
|
-
command = `xdg-open "${url}"`;
|
|
218
|
-
}
|
|
219
|
-
return new Promise((resolve, reject) => {
|
|
220
|
-
exec(command, (error) => {
|
|
221
|
-
if (error) {
|
|
222
|
-
reject(new Error(`Failed to open browser: ${error.message}`));
|
|
223
|
-
} else {
|
|
224
|
-
resolve();
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
async function migrateFromApiKey(apiKey) {
|
|
230
|
-
const deviceId = await getDeviceId();
|
|
231
|
-
const deviceName = await getDeviceName();
|
|
232
|
-
const endpoint = DEFAULT_API_ENDPOINT;
|
|
233
|
-
const response = await fetch(`${endpoint}/v1/cli/migrate`, {
|
|
234
|
-
method: "POST",
|
|
235
|
-
headers: { "Content-Type": "application/json" },
|
|
236
|
-
body: JSON.stringify({ apiKey, deviceId, deviceName })
|
|
237
|
-
});
|
|
238
|
-
if (!response.ok) {
|
|
239
|
-
throw new Error(`Migration failed: ${response.statusText}`);
|
|
240
|
-
}
|
|
241
|
-
const result = await response.json();
|
|
242
|
-
return {
|
|
243
|
-
token: result.accessToken,
|
|
244
|
-
tokenInfo: result.tokenInfo,
|
|
245
|
-
organizationId: result.organizationId,
|
|
246
|
-
environment: "development",
|
|
247
|
-
vendorDir: ".capabilities-vendor",
|
|
248
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
var CONFIG_DIR, CONFIG_FILE, DEVICES_FILE, DEFAULT_API_ENDPOINT, DEFAULT_POLL_INTERVAL, MAX_POLL_ATTEMPTS;
|
|
252
|
-
var init_device_auth_service = __esm({
|
|
253
|
-
"src/services/device-auth.service.ts"() {
|
|
254
|
-
init_esm_shims();
|
|
255
|
-
CONFIG_DIR = join(homedir(), ".oxlayer");
|
|
256
|
-
CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
257
|
-
DEVICES_FILE = join(CONFIG_DIR, "devices.json");
|
|
258
|
-
DEFAULT_API_ENDPOINT = "http://localhost:3001";
|
|
259
|
-
DEFAULT_POLL_INTERVAL = 5;
|
|
260
|
-
MAX_POLL_ATTEMPTS = 120;
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
export {
|
|
265
|
-
getDeviceId,
|
|
266
|
-
getDeviceName,
|
|
267
|
-
initiateDeviceAuth,
|
|
268
|
-
pollForToken,
|
|
269
|
-
saveConfig,
|
|
270
|
-
loadConfig,
|
|
271
|
-
removeConfig,
|
|
272
|
-
getAccessToken,
|
|
273
|
-
validateToken,
|
|
274
|
-
isTokenExpired,
|
|
275
|
-
refreshManifest,
|
|
276
|
-
getManifest,
|
|
277
|
-
isAuthenticated,
|
|
278
|
-
getAuthInfo,
|
|
279
|
-
buildVerificationUrl,
|
|
280
|
-
openBrowser,
|
|
281
|
-
migrateFromApiKey,
|
|
282
|
-
init_device_auth_service
|
|
283
|
-
};
|
|
284
|
-
//# sourceMappingURL=chunk-QERPYPW4.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/device-auth.service.ts"],"sourcesContent":["/**\n * Device Authorization Service\n *\n * Implements the Device Authorization Flow (RFC 8628) for CLI authentication.\n * This enables browser-based login without copying API keys.\n *\n * Flow:\n * 1. CLI requests a device code\n * 2. CLI opens browser with verification URL\n * 3. User logs in and approves the device\n * 4. CLI polls for token completion\n * 5. Token is saved locally\n */\n\nimport type {\n CliConfig,\n DeviceCodeResponse,\n TokenPollResponse,\n TokenScope,\n CapabilityManifest,\n} from '../types/capabilities.js';\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { randomBytes } from 'crypto';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst CONFIG_DIR = join(homedir(), '.oxlayer');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\nconst DEVICES_FILE = join(CONFIG_DIR, 'devices.json');\n\nconst DEFAULT_API_ENDPOINT = process.env.OXLAYER_API_ENDPOINT || 'https://api.oxlayer.dev';\nconst DEFAULT_POLL_INTERVAL = 5; // seconds\nconst MAX_POLL_ATTEMPTS = 120; // 10 minutes total\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface DeviceRegistry {\n devices: Array<{\n deviceId: string;\n deviceName: string;\n createdAt: string;\n lastSeenAt: string;\n }>;\n}\n\ninterface PollingOptions {\n interval?: number;\n maxAttempts?: number;\n onProgress?: (attempt: number, maxAttempts: number) => void;\n}\n\n// ============================================================================\n// Device ID Management\n// ============================================================================\n\n/**\n * Get or create a persistent device ID for this machine\n */\nexport async function getDeviceId(): Promise<string> {\n try {\n const registry = await loadDeviceRegistry();\n const hostname = await getHostname();\n\n // Find existing device for this hostname\n let device = registry.devices.find(d => d.deviceName === hostname);\n\n if (!device) {\n // Create new device\n device = {\n deviceId: generateDeviceId(),\n deviceName: hostname,\n createdAt: new Date().toISOString(),\n lastSeenAt: new Date().toISOString(),\n };\n registry.devices.push(device);\n await saveDeviceRegistry(registry);\n } else {\n // Update last seen\n device.lastSeenAt = new Date().toISOString();\n await saveDeviceRegistry(registry);\n }\n\n return device.deviceId;\n } catch {\n // Fallback to ephemeral device ID\n return generateDeviceId();\n }\n}\n\n/**\n * Get human-readable device name\n */\nexport async function getDeviceName(): Promise<string> {\n return getHostname();\n}\n\nfunction generateDeviceId(): string {\n return `oxl_dev_${randomBytes(16).toString('hex')}`;\n}\n\nasync function getHostname(): Promise<string> {\n const os = await import('os');\n return os.hostname();\n}\n\nasync function loadDeviceRegistry(): Promise<DeviceRegistry> {\n try {\n const content = await fs.readFile(DEVICES_FILE, 'utf-8');\n return JSON.parse(content);\n } catch {\n return { devices: [] };\n }\n}\n\nasync function saveDeviceRegistry(registry: DeviceRegistry): Promise<void> {\n await fs.mkdir(CONFIG_DIR, { recursive: true });\n await fs.writeFile(DEVICES_FILE, JSON.stringify(registry, null, 2));\n}\n\n// ============================================================================\n// Device Authorization Flow\n// ============================================================================\n\n/**\n * Initiate device authorization flow\n *\n * Returns a device code and verification URL for the user to visit\n */\nexport async function initiateDeviceAuth(\n environment: 'development' | 'staging' | 'production' = 'development',\n apiEndpoint?: string\n): Promise<DeviceCodeResponse> {\n const deviceId = await getDeviceId();\n const deviceName = await getDeviceName();\n const endpoint = apiEndpoint || DEFAULT_API_ENDPOINT;\n\n const response = await fetch(`${endpoint}/v1/cli/device/code`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n deviceId,\n deviceName,\n environment,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to initiate device auth: ${error}`);\n }\n\n return response.json();\n}\n\n/**\n * Poll for token completion\n *\n * Polls the endpoint until the user completes authorization or timeout\n */\nexport async function pollForToken(\n pollEndpoint: string,\n deviceCode: string,\n options: PollingOptions = {}\n): Promise<TokenPollResponse & { success: true }> {\n const interval = options.interval || DEFAULT_POLL_INTERVAL;\n const maxAttempts = options.maxAttempts || MAX_POLL_ATTEMPTS;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n options.onProgress?.(attempt, maxAttempts);\n\n const response = await fetch(pollEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ deviceCode }),\n });\n\n if (!response.ok) {\n throw new Error(`Poll request failed: ${response.statusText}`);\n }\n\n const result: TokenPollResponse = await response.json();\n\n if (!result.pending) {\n if (result.error) {\n throw new Error(`Authorization failed: ${result.error}`);\n }\n\n return { ...result, success: true };\n }\n\n // Wait before next poll\n await sleep(interval * 1000);\n }\n\n throw new Error('Authorization timed out. Please try again.');\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// Token Management\n// ============================================================================\n\n/**\n * Save CLI configuration with scoped token\n */\nexport async function saveConfig(config: CliConfig): Promise<void> {\n await fs.mkdir(CONFIG_DIR, { recursive: true });\n await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), {\n mode: 0o600, // Read/write for owner only\n });\n}\n\n/**\n * Load CLI configuration\n */\nexport async function loadConfig(): Promise<CliConfig | null> {\n try {\n const content = await fs.readFile(CONFIG_FILE, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * Remove CLI configuration (logout)\n */\nexport async function removeConfig(): Promise<void> {\n try {\n await fs.unlink(CONFIG_FILE);\n } catch {\n // Ignore if file doesn't exist\n }\n}\n\n/**\n * Get scoped access token\n * Checks config file and falls back to environment variable\n */\nexport async function getAccessToken(): Promise<string | null> {\n // Check environment variable first\n const envToken = process.env.OXLAYER_TOKEN;\n if (envToken) {\n return envToken;\n }\n\n // Check config file\n const config = await loadConfig();\n return config?.token ?? null;\n}\n\n/**\n * Validate token format\n * Accepts both JWT tokens (from device auth flow) and legacy scoped tokens (oxl_cli_*)\n */\nexport function validateToken(token: string): boolean {\n const MIN_TOKEN_LENGTH = 32;\n const isJwt = token.startsWith('eyJ'); // JWTs start with base64-encoded '{'\n const isScopedToken = token.startsWith('oxl_cli_');\n return (\n typeof token === 'string' &&\n (isJwt || isScopedToken) &&\n token.length >= MIN_TOKEN_LENGTH\n );\n}\n\n/**\n * Check if token is expired\n */\nexport function isTokenExpired(config: CliConfig): boolean {\n const expiresAt = new Date(config.tokenInfo.expiresAt);\n return expiresAt < new Date();\n}\n\n/**\n * Refresh capability manifest from API\n */\nexport async function refreshManifest(\n config: CliConfig,\n apiEndpoint?: string\n): Promise<CliConfig> {\n const endpoint = apiEndpoint || config.apiEndpoint || DEFAULT_API_ENDPOINT;\n\n const response = await fetch(`${endpoint}/v1/cli/manifest`, {\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.token}`,\n },\n });\n\n if (!response.ok) {\n // Not implemented yet - return config without manifest\n return {\n ...config,\n updatedAt: new Date().toISOString(),\n };\n }\n\n const manifest: CapabilityManifest = await response.json();\n\n return {\n ...config,\n manifest,\n updatedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Get cached or fetch new capability manifest\n */\nexport async function getManifest(\n apiEndpoint?: string\n): Promise<CapabilityManifest | null> {\n const config = await loadConfig();\n if (!config) {\n return null;\n }\n\n // Check if cached manifest is still valid\n if (config.manifest) {\n const expiresAt = new Date(config.manifest.expiresAt);\n if (expiresAt > new Date()) {\n return config.manifest;\n }\n }\n\n // Refresh manifest\n const updated = await refreshManifest(config, apiEndpoint);\n await saveConfig(updated);\n\n return updated.manifest || null;\n}\n\n// ============================================================================\n// Auth State Helpers\n// ============================================================================\n\n/**\n * Check if user is authenticated\n */\nexport async function isAuthenticated(): Promise<boolean> {\n const config = await loadConfig();\n if (!config) {\n return false;\n }\n\n // Check token expiration\n if (isTokenExpired(config)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get authentication info for display\n */\nexport async function getAuthInfo(): Promise<{\n authenticated: boolean;\n deviceId?: string;\n organizationId?: string;\n expiresAt?: string;\n scopes?: string[];\n}> {\n const config = await loadConfig();\n\n if (!config) {\n return { authenticated: false };\n }\n\n return {\n authenticated: !isTokenExpired(config),\n deviceId: config.tokenInfo.deviceId,\n organizationId: config.organizationId,\n expiresAt: config.tokenInfo.expiresAt,\n scopes: config.tokenInfo.scopes,\n };\n}\n\n// ============================================================================\n// URL Helpers\n// ============================================================================\n\n/**\n * Build verification URL with device code\n */\nexport function buildVerificationUrl(baseUrl: string, deviceCode: string): string {\n const url = new URL(baseUrl);\n url.searchParams.set('device_code', deviceCode);\n return url.toString();\n}\n\n/**\n * Open browser to verification URL\n */\nexport async function openBrowser(url: string): Promise<void> {\n const { exec } = await import('child_process');\n\n const platform = process.platform;\n\n let command: string;\n switch (platform) {\n case 'darwin':\n command = `open \"${url}\"`;\n break;\n case 'win32':\n command = `start \"\" \"${url}\"`;\n break;\n default:\n command = `xdg-open \"${url}\"`;\n }\n\n return new Promise((resolve, reject) => {\n exec(command, (error) => {\n if (error) {\n reject(new Error(`Failed to open browser: ${error.message}`));\n } else {\n resolve();\n }\n });\n });\n}\n\n// ============================================================================\n// Migration Helpers (for transitioning from API key to token)\n// ============================================================================\n\n/**\n * Migrate legacy API key config to new token-based config\n */\nexport async function migrateFromApiKey(apiKey: string): Promise<CliConfig> {\n const deviceId = await getDeviceId();\n const deviceName = await getDeviceName();\n\n // Exchange API key for scoped token\n const endpoint = DEFAULT_API_ENDPOINT;\n const response = await fetch(`${endpoint}/v1/cli/migrate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ apiKey, deviceId, deviceName }),\n });\n\n if (!response.ok) {\n throw new Error(`Migration failed: ${response.statusText}`);\n }\n\n const result = await response.json();\n\n return {\n token: result.accessToken,\n tokenInfo: result.tokenInfo,\n organizationId: result.organizationId,\n environment: 'development',\n vendorDir: '.capabilities-vendor',\n updatedAt: new Date().toISOString(),\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli-VUBGPXL3.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
confirm,
|
|
3
|
-
createSpinner,
|
|
4
|
-
error,
|
|
5
|
-
formatDuration,
|
|
6
|
-
formatSize,
|
|
7
|
-
getBanner,
|
|
8
|
-
header,
|
|
9
|
-
info,
|
|
10
|
-
printCapabilities,
|
|
11
|
-
printList,
|
|
12
|
-
success,
|
|
13
|
-
warning
|
|
14
|
-
} from "./chunk-HOFSFUN5.js";
|
|
15
|
-
import "./chunk-HQST7GVM.js";
|
|
16
|
-
export {
|
|
17
|
-
confirm,
|
|
18
|
-
createSpinner,
|
|
19
|
-
error,
|
|
20
|
-
formatDuration,
|
|
21
|
-
formatSize,
|
|
22
|
-
getBanner,
|
|
23
|
-
header,
|
|
24
|
-
info,
|
|
25
|
-
printCapabilities,
|
|
26
|
-
printList,
|
|
27
|
-
success,
|
|
28
|
-
warning
|
|
29
|
-
};
|
|
30
|
-
//# sourceMappingURL=cli-VUBGPXL3.js.map
|
package/dist/cli-VUBGPXL3.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/login.command.ts","../src/commands/status.command.ts","../src/utils/env.ts","../src/commands/install.command.ts","../src/services/index.ts","../src/services/auth.service.ts","../src/services/download.service.ts","../src/services/hooks.service.ts","../src/services/telemetry.service.ts","../src/commands/resolve.command.ts","../src/commands/logout.command.ts","../src/commands/doctor.command.ts","../src/commands/diff.command.ts","../src/commands/telemetry.command.ts","../src/commands/update.command.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * OxLayer SDK Installer CLI\n *\n * A command-line tool for downloading and installing OxLayer SDK packages\n */\n\nimport { Command } from 'commander';\nimport { getBanner } from './utils/cli.js';\nimport { login } from './commands/login.command.js';\nimport { status } from './commands/status.command.js';\nimport { install } from './commands/install.command.js';\nimport { resolve } from './commands/resolve.command.js';\nimport { logout } from './commands/logout.command.js';\nimport { doctor } from './commands/doctor.command.js';\nimport { diff, showLatest } from './commands/diff.command.js';\nimport { telemetryEnable, telemetryDisable, telemetryStatus } from './commands/telemetry.command.js';\nimport { update, check } from './commands/update.command.js';\nimport { trackCommand, trackError } from './services/telemetry.service.js';\n\nconst program = new Command();\n\n// Show banner on help/version\nprogram.addHelpText('beforeAll', getBanner());\n\nprogram\n .name('oxlayer')\n .description('OxLayer SDK Installer - Download and install private SDK packages')\n .version('0.0.1');\n\n// Login command\nprogram\n .command('login')\n .description('Authenticate with OxLayer Control Panel')\n .option('-k, --key <key>', 'API key (will prompt if not provided)')\n .option('-e, --environment <env>', 'Environment (development|staging|production)', 'development')\n .action(async (options) => {\n trackCommand('login');\n await login(options);\n });\n\n// Status command\nprogram\n .command('status')\n .description('Show installation and authentication status')\n .option('-v, --verbose', 'Show detailed information')\n .action(async (options) => {\n trackCommand('status');\n await status(options);\n });\n\n// Install command\nprogram\n .command('install [version]')\n .description('Install SDK packages')\n .option('-p, --packages <packages...>', 'Specific packages to install')\n .option('-e, --environment <env>', 'Environment (development|staging|production)', 'development')\n .option('--dry-run', 'Show what would be installed without installing')\n .option('-f, --force', 'Force reinstall even if already installed')\n .option('--save', 'Add to dependencies')\n .option('--save-dev', 'Add to devDependencies')\n .action(async (version, options) => {\n trackCommand('install', { sdkVersion: version });\n await install(version || 'latest', options);\n });\n\n// Resolve command\nprogram\n .command('resolve')\n .description('Resolve capabilities for current project')\n .option('-e, --environment <env>', 'Environment (development|staging|production)', 'development')\n .option('-v, --verbose', 'Show usage examples')\n .action(async (options) => {\n trackCommand('resolve');\n await resolve(options);\n });\n\n// Logout command\nprogram\n .command('logout')\n .description('Remove stored API key')\n .action(async () => {\n trackCommand('logout');\n await logout();\n });\n\n// Doctor command\nprogram\n .command('doctor')\n .description('Run diagnostics to troubleshoot issues')\n .option('-v, --verbose', 'Show detailed diagnostic information')\n .option('--fix', 'Attempt to fix common issues automatically')\n .action(async (options) => {\n trackCommand('doctor');\n await doctor(options);\n });\n\n// Diff command\nprogram\n .command('diff [from-version] [to-version]')\n .description('Compare capabilities between SDK versions')\n .option('-v, --verbose', 'Show detailed changes')\n .option('--format <format>', 'Output format (text|json)', 'text')\n .action(async (fromVersion, toVersion, options) => {\n trackCommand('diff');\n if (!fromVersion) {\n await showLatest();\n } else {\n await diff(fromVersion, toVersion || 'latest', options);\n }\n });\n\n// Update command\nprogram\n .command('update')\n .description('Update SDK to the latest version')\n .option('--dry-run', 'Show what would be updated without installing')\n .action(async (options) => {\n trackCommand('update');\n await update(options);\n });\n\n// Check command\nprogram\n .command('check')\n .description('Quick check for SDK updates')\n .action(async () => {\n await check();\n });\n\n// Telemetry commands\nconst telemetryCmd = program\n .command('telemetry')\n .description('Manage telemetry settings');\n\ntelemetryCmd\n .command('enable')\n .description('Enable anonymous usage tracking')\n .action(async () => {\n await telemetryEnable();\n });\n\ntelemetryCmd\n .command('disable')\n .description('Disable anonymous usage tracking')\n .action(async () => {\n await telemetryDisable();\n });\n\ntelemetryCmd\n .command('status')\n .description('Show telemetry status')\n .action(async () => {\n await telemetryStatus();\n });\n\n// Parse arguments\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err);\n trackError('cli', 'parse_error');\n process.exit(1);\n});\n","/**\n * Login Command\n *\n * Authenticate with the OxLayer Control Panel using Device Authorization Flow.\n *\n * This implements a browser-based login flow (similar to GitHub CLI, Azure CLI):\n * 1. CLI requests a device code from the API\n * 2. CLI opens the user's browser to a verification page\n * 3. User logs in and approves the device\n * 4. CLI polls for completion and receives a scoped access token\n */\n\nimport {\n initiateDeviceAuth,\n pollForToken,\n saveConfig,\n openBrowser,\n getDeviceName,\n} from '../services/device-auth.service.js';\nimport { info, success, error, createSpinner, header } from '../utils/cli.js';\nimport type { CliConfig } from '../types/capabilities.js';\n\nexport interface LoginOptions {\n environment?: 'development' | 'staging' | 'production';\n apiEndpoint?: string;\n 'no-browser'?: boolean;\n 'poll-interval'?: number;\n}\n\n/**\n * Login command - authenticate using Device Authorization Flow\n */\nexport async function login(options: LoginOptions = {}): Promise<void> {\n header('OxLayer Authentication');\n\n const deviceName = await getDeviceName();\n info(`Device: ${deviceName}`);\n info(`Environment: ${options.environment || 'development'}`);\n info(`API Endpoint: ${options.apiEndpoint || process.env.OXLAYER_API_ENDPOINT}`);\n console.log();\n\n // Step 1: Initiate device authorization\n const spinner = createSpinner('Initiating device authorization...');\n spinner.start();\n\n let deviceCodeResponse;\n try {\n const apiEndpoint = options.apiEndpoint || process.env.OXLAYER_API_ENDPOINT;\n info(`API Endpoint: ${apiEndpoint}`);\n deviceCodeResponse = await initiateDeviceAuth(\n options.environment || 'development',\n apiEndpoint\n );\n spinner.succeed('Device authorization initiated');\n } catch (err) {\n spinner.fail('Failed to initiate device authorization');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n // Step 2: Display instructions\n console.log();\n info('To complete authentication, follow these steps:');\n console.log();\n\n const verificationUrl = deviceCodeResponse.verificationUrl;\n const userCode = deviceCodeResponse.userCode;\n\n // Show the URL and code\n console.log(` 1. Visit this URL in your browser:`);\n console.log(` ${verificationUrl}`);\n console.log();\n\n console.log(` 2. Enter this code when prompted:`);\n console.log(` ${userCode}`);\n console.log();\n\n // Step 3: Open browser (unless --no-browser flag)\n if (!options['no-browser']) {\n try {\n const urlWithCode = new URL(verificationUrl);\n urlWithCode.searchParams.set('device_code', deviceCodeResponse.deviceCode);\n\n const openSpinner = createSpinner('Opening browser...');\n openSpinner.start();\n await openBrowser(urlWithCode.toString());\n openSpinner.succeed('Browser opened');\n } catch (err) {\n info('Could not open browser automatically. Please visit the URL manually.');\n }\n } else {\n info('Browser auto-open disabled (--no-browser flag set)');\n }\n\n console.log();\n info('Waiting for authentication to complete...');\n\n // Step 4: Poll for token\n const pollSpinner = createSpinner('Waiting for approval');\n\n try {\n pollSpinner.start();\n\n const result = await pollForToken(\n deviceCodeResponse.pollEndpoint,\n deviceCodeResponse.deviceCode,\n {\n interval: options['poll-interval'] || deviceCodeResponse.interval,\n maxAttempts: 120, // 2 minutes\n onProgress: (attempt, maxAttempts) => {\n if (attempt % 8 === 0) {\n // Update every 15 seconds\n pollSpinner.text = `Waiting for approval (${Math.floor((attempt / maxAttempts) * 100)}%)`;\n }\n },\n }\n );\n\n pollSpinner.succeed('Authentication successful');\n\n // Step 5: Save configuration\n const apiEndpoint = options.apiEndpoint || process.env.OXLAYER_API_ENDPOINT;\n const config: CliConfig = {\n token: result.accessToken!,\n tokenInfo: result.tokenInfo!,\n organizationId: result.organizationId!,\n environment: options.environment || 'development',\n vendorDir: '.capabilities-vendor',\n apiEndpoint: apiEndpoint,\n updatedAt: new Date().toISOString(),\n };\n\n await saveConfig(config);\n\n pollSpinner.stop();\n\n console.log();\n success('Logged in successfully');\n info(`Organization: ${result.organizationId}`);\n info(`Device ID: ${result.tokenInfo!.deviceId}`);\n info(`Scopes: ${result.tokenInfo!.scopes.join(', ')}`);\n info(`Expires: ${new Date(result.tokenInfo!.expiresAt).toLocaleString()}`);\n\n // Ensure clean exit\n process.exit(0);\n } catch (err) {\n pollSpinner.fail('Authentication failed');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n}\n","/**\n * Status Command\n *\n * Show current installation status and configuration\n */\n\nimport { getAuthInfo, getManifest } from '../services/device-auth.service.js';\nimport { getInstalledVersion } from '../services/package.service.js';\nimport { detectProjectType, getRecommendedPackages } from '../utils/env.js';\nimport { header, info, success, error, printList } from '../utils/cli.js';\nimport { StatusOptions } from '../types/index.js';\n\n/**\n * Status command - show current configuration and installation status\n */\nexport async function status(options: StatusOptions = {}): Promise<void> {\n header('OxLayer SDK Status');\n\n // Check authentication\n const authInfo = await getAuthInfo();\n if (authInfo.authenticated) {\n success('Authenticated');\n info(`Organization: ${authInfo.organizationId || 'Unknown'}`);\n info(`Device: ${authInfo.deviceId || 'Unknown'}`);\n\n if (options.verbose && authInfo.scopes) {\n info(`Scopes: ${authInfo.scopes.join(', ')}`);\n }\n if (options.verbose && authInfo.expiresAt) {\n const expires = new Date(authInfo.expiresAt);\n const now = new Date();\n const daysUntilExpiry = Math.ceil((expires.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n info(`Expires: ${expires.toLocaleString()} (${daysUntilExpiry > 0 ? `in ${daysUntilExpiry} days` : 'expired'})`);\n }\n } else {\n error('Not authenticated');\n info('Run \"oxlayer login\" to authenticate');\n }\n\n console.log();\n\n // Check capabilities (if authenticated)\n if (authInfo.authenticated) {\n header('Capabilities');\n\n const manifest = await getManifest();\n if (manifest) {\n success(`Capability manifest loaded`);\n info(`Schema Version: ${manifest.schemaVersion}`);\n info(`License: ${manifest.licenseId}`);\n info(`Environment: ${manifest.environment}`);\n\n if (manifest.capabilities) {\n const capabilityCount = Object.keys(manifest.capabilities).length;\n info(`Available Capabilities: ${capabilityCount}`);\n\n if (options.verbose) {\n const capabilityNames = Object.keys(manifest.capabilities);\n if (capabilityNames.length > 0) {\n info('Capabilities:');\n printList(capabilityNames);\n }\n\n // Show manifest expiration\n const manifestExpires = new Date(manifest.expiresAt);\n const now = new Date();\n const daysUntilExpiry = Math.ceil((manifestExpires.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n info(`Manifest Expires: ${manifestExpires.toLocaleString()} (${daysUntilExpiry > 0 ? `in ${daysUntilExpiry} days` : 'expired'})`);\n }\n } else {\n info('No capabilities available in manifest');\n }\n } else {\n info('No capability manifest available');\n info('Run \"oxlayer install\" to fetch the latest capabilities');\n }\n\n console.log();\n }\n\n // Check project\n header('Project');\n\n const projectConfig = await detectProjectType();\n const recommendedPackages = getRecommendedPackages(projectConfig.type);\n\n if (projectConfig.hasPackageJson) {\n success('package.json found');\n info(`Project type: ${projectConfig.type}`);\n info(`Package manager: ${projectConfig.packageManager}`);\n info(`TypeScript: ${projectConfig.hasTsConfig ? 'Yes' : 'No'}`);\n } else {\n error('No package.json found in current directory');\n }\n\n console.log();\n\n // Check installation\n header('Installation');\n\n const installedVersion = await getInstalledVersion();\n if (installedVersion) {\n success(`SDK version ${installedVersion} installed`);\n info(`Location: .capabilities-vendor/${installedVersion}/`);\n\n if (options.verbose) {\n // List installed packages\n const { existsSync } = await import('fs');\n const { join } = await import('path');\n\n const vendorDir = join(process.cwd(), '.capabilities-vendor', installedVersion);\n\n if (existsSync(vendorDir)) {\n const { readdir } = await import('fs/promises');\n const packages = await readdir(vendorDir, { withFileTypes: true });\n const packageNames = packages\n .filter((p) => p.isDirectory())\n .map((p) => p.name);\n\n if (packageNames.length > 0) {\n info('Installed packages:');\n printList(packageNames);\n }\n }\n }\n } else {\n info('No SDK installed');\n info('Run \"oxlayer install\" to install the SDK');\n }\n\n console.log();\n\n // Recommendations\n if (recommendedPackages.length > 0 && !installedVersion) {\n header('Recommended');\n info('For this project, OxLayer recommends installing:');\n printList(recommendedPackages);\n }\n}\n","/**\n * Environment Detection\n *\n * Detect project type and configuration\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { readPackageJson } from '../services/package.service.js';\n\n/**\n * Detected project type\n */\nexport type ProjectType = 'backend' | 'frontend' | 'unknown';\n\n/**\n * Package manager type\n */\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'unknown';\n\n/**\n * Project configuration\n */\nexport interface ProjectConfig {\n type: ProjectType;\n hasPackageJson: boolean;\n hasTsConfig: boolean;\n packageManager: PackageManager;\n rootDir: string;\n}\n\n/**\n * Detect the package manager being used\n */\nexport function detectPackageManager(cwd: string = process.cwd()): PackageManager {\n if (existsSync(join(cwd, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(join(cwd, 'bun.lockb'))) {\n return 'bun';\n }\n if (existsSync(join(cwd, 'yarn.lock'))) {\n return 'yarn';\n }\n if (existsSync(join(cwd, 'package-lock.json'))) {\n return 'npm';\n }\n return 'unknown';\n}\n\n/**\n * Find the project root directory (handles monorepos)\n *\n * Searches upward from the current directory to find package.json\n * Stops at the root or when finding a workspace config (pnpm-workspace.yaml, etc.)\n */\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let currentDir = startDir;\n\n while (currentDir !== '/' && currentDir !== '.') {\n // Check if this is a project root (has package.json)\n if (existsSync(join(currentDir, 'package.json'))) {\n // Also check for workspace indicators - this is definitely a root\n if (existsSync(join(currentDir, 'pnpm-workspace.yaml')) ||\n existsSync(join(currentDir, 'turbo.json')) ||\n existsSync(join(currentDir, 'lerna.json')) ||\n existsSync(join(currentDir, 'nx.json'))) {\n return currentDir;\n }\n\n // Check if package.json has workspaces field\n try {\n const pkgPath = join(currentDir, 'package.json');\n const pkgContent = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(pkgContent);\n if (pkg.workspaces) {\n return currentDir;\n }\n } catch {\n // Ignore parse errors\n }\n\n // If we're at startDir and it has package.json, use it\n if (currentDir === startDir) {\n return currentDir;\n }\n }\n\n // Move up one directory\n const parentDir = join(currentDir, '..');\n if (parentDir === currentDir) {\n // Can't go up further\n break;\n }\n currentDir = parentDir;\n }\n\n // Fallback to start directory\n return startDir;\n}\n\n/**\n * Detect project type based on dependencies\n */\nexport async function detectProjectType(cwd: string = process.cwd()): Promise<ProjectConfig> {\n const rootDir = findProjectRoot(cwd);\n const hasPackageJson = existsSync(join(rootDir, 'package.json'));\n const hasTsConfig = existsSync(join(rootDir, 'tsconfig.json')) || existsSync(join(rootDir, 'tsconfig.json'));\n const packageManager = detectPackageManager(rootDir);\n\n let type: ProjectType = 'unknown';\n\n if (hasPackageJson) {\n try {\n const pkg = await readPackageJson(rootDir);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n // We only support React for frontend and Hono for backend\n const hasReact = 'react' in deps || 'react-dom' in deps || '@types/react' in deps || 'next' in deps;\n const hasHono = 'hono' in deps || '@hono/hono' in deps;\n\n const isFrontend = hasReact;\n const isBackend = hasHono;\n\n if (isFrontend && isBackend) {\n type = 'unknown'; // Both detected - user should specify\n } else if (isFrontend) {\n type = 'frontend';\n } else if (isBackend) {\n type = 'backend';\n }\n } catch {\n // If we can't read package.json, keep as unknown\n }\n }\n\n return {\n type,\n hasPackageJson,\n hasTsConfig,\n packageManager,\n rootDir,\n };\n}\n\n/**\n * Get the install command for a package manager\n */\nexport function getInstallCommand(packageManager: PackageManager): string {\n switch (packageManager) {\n case 'pnpm':\n return 'pnpm install';\n case 'bun':\n return 'bun install';\n case 'yarn':\n return 'yarn install';\n case 'npm':\n return 'npm install';\n default:\n return 'pnpm install'; // Default to pnpm\n }\n}\n\n/**\n * Get recommended packages for a project type\n */\nexport function getRecommendedPackages(projectType: ProjectType): string[] {\n switch (projectType) {\n case 'backend':\n return ['backend-sdk'];\n case 'frontend':\n return ['frontend-sdk'];\n default:\n return ['backend-sdk', 'frontend-sdk', 'cli-tools'];\n }\n}\n\nexport default {\n detectPackageManager,\n detectProjectType,\n findProjectRoot,\n getInstallCommand,\n getRecommendedPackages,\n};\n","/**\n * Install Command\n *\n * Download and install SDK packages as a local workspace\n */\n\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { execSync } from 'child_process';\nimport { requestPackageDownload } from '../services/index.js';\nimport { hasPackageJson } from '../services/index.js';\nimport { downloadFile, extractZip, verifyManifest } from '../services/index.js';\nimport { detectProjectType, findProjectRoot, getInstallCommand, type PackageManager } from '../utils/env.js';\nimport { header, success, error, info, createSpinner, formatDuration } from '../utils/cli.js';\nimport type { InstallOptions, SdkPackageType } from '../types/index.js';\nimport { loadConfig, isTokenExpired } from '../services/device-auth.service.js';\n\nconst VENDOR_DIR = '.capabilities-vendor';\nconst CAPABILITIES_DIR = '.capabilities';\n\n/**\n * Resolve which packages to install based on project type\n */\nfunction resolvePackagesToInstall(\n projectType: string,\n options: InstallOptions\n): SdkPackageType[] {\n if (options.packages && options.packages.length > 0) {\n return options.packages;\n }\n\n // Default packages based on project type\n switch (projectType) {\n case 'backend':\n return ['backend-sdk'];\n case 'frontend':\n return ['frontend-sdk'];\n default:\n return ['backend-sdk', 'frontend-sdk', 'cli-tools'];\n }\n}\n\n/**\n * Generate package.json for the SDK workspace package\n */\nfunction generatePackageJson(version: string, manifest: any): string {\n // Build exports map from manifest packages\n const exports: Record<string, string> = {};\n const dependencies: Record<string, string> = {};\n\n for (const [name, pkg] of Object.entries(manifest.packages) as [string, any][]) {\n const relativePath = pkg.path;\n exports[name] = `./${relativePath}`;\n dependencies[name] = `workspace:*`;\n\n // Also export sub-paths for better DX\n const parts = name.split('/').slice(1); // Remove @oxlayer prefix\n if (parts.length > 1) {\n const subPath = parts.join('-');\n exports[`@oxlayer/${subPath}`] = `./${relativePath}`;\n }\n }\n\n return JSON.stringify({\n name: '@oxlayer/sdk-workspace',\n version: version,\n private: true,\n description: `OxLayer SDK v${version} - Local workspace package`,\n type: 'module',\n exports,\n dependencies,\n }, null, 2);\n}\n\n/**\n * Update or create pnpm-workspace.yaml to include vendor directory\n */\nasync function updateWorkspaceConfig(rootDir: string, vendorVersionDir: string): Promise<void> {\n const workspacePath = join(rootDir, 'pnpm-workspace.yaml');\n const relativeVendorPath = vendorVersionDir.replace(rootDir + '/', '').replace(/^\\//, '');\n\n let workspaceConfig: { packages?: string[] };\n\n try {\n const content = await fs.readFile(workspacePath, 'utf-8');\n // Parse YAML (simple version, just extract packages array)\n const match = content.match(/packages:\\s*\\n((?:\\s*-\\s*[^\\n]+\\n*)+)/);\n if (match) {\n const packages = match[1].split('\\n')\n .map(line => line.replace(/^\\s*-\\s*/, '').trim())\n .filter(line => line.length > 0);\n workspaceConfig = { packages };\n } else {\n workspaceConfig = { packages: [] };\n }\n } catch {\n // File doesn't exist, create new\n workspaceConfig = { packages: [] };\n }\n\n // Add vendor path if not already present\n if (!workspaceConfig.packages?.includes(relativeVendorPath)) {\n workspaceConfig.packages = [...(workspaceConfig.packages || []), relativeVendorPath];\n\n const yamlContent = `packages:\\n${workspaceConfig.packages.map(p => ` - '${p}'`).join('\\n')}\\n`;\n await fs.writeFile(workspacePath, yamlContent, 'utf-8');\n }\n}\n\n/**\n * Create or update the 'current' symlink\n */\nasync function updateCurrentSymlink(baseDir: string, version: string): Promise<void> {\n const currentPath = join(baseDir, 'current');\n const versionPath = join(baseDir, version);\n\n try {\n // Remove existing symlink\n await fs.unlink(currentPath);\n } catch {\n // Doesn't exist, that's fine\n }\n\n // Create new symlink\n await fs.symlink(versionPath, currentPath, 'dir');\n}\n\n/**\n * Add workspace dependency to project's package.json\n */\nasync function addWorkspaceDependency(rootDir: string, vendorVersionPath: string): Promise<void> {\n const packageJsonPath = join(rootDir, 'package.json');\n\n try {\n const content = await fs.readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n\n // Add @oxlayer/sdk-workspace as a workspace dependency\n if (!pkg.dependencies) {\n pkg.dependencies = {};\n }\n\n // Only add if not already present\n if (!pkg.dependencies['@oxlayer/sdk-workspace']) {\n pkg.dependencies['@oxlayer/sdk-workspace'] = 'workspace:*';\n }\n\n // Write back with proper formatting\n await fs.writeFile(packageJsonPath, JSON.stringify(pkg, null, 2) + '\\n', 'utf-8');\n } catch (err) {\n throw new Error(`Failed to update package.json: ${err instanceof Error ? err.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Install command - download and install SDK packages\n */\nexport async function install(version: string, options: InstallOptions = {}): Promise<void> {\n const startTime = Date.now();\n const startDir = process.cwd();\n\n header('OxLayer SDK Installer');\n\n // Find project root (handles monorepos)\n const rootDir = findProjectRoot(startDir);\n\n // Check if we're in a valid project\n if (!await hasPackageJson()) {\n error('No package.json found in current directory');\n info('Navigate to your project directory before installing.');\n process.exit(1);\n }\n\n // Detect project type and package manager\n const projectConfig = await detectProjectType(startDir);\n info(`Project root: ${rootDir === startDir ? '.' : rootDir}`);\n info(`Package manager: ${projectConfig.packageManager}`);\n info(`Project type: ${projectConfig.type}`);\n\n // Resolve packages to install\n const packagesToInstall = resolvePackagesToInstall(projectConfig.type, options);\n info(`Packages: ${packagesToInstall.join(', ')}`);\n\n // Validate authentication\n const authSpinner = createSpinner('Validating authentication...');\n authSpinner.start();\n\n try {\n const config = await loadConfig();\n\n if (!config || !config.token) {\n authSpinner.fail('Authentication required');\n error('Please run: oxlayer login');\n process.exit(1);\n }\n\n // Check if token is expired\n if (isTokenExpired(config)) {\n authSpinner.fail('Token expired');\n error('Your authentication token has expired. Please run: oxlayer login');\n process.exit(1);\n }\n\n authSpinner.succeed('Authenticated');\n\n // Show auth info\n info(`Organization: ${config.organizationId}`);\n info(`Device: ${config.tokenInfo?.deviceId || 'Unknown'}`);\n\n const expiresAt = new Date(config.tokenInfo.expiresAt);\n const now = new Date();\n const daysUntilExpiry = Math.ceil((expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n info(`Token expires: ${expiresAt.toLocaleString()} (${daysUntilExpiry > 0 ? `in ${daysUntilExpiry} days` : 'expired'})`);\n } catch (err) {\n authSpinner.fail('Authentication failed');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n console.log();\n\n // Download packages (all packages are in a single zip)\n const downloadSpinner = createSpinner('Downloading SDK...');\n downloadSpinner.start();\n\n let resolvedVersion = version;\n let manifest: any;\n\n try {\n // Request download URL for the first package type (all are in the same zip)\n const { downloadUrl, version: resolvedVer } = await requestPackageDownload(\n packagesToInstall[0],\n version\n );\n resolvedVersion = resolvedVer;\n\n // Create temp directory for download\n const tempDir = join(rootDir, '.oxlayer-temp');\n await fs.mkdir(tempDir, { recursive: true });\n\n const zipPath = join(tempDir, `oxlayer-sdk-${resolvedVersion}.zip`);\n\n // Download with progress\n let lastProgress = 0;\n await downloadFile(\n downloadUrl,\n zipPath,\n (progress, total) => {\n const percent = Math.floor((progress / total) * 100);\n if (percent - lastProgress >= 10) {\n downloadSpinner.text = `Downloading SDK... ${percent}%`;\n lastProgress = percent;\n }\n }\n );\n\n downloadSpinner.succeed(`Downloaded SDK (${resolvedVersion})`);\n\n // Extract\n const extractSpinner = createSpinner('Extracting SDK...');\n extractSpinner.start();\n\n // Create vendor directory structure\n const vendorBaseDir = join(rootDir, VENDOR_DIR);\n const vendorVersionDir = join(vendorBaseDir, resolvedVersion);\n await fs.mkdir(vendorVersionDir, { recursive: true });\n\n // Extract ZIP\n await extractZip(zipPath, join(tempDir, 'extracted'));\n\n // The zip contains a version directory (e.g., 2026_02_14_001/)\n const extractedBase = join(tempDir, 'extracted', resolvedVersion);\n\n // Verify and read manifest\n const manifestPath = join(extractedBase, 'manifest.json');\n manifest = await verifyManifest(manifestPath);\n\n // Copy all package contents to vendor directory\n await copyDirectory(extractedBase, vendorVersionDir);\n\n // Generate package.json for the workspace\n const packageJsonPath = join(vendorVersionDir, 'package.json');\n const packageJsonContent = generatePackageJson(resolvedVersion, manifest);\n await fs.writeFile(packageJsonPath, packageJsonContent, 'utf-8');\n\n extractSpinner.succeed('Extracted SDK');\n\n // Update workspace configuration\n const workspaceSpinner = createSpinner('Configuring workspace...');\n workspaceSpinner.start();\n\n await updateWorkspaceConfig(rootDir, vendorVersionDir);\n\n // Update 'current' symlink\n await updateCurrentSymlink(vendorBaseDir, resolvedVersion);\n\n // Add workspace dependency to project's package.json\n await addWorkspaceDependency(rootDir, vendorVersionDir);\n\n workspaceSpinner.succeed('Workspace configured');\n\n // Clean up temp directory\n await fs.rm(tempDir, { recursive: true, force: true });\n } catch (err) {\n downloadSpinner.fail('Failed to install SDK');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n console.log();\n\n const duration = Date.now() - startTime;\n\n // Success\n header('Installation Complete');\n success(`SDK version ${resolvedVersion} installed successfully`);\n info(`Duration: ${formatDuration(duration)}`);\n info(`Workspace: ${VENDOR_DIR}/${resolvedVersion}/`);\n info(`Current link: ${CAPABILITIES_DIR}/current -> ${resolvedVersion}`);\n\n // Auto-run package manager install\n const installSpinner = createSpinner('Running package manager install...');\n installSpinner.start();\n\n try {\n const installCommand = getInstallCommand(projectConfig.packageManager);\n execSync(installCommand, { cwd: rootDir, stdio: 'pipe' });\n installSpinner.succeed(`Dependencies installed via ${projectConfig.packageManager}`);\n } catch (err) {\n installSpinner.warn(`Package manager install failed. Please run '${getInstallCommand(projectConfig.packageManager)}' manually.`);\n }\n\n // Next steps\n console.log();\n info('Next steps:');\n console.log(' Import in your code:');\n console.log(' import { SomeCapability } from \\'@oxlayer/sdk-workspace\\';');\n console.log();\n console.log(` To switch SDK versions, update the ${CAPABILITIES_DIR}/current symlink.`);\n}\n\n/**\n * Copy a directory recursively\n */\nasync function copyDirectory(src: string, dest: string): Promise<void> {\n await fs.mkdir(dest, { recursive: true });\n const entries = await fs.readdir(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(src, entry.name);\n const destPath = join(dest, entry.name);\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath);\n } else {\n await fs.copyFile(srcPath, destPath);\n }\n }\n}\n","/**\n * Services Index\n */\n\nexport * from './auth.service.js';\nexport * from './device-auth.service.js';\nexport * from './api.service.js';\nexport * from './download.service.js';\nexport * from './package.service.js';\nexport * from './hooks.service.js';\nexport * from './telemetry.service.js';\n","/**\n * Authentication Service\n *\n * Handles CLI authentication with scoped tokens.\n *\n * @deprecated Most methods are now thin wrappers around device-auth.service.ts.\n * New code should import from device-auth.service.ts directly.\n */\n\nimport type { InstallerConfig } from '../types/index.js';\n\n// Re-export everything from the new device-auth service\nexport * from './device-auth.service.js';\n\n// ============================================================================\n// Legacy API (deprecated)\n// ============================================================================\n\n/**\n * @deprecated Use loadConfig from device-auth.service.ts instead\n * Returns CliConfig instead of InstallerConfig\n */\nexport async function loadConfig(): Promise<InstallerConfig | null> {\n const { loadConfig: loadNewConfig } = await import('./device-auth.service.js');\n const config = await loadNewConfig();\n\n if (!config) {\n return null;\n }\n\n // Convert new config to legacy format for backward compatibility\n return {\n apiKey: config.token, // Map token to apiKey for legacy consumers\n environment: config.environment,\n vendorDir: config.vendorDir,\n apiEndpoint: config.apiEndpoint,\n };\n}\n\n/**\n * @deprecated Use saveConfig from device-auth.service.ts instead\n * Accepts InstallerConfig but converts to CliConfig internally\n */\nexport async function saveConfig(config: InstallerConfig): Promise<void> {\n const { saveConfig: saveNewConfig } = await import('./device-auth.service.js');\n\n // For legacy API key config, we need to migrate\n if (config.apiKey && !config.apiKey.startsWith('oxl_cli_')) {\n // This is an old API key format - would need migration\n // For now, save as-is to avoid breaking existing flows\n const { promises: fs } = await import('fs');\n const { join } = await import('path');\n const { homedir } = await import('os');\n\n const CONFIG_DIR = join(homedir(), '.oxlayer');\n const CONFIG_FILE = join(CONFIG_DIR, 'config.json');\n\n await fs.mkdir(CONFIG_DIR, { recursive: true });\n await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), {\n mode: 0o600,\n });\n return;\n }\n\n // Convert legacy config to new format\n await saveNewConfig({\n token: config.apiKey,\n tokenInfo: {\n token: config.apiKey,\n tokenType: 'Bearer',\n scopes: ['sdk:read', 'capabilities:read', 'downloads:read'],\n expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(),\n deviceId: 'legacy',\n },\n organizationId: '',\n environment: config.environment,\n vendorDir: config.vendorDir,\n apiEndpoint: config.apiEndpoint,\n updatedAt: new Date().toISOString(),\n });\n}\n\n/**\n * @deprecated Use removeConfig from device-auth.service.ts instead\n */\nexport async function removeConfig(): Promise<void> {\n const { removeConfig: removeNewConfig } = await import('./device-auth.service.js');\n await removeNewConfig();\n}\n\n/**\n * @deprecated Use getAccessToken from device-auth.service.ts instead\n */\nexport async function getApiKey(): Promise<string | null> {\n const { getAccessToken } = await import('./device-auth.service.js');\n return getAccessToken();\n}\n\n/**\n * @deprecated Use validateToken from device-auth.service.ts instead\n */\nexport function validateApiKey(apiKey: string): boolean {\n const { validateToken } = require('./device-auth.service.js');\n return validateToken(apiKey);\n}\n\n/**\n * Get the configuration directory path\n */\nexport function getConfigDir(): string {\n const { join } = require('path');\n const { homedir } = require('os');\n return join(homedir(), '.oxlayer');\n}\n\n/**\n * Get the configuration file path\n */\nexport function getConfigFile(): string {\n return require('path').join(getConfigDir(), 'config.json');\n}\n","/**\n * Download Service\n *\n * Handles downloading and verifying SDK packages\n */\n\nimport { createHash } from 'crypto';\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport type { ReleaseManifest } from '../types/index.js';\n\n/**\n * Calculate SHA256 hash of a file\n */\nexport async function calculateSHA256(filePath: string): Promise<string> {\n const content = await fs.readFile(filePath);\n return createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Calculate SHA256 hash of a directory recursively\n */\nexport async function calculateDirSHA256(dirPath: string): Promise<string> {\n const hash = createHash('sha256');\n const { glob } = await import('glob');\n\n const files = await glob('**/*', {\n cwd: dirPath,\n nodir: true,\n absolute: false,\n });\n\n // Sort for consistent hashing\n files.sort();\n\n for (const file of files) {\n const filePath = join(dirPath, file);\n const content = await fs.readFile(filePath);\n const relativePath = file.replace(/\\\\/g, '/');\n\n hash.update(relativePath + '\\0');\n hash.update(content);\n }\n\n return hash.digest('hex');\n}\n\n/**\n * Download a file with progress tracking\n */\nexport async function downloadFile(\n url: string,\n destination: string,\n onProgress?: (progress: number, total: number) => void\n): Promise<void> {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to download: ${response.statusText}`);\n }\n\n const total = parseInt(response.headers.get('content-length') || '0', 10);\n let downloaded = 0;\n\n // Ensure directory exists\n await fs.mkdir(join(destination, '..'), { recursive: true });\n\n const writer = await fs.open(destination, 'w');\n\n try {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('No response body');\n }\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n await writer.write(value);\n downloaded += value.length;\n\n if (onProgress && total > 0) {\n onProgress(downloaded, total);\n }\n }\n } finally {\n await writer.close();\n }\n}\n\n/**\n * Verify downloaded manifest integrity\n */\nexport async function verifyManifest(\n manifestPath: string,\n expectedHash?: string\n): Promise<ReleaseManifest> {\n const content = await fs.readFile(manifestPath, 'utf-8');\n const manifest = JSON.parse(content) as ReleaseManifest;\n\n if (expectedHash && manifest.sha256 !== expectedHash) {\n throw new Error(\n `Manifest SHA256 mismatch. Expected ${expectedHash}, got ${manifest.sha256}`\n );\n }\n\n return manifest;\n}\n\n/**\n * Extract a ZIP file\n */\nexport async function extractZip(zipPath: string, destination: string): Promise<void> {\n const AdmZip = (await import('adm-zip')).default;\n const zip = new AdmZip(zipPath);\n\n await fs.mkdir(destination, { recursive: true });\n zip.extractAllTo(destination, true);\n}\n\n/**\n * Verify extracted directory integrity\n */\nexport async function verifyExtractedIntegrity(\n extractDir: string,\n manifest: ReleaseManifest\n): Promise<boolean> {\n const actualHash = await calculateDirSHA256(extractDir);\n return actualHash === manifest.sha256;\n}\n\nexport default {\n calculateSHA256,\n calculateDirSHA256,\n downloadFile,\n verifyManifest,\n extractZip,\n verifyExtractedIntegrity,\n};\n","/**\n * Post-Install Hooks System\n *\n * Allows SDK packages to run setup code after installation\n */\n\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\n\n/**\n * Post-install context provided to hooks\n */\nexport interface PostInstallContext {\n version: string;\n vendorDir: string;\n projectRoot: string;\n projectType: string;\n packageManager: string;\n capabilities: Record<string, unknown>;\n}\n\n/**\n * Post-install hook function signature\n */\nexport type PostInstallHook = (context: PostInstallContext) => Promise<void> | void;\n\n/**\n * Hook result\n */\nexport interface HookResult {\n hookName: string;\n status: 'success' | 'warning' | 'error';\n message: string;\n output?: string;\n}\n\n/**\n * Hook definition in package.json\n */\nexport interface HookDefinition {\n file: string;\n run?: string;\n}\n\n/**\n * Execute post-install hooks for a given version\n */\nexport async function executeHooks(context: PostInstallContext): Promise<HookResult[]> {\n const results: HookResult[] = [];\n\n // Find all hook files\n const hooksDir = join(context.vendorDir, 'hooks');\n if (!existsSync(hooksDir)) {\n return results;\n }\n\n const hookFiles = await fs.readdir(hooksDir).filter(f => f.endsWith('.js') || f.endsWith('.mjs'));\n\n for (const hookFile of hookFiles) {\n const hookPath = join(hooksDir, hookFile);\n const hookName = hookFile.replace(/\\.(js|mjs)$/, '');\n\n try {\n // Clear require cache to ensure fresh execution\n delete require.cache[require.resolve(hookPath)];\n\n // Load and execute hook\n const hook: PostInstallHook = (await import(hookPath)).default || (await import(hookPath)).postInstall;\n\n if (typeof hook === 'function') {\n await hook(context);\n results.push({\n hookName,\n status: 'success',\n message: 'Hook executed successfully',\n });\n } else {\n results.push({\n hookName,\n status: 'warning',\n message: 'No default export or postInstall function found',\n });\n }\n } catch (err) {\n results.push({\n hookName,\n status: 'error',\n message: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n }\n\n return results;\n}\n\n/**\n * Create a post-install hook file template\n */\nexport async function createHookTemplate(\n hookName: string,\n vendorDir: string\n): Promise<void> {\n const hooksDir = join(vendorDir, 'hooks');\n await fs.mkdir(hooksDir, { recursive: true });\n\n const hookPath = join(hooksDir, `${hookName}.js`);\n\n const template = `/**\n * ${hookName} Post-Install Hook\n *\n * This hook runs after SDK installation.\n * Use it to set up configuration, generate files, or validate environment.\n */\n\nexport default async function postInstall(context) {\n const { version, projectRoot, capabilities } = context;\n\n console.log(\\`Running post-install for SDK \\${version}...\\`);\n\n // Example: Add environment variables to .env\n // const { appendFileSync } = await import('fs');\n // const envPath = require('path').join(projectRoot, '.env');\n // appendFileSync(envPath, \\`\n // # OxLayer SDK\n // OXLAYER_SDK_VERSION=\\${version}\n // \\`);\n\n // Example: Generate config file\n // const { writeFileSync } = await import('fs');\n // const { join } = await import('path');\n // const configPath = join(projectRoot, 'oxlayer.config.json');\n // writeFileSync(configPath, JSON.stringify({\n // version,\n // capabilities: Object.keys(capabilities),\n // }, null, 2));\n\n console.log('Post-install complete!');\n}\n\nexport const hookName = '${hookName}';\nexport const hookVersion = '1.0.0';\n`;\n\n await fs.writeFile(hookPath, template);\n}\n\n/**\n * Built-in post-install hooks\n */\n\n/**\n * Hook: Generate .env file with SDK configuration\n */\nexport async function generateEnvHook(context: PostInstallContext): Promise<void> {\n const envPath = join(context.projectRoot, '.env');\n\n // Check if .env exists\n if (!existsSync(envPath)) {\n const envContent = `\n# OxLayer SDK Configuration\n# Generated by SDK installer\nOXLAYER_SDK_VERSION=${context.version}\nOXLAYER_VENDOR_DIR=.capabilities-vendor/${context.version}\n`;\n\n await fs.writeFile(envPath, envContent.trim());\n }\n}\n\n/**\n * Hook: Update tsconfig.json paths\n */\nexport async function updateTsconfigPathsHook(context: PostInstallContext): Promise<void> {\n const tsconfigPath = join(context.projectRoot, 'tsconfig.json');\n\n if (!existsSync(tsconfigPath)) {\n return;\n }\n\n const tsconfig = JSON.parse(await fs.readFile(tsconfigPath, 'utf-8'));\n\n // Add paths for vendor directory\n if (!tsconfig.compilerOptions) {\n tsconfig.compilerOptions = {};\n }\n\n if (!tsconfig.compilerOptions.paths) {\n tsconfig.compilerOptions.paths = {};\n }\n\n // Add path mapping for SDK packages\n const vendorPath = `.capabilities-vendor/${context.version}`;\n tsconfig.compilerOptions.paths['@oxlayer/*'] = [`${vendorPath}/*`];\n\n await fs.writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2));\n}\n\n/**\n * Hook: Print capability warnings\n */\nexport async function printCapabilityWarningsHook(context: PostInstallContext): Promise<void> {\n const { capabilities } = context;\n\n // Check for specific capability limits and warn if needed\n for (const [capability, limits] of Object.entries(capabilities)) {\n if (typeof limits === 'object' && limits !== null) {\n if ('maxRealms' in limits && (limits as any).maxRealms === 1) {\n console.warn(`⚠️ Warning: Limited to 1 realm for ${capability}`);\n }\n if ('maxStorageGb' in limits && (limits as any).maxStorageGb < 100) {\n console.warn(`⚠️ Warning: Limited to ${(limits as any).maxStorageGb}GB storage for ${capability}`);\n }\n }\n }\n}\n\n/**\n * Execute built-in hooks\n */\nexport async function executeBuiltinHooks(context: PostInstallContext): Promise<void> {\n await generateEnvHook(context);\n await updateTsconfigPathsHook(context);\n await printCapabilityWarningsHook(context);\n}\n\nexport default {\n executeHooks,\n createHookTemplate,\n executeBuiltinHooks,\n};\n","/**\n * Telemetry Service\n *\n * Light, privacy-focused usage tracking\n */\n\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\n\n/**\n * Telemetry event types\n */\nexport type TelemetryEvent =\n | 'install'\n | 'resolve'\n | 'login'\n | 'doctor'\n | 'diff'\n | 'error';\n\n/**\n * Telemetry data (minimal and privacy-focused)\n */\nexport interface TelemetryData {\n event: TelemetryEvent;\n sdkVersion?: string;\n cliVersion: string;\n nodeVersion: string;\n platform: string;\n projectType?: string;\n environment?: string;\n command?: string;\n errorCode?: string;\n}\n\n/**\n * Telemetry configuration\n */\ninterface TelemetryConfig {\n enabled: boolean;\n endpoint?: string;\n userId?: string; // Anonymous user ID\n}\n\nconst TELEMETRY_FILE = join(process.env.HOME || process.env.USERPROFILE || '', '.oxlayer', 'telemetry.json');\nconst TELEMETRY_ENABLED = process.env.OXLAYER_TELEMETRY !== '0';\n\n/**\n * Get or create telemetry config\n */\nasync function getTelemetryConfig(): Promise<TelemetryConfig> {\n try {\n if (existsSync(TELEMETRY_FILE)) {\n const content = await fs.readFile(TELEMETRY_FILE, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // File doesn't exist or is invalid\n }\n\n // Create new config with anonymous user ID\n const config: TelemetryConfig = {\n enabled: TELEMETRY_ENABLED,\n userId: generateAnonymousId(),\n };\n\n await saveTelemetryConfig(config);\n return config;\n}\n\n/**\n * Save telemetry config\n */\nasync function saveTelemetryConfig(config: TelemetryConfig): Promise<void> {\n const dir = join(process.env.HOME || process.env.USERPROFILE || '', '.oxlayer');\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(TELEMETRY_FILE, JSON.stringify(config, null, 2));\n}\n\n/**\n * Generate anonymous user ID\n */\nfunction generateAnonymousId(): string {\n // Generate a random ID that persists across sessions\n // Use webcrypto API which is available in Node.js\n const bytes = new Uint8Array(8);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Send telemetry event (fire-and-forget)\n */\nexport async function trackEvent(data: TelemetryData): Promise<void> {\n const config = await getTelemetryConfig();\n\n if (!config.enabled) {\n return; // Telemetry disabled\n }\n\n // Add metadata\n const enrichedData: TelemetryData = {\n ...data,\n userId: config.userId,\n timestamp: new Date().toISOString(),\n } as TelemetryData;\n\n // Send in background, don't await\n sendTelemetry(enrichedData).catch(() => {\n // Silently fail - telemetry should never break the CLI\n });\n}\n\n/**\n * Send telemetry to server (non-blocking)\n */\nasync function sendTelemetry(data: Record<string, unknown>): Promise<void> {\n const endpoint = process.env.OXLAYER_TELEMETRY_ENDPOINT || 'https://telemetry.oxlayer.dev/v1/event';\n\n try {\n await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n // Keep request light - don't wait for response\n keepalive: true,\n }).catch(() => {\n // Network error - ignore\n });\n } catch {\n // Ignore all errors - telemetry is fire-and-forget\n }\n}\n\n/**\n * Track CLI command execution\n */\nexport function trackCommand(\n command: string,\n options: {\n sdkVersion?: string;\n projectType?: string;\n environment?: string;\n } = {}\n): void {\n trackEvent({\n event: command,\n command,\n ...options,\n cliVersion: '0.0.1',\n nodeVersion: process.version,\n platform: process.platform,\n });\n}\n\n/**\n * Track error\n */\nexport function trackError(\n command: string,\n errorCode: string,\n options: {\n sdkVersion?: string;\n projectType?: string;\n } = {}\n): void {\n trackEvent({\n event: 'error',\n command,\n errorCode,\n ...options,\n cliVersion: '0.0.1',\n nodeVersion: process.version,\n platform: process.platform,\n });\n}\n\n/**\n * Enable telemetry\n */\nexport async function enableTelemetry(): Promise<void> {\n const config = await getTelemetryConfig();\n config.enabled = true;\n await saveTelemetryConfig(config);\n}\n\n/**\n * Disable telemetry\n */\nexport async function disableTelemetry(): Promise<void> {\n const config = await getTelemetryConfig();\n config.enabled = false;\n await saveTelemetryConfig(config);\n}\n\n/**\n * Get telemetry status\n */\nexport async function getTelemetryStatus(): Promise<{ enabled: boolean; userId: string }> {\n const config = await getTelemetryConfig();\n return {\n enabled: config.enabled,\n userId: config.userId || '',\n };\n}\n\nexport default {\n trackEvent,\n trackCommand,\n trackError,\n enableTelemetry,\n disableTelemetry,\n getTelemetryStatus,\n};\n","/**\n * Resolve Command\n *\n * Resolve capabilities for the current project\n */\n\nimport { resolveCapabilities } from '../services/index.js';\nimport { detectProjectType } from '../utils/env.js';\nimport { header, success, error, info, printCapabilities } from '../utils/cli.js';\nimport type { CapabilityName, Environment } from '../types/index.js';\n\nexport interface ResolveOptions {\n environment?: Environment;\n verbose?: boolean;\n}\n\n/**\n * Resolve command - show capability configuration for the project\n */\nexport async function resolve(options: ResolveOptions = {}): Promise<void> {\n header('OxLayer Capability Resolution');\n\n // Detect project type to determine capabilities\n const projectConfig = await detectProjectType();\n const environment = options.environment || 'development';\n\n info(`Project type: ${projectConfig.type}`);\n info(`Environment: ${environment}`);\n\n // Determine capabilities based on project type\n const capabilitiesToRequest: CapabilityName[] = [];\n\n switch (projectConfig.type) {\n case 'backend':\n capabilitiesToRequest.push(\n 'auth',\n 'storage',\n 'cache',\n 'events',\n 'queues',\n 'metrics',\n 'telemetry'\n );\n break;\n case 'frontend':\n capabilitiesToRequest.push('auth', 'storage');\n break;\n default:\n // Request all capabilities for unknown projects\n capabilitiesToRequest.push(\n 'auth',\n 'storage',\n 'search',\n 'vector',\n 'cache',\n 'events',\n 'queues',\n 'metrics',\n 'telemetry'\n );\n }\n\n const spinner = await import('../utils/cli.js').then(m => m.createSpinner('Resolving capabilities...'));\n spinner.start();\n\n try {\n const result = await resolveCapabilities(capabilitiesToRequest, environment);\n\n spinner.succeed('Capabilities resolved');\n\n console.log();\n\n // Show license info\n info(`Organization: ${result.organizationId}`);\n info(`License: ${result.licenseId}`);\n info(`Resolved at: ${new Date(result.resolvedAt).toLocaleString()}`);\n\n console.log();\n\n // Show capabilities\n header('Available Capabilities');\n printCapabilities(result.capabilities);\n\n // Show example usage\n if (options.verbose) {\n console.log();\n header('Usage Example');\n console.log();\n console.log('Import and use capabilities in your code:');\n console.log();\n console.log(chalk.gray('```typescript'));\n console.log(chalk.gray('import { resolveCapabilities } from \\'@oxlayer/capabilities-internal\\';'));\n console.log();\n console.log(chalk.gray('const capabilities = await resolveCapabilities({'));\n console.log(chalk.gray(` projectId: 'your-project-id',`));\n console.log(chalk.gray(` environment: '${environment}',`));\n console.log(chalk.gray(` requested: ['${capabilitiesToRequest.join(\"', '\")}']`));\n console.log(chalk.gray('});'));\n console.log(chalk.gray('```'));\n console.log();\n }\n\n success(`Your project has access to ${Object.keys(result.capabilities).length} capabilities`);\n } catch (err) {\n spinner.fail('Failed to resolve capabilities');\n error(err instanceof Error ? err.message : 'Unknown error');\n\n if (err instanceof Error && err.message.includes('API key')) {\n console.log();\n info('Make sure you\\'re authenticated:');\n console.log(' oxlayer login');\n }\n\n process.exit(1);\n }\n}\n\nconst chalk = (await import('chalk')).default;\n","/**\n * Logout Command\n *\n * Remove stored API key and configuration\n */\n\nimport { removeConfig, getConfigFile } from '../services/auth.service.js';\nimport { success, info, warning } from '../utils/cli.js';\n\n/**\n * Logout command - remove stored credentials\n */\nexport async function logout(): Promise<void> {\n try {\n await removeConfig();\n success('Logged out successfully');\n info(`Configuration removed from ${getConfigFile()}`);\n info('Your API key is no longer stored locally.');\n } catch (err) {\n warning('Could not remove configuration');\n info(err instanceof Error ? err.message : 'Unknown error');\n }\n}\n","/**\n * Doctor Command\n *\n * Diagnostic tool for troubleshooting SDK installation and configuration\n */\n\nimport { loadConfig } from '../services/auth.service.js';\nimport { getInstalledVersion, getVendorDir } from '../services/index.js';\nimport { healthCheck } from '../services/index.js';\nimport { detectProjectType } from '../utils/env.js';\nimport { header, success, error, warning, info, printList } from '../utils/cli.js';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\n\nexport interface DoctorOptions {\n verbose?: boolean;\n fix?: boolean;\n}\n\ninterface DiagnosticResult {\n name: string;\n status: 'pass' | 'warn' | 'fail';\n message: string;\n fix?: string;\n}\n\n/**\n * Run diagnostics\n */\nasync function runDiagnostics(options: DoctorOptions): Promise<DiagnosticResult[]> {\n const results: DiagnosticResult[] = [];\n\n // 1. Check authentication\n const config = await loadConfig();\n if (config) {\n results.push({\n name: 'Authentication',\n status: 'pass',\n message: 'API key configured',\n });\n } else {\n results.push({\n name: 'Authentication',\n status: 'fail',\n message: 'Not authenticated',\n fix: 'Run: oxlayer login',\n });\n }\n\n // 2. Check API connectivity\n try {\n const isHealthy = await healthCheck();\n if (isHealthy) {\n results.push({\n name: 'API Connectivity',\n status: 'pass',\n message: 'Control Panel API is reachable',\n });\n } else {\n results.push({\n name: 'API Connectivity',\n status: 'fail',\n message: 'API health check failed',\n fix: 'Check your network connection',\n });\n }\n } catch {\n results.push({\n name: 'API Connectivity',\n status: 'fail',\n message: 'Cannot reach Control Panel API',\n fix: 'Check your network connection or API endpoint',\n });\n }\n\n // 3. Check project structure\n const projectConfig = await detectProjectType();\n if (projectConfig.hasPackageJson) {\n results.push({\n name: 'Project Structure',\n status: 'pass',\n message: `Found ${projectConfig.type} project with ${projectConfig.packageManager}`,\n });\n } else {\n results.push({\n name: 'Project Structure',\n status: 'warn',\n message: 'No package.json found',\n fix: 'Navigate to your project directory',\n });\n }\n\n // 4. Check TypeScript config\n if (projectConfig.hasTsConfig) {\n results.push({\n name: 'TypeScript',\n status: 'pass',\n message: 'TypeScript configuration found',\n });\n } else {\n results.push({\n name: 'TypeScript',\n status: 'warn',\n message: 'No TypeScript configuration found',\n fix: 'Run: npx tsc --init',\n });\n }\n\n // 5. Check SDK installation\n const installedVersion = await getInstalledVersion();\n if (installedVersion) {\n const vendorDir = getVendorDir(installedVersion);\n const manifestPath = join(vendorDir, 'manifest.json');\n\n if (existsSync(manifestPath)) {\n results.push({\n name: 'SDK Installation',\n status: 'pass',\n message: `SDK version ${installedVersion} installed`,\n });\n } else {\n results.push({\n name: 'SDK Installation',\n status: 'warn',\n message: `SDK version ${installedVersion} incomplete (missing manifest)`,\n fix: 'Run: oxlayer install --force',\n });\n }\n } else {\n results.push({\n name: 'SDK Installation',\n status: 'warn',\n message: 'No SDK installed',\n fix: 'Run: oxlayer install',\n });\n }\n\n // 6. Check for .gitignore\n const gitignorePath = join(process.cwd(), '.gitignore');\n if (existsSync(gitignorePath)) {\n const gitignoreContent = await import('fs/promises').then(fs => fs.readFile(gitignorePath, 'utf-8'));\n const hasVendorIgnore = gitignoreContent.includes('.capabilities-vendor');\n\n if (hasVendorIgnore) {\n results.push({\n name: '.gitignore',\n status: 'pass',\n message: 'Vendor directory is ignored',\n });\n } else {\n results.push({\n name: '.gitignore',\n status: 'warn',\n message: 'Vendor directory not in .gitignore',\n fix: 'Add \".capabilities-vendor/\" to .gitignore',\n });\n }\n } else {\n results.push({\n name: '.gitignore',\n status: 'warn',\n message: 'No .gitignore found',\n fix: 'Create .gitignore and add \".capabilities-vendor/\"',\n });\n }\n\n // 7. Check environment variables\n if (process.env.OXLAYER_API_KEY) {\n results.push({\n name: 'Environment Variables',\n status: 'pass',\n message: 'OXLAYER_API_KEY is set',\n });\n } else if (!config) {\n results.push({\n name: 'Environment Variables',\n status: 'warn',\n message: 'No API key in environment or config',\n fix: 'Set OXLAYER_API_KEY or run: oxlayer login',\n });\n }\n\n // 8. Check node version\n const nodeVersion = process.version;\n const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0], 10);\n if (majorVersion >= 18) {\n results.push({\n name: 'Node Version',\n status: 'pass',\n message: `Node ${nodeVersion} (supported)`,\n });\n } else {\n results.push({\n name: 'Node Version',\n status: 'fail',\n message: `Node ${nodeVersion} is not supported (requires >= 18)`,\n fix: 'Upgrade to Node.js 18 or later',\n });\n }\n\n // 9. Capability check (verbose only)\n if (options.verbose && config) {\n try {\n const { resolveCapabilities } = await import('../services/api.service.js');\n const capabilities = await resolveCapabilities(['auth', 'storage'], 'development');\n\n if (Object.keys(capabilities.capabilities).length > 0) {\n results.push({\n name: 'Capabilities',\n status: 'pass',\n message: `${Object.keys(capabilities.capabilities).length} capabilities available`,\n });\n } else {\n results.push({\n name: 'Capabilities',\n status: 'warn',\n message: 'No capabilities available',\n fix: 'Check your license configuration',\n });\n }\n } catch {\n results.push({\n name: 'Capabilities',\n status: 'fail',\n message: 'Could not resolve capabilities',\n fix: 'Check your API key and license',\n });\n }\n }\n\n return results;\n}\n\n/**\n * Print diagnostic results\n */\nfunction printDiagnostics(results: DiagnosticResult[]): void {\n let passCount = 0;\n let warnCount = 0;\n let failCount = 0;\n\n for (const result of results) {\n switch (result.status) {\n case 'pass':\n success(`${result.name}: ${result.message}`);\n passCount++;\n break;\n case 'warn':\n warning(`${result.name}: ${result.message}`);\n if (result.fix) {\n info(` → ${result.fix}`);\n }\n warnCount++;\n break;\n case 'fail':\n error(`${result.name}: ${result.message}`);\n if (result.fix) {\n info(` → ${result.fix}`);\n }\n failCount++;\n break;\n }\n }\n\n console.log();\n\n // Summary\n if (failCount === 0 && warnCount === 0) {\n success('All checks passed! Your system is properly configured.');\n } else if (failCount === 0) {\n warning(`${warnCount} warning(s) found. Consider fixing them for optimal performance.`);\n } else {\n error(`${failCount} error(s) and ${warnCount} warning(s) found. Please fix the errors.`);\n }\n}\n\n/**\n * Doctor command - run diagnostics\n */\nexport async function doctor(options: DoctorOptions = {}): Promise<void> {\n header('OxLayer SDK Diagnostics');\n\n const results = await runDiagnostics(options);\n\n console.log();\n printDiagnostics(results);\n\n // Exit with error code if there are failures\n if (results.some(r => r.status === 'fail')) {\n process.exit(1);\n }\n}\n","/**\n * Diff Command\n *\n * Compare capabilities between SDK versions\n */\n\nimport type { CapabilityLimits } from '../types/index.js';\nimport { header, success, error, info, printList } from '../utils/cli.js';\n\nexport interface DiffOptions {\n verbose?: boolean;\n format?: 'text' | 'json';\n}\n\n/**\n * Capability change type\n */\ntype ChangeType = 'added' | 'removed' | 'modified' | 'unchanged';\n\n/**\n * Capability diff entry\n */\ninterface CapabilityDiff {\n name: string;\n change: ChangeType;\n before?: CapabilityLimits;\n after?: CapabilityLimits;\n changes?: string[];\n}\n\n/**\n * Format a limit value for display\n */\nfunction formatLimitValue(key: string, value: unknown): string {\n if (typeof value === 'boolean') {\n return value ? '✓ enabled' : '✗ disabled';\n }\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n if (typeof value === 'object' && value !== null) {\n return JSON.stringify(value);\n }\n return String(value);\n}\n\n/**\n * Get changed limits between two capability configs\n */\nfunction getCapabilityChanges(\n before: CapabilityLimits,\n after: CapabilityLimits\n): string[] {\n const changes: string[] = [];\n const allKeys = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const key of allKeys) {\n const beforeValue = before[key as keyof CapabilityLimits];\n const afterValue = after[key as keyof CapabilityLimits];\n\n if (JSON.stringify(beforeValue) !== JSON.stringify(afterValue)) {\n changes.push(\n ` ${key}: ${formatLimitValue(key, beforeValue)} → ${formatLimitValue(key, afterValue)}`\n );\n }\n }\n\n return changes;\n}\n\n/**\n * Diff capabilities between two versions\n */\nexport async function diff(\n fromVersion: string,\n toVersion: string,\n options: DiffOptions = {}\n): Promise<void> {\n header(`Capability Diff: ${fromVersion} → ${toVersion}`);\n\n const spinner = await import('../utils/cli.js').then(m => m.createSpinner('Fetching manifests...'));\n spinner.start();\n\n try {\n // In a real implementation, we would fetch manifests from the API\n // For now, we'll simulate this with mock data\n spinner.succeed('Manifests fetched');\n\n // Mock data for demonstration\n const beforeCapabilities: Record<string, CapabilityLimits> = {\n auth: { maxRealms: 1, sso: false, rbac: true },\n storage: { encryption: false, maxStorageGb: 100 },\n vector: { maxVectorCollections: 10, maxVectorDimensions: 1536 },\n };\n\n const afterCapabilities: Record<string, CapabilityLimits> = {\n auth: { maxRealms: 5, sso: true, rbac: true },\n storage: { encryption: true, maxStorageGb: 1000 },\n search: { maxResults: 10000 },\n vector: { maxVectorCollections: 50, hybridSearch: true },\n };\n\n const diffs: CapabilityDiff[] = [];\n\n // Find added capabilities\n for (const [name, limits] of Object.entries(afterCapabilities)) {\n if (!(name in beforeCapabilities)) {\n diffs.push({\n name,\n change: 'added',\n after: limits,\n });\n }\n }\n\n // Find removed capabilities\n for (const [name, limits] of Object.entries(beforeCapabilities)) {\n if (!(name in afterCapabilities)) {\n diffs.push({\n name,\n change: 'removed',\n before: limits,\n });\n }\n }\n\n // Find modified capabilities\n for (const name of Object.keys(beforeCapabilities)) {\n if (name in afterCapabilities) {\n const before = beforeCapabilities[name]!;\n const after = afterCapabilities[name]!;\n const changes = getCapabilityChanges(before, after);\n\n if (changes.length > 0) {\n diffs.push({\n name,\n change: 'modified',\n before,\n after,\n changes,\n });\n }\n }\n }\n\n console.log();\n\n // Print summary\n const addedCount = diffs.filter(d => d.change === 'added').length;\n const removedCount = diffs.filter(d => d.change === 'removed').length;\n const modifiedCount = diffs.filter(d => d.change === 'modified').length;\n\n if (addedCount > 0) {\n success(`${addedCount} capability(ies) added`);\n }\n if (modifiedCount > 0) {\n info(`${modifiedCount} capability(ies) modified`);\n }\n if (removedCount > 0) {\n error(`${removedCount} capability(ies) removed`);\n }\n\n console.log();\n\n // Print detailed diffs\n if (options.verbose || diffs.length > 0) {\n header('Detailed Changes');\n\n for (const diff of diffs) {\n switch (diff.change) {\n case 'added':\n success(`+ ${diff.name} (new)`);\n if (options.verbose && diff.after) {\n const limits = Object.entries(diff.after)\n .map(([k, v]) => ` ${k}: ${formatLimitValue(k, v)}`)\n .join('\\n');\n console.log(limits);\n }\n break;\n case 'removed':\n error(`- ${diff.name} (removed)`);\n if (options.verbose && diff.before) {\n const limits = Object.entries(diff.before)\n .map(([k, v]) => ` ${k}: ${formatLimitValue(k, v)}`)\n .join('\\n');\n console.log(limits);\n }\n break;\n case 'modified':\n info(`~ ${diff.name} (modified)`);\n if (diff.changes && diff.changes.length > 0) {\n console.log(diff.changes.join('\\n'));\n }\n break;\n }\n console.log();\n }\n }\n\n // Print upgrade recommendations\n header('Upgrade Recommendations');\n\n if (modifiedCount > 0) {\n const modifiedDiffs = diffs.filter(d => d.change === 'modified');\n\n for (const diff of modifiedDiffs) {\n const breakingChanges = diff.changes?.filter(c =>\n c.includes('→') && !c.includes('0 →')\n );\n\n if (breakingChanges && breakingChanges.length > 0) {\n warning(`${diff.name}: Review breaking changes`);\n printList(breakingChanges);\n }\n }\n }\n\n if (removedCount > 0) {\n warning('Some capabilities were removed. Check your code for usage.');\n const removed = diffs.filter(d => d.change === 'removed').map(d => d.name);\n printList(removed);\n }\n\n } catch (err) {\n spinner.fail('Failed to compare versions');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n}\n\n/**\n * Show latest version and current installed version\n */\nexport async function showLatest(): Promise<void> {\n const spinner = await import('../utils/cli.js').then(m => m.createSpinner('Checking for updates...'));\n spinner.start();\n\n try {\n const { getInstalledVersion } = await import('../services/package.service.js');\n const { getLatestVersion } = await import('../services/api.service.js');\n\n const installed = await getInstalledVersion();\n const latest = await getLatestVersion();\n\n spinner.succeed('Version check complete');\n\n header('Version Information');\n info(`Installed: ${installed || 'None'}`);\n info(`Latest: ${latest}`);\n\n if (installed !== latest) {\n console.log();\n success('New version available!');\n info(`Run: oxlayer install ${latest}`);\n } else if (installed) {\n console.log();\n success('You\\'re up to date!');\n }\n\n } catch (err) {\n spinner.fail('Failed to check version');\n error(err instanceof Error ? err.message : 'Unknown error');\n }\n}\n","/**\n * Telemetry Commands\n *\n * Manage anonymous usage tracking and telemetry\n */\n\nimport { success, info, warning } from '../utils/cli.js';\n\n/**\n * Enable telemetry\n */\nexport async function telemetryEnable(): Promise<void> {\n success('Telemetry enabled');\n info('Anonymous usage data will be collected to improve the SDK');\n}\n\n/**\n * Disable telemetry\n */\nexport async function telemetryDisable(): Promise<void> {\n warning('Telemetry disabled');\n info('No usage data will be collected');\n}\n\n/**\n * Show telemetry status\n */\nexport async function telemetryStatus(): Promise<void> {\n info('Checking telemetry status...');\n // TODO: Implement actual telemetry status check\n info('Telemetry status: unknown (not implemented yet)');\n}\n","/**\n * Update Commands\n *\n * Update SDK to the latest version\n */\n\nimport { success, info, warning } from '../utils/cli.js';\n\n/**\n * Update SDK to the latest version\n */\nexport async function update(options: { dryRun?: boolean } = {}): Promise<void> {\n if (options.dryRun) {\n info('Dry run mode: Would update SDK to latest version');\n return;\n }\n\n info('Checking for SDK updates...');\n // TODO: Implement actual update logic\n success('SDK is up to date');\n}\n\n/**\n * Quick check for SDK updates\n */\nexport async function check(): Promise<void> {\n info('Checking for SDK updates...');\n // TODO: Implement actual check logic\n success('No updates available');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAOA,SAAS,eAAe;;;ACPxB;AAYA;AAoBA,eAAsB,MAAM,UAAwB,CAAC,GAAkB;AACrE,SAAO,wBAAwB;AAE/B,QAAM,aAAa,MAAM,cAAc;AACvC,OAAK,WAAW,UAAU,EAAE;AAC5B,OAAK,gBAAgB,QAAQ,eAAe,aAAa,EAAE;AAC3D,OAAK,iBAAiB,QAAQ,eAAe,uBAAgC,EAAE;AAC/E,UAAQ,IAAI;AAGZ,QAAM,UAAU,cAAc,oCAAoC;AAClE,UAAQ,MAAM;AAEd,MAAI;AACJ,MAAI;AACF,UAAM,cAAc,QAAQ,eAAe;AAC3C,SAAK,iBAAiB,WAAW,EAAE;AACnC,yBAAqB,MAAM;AAAA,MACzB,QAAQ,eAAe;AAAA,MACvB;AAAA,IACF;AACA,YAAQ,QAAQ,gCAAgC;AAAA,EAClD,SAAS,KAAK;AACZ,YAAQ,KAAK,yCAAyC;AACtD,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,UAAQ,IAAI;AACZ,OAAK,iDAAiD;AACtD,UAAQ,IAAI;AAEZ,QAAM,kBAAkB,mBAAmB;AAC3C,QAAM,WAAW,mBAAmB;AAGpC,UAAQ,IAAI,sCAAsC;AAClD,UAAQ,IAAI,QAAQ,eAAe,EAAE;AACrC,UAAQ,IAAI;AAEZ,UAAQ,IAAI,qCAAqC;AACjD,UAAQ,IAAI,QAAQ,QAAQ,EAAE;AAC9B,UAAQ,IAAI;AAGZ,MAAI,CAAC,QAAQ,YAAY,GAAG;AAC1B,QAAI;AACF,YAAM,cAAc,IAAI,IAAI,eAAe;AAC3C,kBAAY,aAAa,IAAI,eAAe,mBAAmB,UAAU;AAEzE,YAAM,cAAc,cAAc,oBAAoB;AACtD,kBAAY,MAAM;AAClB,YAAM,YAAY,YAAY,SAAS,CAAC;AACxC,kBAAY,QAAQ,gBAAgB;AAAA,IACtC,SAAS,KAAK;AACZ,WAAK,sEAAsE;AAAA,IAC7E;AAAA,EACF,OAAO;AACL,SAAK,oDAAoD;AAAA,EAC3D;AAEA,UAAQ,IAAI;AACZ,OAAK,2CAA2C;AAGhD,QAAM,cAAc,cAAc,sBAAsB;AAExD,MAAI;AACF,gBAAY,MAAM;AAElB,UAAM,SAAS,MAAM;AAAA,MACnB,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB;AAAA,QACE,UAAU,QAAQ,eAAe,KAAK,mBAAmB;AAAA,QACzD,aAAa;AAAA;AAAA,QACb,YAAY,CAAC,SAAS,gBAAgB;AACpC,cAAI,UAAU,MAAM,GAAG;AAErB,wBAAY,OAAO,yBAAyB,KAAK,MAAO,UAAU,cAAe,GAAG,CAAC;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,gBAAY,QAAQ,2BAA2B;AAG/C,UAAM,cAAc,QAAQ,eAAe;AAC3C,UAAM,SAAoB;AAAA,MACxB,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,gBAAgB,OAAO;AAAA,MACvB,aAAa,QAAQ,eAAe;AAAA,MACpC,WAAW;AAAA,MACX;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAEA,UAAM,WAAW,MAAM;AAEvB,gBAAY,KAAK;AAEjB,YAAQ,IAAI;AACZ,YAAQ,wBAAwB;AAChC,SAAK,iBAAiB,OAAO,cAAc,EAAE;AAC7C,SAAK,cAAc,OAAO,UAAW,QAAQ,EAAE;AAC/C,SAAK,WAAW,OAAO,UAAW,OAAO,KAAK,IAAI,CAAC,EAAE;AACrD,SAAK,YAAY,IAAI,KAAK,OAAO,UAAW,SAAS,EAAE,eAAe,CAAC,EAAE;AAGzE,YAAQ,KAAK,CAAC;AAAA,EAChB,SAAS,KAAK;AACZ,gBAAY,KAAK,uBAAuB;AACxC,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;ACtJA;AAMA;;;ACNA;AAMA,SAAS,YAAY,oBAAoB;AACzC,SAAS,YAAY;AA2Bd,SAAS,qBAAqB,MAAc,QAAQ,IAAI,GAAmB;AAChF,MAAI,WAAW,KAAK,KAAK,gBAAgB,CAAC,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,MAAI,WAAW,KAAK,KAAK,WAAW,CAAC,GAAG;AACtC,WAAO;AAAA,EACT;AACA,MAAI,WAAW,KAAK,KAAK,WAAW,CAAC,GAAG;AACtC,WAAO;AAAA,EACT;AACA,MAAI,WAAW,KAAK,KAAK,mBAAmB,CAAC,GAAG;AAC9C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQO,SAAS,gBAAgB,WAAmB,QAAQ,IAAI,GAAW;AACxE,MAAI,aAAa;AAEjB,SAAO,eAAe,OAAO,eAAe,KAAK;AAE/C,QAAI,WAAW,KAAK,YAAY,cAAc,CAAC,GAAG;AAEhD,UAAI,WAAW,KAAK,YAAY,qBAAqB,CAAC,KAClD,WAAW,KAAK,YAAY,YAAY,CAAC,KACzC,WAAW,KAAK,YAAY,YAAY,CAAC,KACzC,WAAW,KAAK,YAAY,SAAS,CAAC,GAAG;AAC3C,eAAO;AAAA,MACT;AAGA,UAAI;AACF,cAAM,UAAU,KAAK,YAAY,cAAc;AAC/C,cAAM,aAAa,aAAa,SAAS,OAAO;AAChD,cAAM,MAAM,KAAK,MAAM,UAAU;AACjC,YAAI,IAAI,YAAY;AAClB,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AAAA,MAER;AAGA,UAAI,eAAe,UAAU;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,YAAY,IAAI;AACvC,QAAI,cAAc,YAAY;AAE5B;AAAA,IACF;AACA,iBAAa;AAAA,EACf;AAGA,SAAO;AACT;AAKA,eAAsB,kBAAkB,MAAc,QAAQ,IAAI,GAA2B;AAC3F,QAAM,UAAU,gBAAgB,GAAG;AACnC,QAAMA,kBAAiB,WAAW,KAAK,SAAS,cAAc,CAAC;AAC/D,QAAM,cAAc,WAAW,KAAK,SAAS,eAAe,CAAC,KAAK,WAAW,KAAK,SAAS,eAAe,CAAC;AAC3G,QAAM,iBAAiB,qBAAqB,OAAO;AAEnD,MAAI,OAAoB;AAExB,MAAIA,iBAAgB;AAClB,QAAI;AACF,YAAM,MAAM,MAAM,gBAAgB,OAAO;AACzC,YAAM,OAAO,EAAE,GAAG,IAAI,cAAc,GAAG,IAAI,gBAAgB;AAG3D,YAAM,WAAW,WAAW,QAAQ,eAAe,QAAQ,kBAAkB,QAAQ,UAAU;AAC/F,YAAM,UAAU,UAAU,QAAQ,gBAAgB;AAElD,YAAM,aAAa;AACnB,YAAM,YAAY;AAElB,UAAI,cAAc,WAAW;AAC3B,eAAO;AAAA,MACT,WAAW,YAAY;AACrB,eAAO;AAAA,MACT,WAAW,WAAW;AACpB,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,gBAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,kBAAkB,gBAAwC;AACxE,UAAQ,gBAAgB;AAAA,IACtB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,uBAAuB,aAAoC;AACzE,UAAQ,aAAa;AAAA,IACnB,KAAK;AACH,aAAO,CAAC,aAAa;AAAA,IACvB,KAAK;AACH,aAAO,CAAC,cAAc;AAAA,IACxB;AACE,aAAO,CAAC,eAAe,gBAAgB,WAAW;AAAA,EACtD;AACF;;;ADhKA,eAAsB,OAAO,UAAyB,CAAC,GAAkB;AACvE,SAAO,oBAAoB;AAG3B,QAAM,WAAW,MAAM,YAAY;AACnC,MAAI,SAAS,eAAe;AAC1B,YAAQ,eAAe;AACvB,SAAK,iBAAiB,SAAS,kBAAkB,SAAS,EAAE;AAC5D,SAAK,WAAW,SAAS,YAAY,SAAS,EAAE;AAEhD,QAAI,QAAQ,WAAW,SAAS,QAAQ;AACtC,WAAK,WAAW,SAAS,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,IAC9C;AACA,QAAI,QAAQ,WAAW,SAAS,WAAW;AACzC,YAAM,UAAU,IAAI,KAAK,SAAS,SAAS;AAC3C,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,kBAAkB,KAAK,MAAM,QAAQ,QAAQ,IAAI,IAAI,QAAQ,MAAM,MAAO,KAAK,KAAK,GAAG;AAC7F,WAAK,YAAY,QAAQ,eAAe,CAAC,KAAK,kBAAkB,IAAI,MAAM,eAAe,UAAU,SAAS,GAAG;AAAA,IACjH;AAAA,EACF,OAAO;AACL,UAAM,mBAAmB;AACzB,SAAK,qCAAqC;AAAA,EAC5C;AAEA,UAAQ,IAAI;AAGZ,MAAI,SAAS,eAAe;AAC1B,WAAO,cAAc;AAErB,UAAM,WAAW,MAAM,YAAY;AACnC,QAAI,UAAU;AACZ,cAAQ,4BAA4B;AACpC,WAAK,mBAAmB,SAAS,aAAa,EAAE;AAChD,WAAK,YAAY,SAAS,SAAS,EAAE;AACrC,WAAK,gBAAgB,SAAS,WAAW,EAAE;AAE3C,UAAI,SAAS,cAAc;AACzB,cAAM,kBAAkB,OAAO,KAAK,SAAS,YAAY,EAAE;AAC3D,aAAK,2BAA2B,eAAe,EAAE;AAEjD,YAAI,QAAQ,SAAS;AACnB,gBAAM,kBAAkB,OAAO,KAAK,SAAS,YAAY;AACzD,cAAI,gBAAgB,SAAS,GAAG;AAC9B,iBAAK,eAAe;AACpB,sBAAU,eAAe;AAAA,UAC3B;AAGA,gBAAM,kBAAkB,IAAI,KAAK,SAAS,SAAS;AACnD,gBAAM,MAAM,oBAAI,KAAK;AACrB,gBAAM,kBAAkB,KAAK,MAAM,gBAAgB,QAAQ,IAAI,IAAI,QAAQ,MAAM,MAAO,KAAK,KAAK,GAAG;AACrG,eAAK,qBAAqB,gBAAgB,eAAe,CAAC,KAAK,kBAAkB,IAAI,MAAM,eAAe,UAAU,SAAS,GAAG;AAAA,QAClI;AAAA,MACF,OAAO;AACL,aAAK,uCAAuC;AAAA,MAC9C;AAAA,IACF,OAAO;AACL,WAAK,kCAAkC;AACvC,WAAK,wDAAwD;AAAA,IAC/D;AAEA,YAAQ,IAAI;AAAA,EACd;AAGA,SAAO,SAAS;AAEhB,QAAM,gBAAgB,MAAM,kBAAkB;AAC9C,QAAM,sBAAsB,uBAAuB,cAAc,IAAI;AAErE,MAAI,cAAc,gBAAgB;AAChC,YAAQ,oBAAoB;AAC5B,SAAK,iBAAiB,cAAc,IAAI,EAAE;AAC1C,SAAK,oBAAoB,cAAc,cAAc,EAAE;AACvD,SAAK,eAAe,cAAc,cAAc,QAAQ,IAAI,EAAE;AAAA,EAChE,OAAO;AACL,UAAM,4CAA4C;AAAA,EACpD;AAEA,UAAQ,IAAI;AAGZ,SAAO,cAAc;AAErB,QAAM,mBAAmB,MAAM,oBAAoB;AACnD,MAAI,kBAAkB;AACpB,YAAQ,eAAe,gBAAgB,YAAY;AACnD,SAAK,kCAAkC,gBAAgB,GAAG;AAE1D,QAAI,QAAQ,SAAS;AAEnB,YAAM,EAAE,YAAAC,YAAW,IAAI,MAAM,OAAO,IAAI;AACxC,YAAM,EAAE,MAAAC,MAAK,IAAI,MAAM,OAAO,MAAM;AAEpC,YAAM,YAAYA,MAAK,QAAQ,IAAI,GAAG,wBAAwB,gBAAgB;AAE9E,UAAID,YAAW,SAAS,GAAG;AACzB,cAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,aAAa;AAC9C,cAAM,WAAW,MAAM,QAAQ,WAAW,EAAE,eAAe,KAAK,CAAC;AACjE,cAAM,eAAe,SAClB,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7B,IAAI,CAAC,MAAM,EAAE,IAAI;AAEpB,YAAI,aAAa,SAAS,GAAG;AAC3B,eAAK,qBAAqB;AAC1B,oBAAU,YAAY;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,SAAK,kBAAkB;AACvB,SAAK,0CAA0C;AAAA,EACjD;AAEA,UAAQ,IAAI;AAGZ,MAAI,oBAAoB,SAAS,KAAK,CAAC,kBAAkB;AACvD,WAAO,aAAa;AACpB,SAAK,kDAAkD;AACvD,cAAU,mBAAmB;AAAA,EAC/B;AACF;;;AE1IA;AAMA,SAAS,YAAYE,WAAU;AAC/B,SAAS,QAAAC,aAAY;AACrB,SAAS,gBAAgB;;;ACRzB;;;ACAA;AAYA;AAUA,eAAsBC,cAA8C;AAClE,QAAM,EAAE,YAAY,cAAc,IAAI,MAAM,OAAO,mCAA0B;AAC7E,QAAM,SAAS,MAAM,cAAc;AAEnC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAGA,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,WAAW,OAAO;AAAA,IAClB,aAAa,OAAO;AAAA,EACtB;AACF;AAgDA,eAAsB,eAA8B;AAClD,QAAM,EAAE,cAAc,gBAAgB,IAAI,MAAM,OAAO,mCAA0B;AACjF,QAAM,gBAAgB;AACxB;AAqBO,SAAS,eAAuB;AACrC,QAAM,EAAE,MAAAC,MAAK,IAAI,UAAQ,MAAM;AAC/B,QAAM,EAAE,QAAQ,IAAI,UAAQ,IAAI;AAChC,SAAOA,MAAK,QAAQ,GAAG,UAAU;AACnC;AAKO,SAAS,gBAAwB;AACtC,SAAO,UAAQ,MAAM,EAAE,KAAK,aAAa,GAAG,aAAa;AAC3D;;;ADnHA;;;AELA;AAOA,SAAS,YAAY,UAAU;AAC/B,SAAS,QAAAC,aAAY;AA0CrB,eAAsB,aACpB,KACA,aACA,YACe;AACf,QAAM,WAAW,MAAM,MAAM,GAAG;AAEhC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,uBAAuB,SAAS,UAAU,EAAE;AAAA,EAC9D;AAEA,QAAM,QAAQ,SAAS,SAAS,QAAQ,IAAI,gBAAgB,KAAK,KAAK,EAAE;AACxE,MAAI,aAAa;AAGjB,QAAM,GAAG,MAAMC,MAAK,aAAa,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAE3D,QAAM,SAAS,MAAM,GAAG,KAAK,aAAa,GAAG;AAE7C,MAAI;AACF,UAAM,SAAS,SAAS,MAAM,UAAU;AACxC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AAEA,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,UAAI,KAAM;AAEV,YAAM,OAAO,MAAM,KAAK;AACxB,oBAAc,MAAM;AAEpB,UAAI,cAAc,QAAQ,GAAG;AAC3B,mBAAW,YAAY,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AACF;AAKA,eAAsB,eACpB,cACA,cAC0B;AAC1B,QAAM,UAAU,MAAM,GAAG,SAAS,cAAc,OAAO;AACvD,QAAM,WAAW,KAAK,MAAM,OAAO;AAEnC,MAAI,gBAAgB,SAAS,WAAW,cAAc;AACpD,UAAM,IAAI;AAAA,MACR,sCAAsC,YAAY,SAAS,SAAS,MAAM;AAAA,IAC5E;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAsB,WAAW,SAAiB,aAAoC;AACpF,QAAM,UAAU,MAAM,OAAO,SAAS,GAAG;AACzC,QAAM,MAAM,IAAI,OAAO,OAAO;AAE9B,QAAM,GAAG,MAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAC/C,MAAI,aAAa,aAAa,IAAI;AACpC;;;ACxHA;;;ACAA;AAMA,SAAS,YAAYC,WAAU;AAC/B,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAAC,mBAAkB;AAqC3B,IAAM,iBAAiBD,MAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,IAAI,YAAY,gBAAgB;AAC3G,IAAM,oBAAoB,QAAQ,IAAI,sBAAsB;AAK5D,eAAe,qBAA+C;AAC5D,MAAI;AACF,QAAIC,YAAW,cAAc,GAAG;AAC9B,YAAM,UAAU,MAAMF,IAAG,SAAS,gBAAgB,OAAO;AACzD,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,QAAM,SAA0B;AAAA,IAC9B,SAAS;AAAA,IACT,QAAQ,oBAAoB;AAAA,EAC9B;AAEA,QAAM,oBAAoB,MAAM;AAChC,SAAO;AACT;AAKA,eAAe,oBAAoB,QAAwC;AACzE,QAAM,MAAMC,MAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,IAAI,UAAU;AAC9E,QAAMD,IAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACvC,QAAMA,IAAG,UAAU,gBAAgB,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AACpE;AAKA,SAAS,sBAA8B;AAGrC,QAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,SAAO,gBAAgB,KAAK;AAC5B,SAAO,MAAM,KAAK,OAAO,OAAK,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACxE;AAKA,eAAsB,WAAW,MAAoC;AACnE,QAAM,SAAS,MAAM,mBAAmB;AAExC,MAAI,CAAC,OAAO,SAAS;AACnB;AAAA,EACF;AAGA,QAAM,eAA8B;AAAA,IAClC,GAAG;AAAA,IACH,QAAQ,OAAO;AAAA,IACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAGA,gBAAc,YAAY,EAAE,MAAM,MAAM;AAAA,EAExC,CAAC;AACH;AAKA,eAAe,cAAc,MAA8C;AACzE,QAAM,WAAW,QAAQ,IAAI,8BAA8B;AAE3D,MAAI;AACF,UAAM,MAAM,UAAU;AAAA,MACpB,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA;AAAA,MAEzB,WAAW;AAAA,IACb,CAAC,EAAE,MAAM,MAAM;AAAA,IAEf,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;AAKO,SAAS,aACd,SACA,UAII,CAAC,GACC;AACN,aAAW;AAAA,IACT,OAAO;AAAA,IACP;AAAA,IACA,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,aAAa,QAAQ;AAAA,IACrB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACH;AAKO,SAAS,WACd,SACA,WACA,UAGI,CAAC,GACC;AACN,aAAW;AAAA,IACT,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,aAAa,QAAQ;AAAA,IACrB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACH;;;ALnKA;AAEA,IAAM,aAAa;AACnB,IAAM,mBAAmB;AAKzB,SAAS,yBACP,aACA,SACkB;AAClB,MAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,GAAG;AACnD,WAAO,QAAQ;AAAA,EACjB;AAGA,UAAQ,aAAa;AAAA,IACnB,KAAK;AACH,aAAO,CAAC,aAAa;AAAA,IACvB,KAAK;AACH,aAAO,CAAC,cAAc;AAAA,IACxB;AACE,aAAO,CAAC,eAAe,gBAAgB,WAAW;AAAA,EACtD;AACF;AAKA,SAAS,oBAAoB,SAAiB,UAAuB;AAEnE,QAAM,UAAkC,CAAC;AACzC,QAAM,eAAuC,CAAC;AAE9C,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,QAAQ,GAAsB;AAC9E,UAAM,eAAe,IAAI;AACzB,YAAQ,IAAI,IAAI,KAAK,YAAY;AACjC,iBAAa,IAAI,IAAI;AAGrB,UAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,MAAM,CAAC;AACrC,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,UAAU,MAAM,KAAK,GAAG;AAC9B,cAAQ,YAAY,OAAO,EAAE,IAAI,KAAK,YAAY;AAAA,IACpD;AAAA,EACF;AAEA,SAAO,KAAK,UAAU;AAAA,IACpB,MAAM;AAAA,IACN;AAAA,IACA,SAAS;AAAA,IACT,aAAa,gBAAgB,OAAO;AAAA,IACpC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,GAAG,MAAM,CAAC;AACZ;AAKA,eAAe,sBAAsB,SAAiB,kBAAyC;AAC7F,QAAM,gBAAgBG,MAAK,SAAS,qBAAqB;AACzD,QAAM,qBAAqB,iBAAiB,QAAQ,UAAU,KAAK,EAAE,EAAE,QAAQ,OAAO,EAAE;AAExF,MAAI;AAEJ,MAAI;AACF,UAAM,UAAU,MAAMC,IAAG,SAAS,eAAe,OAAO;AAExD,UAAM,QAAQ,QAAQ,MAAM,uCAAuC;AACnE,QAAI,OAAO;AACT,YAAM,WAAW,MAAM,CAAC,EAAE,MAAM,IAAI,EACjC,IAAI,UAAQ,KAAK,QAAQ,YAAY,EAAE,EAAE,KAAK,CAAC,EAC/C,OAAO,UAAQ,KAAK,SAAS,CAAC;AACjC,wBAAkB,EAAE,SAAS;AAAA,IAC/B,OAAO;AACL,wBAAkB,EAAE,UAAU,CAAC,EAAE;AAAA,IACnC;AAAA,EACF,QAAQ;AAEN,sBAAkB,EAAE,UAAU,CAAC,EAAE;AAAA,EACnC;AAGA,MAAI,CAAC,gBAAgB,UAAU,SAAS,kBAAkB,GAAG;AAC3D,oBAAgB,WAAW,CAAC,GAAI,gBAAgB,YAAY,CAAC,GAAI,kBAAkB;AAEnF,UAAM,cAAc;AAAA,EAAc,gBAAgB,SAAS,IAAI,OAAK,QAAQ,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA;AAC5F,UAAMA,IAAG,UAAU,eAAe,aAAa,OAAO;AAAA,EACxD;AACF;AAKA,eAAe,qBAAqB,SAAiB,SAAgC;AACnF,QAAM,cAAcD,MAAK,SAAS,SAAS;AAC3C,QAAM,cAAcA,MAAK,SAAS,OAAO;AAEzC,MAAI;AAEF,UAAMC,IAAG,OAAO,WAAW;AAAA,EAC7B,QAAQ;AAAA,EAER;AAGA,QAAMA,IAAG,QAAQ,aAAa,aAAa,KAAK;AAClD;AAKA,eAAe,uBAAuB,SAAiB,mBAA0C;AAC/F,QAAM,kBAAkBD,MAAK,SAAS,cAAc;AAEpD,MAAI;AACF,UAAM,UAAU,MAAMC,IAAG,SAAS,iBAAiB,OAAO;AAC1D,UAAM,MAAM,KAAK,MAAM,OAAO;AAG9B,QAAI,CAAC,IAAI,cAAc;AACrB,UAAI,eAAe,CAAC;AAAA,IACtB;AAGA,QAAI,CAAC,IAAI,aAAa,wBAAwB,GAAG;AAC/C,UAAI,aAAa,wBAAwB,IAAI;AAAA,IAC/C;AAGA,UAAMA,IAAG,UAAU,iBAAiB,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI,MAAM,OAAO;AAAA,EAClF,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,kCAAkC,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAAA,EAC1G;AACF;AAKA,eAAsB,QAAQ,SAAiB,UAA0B,CAAC,GAAkB;AAC1F,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,WAAW,QAAQ,IAAI;AAE7B,SAAO,uBAAuB;AAG9B,QAAM,UAAU,gBAAgB,QAAQ;AAGxC,MAAI,CAAC,MAAM,eAAe,GAAG;AAC3B,UAAM,4CAA4C;AAClD,SAAK,uDAAuD;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,gBAAgB,MAAM,kBAAkB,QAAQ;AACtD,OAAK,iBAAiB,YAAY,WAAW,MAAM,OAAO,EAAE;AAC5D,OAAK,oBAAoB,cAAc,cAAc,EAAE;AACvD,OAAK,iBAAiB,cAAc,IAAI,EAAE;AAG1C,QAAM,oBAAoB,yBAAyB,cAAc,MAAM,OAAO;AAC9E,OAAK,aAAa,kBAAkB,KAAK,IAAI,CAAC,EAAE;AAGhD,QAAM,cAAc,cAAc,8BAA8B;AAChE,cAAY,MAAM;AAElB,MAAI;AACF,UAAM,SAAS,MAAM,WAAW;AAEhC,QAAI,CAAC,UAAU,CAAC,OAAO,OAAO;AAC5B,kBAAY,KAAK,yBAAyB;AAC1C,YAAM,2BAA2B;AACjC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,QAAI,eAAe,MAAM,GAAG;AAC1B,kBAAY,KAAK,eAAe;AAChC,YAAM,kEAAkE;AACxE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,gBAAY,QAAQ,eAAe;AAGnC,SAAK,iBAAiB,OAAO,cAAc,EAAE;AAC7C,SAAK,WAAW,OAAO,WAAW,YAAY,SAAS,EAAE;AAEzD,UAAM,YAAY,IAAI,KAAK,OAAO,UAAU,SAAS;AACrD,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,kBAAkB,KAAK,MAAM,UAAU,QAAQ,IAAI,IAAI,QAAQ,MAAM,MAAO,KAAK,KAAK,GAAG;AAC/F,SAAK,kBAAkB,UAAU,eAAe,CAAC,KAAK,kBAAkB,IAAI,MAAM,eAAe,UAAU,SAAS,GAAG;AAAA,EACzH,SAAS,KAAK;AACZ,gBAAY,KAAK,uBAAuB;AACxC,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI;AAGZ,QAAM,kBAAkB,cAAc,oBAAoB;AAC1D,kBAAgB,MAAM;AAEtB,MAAI,kBAAkB;AACtB,MAAI;AAEJ,MAAI;AAEF,UAAM,EAAE,aAAa,SAAS,YAAY,IAAI,MAAM;AAAA,MAClD,kBAAkB,CAAC;AAAA,MACnB;AAAA,IACF;AACA,sBAAkB;AAGlB,UAAM,UAAUD,MAAK,SAAS,eAAe;AAC7C,UAAMC,IAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAE3C,UAAM,UAAUD,MAAK,SAAS,eAAe,eAAe,MAAM;AAGlE,QAAI,eAAe;AACnB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,CAAC,UAAU,UAAU;AACnB,cAAM,UAAU,KAAK,MAAO,WAAW,QAAS,GAAG;AACnD,YAAI,UAAU,gBAAgB,IAAI;AAChC,0BAAgB,OAAO,sBAAsB,OAAO;AACpD,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAEA,oBAAgB,QAAQ,mBAAmB,eAAe,GAAG;AAG7D,UAAM,iBAAiB,cAAc,mBAAmB;AACxD,mBAAe,MAAM;AAGrB,UAAM,gBAAgBA,MAAK,SAAS,UAAU;AAC9C,UAAM,mBAAmBA,MAAK,eAAe,eAAe;AAC5D,UAAMC,IAAG,MAAM,kBAAkB,EAAE,WAAW,KAAK,CAAC;AAGpD,UAAM,WAAW,SAASD,MAAK,SAAS,WAAW,CAAC;AAGpD,UAAM,gBAAgBA,MAAK,SAAS,aAAa,eAAe;AAGhE,UAAM,eAAeA,MAAK,eAAe,eAAe;AACxD,eAAW,MAAM,eAAe,YAAY;AAG5C,UAAM,cAAc,eAAe,gBAAgB;AAGnD,UAAM,kBAAkBA,MAAK,kBAAkB,cAAc;AAC7D,UAAM,qBAAqB,oBAAoB,iBAAiB,QAAQ;AACxE,UAAMC,IAAG,UAAU,iBAAiB,oBAAoB,OAAO;AAE/D,mBAAe,QAAQ,eAAe;AAGtC,UAAM,mBAAmB,cAAc,0BAA0B;AACjE,qBAAiB,MAAM;AAEvB,UAAM,sBAAsB,SAAS,gBAAgB;AAGrD,UAAM,qBAAqB,eAAe,eAAe;AAGzD,UAAM,uBAAuB,SAAS,gBAAgB;AAEtD,qBAAiB,QAAQ,sBAAsB;AAG/C,UAAMA,IAAG,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACvD,SAAS,KAAK;AACZ,oBAAgB,KAAK,uBAAuB;AAC5C,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI;AAEZ,QAAM,WAAW,KAAK,IAAI,IAAI;AAG9B,SAAO,uBAAuB;AAC9B,UAAQ,eAAe,eAAe,yBAAyB;AAC/D,OAAK,aAAa,eAAe,QAAQ,CAAC,EAAE;AAC5C,OAAK,cAAc,UAAU,IAAI,eAAe,GAAG;AACnD,OAAK,iBAAiB,gBAAgB,eAAe,eAAe,EAAE;AAGtE,QAAM,iBAAiB,cAAc,oCAAoC;AACzE,iBAAe,MAAM;AAErB,MAAI;AACF,UAAM,iBAAiB,kBAAkB,cAAc,cAAc;AACrE,aAAS,gBAAgB,EAAE,KAAK,SAAS,OAAO,OAAO,CAAC;AACxD,mBAAe,QAAQ,8BAA8B,cAAc,cAAc,EAAE;AAAA,EACrF,SAAS,KAAK;AACZ,mBAAe,KAAK,+CAA+C,kBAAkB,cAAc,cAAc,CAAC,aAAa;AAAA,EACjI;AAGA,UAAQ,IAAI;AACZ,OAAK,aAAa;AAClB,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,iEAAmE;AAC/E,UAAQ,IAAI;AACZ,UAAQ,IAAI,wCAAwC,gBAAgB,mBAAmB;AACzF;AAKA,eAAe,cAAc,KAAa,MAA6B;AACrE,QAAMA,IAAG,MAAM,MAAM,EAAE,WAAW,KAAK,CAAC;AACxC,QAAM,UAAU,MAAMA,IAAG,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAE7D,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAUD,MAAK,KAAK,MAAM,IAAI;AACpC,UAAM,WAAWA,MAAK,MAAM,MAAM,IAAI;AAEtC,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,cAAc,SAAS,QAAQ;AAAA,IACvC,OAAO;AACL,YAAMC,IAAG,SAAS,SAAS,QAAQ;AAAA,IACrC;AAAA,EACF;AACF;;;AMtWA;AAmBA,eAAsB,QAAQ,UAA0B,CAAC,GAAkB;AACzE,SAAO,+BAA+B;AAGtC,QAAM,gBAAgB,MAAM,kBAAkB;AAC9C,QAAM,cAAc,QAAQ,eAAe;AAE3C,OAAK,iBAAiB,cAAc,IAAI,EAAE;AAC1C,OAAK,gBAAgB,WAAW,EAAE;AAGlC,QAAM,wBAA0C,CAAC;AAEjD,UAAQ,cAAc,MAAM;AAAA,IAC1B,KAAK;AACH,4BAAsB;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF,KAAK;AACH,4BAAsB,KAAK,QAAQ,SAAS;AAC5C;AAAA,IACF;AAEE,4BAAsB;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,EACJ;AAEA,QAAM,UAAU,MAAM,OAAO,mBAAiB,EAAE,KAAK,OAAK,EAAE,cAAc,2BAA2B,CAAC;AACtG,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,SAAS,MAAM,oBAAoB,uBAAuB,WAAW;AAE3E,YAAQ,QAAQ,uBAAuB;AAEvC,YAAQ,IAAI;AAGZ,SAAK,iBAAiB,OAAO,cAAc,EAAE;AAC7C,SAAK,YAAY,OAAO,SAAS,EAAE;AACnC,SAAK,gBAAgB,IAAI,KAAK,OAAO,UAAU,EAAE,eAAe,CAAC,EAAE;AAEnE,YAAQ,IAAI;AAGZ,WAAO,wBAAwB;AAC/B,sBAAkB,OAAO,YAAY;AAGrC,QAAI,QAAQ,SAAS;AACnB,cAAQ,IAAI;AACZ,aAAO,eAAe;AACtB,cAAQ,IAAI;AACZ,cAAQ,IAAI,2CAA2C;AACvD,cAAQ,IAAI;AACZ,cAAQ,IAAI,MAAM,KAAK,eAAe,CAAC;AACvC,cAAQ,IAAI,MAAM,KAAK,uEAAyE,CAAC;AACjG,cAAQ,IAAI;AACZ,cAAQ,IAAI,MAAM,KAAK,kDAAkD,CAAC;AAC1E,cAAQ,IAAI,MAAM,KAAK,iCAAiC,CAAC;AACzD,cAAQ,IAAI,MAAM,KAAK,mBAAmB,WAAW,IAAI,CAAC;AAC1D,cAAQ,IAAI,MAAM,KAAK,kBAAkB,sBAAsB,KAAK,MAAM,CAAC,IAAI,CAAC;AAChF,cAAQ,IAAI,MAAM,KAAK,KAAK,CAAC;AAC7B,cAAQ,IAAI,MAAM,KAAK,KAAK,CAAC;AAC7B,cAAQ,IAAI;AAAA,IACd;AAEA,YAAQ,8BAA8B,OAAO,KAAK,OAAO,YAAY,EAAE,MAAM,eAAe;AAAA,EAC9F,SAAS,KAAK;AACZ,YAAQ,KAAK,gCAAgC;AAC7C,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAE1D,QAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,SAAS,GAAG;AAC3D,cAAQ,IAAI;AACZ,WAAK,iCAAkC;AACvC,cAAQ,IAAI,iBAAiB;AAAA,IAC/B;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,IAAM,SAAS,MAAM,OAAO,OAAO,GAAG;;;ACrHtC;AAYA,eAAsB,SAAwB;AAC5C,MAAI;AACF,UAAM,aAAa;AACnB,YAAQ,yBAAyB;AACjC,SAAK,8BAA8B,cAAc,CAAC,EAAE;AACpD,SAAK,2CAA2C;AAAA,EAClD,SAAS,KAAK;AACZ,IAAAC,SAAQ,gCAAgC;AACxC,SAAK,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,EAC3D;AACF;;;ACtBA;AAWA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AAiBrB,eAAe,eAAe,SAAqD;AACjF,QAAM,UAA8B,CAAC;AAGrC,QAAM,SAAS,MAAMC,YAAW;AAChC,MAAI,QAAQ;AACV,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,MAAI;AACF,UAAM,YAAY,MAAM,YAAY;AACpC,QAAI,WAAW;AACb,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,QAAQ;AACN,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,QAAM,gBAAgB,MAAM,kBAAkB;AAC9C,MAAI,cAAc,gBAAgB;AAChC,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,SAAS,cAAc,IAAI,iBAAiB,cAAc,cAAc;AAAA,IACnF,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,MAAI,cAAc,aAAa;AAC7B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,QAAM,mBAAmB,MAAM,oBAAoB;AACnD,MAAI,kBAAkB;AACpB,UAAM,YAAY,aAAa,gBAAgB;AAC/C,UAAM,eAAeD,MAAK,WAAW,eAAe;AAEpD,QAAID,YAAW,YAAY,GAAG;AAC5B,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS,eAAe,gBAAgB;AAAA,MAC1C,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS,eAAe,gBAAgB;AAAA,QACxC,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,QAAM,gBAAgBC,MAAK,QAAQ,IAAI,GAAG,YAAY;AACtD,MAAID,YAAW,aAAa,GAAG;AAC7B,UAAM,mBAAmB,MAAM,OAAO,aAAa,EAAE,KAAK,CAAAG,QAAMA,IAAG,SAAS,eAAe,OAAO,CAAC;AACnG,UAAM,kBAAkB,iBAAiB,SAAS,sBAAsB;AAExE,QAAI,iBAAiB;AACnB,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,IAAI,iBAAiB;AAC/B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,WAAW,CAAC,QAAQ;AAClB,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,QAAM,cAAc,QAAQ;AAC5B,QAAM,eAAe,SAAS,YAAY,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE;AACpE,MAAI,gBAAgB,IAAI;AACtB,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,QAAQ,WAAW;AAAA,IAC9B,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,QAAQ,WAAW;AAAA,MAC5B,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,WAAW,QAAQ;AAC7B,QAAI;AACF,YAAM,EAAE,qBAAAC,qBAAoB,IAAI,MAAM,OAAO,2BAA4B;AACzE,YAAM,eAAe,MAAMA,qBAAoB,CAAC,QAAQ,SAAS,GAAG,aAAa;AAEjF,UAAI,OAAO,KAAK,aAAa,YAAY,EAAE,SAAS,GAAG;AACrD,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS,GAAG,OAAO,KAAK,aAAa,YAAY,EAAE,MAAM;AAAA,QAC3D,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,KAAK;AAAA,QACP,CAAC;AAAA,MACH;AAAA,IACF,QAAQ;AACN,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,iBAAiB,SAAmC;AAC3D,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,aAAW,UAAU,SAAS;AAC5B,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK;AACH,gBAAQ,GAAG,OAAO,IAAI,KAAK,OAAO,OAAO,EAAE;AAC3C;AACA;AAAA,MACF,KAAK;AACH,QAAAC,SAAQ,GAAG,OAAO,IAAI,KAAK,OAAO,OAAO,EAAE;AAC3C,YAAI,OAAO,KAAK;AACd,eAAK,YAAO,OAAO,GAAG,EAAE;AAAA,QAC1B;AACA;AACA;AAAA,MACF,KAAK;AACH,cAAM,GAAG,OAAO,IAAI,KAAK,OAAO,OAAO,EAAE;AACzC,YAAI,OAAO,KAAK;AACd,eAAK,YAAO,OAAO,GAAG,EAAE;AAAA,QAC1B;AACA;AACA;AAAA,IACJ;AAAA,EACF;AAEA,UAAQ,IAAI;AAGZ,MAAI,cAAc,KAAK,cAAc,GAAG;AACtC,YAAQ,wDAAwD;AAAA,EAClE,WAAW,cAAc,GAAG;AAC1B,IAAAA,SAAQ,GAAG,SAAS,kEAAkE;AAAA,EACxF,OAAO;AACL,UAAM,GAAG,SAAS,iBAAiB,SAAS,2CAA2C;AAAA,EACzF;AACF;AAKA,eAAsB,OAAO,UAAyB,CAAC,GAAkB;AACvE,SAAO,yBAAyB;AAEhC,QAAM,UAAU,MAAM,eAAe,OAAO;AAE5C,UAAQ,IAAI;AACZ,mBAAiB,OAAO;AAGxB,MAAI,QAAQ,KAAK,OAAK,EAAE,WAAW,MAAM,GAAG;AAC1C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;ACnSA;AAiCA,SAAS,iBAAiB,KAAa,OAAwB;AAC7D,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,QAAQ,mBAAc;AAAA,EAC/B;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AACA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,SAAO,OAAO,KAAK;AACrB;AAKA,SAAS,qBACP,QACA,OACU;AACV,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,CAAC,CAAC;AAEvE,aAAW,OAAO,SAAS;AACzB,UAAM,cAAc,OAAO,GAA6B;AACxD,UAAM,aAAa,MAAM,GAA6B;AAEtD,QAAI,KAAK,UAAU,WAAW,MAAM,KAAK,UAAU,UAAU,GAAG;AAC9D,cAAQ;AAAA,QACN,KAAK,GAAG,KAAK,iBAAiB,KAAK,WAAW,CAAC,WAAM,iBAAiB,KAAK,UAAU,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAsB,KACpB,aACA,WACA,UAAuB,CAAC,GACT;AACf,SAAO,oBAAoB,WAAW,WAAM,SAAS,EAAE;AAEvD,QAAM,UAAU,MAAM,OAAO,mBAAiB,EAAE,KAAK,OAAK,EAAE,cAAc,uBAAuB,CAAC;AAClG,UAAQ,MAAM;AAEd,MAAI;AAGF,YAAQ,QAAQ,mBAAmB;AAGnC,UAAM,qBAAuD;AAAA,MAC3D,MAAM,EAAE,WAAW,GAAG,KAAK,OAAO,MAAM,KAAK;AAAA,MAC7C,SAAS,EAAE,YAAY,OAAO,cAAc,IAAI;AAAA,MAChD,QAAQ,EAAE,sBAAsB,IAAI,qBAAqB,KAAK;AAAA,IAChE;AAEA,UAAM,oBAAsD;AAAA,MAC1D,MAAM,EAAE,WAAW,GAAG,KAAK,MAAM,MAAM,KAAK;AAAA,MAC5C,SAAS,EAAE,YAAY,MAAM,cAAc,IAAK;AAAA,MAChD,QAAQ,EAAE,YAAY,IAAM;AAAA,MAC5B,QAAQ,EAAE,sBAAsB,IAAI,cAAc,KAAK;AAAA,IACzD;AAEA,UAAM,QAA0B,CAAC;AAGjC,eAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AAC9D,UAAI,EAAE,QAAQ,qBAAqB;AACjC,cAAM,KAAK;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,UACR,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAGA,eAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,kBAAkB,GAAG;AAC/D,UAAI,EAAE,QAAQ,oBAAoB;AAChC,cAAM,KAAK;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AAGA,eAAW,QAAQ,OAAO,KAAK,kBAAkB,GAAG;AAClD,UAAI,QAAQ,mBAAmB;AAC7B,cAAM,SAAS,mBAAmB,IAAI;AACtC,cAAM,QAAQ,kBAAkB,IAAI;AACpC,cAAM,UAAU,qBAAqB,QAAQ,KAAK;AAElD,YAAI,QAAQ,SAAS,GAAG;AACtB,gBAAM,KAAK;AAAA,YACT;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,IAAI;AAGZ,UAAM,aAAa,MAAM,OAAO,OAAK,EAAE,WAAW,OAAO,EAAE;AAC3D,UAAM,eAAe,MAAM,OAAO,OAAK,EAAE,WAAW,SAAS,EAAE;AAC/D,UAAM,gBAAgB,MAAM,OAAO,OAAK,EAAE,WAAW,UAAU,EAAE;AAEjE,QAAI,aAAa,GAAG;AAClB,cAAQ,GAAG,UAAU,wBAAwB;AAAA,IAC/C;AACA,QAAI,gBAAgB,GAAG;AACrB,WAAK,GAAG,aAAa,2BAA2B;AAAA,IAClD;AACA,QAAI,eAAe,GAAG;AACpB,YAAM,GAAG,YAAY,0BAA0B;AAAA,IACjD;AAEA,YAAQ,IAAI;AAGZ,QAAI,QAAQ,WAAW,MAAM,SAAS,GAAG;AACvC,aAAO,kBAAkB;AAEzB,iBAAWC,SAAQ,OAAO;AACxB,gBAAQA,MAAK,QAAQ;AAAA,UACnB,KAAK;AACH,oBAAQ,KAAKA,MAAK,IAAI,QAAQ;AAC9B,gBAAI,QAAQ,WAAWA,MAAK,OAAO;AACjC,oBAAM,SAAS,OAAO,QAAQA,MAAK,KAAK,EACrC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,KAAK,iBAAiB,GAAG,CAAC,CAAC,EAAE,EACrD,KAAK,IAAI;AACZ,sBAAQ,IAAI,MAAM;AAAA,YACpB;AACA;AAAA,UACF,KAAK;AACH,kBAAM,KAAKA,MAAK,IAAI,YAAY;AAChC,gBAAI,QAAQ,WAAWA,MAAK,QAAQ;AAClC,oBAAM,SAAS,OAAO,QAAQA,MAAK,MAAM,EACtC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,KAAK,iBAAiB,GAAG,CAAC,CAAC,EAAE,EACrD,KAAK,IAAI;AACZ,sBAAQ,IAAI,MAAM;AAAA,YACpB;AACA;AAAA,UACF,KAAK;AACH,iBAAK,KAAKA,MAAK,IAAI,aAAa;AAChC,gBAAIA,MAAK,WAAWA,MAAK,QAAQ,SAAS,GAAG;AAC3C,sBAAQ,IAAIA,MAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,YACrC;AACA;AAAA,QACJ;AACA,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF;AAGA,WAAO,yBAAyB;AAEhC,QAAI,gBAAgB,GAAG;AACrB,YAAM,gBAAgB,MAAM,OAAO,OAAK,EAAE,WAAW,UAAU;AAE/D,iBAAWA,SAAQ,eAAe;AAChC,cAAM,kBAAkBA,MAAK,SAAS;AAAA,UAAO,OAC3C,EAAE,SAAS,QAAG,KAAK,CAAC,EAAE,SAAS,UAAK;AAAA,QACtC;AAEA,YAAI,mBAAmB,gBAAgB,SAAS,GAAG;AACjD,kBAAQ,GAAGA,MAAK,IAAI,2BAA2B;AAC/C,oBAAU,eAAe;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe,GAAG;AACpB,cAAQ,4DAA4D;AACpE,YAAM,UAAU,MAAM,OAAO,OAAK,EAAE,WAAW,SAAS,EAAE,IAAI,OAAK,EAAE,IAAI;AACzE,gBAAU,OAAO;AAAA,IACnB;AAAA,EAEF,SAAS,KAAK;AACZ,YAAQ,KAAK,4BAA4B;AACzC,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAKA,eAAsB,aAA4B;AAChD,QAAM,UAAU,MAAM,OAAO,mBAAiB,EAAE,KAAK,OAAK,EAAE,cAAc,yBAAyB,CAAC;AACpG,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,EAAE,qBAAAC,qBAAoB,IAAI,MAAM,OAAO,+BAAgC;AAC7E,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,2BAA4B;AAEtE,UAAM,YAAY,MAAMA,qBAAoB;AAC5C,UAAM,SAAS,MAAM,iBAAiB;AAEtC,YAAQ,QAAQ,wBAAwB;AAExC,WAAO,qBAAqB;AAC5B,SAAK,cAAc,aAAa,MAAM,EAAE;AACxC,SAAK,WAAW,MAAM,EAAE;AAExB,QAAI,cAAc,QAAQ;AACxB,cAAQ,IAAI;AACZ,cAAQ,wBAAwB;AAChC,WAAK,wBAAwB,MAAM,EAAE;AAAA,IACvC,WAAW,WAAW;AACpB,cAAQ,IAAI;AACZ,cAAQ,oBAAqB;AAAA,IAC/B;AAAA,EAEF,SAAS,KAAK;AACZ,YAAQ,KAAK,yBAAyB;AACtC,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,EAC5D;AACF;;;ACvQA;AAWA,eAAsB,kBAAiC;AACrD,UAAQ,mBAAmB;AAC3B,OAAK,2DAA2D;AAClE;AAKA,eAAsB,mBAAkC;AACtD,EAAAC,SAAQ,oBAAoB;AAC5B,OAAK,iCAAiC;AACxC;AAKA,eAAsB,kBAAiC;AACrD,OAAK,8BAA8B;AAEnC,OAAK,iDAAiD;AACxD;;;AC/BA;AAWA,eAAsB,OAAO,UAAgC,CAAC,GAAkB;AAC9E,MAAI,QAAQ,QAAQ;AAClB,SAAK,kDAAkD;AACvD;AAAA,EACF;AAEA,OAAK,6BAA6B;AAElC,UAAQ,mBAAmB;AAC7B;AAKA,eAAsB,QAAuB;AAC3C,OAAK,6BAA6B;AAElC,UAAQ,sBAAsB;AAChC;;;AfTA,IAAM,UAAU,IAAI,QAAQ;AAG5B,QAAQ,YAAY,aAAa,UAAU,CAAC;AAE5C,QACG,KAAK,SAAS,EACd,YAAY,mEAAmE,EAC/E,QAAQ,OAAO;AAGlB,QACG,QAAQ,OAAO,EACf,YAAY,yCAAyC,EACrD,OAAO,mBAAmB,uCAAuC,EACjE,OAAO,2BAA2B,gDAAgD,aAAa,EAC/F,OAAO,OAAO,YAAY;AACzB,eAAa,OAAO;AACpB,QAAM,MAAM,OAAO;AACrB,CAAC;AAGH,QACG,QAAQ,QAAQ,EAChB,YAAY,6CAA6C,EACzD,OAAO,iBAAiB,2BAA2B,EACnD,OAAO,OAAO,YAAY;AACzB,eAAa,QAAQ;AACrB,QAAM,OAAO,OAAO;AACtB,CAAC;AAGH,QACG,QAAQ,mBAAmB,EAC3B,YAAY,sBAAsB,EAClC,OAAO,gCAAgC,8BAA8B,EACrE,OAAO,2BAA2B,gDAAgD,aAAa,EAC/F,OAAO,aAAa,iDAAiD,EACrE,OAAO,eAAe,2CAA2C,EACjE,OAAO,UAAU,qBAAqB,EACtC,OAAO,cAAc,wBAAwB,EAC7C,OAAO,OAAO,SAAS,YAAY;AAClC,eAAa,WAAW,EAAE,YAAY,QAAQ,CAAC;AAC/C,QAAM,QAAQ,WAAW,UAAU,OAAO;AAC5C,CAAC;AAGH,QACG,QAAQ,SAAS,EACjB,YAAY,0CAA0C,EACtD,OAAO,2BAA2B,gDAAgD,aAAa,EAC/F,OAAO,iBAAiB,qBAAqB,EAC7C,OAAO,OAAO,YAAY;AACzB,eAAa,SAAS;AACtB,QAAM,QAAQ,OAAO;AACvB,CAAC;AAGH,QACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,OAAO,YAAY;AAClB,eAAa,QAAQ;AACrB,QAAM,OAAO;AACf,CAAC;AAGH,QACG,QAAQ,QAAQ,EAChB,YAAY,wCAAwC,EACpD,OAAO,iBAAiB,sCAAsC,EAC9D,OAAO,SAAS,4CAA4C,EAC5D,OAAO,OAAO,YAAY;AACzB,eAAa,QAAQ;AACrB,QAAM,OAAO,OAAO;AACtB,CAAC;AAGH,QACG,QAAQ,kCAAkC,EAC1C,YAAY,2CAA2C,EACvD,OAAO,iBAAiB,uBAAuB,EAC/C,OAAO,qBAAqB,6BAA6B,MAAM,EAC/D,OAAO,OAAO,aAAa,WAAW,YAAY;AACjD,eAAa,MAAM;AACnB,MAAI,CAAC,aAAa;AAChB,UAAM,WAAW;AAAA,EACnB,OAAO;AACL,UAAM,KAAK,aAAa,aAAa,UAAU,OAAO;AAAA,EACxD;AACF,CAAC;AAGH,QACG,QAAQ,QAAQ,EAChB,YAAY,kCAAkC,EAC9C,OAAO,aAAa,+CAA+C,EACnE,OAAO,OAAO,YAAY;AACzB,eAAa,QAAQ;AACrB,QAAM,OAAO,OAAO;AACtB,CAAC;AAGH,QACG,QAAQ,OAAO,EACf,YAAY,6BAA6B,EACzC,OAAO,YAAY;AAClB,QAAM,MAAM;AACd,CAAC;AAGH,IAAM,eAAe,QAClB,QAAQ,WAAW,EACnB,YAAY,2BAA2B;AAE1C,aACG,QAAQ,QAAQ,EAChB,YAAY,iCAAiC,EAC7C,OAAO,YAAY;AAClB,QAAM,gBAAgB;AACxB,CAAC;AAEH,aACG,QAAQ,SAAS,EACjB,YAAY,kCAAkC,EAC9C,OAAO,YAAY;AAClB,QAAM,iBAAiB;AACzB,CAAC;AAEH,aACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,OAAO,YAAY;AAClB,QAAM,gBAAgB;AACxB,CAAC;AAGH,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,QAAQ;AAC9C,UAAQ,MAAM,GAAG;AACjB,aAAW,OAAO,aAAa;AAC/B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["hasPackageJson","existsSync","join","fs","join","loadConfig","join","join","join","fs","join","existsSync","join","fs","warning","existsSync","join","loadConfig","fs","resolveCapabilities","warning","diff","getInstalledVersion","warning"]}
|