feat(cli): crafter-debug, the client agents drive an app with
Cli::Run is the whole client but its transport, so tests run it in process against a real Session; main will hand it the QUIC connection. - Commands: ls, status, cmds, help, call, get, set, pause, resume, step, wait, trace, log (with --follow), screenshot, quit, debugger, guide and version, with -i, --json and --timeout. - call types key=value from the command's argument schema (slot=1 is a number, name=1 a string, at.x=3 nests), so agents need no JSON for simple calls; a value that cannot fit its field is a usage error before anything is sent. - The instance comes from discovery; one running instance needs no -i. The record's protocol is checked before any request: a mismatch exits 4, says which side is newer and prints the app's own client. Other sources only warn. - A request with no reply is diagnosed: the app has exited, stopped in a debugger (with the attach command), or no longer calls Pump (with what to change). Exit codes: 2 usage, 3 no instance, 4 version, 5 timeout, 6 the app's error. - Output is short by default, arrays cut at 20 with a note; --json prints everything. `guide` is the full reference for agents. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
37e0d9b9ae
commit
34c60dcd34
7 changed files with 1359 additions and 10 deletions
|
|
@ -1,13 +1,26 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
// Spike placeholder for the crafter-debug client: reports where it runs.
|
||||
// crafter-debug: Cli::Run with the real transport.
|
||||
import std;
|
||||
namespace fs = std::filesystem;
|
||||
import Crafter.Debug.Core;
|
||||
import Crafter.Debug.Cli;
|
||||
using namespace Crafter::Debug;
|
||||
|
||||
namespace {
|
||||
// Until the QUIC transport lands: every call reports it unreachable.
|
||||
class Unbuilt : public Cli::Connection {
|
||||
public:
|
||||
std::expected<Value, Cli::CallError> Call(const Value&, std::chrono::milliseconds, const std::function<bool(const Value&)>&) override {
|
||||
return std::unexpected(Cli::CallError{ Cli::CallError::Kind::Unreachable, "this client was built without its transport" });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::println("crafter-debug spike client at {}", fs::read_symlink("/proc/self/exe").string());
|
||||
std::println("inside a Flatpak sandbox: {}", fs::exists("/.flatpak-info"));
|
||||
for (std::int32_t i = 1; i < argc; ++i) std::println("arg: {}", std::string_view(argv[i]));
|
||||
return 0;
|
||||
const std::vector<std::string_view> args(argv + 1, argv + argc);
|
||||
Cli::Environment environment;
|
||||
environment.connect = [](const InstanceRecord&) -> std::unique_ptr<Cli::Connection> { return std::make_unique<Unbuilt>(); };
|
||||
environment.haveLldb = [] { return std::filesystem::exists("/app/bin/lldb") || std::filesystem::exists("/usr/bin/lldb"); };
|
||||
return Cli::Run(args, environment);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue