Skip to content

Feature request: Explicit workspace integration contract #60

@manuelkiessling

Description

@manuelkiessling

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)

  • Define schema and strict validation for .sitebuilder/project.yaml (versioned).
  • Implement a ProjectContractResolver + ResolvedProjectContract model.
  • Implement “missing contract” and “invalid contract” capability gating + error messaging.

Replace hardcoded assumptions

  • Refactor build/test/quality execution to use ResolvedProjectContract.commands.* instead of hardcoded npm run ....
  • Replace DistFileScanner with a contract-driven build-output scanner (dirs + globs), remove dist constant.
  • Replace default workspace setup steps with contract-driven commands.setup (and/or a contract-defined setup-step provider).

Agent behavior/docs

  • Update agent template generation to be contract-centric (no Node/landingpages assumptions).
  • Feed agent.setupGuidance into agent context on reset/setup lifecycle only.

UI & messaging

  • Update translations/copy to remove “landingpages-only” messaging.
  • Add UI guidance for missing/invalid contract (include minimal YAML example).
  • Document the contract and provide examples for multiple stacks.

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.

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions