forked from netclaw-dev/skill-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
137 lines (117 loc) · 5.04 KB
/
Copy pathProgram.cs
File metadata and controls
137 lines (117 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// -----------------------------------------------------------------------
// <copyright file="Program.cs" company="Petabridge, LLC">
// Copyright (C) 2026 - 2026 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------
using System.Reflection;
using Netclaw.SkillClient;
using Netclaw.SkillServer.Cli;
using Netclaw.SkillServer.Cli.Commands;
using Netclaw.SkillServer.Cli.Config;
using System.Net.Http.Headers;
using Netclaw.SkillServer.Cli.Output;
var parsedArgs = CliArgsParser.Parse(args);
if (parsedArgs.Version)
{
var version = Assembly.GetExecutingAssembly()
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion
?? Assembly.GetExecutingAssembly().GetName().Version?.ToString()
?? "unknown";
Console.WriteLine($"skillserver {version}");
return 0;
}
if (parsedArgs.Help && parsedArgs.Command == "")
{
PrintHelp();
return 0;
}
if (parsedArgs.Command == "")
{
PrintHelp();
return 1;
}
if (parsedArgs.Command == "config")
return await ConfigCommand.ExecuteAsync(parsedArgs);
// lint operates entirely on local files — no server URL or auth needed
if (parsedArgs.Command == "lint")
return await LintCommand.ExecuteAsync(parsedArgs);
// --help on subcommands works without auth
if (parsedArgs.Help)
{
using var helpClient = new SkillServerClient("http://placeholder");
return await DispatchAsync(parsedArgs, helpClient);
}
var resolver = new ConfigResolver();
var config = resolver.Resolve(parsedArgs.ServerUrl, parsedArgs.ApiKey);
var requiresAuth = parsedArgs.Command is not "list" and not "versions" and not "verify";
if (!config.HasServerUrl)
{
ConsoleOutput.WriteError("Error: Server URL not configured.");
ConsoleOutput.WriteError("Set SKILLSERVER_URL or run 'skillserver config init'");
return 1;
}
if (requiresAuth && !config.HasApiKey)
{
ConsoleOutput.WriteError("Error: Authentication required.");
ConsoleOutput.WriteError("Set SKILLSERVER_API_KEY or run 'skillserver config init'");
return 1;
}
using var httpClient = CreateHttpClient(config, parsedArgs.Verbose);
using var client = new SkillServerClient(httpClient);
return await DispatchAsync(parsedArgs, client);
static async Task<int> DispatchAsync(ParsedArgs parsedArgs, SkillServerClient client) =>
parsedArgs.Command switch
{
"publish" => await PublishCommand.ExecuteAsync(parsedArgs, client),
"publish-all" => await PublishAllCommand.ExecuteAsync(parsedArgs, client),
"delete" => await DeleteCommand.ExecuteAsync(parsedArgs, client),
"list" => await ListCommand.ExecuteAsync(parsedArgs, client),
"versions" => await VersionsCommand.ExecuteAsync(parsedArgs, client),
"verify" => await VerifyCommand.ExecuteAsync(parsedArgs, client),
"api-key" => await ApiKeyCommand.ExecuteAsync(parsedArgs, client),
_ => UnknownCommand(parsedArgs.Command)
};
static int UnknownCommand(string command)
{
ConsoleOutput.WriteError($"Unknown command: '{command}'");
Console.WriteLine();
PrintHelp();
return 1;
}
static HttpClient CreateHttpClient(ResolvedConfig config, bool verbose)
{
HttpMessageHandler handler = verbose
? new VerboseLoggingHandler()
: new HttpClientHandler();
var client = new HttpClient(handler)
{
BaseAddress = new Uri(config.ServerUrl!.TrimEnd('/') + "/")
};
if (!string.IsNullOrEmpty(config.ApiKey))
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", config.ApiKey);
return client;
}
static void PrintHelp()
{
Console.WriteLine("Usage: skillserver <command> [options]");
Console.WriteLine();
Console.WriteLine("Commands:");
Console.WriteLine(" publish <path> Publish a skill directory to the server");
Console.WriteLine(" publish-all <path> Batch-publish all skills in a directory");
Console.WriteLine(" lint <path> Validate skills against spec (no auth required)");
Console.WriteLine(" delete <name> <version> Delete a published skill version");
Console.WriteLine(" list List skills on the server");
Console.WriteLine(" versions <name> List all versions of a skill");
Console.WriteLine(" verify <path> Verify local skill matches published version");
Console.WriteLine(" config Manage CLI configuration");
Console.WriteLine(" api-key Manage server API keys");
Console.WriteLine();
Console.WriteLine("Global options:");
Console.WriteLine(" --server-url <url> SkillServer URL (overrides config/env)");
Console.WriteLine(" --api-key <key> API key (overrides config/env)");
Console.WriteLine(" --output <text|json> Output format (default: text)");
Console.WriteLine(" --verbose, -v Enable verbose output");
Console.WriteLine(" --help, -h Show help");
Console.WriteLine(" --version Show version");
}