141 lines
4.3 KiB
C#
141 lines
4.3 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Nodes;
|
|
using ArtificersScrollwork.Sidecar.Parsing;
|
|
using ArtificersScrollwork.Sidecar.Gumps;
|
|
|
|
/// <summary>
|
|
/// Entry point for the ASW C# sidecar.
|
|
/// Reads newline-delimited JSON requests from stdin, writes responses to stdout.
|
|
///
|
|
/// Request: { "id": "uuid", "command": "cmd_name", "args": { ... } }
|
|
/// Response: { "id": "uuid", "ok": true, "data": { ... } }
|
|
/// | { "id": "uuid", "ok": false, "error": "message" }
|
|
/// </summary>
|
|
|
|
var options = new JsonSerializerOptions
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
|
|
WriteIndented = false,
|
|
};
|
|
|
|
ScriptIndexer? indexer = null;
|
|
CallChainTracer? tracer = null;
|
|
|
|
while (true)
|
|
{
|
|
var line = Console.ReadLine();
|
|
if (line is null) break;
|
|
|
|
JsonObject? request;
|
|
try { request = JsonSerializer.Deserialize<JsonObject>(line, options); }
|
|
catch { continue; }
|
|
if (request is null) continue;
|
|
|
|
var id = request["id"]?.GetValue<string>() ?? "";
|
|
var command = request["command"]?.GetValue<string>() ?? "";
|
|
var reqArgs = request["args"] as JsonObject ?? new JsonObject();
|
|
|
|
try
|
|
{
|
|
JsonNode? data = command switch
|
|
{
|
|
"index_scripts" => HandleIndexScripts(reqArgs),
|
|
"get_class" => HandleGetClass(reqArgs),
|
|
"trace_method" => HandleTraceMethod(reqArgs),
|
|
"extract_gump" => HandleExtractGump(reqArgs),
|
|
"search" => HandleSearch(reqArgs),
|
|
_ => throw new InvalidOperationException($"Unknown command: {command}"),
|
|
};
|
|
|
|
WriteResponse(id, true, data, null, options);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
WriteResponse(id, false, null, ex.Message, options);
|
|
}
|
|
}
|
|
|
|
// ── Command handlers ──────────────────────────────────────────────────────────
|
|
|
|
JsonNode HandleIndexScripts(JsonObject args)
|
|
{
|
|
var path = args["path"]?.GetValue<string>()
|
|
?? throw new ArgumentException("Missing 'path' argument");
|
|
|
|
indexer = new ScriptIndexer();
|
|
var index = indexer.IndexDirectory(path);
|
|
|
|
// Build a compilation for the tracer
|
|
tracer = new CallChainTracer(indexer.Compilation
|
|
?? throw new InvalidOperationException("Compilation not available after indexing"));
|
|
|
|
return JsonSerializer.SerializeToNode(index, options)!;
|
|
}
|
|
|
|
JsonNode HandleGetClass(JsonObject args)
|
|
{
|
|
EnsureIndexer();
|
|
var className = args["class"]?.GetValue<string>()
|
|
?? throw new ArgumentException("Missing 'class' argument");
|
|
|
|
var info = indexer!.GetClass(className)
|
|
?? throw new KeyNotFoundException($"Class '{className}' not found in index");
|
|
|
|
return JsonSerializer.SerializeToNode(info, options)!;
|
|
}
|
|
|
|
JsonNode HandleTraceMethod(JsonObject args)
|
|
{
|
|
EnsureIndexer();
|
|
|
|
if (tracer is null)
|
|
throw new InvalidOperationException("Tracer not initialized — send index_scripts first");
|
|
|
|
var className = args["class"]?.GetValue<string>()
|
|
?? throw new ArgumentException("Missing 'class' argument");
|
|
var methodName = args["method"]?.GetValue<string>()
|
|
?? throw new ArgumentException("Missing 'method' argument");
|
|
|
|
var flowNode = tracer.TraceMethod(className, methodName);
|
|
return JsonSerializer.SerializeToNode(flowNode, options)!;
|
|
}
|
|
|
|
JsonNode HandleExtractGump(JsonObject args)
|
|
{
|
|
EnsureIndexer();
|
|
throw new NotImplementedException("extract_gump not yet implemented (Phase 4)");
|
|
}
|
|
|
|
JsonNode HandleSearch(JsonObject args)
|
|
{
|
|
EnsureIndexer();
|
|
var query = args["query"]?.GetValue<string>()
|
|
?? throw new ArgumentException("Missing 'query' argument");
|
|
|
|
var results = indexer!.Search(query);
|
|
return JsonSerializer.SerializeToNode(results, options)!;
|
|
}
|
|
|
|
void EnsureIndexer()
|
|
{
|
|
if (indexer is null)
|
|
throw new InvalidOperationException("Scripts not indexed — send index_scripts first");
|
|
}
|
|
|
|
static void WriteResponse(string id, bool ok, JsonNode? data, string? error, JsonSerializerOptions opts)
|
|
{
|
|
var response = new JsonObject
|
|
{
|
|
["id"] = id,
|
|
["ok"] = ok,
|
|
};
|
|
|
|
if (ok && data is not null)
|
|
response["data"] = data;
|
|
else if (!ok)
|
|
response["error"] = error ?? "Unknown error";
|
|
|
|
Console.WriteLine(JsonSerializer.Serialize(response, opts));
|
|
Console.Out.Flush();
|
|
}
|