Commit graph Crafter.Debug/tooling/interfaces
Author SHA1 Message Date
2217037d72
feat(cli): pick the app of the project the launcher belongs to
Discovery is per user, so every project's launcher sees every debug app
running, and with two of them up every command refused to guess and
asked for -i, though the agent in one project meant its own app. Two
copies of the example, both named basic, could only be told apart by
id.

The launcher now exports CRAFTER_DEBUG_PROJECT, its project's directory
(flatpak-spawn gets it spelled out), and the client counts an app as
the project's when its executable lies under it, as `-r` runs it from
<project>/bin/<variant>/. With other projects' apps running, commands
pick this project's; two copies of it still need -i. Another project's
app is never picked by default: with this project's app not up yet, or
crashed, the agent would otherwise drive, or quit, someone else's. It
is listed instead, for -i.

`ls` lists this project's apps first, marked, `--json` says which are,
and `--wait` waits for one of them rather than any app; the exit code
says whether one runs. A client started without the launcher has no
project and picks the one app running, as before, and the command the
protocol check prints for an older app's own client now names it with
-i.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 18:33:59 +01:00
8e7f8c5f3b
fix(tooling): build first, then start the app, then list it
The notes had agents start `crafter-build <flag> -r` in the background
and run `crafter-debug ls --wait 60s` straight after. That raced the
build: the first agent to follow them ran the plain build's stub, which
said "no debug build yet" and exited, since the client `ls --wait` needs
is one of the things the debug build compiles, and it polled by hand
until the build was done.

The race came from the order, so the order changes: build with the flag
in the foreground, which ends once the app and the client are built,
then start the app with -r in the background, then `ls --wait`, which
now only waits for what it is for, the app registering. A launcher that
polls for the build instead was tried and dropped: a shell loop that
reruns itself each second, and waits out its whole --wait when no build
is coming at all.

The consumer notes, the client's guide and the README say so, and the
stub and the not-yet-built launcher name the step that was skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 18:24:35 +01:00
6da3b274a6
feat(tooling): Debug::Use says whether it added the library
A consumer adds its debug-only sources, the ones that import
Crafter.Debug, under the same condition Use adds the library. Testing
its own flag is not that condition: a build with the flag for a target
other than native Linux gets neither the library nor the define, and
its debug-only sources would then fail to import Crafter.Debug. Use
now returns whether it added them, and the README shows the pattern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 03:21:41 +01:00
fb2c06c32e
feat(tooling): wire consumers in through Debug::Use and a launcher
A consumer loads Crafter.Debug.Build through
  #pragma crafter dependency "<Crafter.Debug>" project "tooling/project.cpp"
and calls Debug::Use in its own CrafterBuildProject, the way
Crafter.LintRules gets in. With the consumer's flag on, Use adds the
library from the checkout the pragma loaded, and writes
build/crafter-debug: a POSIX sh launcher for the client that library
builds. The client is one of the library's dependencies, so a debug
build compiles it in the same pass as the app, from the same sources.

Why a launcher and not a script: every `crafter-build run` loads the
whole project first, which costs 13-28 s per call on 3DForts (a git
pull per unpinned dependency plus rescanning sources), while the
launcher is one sandbox start, 0.08 s. A client built in the Flatpak
links the Flatpak's libc++ against the runtime's glibc, so the launcher
starts it through `flatpak run` and never on the host itself; inside a
CrafterBuild sandbox it runs it directly.

The library, the client and examples/Basic are placeholders that prove
the wiring: the debug build writes a launcher whose client exists, a
plain build has no Crafter::Debug symbols and keeps the notes from
tooling/AGENTS.consumer.md, and a fresh plain build writes a stub that
names the flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 01:18:07 +01:00