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>
A consumer's `#pragma crafter dependency "https://.../Crafter.Debug.git"
project "tooling/project.cpp"`, the line the README gives, failed at
load: "No module declaration found in <clone>/interfaces/Crafter.Debug.
Build.cppm". crafter-build runs a git source's project file from the
root of the clone, and a local path's from the file's own directory, so
tooling/project.cpp's "./" and relative sources named the repository
root. Every test so far loaded it through a local path, where they
happened to be right.
It now spells its path and sources from its own file, which names
tooling/ either way. The notes need nothing: crafter-build reads them
beside the project file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
The consumer notes only said how to drive a running app. They now also
say how to add to what an agent can reach: where the hook points and
registrations go, gating pause and step, registering commands,
watches, samples and checks, and the rules that keep that code right
(handlers run on the app's thread and must not block; Async for
results that take frames; call the app's own code paths instead of
re-implementing them, the lesson from 3DForts' drifting verbs; Group
for per-object state; which types travel).
All of it stays in tooling/AGENTS.consumer.md, which every build
merges through the unconditional pragma. Notes beside the root
project.cpp would only come with debug builds, when the library is in
the graph, and would then duplicate these; AGENTS.template.md now says
so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- README: how the pieces fit, adding Crafter.Debug to a project
(Debug::Use, the shared-args rule, Session and Pump, the AGENTS.md
checklist), the app-side API with examples, the fixed-step and
Crafter.Graphics patterns, a shim module for calls without #ifdefs,
and the agent side: commands, exit codes, stopping apps, attaching
a debugger, version skew.
- AGENTS.template.md: the configurations and partitions, commands,
test conventions (including the dangling Value::Find pointer two
tests hit), style, design rules, security and gotchas.
- tooling/AGENTS.consumer.md: what every consumer's agents read in
each session, kept short: the loop, exit codes and the gotchas,
pointing at `crafter-debug guide` for the rest.
The QUIC transport the README describes lands next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>