SmolForge
Forge papercuts from a SolidStart deploy attempt · tim Gist
Forge papercuts from a SolidStart deploy attempt
forge-papercuts.md
# Forge papercuts — SolidStart deploy attempt
Context: fresh SolidStart 2.0 app in `tim/forge-tester`, trying to get Forge Deploy running end to end. Ordered roughly by impact. One item is marked as inference rather than confirmed.
## Blocking
**1. `Enable` on a Deploy project fails with no reason.**
Creating a project succeeds but lands in `state: "disabled"`. Clicking Enable returns only *"Deploy project eligibility checks did not pass"*. The API gives `state_reason: null`, and `sf deploy status` adds nothing. There's no way to find out what check failed or what to do about it.
*Inference, not confirmed:* the Release Operations panel separately reads "No approved provider target", so this may be an account-level provider approval. Nothing in the UI connects those two messages.
**2. `sf deploy check` says "Valid" for a config that cannot possibly deploy.**
It validates the file in isolation, with no awareness that the repo has no Deploy project or that the account isn't eligible. A "valid manifest, but no enabled project for this repo" warning would have saved the entire detour.
```
$ pnpm exec sf deploy check
Valid forgeBuild.ts (Forge config v1; http,state,realtime).
```
**3. Committing `forgeBuild.ts` isn't sufficient, and nothing says so.**
The manifest docs read as though the file is the activation step. You also need a project created *and* enabled via Sites. Worth one sentence at the top of the manifest page.
## Docs are unreadable to agents
**4. `/docs/*` and `/spec/` are client-rendered.**
```
$ curl -s https://forge.smol.ai/docs/deploy/manifest-v1 | tail -3
<div id="root"></div>
</body>
</html>
```
2.9 KB shell, no content. Reading the spec required driving a real Chrome session. For a platform built for "AI-native workflows", the docs are the one thing agents can't fetch.
**5. `.md` suffix returns the SPA shell with HTTP 200.**
`/docs/deploy/manifest-v1.md` doesn't 404 — it silently serves HTML, so a fetcher can't detect the failure. The rendered page has a "Copy Markdown" / "Source" affordance, so the markdown exists; it just has no addressable URL.
**6. `app.entrypoint` semantics are ambiguous for framework builds.**
The spec describes it as "JavaScript or TypeScript source bundled by Forge's pinned compiler." For any framework with its own bundler (SolidStart/Nitro, SvelteKit, etc.) the natural entrypoint is an *already-bundled* output file. Whether Forge accepts that is still unknown. An example using a framework build output would settle it.
## CLI
**7. `--help` on a subcommand is ignored and the command runs anyway.**
`sf deploy check --help` executed the check instead of printing usage.
**8. Docs say `sf auth login`, but `sf` isn't on PATH.**
`@smolai/forge` installs as a devDependency, so the bin is local — it's `pnpm exec sf` / `npx smolforge`. The docs' bare `sf ...` invocations fail with `command not found` for anyone following them literally.
**9. No pull request commands in the CLI.**
For a "Forge CLI for coding agents," there's no `sf pr create` / `list` / `view`. PR creation is browser-only, which is the one thing an agent handles worst.
**10. `default_head_sha` is `null`** in `sf deploy list` → `release_status`, even though `main` has commits and pushes succeeded.
## Web UI
**11. The PR diff renders a 2-line insertion as +22 / −20.**
`git show` confirms `1 file changed, 2 insertions(+)`, LF endings unchanged, but the PR view shows the whole file replaced. Makes small PRs unreviewable.
**12. PR preview status surfaces a raw `Request failed (404)`.**
When no Deploy project exists, the PR page shows "Preview status unavailable — Request failed (404)" rather than "Deploy isn't configured for this repository."
**13. The Enable button silently no-ops right after project creation.**
The edit form collapses on create, so a click lands on a re-rendered element and does nothing — no error, no state change. You have to reopen via Edit and click again to get the real eligibility error.
**14. `/owner/repo/compare/main...branch` renders blank.**
The GitHub-compatible compare URL isn't supported (the real path is `/pulls/new`), and it fails as an empty page rather than a redirect or 404. Nice-to-have, not a bug — Forge never claimed that URL shape.
## Not a Forge issue, but worth a docs note
The build initially targeted the wrong runtime because Nitro defaults to the `node-server` preset, which emits a Node HTTP server rather than a Worker module. That's a SolidStart/Nitro default, not a Forge problem — but a docs line saying "your entrypoint must be Workers-compatible" would have caught it before a deploy attempt. The fix was `nitro({ preset: "cloudflare_module" })` in `vite.config.ts`, which emits to the same path so the manifest was unaffected.
## The manifest, for reference
Validates clean; never got to build.
```ts
import { defineForge } from '@smolai/forge/config';
export default defineForge({
version: 1,
name: 'forge-tester',
build: { command: 'pnpm build', workingDirectory: '.' },
app: { entrypoint: '.output/server/index.mjs' },
routes: [{ pattern: '/*', to: 'app.http' }],
});
```
Versions: `@smolai/forge` 0.4.0-preview.0, `@solidjs/start` 2.0.0, nitro 3.0.260610-beta, vite 8.1.4, pnpm 10.33.0.