Problem
sitebuilder-webapp is already generalized in many areas, but key workflows still assume a specific workspace shape (historically: landingpages-ai-template conventions like dist/ scanning and npm run build/test/quality). This creates implicit coupling, makes non-Node/non-template repos hard to support, and leaves “support” semantics unclear.
We want a strict, structured integration approach that keeps SiteBuilder clean from legacy heuristics, while still enabling projects to become compatible by adapting their own repos/tooling outside SiteBuilder.
Goals
- Explicit integration only: a workspace is “SiteBuilder-integrated” iff it provides a repo-owned contract file.
- Generalize across toolchains: support Node, Python, Ruby, Go/static site generators, etc., by configuring commands + build outputs.
- Strictness: validate configuration with clear, actionable error messages (missing/invalid contract).
- No template heuristics: SiteBuilder must not infer “landingpages” from conventions.
- Optional human guidance: allow free-form setup notes that are injected into the agent during workspace reset/setup.
Non-goals
- Guarantee existing projects “work unchanged”. Instead: they work after owners adapt them to the contract.
- Add long-lived “compatibility modes” or convention-based auto-detection.
- Encode every workflow as executable steps; free-form guidance is allowed, but optional.
Proposal
1) Add a repo-local integration contract file
Introduce a versioned YAML file at workspace root:
- Path:
.sitebuilder/project.yaml
- Purpose: declare what SiteBuilder needs to run setup/build/test/quality and to find previewable outputs.
Contract responsibilities
- Commands: optional, ordered lists of shell commands for
setup/build/test/quality
- Paths: one or more build output directories
- Preview rules: file globs (default: HTML)
- Runner (optional): specify how to run commands (plain shell vs
mise, etc.)
- Agent setup guidance (optional): free-form text injected into agent context during reset/setup
2) Missing/invalid contract behavior (strict)
If .sitebuilder/project.yaml is missing:
- Do not guess project type.
- Allow safe functionality (browse/edit files, etc.), but disable build/test/quality and preview listing.
- Return actionable errors in the UI/API (with a minimal contract example and link to docs).
If .sitebuilder/project.yaml exists but is invalid:
- Treat as not integrated for the affected capabilities.
- Show validation errors (field paths + explanation).
YAML schema (directional)
version: 1
runner:
type: shell # or: mise
# options: {} # optional; e.g. workingDir behavior, env, etc.
paths:
buildDirs:
- dist
preview:
fileGlobs:
- "**/*.html"
commands:
setup:
- "mise trust"
- "mise exec -- npm install --no-save"
build:
- "mise exec -- npm run build"
test:
- "mise exec -- npm test"
quality:
- "mise exec -- npm run quality"
agent:
setupGuidance: |
## Setup notes (optional)
- Add required env vars in `.env` (see README).
- If build fails with X, run Y and retry.
- After setup, verify by opening `dist/index.html`.
Notes:
commands.* are optional; if absent, SiteBuilder should clearly state “capability not configured”.
preview.fileGlobs should default to ["**/*.html"] if omitted.
paths.buildDirs should be required for preview listing; if absent, preview listing is disabled.
Runtime behavior changes (high level)
Contract resolution
- Load and validate
.sitebuilder/project.yaml per workspace (per request).
- Provide a
ResolvedProjectContract to services that currently use hardcoded assumptions.
Command execution (build/test/quality/setup)
Replace hardcoded npm run ... usage with:
- Execute
commands.quality[] / commands.test[] / commands.build[] from the contract.
- For setup/reset: execute
commands.setup[] (if configured).
- Respect
runner.type:
shell: run the command as-is in the workspace
mise: either wrap commands or allow contract to already include mise exec -- ... (decision needed during implementation)
Build output scanning / preview listing
Replace dist/-specific scanning with:
- For each
paths.buildDirs[], scan for files matching preview.fileGlobs[]
- For each matched file, create preview link via existing
/workspaces/{id}/{relativePath} mechanism
Agent injection: setup guidance
During workspace reset/setup only:
- Append
agent.setupGuidance to the agent’s context/prompt for that lifecycle event
- Do not inject it into every normal editing session unless explicitly desired
Implementation checklist
Backend (core)
Replace hardcoded assumptions
Agent behavior/docs
UI & messaging
Acceptance criteria
- No heuristics: no landingpages auto-detection or convention-based fallback in runtime behavior.
- Contract-driven: build/test/quality/preview listing use only the contract values.
- Strict errors:
- Missing contract => capabilities disabled + clear instructions
- Invalid contract => validation errors shown + capabilities disabled
- Multi-toolchain: at least one non-Node example contract works end-to-end (setup/build + preview listing).
- Setup guidance: free-form
agent.setupGuidance is injected into the agent only during reset/setup.
Problem
sitebuilder-webappis already generalized in many areas, but key workflows still assume a specific workspace shape (historically:landingpages-ai-templateconventions likedist/scanning andnpm run build/test/quality). This creates implicit coupling, makes non-Node/non-template repos hard to support, and leaves “support” semantics unclear.We want a strict, structured integration approach that keeps SiteBuilder clean from legacy heuristics, while still enabling projects to become compatible by adapting their own repos/tooling outside SiteBuilder.
Goals
Non-goals
Proposal
1) Add a repo-local integration contract file
Introduce a versioned YAML file at workspace root:
.sitebuilder/project.yamlContract responsibilities
setup/build/test/qualitymise, etc.)2) Missing/invalid contract behavior (strict)
If
.sitebuilder/project.yamlis missing:If
.sitebuilder/project.yamlexists but is invalid:YAML schema (directional)
Notes:
commands.*are optional; if absent, SiteBuilder should clearly state “capability not configured”.preview.fileGlobsshould default to["**/*.html"]if omitted.paths.buildDirsshould be required for preview listing; if absent, preview listing is disabled.Runtime behavior changes (high level)
Contract resolution
.sitebuilder/project.yamlper workspace (per request).ResolvedProjectContractto services that currently use hardcoded assumptions.Command execution (build/test/quality/setup)
Replace hardcoded
npm run ...usage with:commands.quality[]/commands.test[]/commands.build[]from the contract.commands.setup[](if configured).runner.type:shell: run the command as-is in the workspacemise: either wrap commands or allow contract to already includemise exec -- ...(decision needed during implementation)Build output scanning / preview listing
Replace
dist/-specific scanning with:paths.buildDirs[], scan for files matchingpreview.fileGlobs[]/workspaces/{id}/{relativePath}mechanismAgent injection: setup guidance
During workspace reset/setup only:
agent.setupGuidanceto the agent’s context/prompt for that lifecycle eventImplementation checklist
Backend (core)
.sitebuilder/project.yaml(versioned).ProjectContractResolver+ResolvedProjectContractmodel.Replace hardcoded assumptions
ResolvedProjectContract.commands.*instead of hardcodednpm run ....DistFileScannerwith a contract-driven build-output scanner (dirs + globs), removedistconstant.commands.setup(and/or a contract-defined setup-step provider).Agent behavior/docs
agent.setupGuidanceinto agent context on reset/setup lifecycle only.UI & messaging
Acceptance criteria
agent.setupGuidanceis injected into the agent only during reset/setup.