skillo 0.1.2 → 0.1.4
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 +0 -1
- package/dist/{api-client-AN7GGMUP.js → api-client-HTWGTHC2.js} +2 -2
- package/dist/{chunk-SBUZE4TL.js → chunk-QNRWQL6M.js} +2 -2
- package/dist/chunk-QNRWQL6M.js.map +1 -0
- package/dist/cli.js +5 -5
- package/dist/cli.js.map +1 -1
- package/package.json +1 -8
- package/dist/chunk-SBUZE4TL.js.map +0 -1
- /package/dist/{api-client-AN7GGMUP.js.map → api-client-HTWGTHC2.js.map} +0 -0
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ApiClient,
|
|
4
4
|
getApiClient
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QNRWQL6M.js";
|
|
6
6
|
import "./chunk-SWPZL2RI.js";
|
|
7
7
|
export {
|
|
8
8
|
ApiClient,
|
|
9
9
|
getApiClient
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=api-client-
|
|
11
|
+
//# sourceMappingURL=api-client-HTWGTHC2.js.map
|
|
@@ -174,7 +174,7 @@ function convertKeysToSnakeCase(obj) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// src/core/api-client.ts
|
|
177
|
-
var DEFAULT_API_URL = "https://skillo.one/api/cli";
|
|
177
|
+
var DEFAULT_API_URL = "https://www.skillo.one/api/cli";
|
|
178
178
|
var ApiClient = class {
|
|
179
179
|
baseUrl;
|
|
180
180
|
apiKey;
|
|
@@ -533,4 +533,4 @@ export {
|
|
|
533
533
|
ApiClient,
|
|
534
534
|
getApiClient
|
|
535
535
|
};
|
|
536
|
-
//# sourceMappingURL=chunk-
|
|
536
|
+
//# sourceMappingURL=chunk-QNRWQL6M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/config.ts","../src/core/api-client.ts"],"sourcesContent":["/**\n * Configuration management for Skillo.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from \"fs\";\nimport { dirname } from \"path\";\nimport YAML from \"yaml\";\nimport { ensureDirectory, getConfigFile } from \"../utils/paths.js\";\n\nexport interface SkilloConfig {\n // Shell settings\n defaultShell: string | null;\n\n // Pattern detection\n patternDetection: {\n minCount: number;\n sessionTimeout: number;\n similarityThreshold: number;\n maxSequenceLength: number;\n };\n\n // Privacy settings\n privacy: {\n autoRedact: boolean;\n trackOutput: boolean;\n neverTrack: string[];\n redactionPatterns: string[];\n };\n\n // Notification settings\n notifications: {\n enabled: boolean;\n style: \"inline\" | \"desktop\" | \"both\";\n sound: boolean;\n };\n\n // Skill generation\n skillGeneration: {\n outputDir: string | null;\n includeScripts: boolean;\n includeExamples: boolean;\n autoGenerate: boolean;\n };\n\n // Claude Code integration\n claudeCode: {\n watchConversations: boolean;\n conversationDir: string | null;\n };\n\n // Daemon settings\n daemon: {\n logLevel: \"DEBUG\" | \"INFO\" | \"WARN\" | \"ERROR\";\n patternCheckInterval: number;\n conversationCheckInterval: number;\n };\n\n // Team settings\n team: {\n enabled: boolean;\n slug: string | null;\n autoSync: boolean;\n syncInterval: number;\n };\n\n // API settings\n api: {\n baseUrl: string | null;\n timeout: number;\n };\n\n // API key (stored separately, not in YAML for security)\n apiKey?: string;\n}\n\nexport function getDefaultConfig(): SkilloConfig {\n return {\n defaultShell: null,\n\n patternDetection: {\n minCount: 3,\n sessionTimeout: 30,\n similarityThreshold: 0.8,\n maxSequenceLength: 10,\n },\n\n privacy: {\n autoRedact: true,\n trackOutput: false,\n neverTrack: [\n \"*password*\",\n \"*secret*\",\n \"vault *\",\n \"1password *\",\n \"op *\",\n \"export *_KEY=*\",\n \"export *_SECRET=*\",\n \"export *_TOKEN=*\",\n ],\n redactionPatterns: [\n \"password[=:]\\\\s*\\\\S+\",\n \"token[=:]\\\\s*\\\\S+\",\n \"secret[=:]\\\\s*\\\\S+\",\n \"api[_-]?key[=:]\\\\s*\\\\S+\",\n \"auth[=:]\\\\s*\\\\S+\",\n \"bearer\\\\s+\\\\S+\",\n \"-----BEGIN.*PRIVATE KEY-----\",\n \"AKIA[0-9A-Z]{16}\",\n '[\"\\'][A-Za-z0-9+/]{40,}[\"\\']',\n ],\n },\n\n notifications: {\n enabled: true,\n style: \"inline\",\n sound: false,\n },\n\n skillGeneration: {\n outputDir: null,\n includeScripts: true,\n includeExamples: true,\n autoGenerate: false,\n },\n\n claudeCode: {\n watchConversations: true,\n conversationDir: null,\n },\n\n daemon: {\n logLevel: \"INFO\",\n patternCheckInterval: 60,\n conversationCheckInterval: 5,\n },\n\n team: {\n enabled: false,\n slug: null,\n autoSync: true,\n syncInterval: 300,\n },\n\n api: {\n baseUrl: null,\n timeout: 30000,\n },\n };\n}\n\nfunction deepMerge<T extends object>(base: T, override: Partial<T>): T {\n const result = { ...base };\n\n for (const key of Object.keys(override) as Array<keyof T>) {\n const value = override[key];\n if (\n value !== undefined &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n result[key] = deepMerge(\n result[key] as Record<string, unknown>,\n value as Record<string, unknown>\n ) as T[keyof T];\n } else if (value !== undefined) {\n result[key] = value as T[keyof T];\n }\n }\n\n return result;\n}\n\nexport function loadConfig(path?: string): SkilloConfig {\n const configPath = path || getConfigFile();\n\n if (!existsSync(configPath)) {\n return getDefaultConfig();\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\");\n const parsed = YAML.parse(content) || {};\n\n // Convert snake_case to camelCase for compatibility\n const converted = convertKeysToCamelCase(parsed);\n const defaultConfig = getDefaultConfig();\n\n // Deep merge with default config\n return deepMerge(defaultConfig, converted as Partial<SkilloConfig>);\n } catch {\n return getDefaultConfig();\n }\n}\n\nexport function saveConfig(config: SkilloConfig, path?: string): void {\n const configPath = path || getConfigFile();\n\n ensureDirectory(dirname(configPath));\n\n // Convert camelCase to snake_case for YAML file\n const converted = convertKeysToSnakeCase(config);\n\n const content = YAML.stringify(converted, {\n indent: 2,\n lineWidth: 0,\n });\n\n writeFileSync(configPath, content, \"utf-8\");\n}\n\nexport function getConfigValue(config: SkilloConfig, key: string): unknown {\n const keys = key.split(\".\");\n let current: unknown = config;\n\n for (const k of keys) {\n if (current && typeof current === \"object\" && k in current) {\n current = (current as Record<string, unknown>)[k];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\nexport function setConfigValue(config: SkilloConfig, key: string, value: unknown): SkilloConfig {\n const keys = key.split(\".\");\n const result = JSON.parse(JSON.stringify(config)) as SkilloConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n if (!(k in current)) {\n current[k] = {};\n }\n current = current[k] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return result;\n}\n\n// Helper functions for key conversion\nfunction toCamelCase(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\nfunction toSnakeCase(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\nfunction convertKeysToCamelCase(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map(convertKeysToCamelCase);\n }\n\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[toCamelCase(key)] = convertKeysToCamelCase(value);\n }\n return result;\n }\n\n return obj;\n}\n\nfunction convertKeysToSnakeCase(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map(convertKeysToSnakeCase);\n }\n\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[toSnakeCase(key)] = convertKeysToSnakeCase(value);\n }\n return result;\n }\n\n return obj;\n}\n","/**\n * Skillo Platform API Client\n *\n * Handles communication with the Skillo platform API.\n */\n\nimport { loadConfig, saveConfig } from \"./config.js\";\n\nconst DEFAULT_API_URL = \"https://www.skillo.one/api/cli\";\n\ninterface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n}\n\ninterface AuthResponse {\n success: boolean;\n user: {\n id: string;\n email: string;\n name: string;\n };\n}\n\ninterface SyncResponse {\n success: boolean;\n skills?: Array<{\n id: string;\n name: string;\n slug: string;\n description: string;\n content: string;\n commands: string[];\n }>;\n patterns?: Array<{\n id: string;\n name: string;\n description: string;\n commands: string[];\n status: string;\n }>;\n}\n\ninterface GenerateResponse {\n success: boolean;\n skill: {\n id: string;\n name: string;\n slug: string;\n description: string;\n content: string;\n commands: string[];\n };\n}\n\ninterface DeviceAuthResponse {\n code: string;\n verification_url: string;\n expires_in: number;\n interval: number;\n}\n\ninterface TokenStatusResponse {\n status: \"pending\" | \"ready\" | \"expired\" | \"used\" | \"not_found\";\n}\n\ninterface TokenExchangeResponse {\n success: boolean;\n api_key: string;\n user: {\n id: string;\n };\n}\n\nexport class ApiClient {\n private baseUrl: string;\n private apiKey: string | null;\n\n constructor() {\n const config = loadConfig();\n this.baseUrl = config.api?.baseUrl || DEFAULT_API_URL;\n this.apiKey = this.loadApiKey();\n }\n\n /**\n * Load API key from config\n */\n private loadApiKey(): string | null {\n const config = loadConfig();\n return (config as { apiKey?: string }).apiKey || null;\n }\n\n /**\n * Save API key to config\n */\n saveApiKey(key: string): void {\n const config = loadConfig();\n (config as { apiKey?: string }).apiKey = key;\n saveConfig(config);\n this.apiKey = key;\n }\n\n /**\n * Clear API key from config\n */\n clearApiKey(): void {\n const config = loadConfig();\n delete (config as { apiKey?: string }).apiKey;\n saveConfig(config);\n this.apiKey = null;\n }\n\n /**\n * Check if API key is configured\n */\n hasApiKey(): boolean {\n return !!this.apiKey;\n }\n\n /**\n * Get the configured API key (masked)\n */\n getMaskedApiKey(): string | null {\n if (!this.apiKey) return null;\n return `${this.apiKey.substring(0, 12)}...${this.apiKey.substring(this.apiKey.length - 4)}`;\n }\n\n /**\n * Set the API base URL\n */\n setBaseUrl(url: string): void {\n const config = loadConfig();\n if (!config.api) {\n (config as { api?: { baseUrl: string } }).api = { baseUrl: url };\n } else {\n config.api.baseUrl = url;\n }\n saveConfig(config);\n this.baseUrl = url;\n }\n\n /**\n * Make an authenticated API request\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<ApiResponse<T>> {\n if (!this.apiKey) {\n return { success: false, error: \"No API key configured. Run 'skillo login' first.\" };\n }\n\n const url = `${this.baseUrl}${endpoint}`;\n const headers: HeadersInit = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n };\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n const data = await response.json();\n\n if (process.env.SKILLO_DEBUG) {\n console.log('[DEBUG] Request:', url);\n console.log('[DEBUG] Status:', response.status);\n console.log('[DEBUG] Response:', JSON.stringify(data));\n }\n\n if (!response.ok) {\n return {\n success: false,\n error: data.error || `Request failed with status ${response.status}`,\n };\n }\n\n // If the response already has success/data structure, return as-is\n // Otherwise wrap the data\n if (data.success !== undefined && data.data !== undefined) {\n return { success: data.success, data: data.data as T, message: data.message };\n }\n\n // If response just has success field (no data wrapper), return as-is\n if (data.success !== undefined) {\n return data;\n }\n\n // Legacy: wrap raw data\n return { success: true, data: data as T };\n } catch (error) {\n if (process.env.SKILLO_DEBUG) {\n console.log('[DEBUG] Error:', error);\n }\n if (error instanceof Error) {\n if (error.message.includes(\"ECONNREFUSED\")) {\n return {\n success: false,\n error: \"Cannot connect to Skillo platform. Is the server running?\",\n };\n }\n return { success: false, error: error.message };\n }\n return { success: false, error: \"Unknown error occurred\" };\n }\n }\n\n /**\n * Authenticate with the platform\n */\n async authenticate(): Promise<ApiResponse<AuthResponse>> {\n return this.request<AuthResponse>(\"/auth\", { method: \"POST\" });\n }\n\n /**\n * Sync commands to platform\n */\n async syncCommands(\n commands: Array<{\n timestamp: string;\n command: string;\n normalized: string;\n cwd: string;\n exitCode?: number | null;\n durationMs?: number | null;\n sessionId?: string;\n variables?: Record<string, string> | null;\n }>\n ): Promise<ApiResponse> {\n return this.request(\"/sync\", {\n method: \"POST\",\n body: JSON.stringify({\n type: \"commands\",\n data: commands,\n }),\n });\n }\n\n /**\n * Sync a pattern to platform\n */\n async syncPattern(pattern: {\n sourceType: string;\n name?: string;\n description?: string;\n commands: string[];\n category?: string;\n frequency?: number;\n score?: number;\n firstSeen?: string;\n lastSeen?: string;\n context?: Record<string, unknown>;\n }): Promise<ApiResponse<{ pattern: { id: string; name: string; status: string } }>> {\n return this.request(\"/sync\", {\n method: \"POST\",\n body: JSON.stringify({\n type: \"pattern\",\n data: pattern,\n }),\n });\n }\n\n /**\n * Create a session on the platform\n */\n async createSession(session: {\n startedAt: string;\n shell: string;\n endedAt?: string;\n commandCount?: number;\n }): Promise<ApiResponse<{ session: { id: string } }>> {\n return this.request(\"/sync\", {\n method: \"POST\",\n body: JSON.stringify({\n type: \"session\",\n data: session,\n }),\n });\n }\n\n /**\n * End a session on the platform\n */\n async endSession(sessionId: string): Promise<ApiResponse<{ success: boolean }>> {\n return this.request(\"/sessions\", {\n method: \"PATCH\",\n body: JSON.stringify({ sessionId }),\n });\n }\n\n /**\n * Start a new session on the platform (for standalone terminals)\n */\n async startSession(shell: string): Promise<ApiResponse<{ sessionId: string }>> {\n return this.request(\"/sessions\", {\n method: \"POST\",\n body: JSON.stringify({ shell }),\n });\n }\n\n /**\n * Download skills and patterns from platform\n */\n async downloadData(type: \"all\" | \"skills\" | \"patterns\" = \"all\"): Promise<ApiResponse<SyncResponse>> {\n return this.request<SyncResponse>(`/sync?type=${type}`, { method: \"GET\" });\n }\n\n /**\n * Generate a skill from a pattern\n */\n async generateSkill(options: {\n patternId?: string;\n commands?: string[];\n name?: string;\n description?: string;\n category?: string;\n context?: Record<string, unknown>;\n }): Promise<ApiResponse<GenerateResponse>> {\n return this.request<GenerateResponse>(\"/generate\", {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n }\n\n /**\n * Start device authorization flow (no auth required)\n */\n async startDeviceAuth(deviceName?: string): Promise<ApiResponse<DeviceAuthResponse>> {\n const url = `${this.baseUrl}/auth/device`;\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ device_name: deviceName }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n return {\n success: false,\n error: data.error || `Request failed with status ${response.status}`,\n };\n }\n\n return { success: true, data };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes(\"ECONNREFUSED\")) {\n return {\n success: false,\n error: \"Cannot connect to Skillo platform. Is the server running?\",\n };\n }\n return { success: false, error: error.message };\n }\n return { success: false, error: \"Unknown error occurred\" };\n }\n }\n\n /**\n * Check token status (polling)\n */\n async checkTokenStatus(code: string): Promise<ApiResponse<TokenStatusResponse>> {\n const url = `${this.baseUrl}/token?code=${encodeURIComponent(code)}`;\n try {\n const response = await fetch(url, { method: \"GET\" });\n const data = await response.json();\n\n if (!response.ok) {\n return {\n success: false,\n error: data.error || `Request failed with status ${response.status}`,\n };\n }\n\n return { success: true, data };\n } catch (error) {\n if (error instanceof Error) {\n return { success: false, error: error.message };\n }\n return { success: false, error: \"Unknown error occurred\" };\n }\n }\n\n /**\n * Exchange code for API key\n */\n async exchangeToken(code: string, deviceName?: string): Promise<ApiResponse<TokenExchangeResponse>> {\n const url = `${this.baseUrl}/token`;\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code, device_name: deviceName }),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n return {\n success: false,\n error: data.error || `Request failed with status ${response.status}`,\n };\n }\n\n return { success: true, data };\n } catch (error) {\n if (error instanceof Error) {\n return { success: false, error: error.message };\n }\n return { success: false, error: \"Unknown error occurred\" };\n }\n }\n\n /**\n * Sync Claude Code prompts to platform\n */\n async syncClaudePrompts(\n prompts: Array<{\n display: string;\n timestamp: number;\n project: string;\n sessionId: string;\n pastedContents?: Record<string, unknown>;\n }>,\n options?: {\n terminalSessionId?: string;\n projectPath?: string;\n }\n ): Promise<ApiResponse<{\n sessionsCreated: number;\n promptsCreated: number;\n promptsSkipped: number;\n }>> {\n return this.request(\"/claude\", {\n method: \"POST\",\n body: JSON.stringify({\n prompts,\n terminalSessionId: options?.terminalSessionId,\n projectPath: options?.projectPath,\n }),\n });\n }\n\n /**\n * Get Claude Code sessions from platform\n */\n async getClaudeSessions(limit = 20): Promise<ApiResponse<{\n sessions: Array<{\n id: string;\n claudeSessionId: string;\n projectPath: string;\n projectName: string;\n startedAt: string;\n endedAt?: string;\n promptCount: number;\n prompts?: Array<{\n id: string;\n prompt: string;\n timestamp: string;\n category?: string;\n }>;\n }>;\n }>> {\n return this.request(`/claude?limit=${limit}`, { method: \"GET\" });\n }\n\n // ============================================================================\n // PROJECT TRACKING\n // ============================================================================\n\n /**\n * Connect a project for tracking\n */\n async connectProject(params: {\n path: string;\n name?: string;\n gitRemote?: string;\n gitRemoteNormalized?: string;\n language?: string;\n framework?: string;\n }): Promise<ApiResponse<{\n id: string;\n name: string;\n path: string;\n trackingEnabled: boolean;\n connectedAt: string;\n }>> {\n return this.request(\"/projects/connect\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n /**\n * Disconnect a project from tracking\n */\n async disconnectProject(path: string): Promise<ApiResponse<{\n id: string;\n name: string;\n trackingEnabled: boolean;\n }>> {\n return this.request(`/projects/connect?path=${encodeURIComponent(path)}`, {\n method: \"DELETE\",\n });\n }\n\n /**\n * Get tracking status for a project\n */\n async getProjectStatus(path: string): Promise<ApiResponse<{\n connected: boolean;\n tracked: boolean;\n connectedAt?: string;\n project?: {\n id: string;\n name: string;\n path: string;\n gitRemote?: string;\n gitRemoteNormalized?: string;\n trackingEnabled: boolean;\n };\n }>> {\n return this.request(`/projects/connect?path=${encodeURIComponent(path)}`, {\n method: \"GET\",\n });\n }\n\n /**\n * List all tracked projects\n */\n async listProjects(includeDisabled = false): Promise<ApiResponse<{\n projects: Array<{\n id: string;\n name: string;\n path: string;\n gitRemote?: string;\n gitRemoteNormalized?: string;\n trackingEnabled: boolean;\n connectedAt?: string;\n }>;\n totalTracked: number;\n totalProjects: number;\n }>> {\n return this.request(`/projects/tracked?includeDisabled=${includeDisabled}`, {\n method: \"GET\",\n });\n }\n\n /**\n * Check if a path is in a tracked project\n * Returns the project if tracked, null if not\n */\n async isProjectTracked(path: string): Promise<{\n tracked: boolean;\n project?: {\n id: string;\n name: string;\n path: string;\n };\n }> {\n const result = await this.getProjectStatus(path);\n if (result.success && result.data?.connected) {\n return {\n tracked: true,\n project: result.data.project ? {\n id: result.data.project.id,\n name: result.data.project.name,\n path: result.data.project.path,\n } : undefined,\n };\n }\n return { tracked: false };\n }\n}\n\n// Singleton instance\nlet clientInstance: ApiClient | null = null;\n\nexport function getApiClient(): ApiClient {\n if (!clientInstance) {\n clientInstance = new ApiClient();\n }\n return clientInstance;\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
loadConfig,
|
|
7
7
|
saveConfig,
|
|
8
8
|
setConfigValue
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QNRWQL6M.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureDirectory,
|
|
12
12
|
getConfigDir,
|
|
@@ -848,7 +848,7 @@ patternsCommand.command("ignore <id>").description("Ignore a pattern (never sugg
|
|
|
848
848
|
}
|
|
849
849
|
});
|
|
850
850
|
patternsCommand.command("generate <id>").description("Generate a skill from a pattern").option("-n, --name <name>", "Custom skill name").option("--dry-run", "Preview without creating").action(async (id, options) => {
|
|
851
|
-
const { getApiClient: getApiClient2 } = await import("./api-client-
|
|
851
|
+
const { getApiClient: getApiClient2 } = await import("./api-client-HTWGTHC2.js");
|
|
852
852
|
const { writeFileSync: writeFileSync5, mkdirSync: mkdirSync2 } = await import("fs");
|
|
853
853
|
const { join: join6 } = await import("path");
|
|
854
854
|
const { getSkillsDir: getSkillsDir2, ensureDirectory: ensureDirectory2 } = await import("./paths-YODCFIEO.js");
|
|
@@ -1200,7 +1200,7 @@ var recordCommand = new Command6("record").description("Record a command (used b
|
|
|
1200
1200
|
db.close();
|
|
1201
1201
|
if (options.sync !== false) {
|
|
1202
1202
|
try {
|
|
1203
|
-
const { getApiClient: getApiClient2 } = await import("./api-client-
|
|
1203
|
+
const { getApiClient: getApiClient2 } = await import("./api-client-HTWGTHC2.js");
|
|
1204
1204
|
const client = getApiClient2();
|
|
1205
1205
|
if (client.hasApiKey()) {
|
|
1206
1206
|
await client.syncCommands([{
|
|
@@ -1807,7 +1807,7 @@ sessionCommand.command("list").description("List active sessions").action(async
|
|
|
1807
1807
|
logger_default.error("Not logged in. Run 'skillo login' first.");
|
|
1808
1808
|
process.exit(1);
|
|
1809
1809
|
}
|
|
1810
|
-
logger_default.info("Check your sessions at: https://skillo.one/terminal");
|
|
1810
|
+
logger_default.info("Check your sessions at: https://www.skillo.one/terminal");
|
|
1811
1811
|
});
|
|
1812
1812
|
|
|
1813
1813
|
// src/commands/claude.ts
|
|
@@ -2428,7 +2428,7 @@ async function openBrowser(url) {
|
|
|
2428
2428
|
function sleep(ms) {
|
|
2429
2429
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
2430
2430
|
}
|
|
2431
|
-
var loginCommand = new Command11("login").description("Login to Skillo platform").argument("[api-key]", "Your Skillo API key (optional, will use browser auth if not provided)").option("-u, --url <url>", "Platform URL (default: https://skillo.one)").option("-n, --no-browser", "Don't open browser automatically").action(async (apiKey, options) => {
|
|
2431
|
+
var loginCommand = new Command11("login").description("Login to Skillo platform").argument("[api-key]", "Your Skillo API key (optional, will use browser auth if not provided)").option("-u, --url <url>", "Platform URL (default: https://www.skillo.one)").option("-n, --no-browser", "Don't open browser automatically").action(async (apiKey, options) => {
|
|
2432
2432
|
const client = getApiClient();
|
|
2433
2433
|
logger_default.blank();
|
|
2434
2434
|
if (options?.url) {
|