You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gapp init is drifting toward a dumping ground for every possible
gapp.yaml configuration option. It already accepts entrypoint, mcp_path, auth, runtime, secrets, and domain as keyword
arguments, and there is steady pressure to add more. This creates
several problems:
Conflated responsibilities.gapp init today does three
different things: (a) bootstrap gapp.yaml, (b) add a gapp-solution topic to the GitHub repo, and (c) register the
solution path in ~/.config/gapp/solutions.yaml. Stuffing
per-field configuration into the same command blurs whether it
is a one-time project-setup step or an ongoing configuration
editor.
MCP-specific defaults in a cloud-agnostic tool.init
currently seeds a manifest with service.entrypoint: PACKAGE.mcp.server:mcp_app — an assumption that the app is an
MCP server using a specific module layout. gapp does not (and
should not) know that the target is an MCP server.
No structured editing surface. Users who want to change one
field — add an env var, declare a secret, set a domain — either
rerun init with a growing pile of flags or hand-edit the yaml.
Hand-editing is exactly what schema validation is supposed to
make unnecessary; rerunning init pretends the command is
idempotent configuration rather than one-time setup.
Name is a special case that leaks out. See the companion
issue on solution-name resolution strategy — the name is
effectively bootstrap-only (locked after init because labels,
buckets, and discovery state are name-scoped), and the current
yaml freely allows editing it, risking silent breakage.
Desired direction (no prescription — exploration)
Keep gapp init narrow and introduce a dedicated gapp manifest
command group for structured editing. The exact split is open; this
issue is the place to decide.
Possible taxonomy
gapp init — bootstrap only. Creates a minimal gapp.yaml,
applies the GitHub topic, registers in solutions.yaml. Does not take per-field flags. Requires the bare minimum needed
for any deployable app (not assuming MCP, not assuming a
particular framework). On success, prints a suggestion list
pointing at manifest subcommands for further configuration.
gapp manifest schema — already implemented.
gapp manifest verify — already implemented.
gapp manifest init — scaffold yaml only (no GitHub topic, no
registration). Useful for repos that are already initialized
but want a fresh or extended yaml.
gapp manifest env add|list|remove — structured env var
editing. Fields map to EnvEntry in the schema. Supports both
plain values and secret references.
gapp manifest secrets add|list|remove — prerequisites secrets
editing (note: plural — secrets, not secret, for
consistency with list semantics; existing singular gapp secret * / gapp_secret_* surface would migrate).
gapp manifest set <key>=<value> — or per-field subcommands
(gapp manifest set domain ..., gapp manifest set public ...)
— for the simple scalar fields.
Interactive vs non-interactive: open question. Should gapp manifest env add with no flags drop into an interactive
prompt? Or fail and require flags? Or interactive by default
with --non-interactive to require flags?
Open design questions
Decide these explicitly before implementing:
Does gapp init stay as the one-shot entry point or get
decomposed? If decomposed, what replaces it? If kept, what
exactly goes in it vs in the manifest group?
Should gapp init be an alias for gapp manifest init plus
the two project-registration side-effects? Only if those
side-effects really are optional in some flows.
What fields are MCP-specific vs generic? Anything MCP-aware
should go to a separate plugin/profile, not be gapp's default.
Naming convention across commands and tools. Plural for
collections (secrets, envs?), singular for scalars
(domain, public). Decide and apply uniformly across CLI
and MCP tool names.
Interactive vs non-interactive defaults.
Migration of existing gapp secret * / gapp_secret_*
commands for consistency with the new plural form.
Current state (for context)
Schema single-source-of-truth is established in gapp/admin/sdk/schema.py (see Formal schema validation for gapp.yaml (fail fast with clear errors) #26). Every manifest operation
can derive valid field names, types, and descriptions from the
Pydantic model. The CLI can introspect the schema at runtime
(via Manifest.model_fields and its submodels) — structured
editing commands should use this so they never drift from the
schema.
gapp manifest schema and gapp manifest verify subcommands
exist and are plumbed through CLI + MCP + SDK with uniform JSON
error delivery.
gapp init still has the MCP-specific default service.entrypoint: PACKAGE.mcp.server:mcp_app baked in —
explicit candidate for removal.
Non-goals for this issue
Implementation. This issue is the design conversation. A
subsequent PR/issue does the work once the taxonomy is agreed.
Renaming support. See the companion issue on name resolution.
Work breakdown
Decide the command taxonomy above.
Decide the interactive/non-interactive posture.
Decide what (if any) MCP-specific defaults stay in gapp init.
Decide plural vs singular naming convention and apply it
uniformly across all CLI commands and MCP tools.
Implement decided commands. Ensure each field-editing
subcommand derives its accepted fields and types from the
Pydantic schema models in gapp/admin/sdk/schema.py — no
re-declaration of field lists anywhere (the single-source-of-
truth rule in CONTRIBUTING.md).
Add tests covering: scaffold correctness, idempotency, and
that every schema field has a structured CLI path (so adding
a field automatically gets a command, or clearly doesn't).
Update CONTRIBUTING.md with the chosen taxonomy and the
rationale behind it.
Update README.md to show the new editing surface and
remove any suggestion to hand-edit gapp.yaml.
Update SKILL docs (skills/deploy/SKILL.md, skills/secrets/SKILL.md) to prefer manifest subcommands
over yaml hand-edits.
Problem
gapp initis drifting toward a dumping ground for every possiblegapp.yaml configuration option. It already accepts
entrypoint,mcp_path,auth,runtime,secrets, anddomainas keywordarguments, and there is steady pressure to add more. This creates
several problems:
gapp inittoday does threedifferent things: (a) bootstrap
gapp.yaml, (b) add agapp-solutiontopic to the GitHub repo, and (c) register thesolution path in
~/.config/gapp/solutions.yaml. Stuffingper-field configuration into the same command blurs whether it
is a one-time project-setup step or an ongoing configuration
editor.
initcurrently seeds a manifest with
service.entrypoint: PACKAGE.mcp.server:mcp_app— an assumption that the app is anMCP server using a specific module layout. gapp does not (and
should not) know that the target is an MCP server.
field — add an env var, declare a secret, set a domain — either
rerun
initwith a growing pile of flags or hand-edit the yaml.Hand-editing is exactly what schema validation is supposed to
make unnecessary; rerunning
initpretends the command isidempotent configuration rather than one-time setup.
issue on solution-name resolution strategy — the name is
effectively bootstrap-only (locked after init because labels,
buckets, and discovery state are name-scoped), and the current
yaml freely allows editing it, risking silent breakage.
Desired direction (no prescription — exploration)
Keep
gapp initnarrow and introduce a dedicatedgapp manifestcommand group for structured editing. The exact split is open; this
issue is the place to decide.
Possible taxonomy
gapp init— bootstrap only. Creates a minimalgapp.yaml,applies the GitHub topic, registers in
solutions.yaml. Doesnot take per-field flags. Requires the bare minimum needed
for any deployable app (not assuming MCP, not assuming a
particular framework). On success, prints a suggestion list
pointing at manifest subcommands for further configuration.
gapp manifest schema— already implemented.gapp manifest verify— already implemented.gapp manifest init— scaffold yaml only (no GitHub topic, noregistration). Useful for repos that are already initialized
but want a fresh or extended yaml.
gapp manifest env add|list|remove— structured env varediting. Fields map to
EnvEntryin the schema. Supports bothplain values and secret references.
gapp manifest secrets add|list|remove— prerequisites secretsediting (note: plural —
secrets, notsecret, forconsistency with list semantics; existing singular
gapp secret */gapp_secret_*surface would migrate).gapp manifest set <key>=<value>— or per-field subcommands(
gapp manifest set domain ...,gapp manifest set public ...)— for the simple scalar fields.
gapp manifest env addwith no flags drop into an interactiveprompt? Or fail and require flags? Or interactive by default
with
--non-interactiveto require flags?Open design questions
Decide these explicitly before implementing:
gapp initstay as the one-shot entry point or getdecomposed? If decomposed, what replaces it? If kept, what
exactly goes in it vs in the manifest group?
gapp initbe an alias forgapp manifest initplusthe two project-registration side-effects? Only if those
side-effects really are optional in some flows.
should go to a separate plugin/profile, not be gapp's default.
collections (
secrets,envs?), singular for scalars(
domain,public). Decide and apply uniformly across CLIand MCP tool names.
gapp secret */gapp_secret_*commands for consistency with the new plural form.
Current state (for context)
gapp/admin/sdk/schema.py(see Formal schema validation for gapp.yaml (fail fast with clear errors) #26). Every manifest operationcan derive valid field names, types, and descriptions from the
Pydantic model. The CLI can introspect the schema at runtime
(via
Manifest.model_fieldsand its submodels) — structuredediting commands should use this so they never drift from the
schema.
gapp manifest schemaandgapp manifest verifysubcommandsexist and are plumbed through CLI + MCP + SDK with uniform JSON
error delivery.
gapp initstill has the MCP-specific defaultservice.entrypoint: PACKAGE.mcp.server:mcp_appbaked in —explicit candidate for removal.
Non-goals for this issue
subsequent PR/issue does the work once the taxonomy is agreed.
Work breakdown
gapp init.uniformly across all CLI commands and MCP tools.
subcommand derives its accepted fields and types from the
Pydantic schema models in
gapp/admin/sdk/schema.py— nore-declaration of field lists anywhere (the single-source-of-
truth rule in CONTRIBUTING.md).
that every schema field has a structured CLI path (so adding
a field automatically gets a command, or clearly doesn't).
CONTRIBUTING.mdwith the chosen taxonomy and therationale behind it.
README.mdto show the new editing surface andremove any suggestion to hand-edit
gapp.yaml.skills/deploy/SKILL.md,skills/secrets/SKILL.md) to prefer manifest subcommandsover yaml hand-edits.