Skip to content

feat(module): scaffold local source tree on init#17

Merged
I-am-nothing merged 3 commits into
mainfrom
feat/module-init-scaffold
May 5, 2026
Merged

feat(module): scaffold local source tree on init#17
I-am-nothing merged 3 commits into
mainfrom
feat/module-init-scaffold

Conversation

@I-am-nothing

Copy link
Copy Markdown
Contributor

Summary

  • mirrorstack module init now registers the module on the platform AND scaffolds a local Go source tree from the embedded SDK template
  • Two new flags: --no-scaffold (register only) and --dir <path> (override default ./<slug>/)
  • Pre-flights writability of the scaffold target before any remote POST — never leaves a registered module without a local tree
  • Pins SDK v0.1.0 (cut in chore: add release workflow + cut v0.1.0 app-module-sdk#93) so scaffolded modules resolve via the Go module proxy with no replace directive

After this lands

mirrorstack module init           # → ./<slug>/{main.go, mcp.go, routes.go, go.mod, sql/app/0001_init.up.sql}
cd <slug> && go mod tidy && go build ./...
# next PR: mirrorstack dev (still WSS-less local pg + go run shell)

Why vendor templates instead of fetch from SDK?

Self-contained build — cargo build of the CLI doesn't depend on a sibling SDK checkout being present. Trade-off: when the SDK's examples/template/ changes shape, the vendored copy here must be re-synced manually. Documented in scaffold.rs module doc.

Test plan

  • cargo test — 40 tests pass (10 new for scaffolding)
  • cargo clippy --all-targets -- -D warnings clean
  • End-to-end: scaffold a media module into /tmp, run go mod tidy && go vet && go build — all clean (SDK resolves via Go proxy)
  • Race protection: write_tree refuses to clobber a file that appeared after the empty-dir check (test added)
  • Reviewer: cd ~/Documents/MirrorStack-AI-V2 && ./mirrorstack-cli/mirrorstack module init against local stack, sanity-check scaffolded tree

🤖 Generated with Claude Code

I-am-nothing and others added 3 commits May 4, 2026 17:53
`mirrorstack module init` now does both halves of "create a module":
register on the platform AND scaffold a local Go source tree from the
SDK template. Without this, every developer's first `mirrorstack dev`
(future) would have nothing to launch.

Two new flags:
- --no-scaffold: register only, skip filesystem (CI / re-registration)
- --dir <path>: override default ./<slug>/ (use --dir . for cwd)

The scaffold target's writability is checked before any remote POST so
we never leave a registered module without a local tree because of e.g.
a non-empty target dir. Each file is written via OpenOptions::create_new
so a file slipped in during the API round-trip surfaces as an error
instead of a silent overwrite.

Templates are vendored under templates/module/ and embedded via
include_str!. Source of truth for the shape is app-module-sdk's
examples/template/; vendored copies must be re-synced when the SDK
changes shape (no automatic mirror yet).

go.mod.tmpl pins github.com/mirrorstack-ai/app-module-sdk v0.1.0 — the
SDK's first published tag — so scaffolded modules `go mod tidy` cleanly
from anywhere on disk, no replace directive needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Used by devs as a convenience pointer to target/release/mirrorstack so
they can run ./mirrorstack from the repo root without typing the full
target path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI fmt --check failed on the SQL_INIT include_str! line; rustfmt prefers
the long form on a single line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@I-am-nothing I-am-nothing merged commit 7dad499 into main May 5, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant