diff --git a/docs/.vitepress/theme/components/LighthouseProductView.vue b/docs/.vitepress/theme/components/LighthouseProductView.vue new file mode 100644 index 0000000..bc06eea --- /dev/null +++ b/docs/.vitepress/theme/components/LighthouseProductView.vue @@ -0,0 +1,108 @@ + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index f500244..fdaa91b 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -7358,3 +7358,15 @@ html:not(.dark) .gf-blog-visual { --gf-ink: #FFFFFF; --gf-ink-2: #A9A1B3; } +/* Atlas uses its source-owned product banner while the framework guide remains the preferred user path. */ +.vp-doc .gf-atlas-banner { + margin: 1.5rem 0 1.75rem; +} + +.vp-doc .gf-atlas-banner img { + display: block; + width: 100%; + border: 1px solid var(--vp-c-divider); + border-radius: 16px; + box-shadow: 0 18px 48px rgb(0 0 0 / 18%); +} diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index f18d53b..cab8aaf 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -8,6 +8,7 @@ import StarterKitOptions from './components/StarterKitOptions.vue' import SitePreview from './components/SitePreview.vue' import CodeFile from './components/CodeFile.vue' import MakeCommandTabs from './components/MakeCommandTabs.vue' +import LighthouseProductView from './components/LighthouseProductView.vue' import './custom.css' /* The hero is imported STATICALLY on purpose. As an async component it @@ -683,6 +684,7 @@ export default { ctx.app.component('GoForjLiveTerminal', GoForjLiveTerminal) ctx.app.component('CodeFile', CodeFile) ctx.app.component('MakeCommandTabs', MakeCommandTabs) + ctx.app.component('LighthouseProductView', LighthouseProductView) }, Layout: () => { const { theme } = useData() diff --git a/docs/developer-tools/atlas.md b/docs/developer-tools/atlas.md index e935e87..5af1f30 100644 --- a/docs/developer-tools/atlas.md +++ b/docs/developer-tools/atlas.md @@ -7,8 +7,14 @@ description: Agent support for GoForj projects, including local guidance, skills Atlas gives AI coding agents enough local project context to work inside a GoForj App without guessing at framework conventions. +

GoForj Atlas — a map for your coding agent

+ It is optional, but first-class. During `forj new`, the `Atlas - Agent Support` step can install agent guidance for the tools you use. Atlas can also be added later from an existing project. +If you are building a GoForj Project, use this guide and the `forj atlas:*` commands. That CLI path installs the right project files and runs Atlas without requiring a separate Atlas binary. Use the [standalone Atlas library reference](/atlas) only when embedding Atlas in another Go program or contributing to its Go module. + +Atlas starts with read-only project inspection. GoForj make commands remain the write path for framework scaffolding, so agent context does not become an arbitrary shell or file-mutation API. + ## Install and Verify During project creation, run the wizard: @@ -35,7 +41,7 @@ forj atlas:install --dry-run forj atlas:update --dry-run ``` -## What Atlas adds +## What Atlas Adds Atlas installs lightweight project files that teach agents the GoForj way to build: @@ -47,7 +53,14 @@ Atlas installs lightweight project files that teach agents the GoForj way to bui The goal is not to make agents louder. The goal is to make them less surprising. -## Project-owned skills +| Layer | What It Gives the Agent | +| --- | --- | +| Guidance | Project-wide GoForj conventions in the agent's native instruction file. | +| Skills | Focused workflows selected for the Project's components, Apps, and starter kit. | +| MCP context | Read-only project layout, ownership, docs, routes, resources, runtime evidence, and validation plans. | +| Project skills | Team-specific rules under `.ai/skills` that Atlas synchronizes into each selected agent's native format. | + +## Project-Owned Skills Atlas ships with built-in GoForj skills, but your project can add its own. @@ -113,7 +126,7 @@ Choose individual agents and surfaces when you want a smaller or more explicit i forj atlas:install --agent codex --agent copilot --agent gemini --guidelines --skills --mcp ``` -## Supported agents +## Supported Agents Atlas is designed around local project files and editor-readable instructions, so the same project can support multiple agents: @@ -133,7 +146,7 @@ Atlas writes each agent's native project files: | GitHub Copilot | `.github/copilot-instructions.md` | `.github/instructions/*.instructions.md` | `.vscode/mcp.json` | | Gemini CLI | `GEMINI.md` | `.gemini/skills/*/GEMINI.md` | `.gemini/settings.json` | -## MCP context +## MCP Context Atlas can expose GoForj context through an MCP server. The MCP server loads docs and project metadata locally, then serves focused slices of context to the agent. @@ -163,7 +176,7 @@ Atlas reports the active docs version and revision through `application-info` an Use `version-alignment` when an agent needs to compare the project GoForj version, Atlas version, and active docs bundle before following docs from a branch or release. -## Workflow skills +## Workflow Skills Atlas installs workflow skills for high-leverage GoForj changes. They are short, task-focused guides that tell an agent which app owns the change, which `forj make:*` command to prefer, which generated files not to edit by hand, which docs sections to read, and which validation commands prove the work. @@ -182,7 +195,9 @@ Built-in workflow skills cover: Atlas also includes starter-kit overlays for Vue, React, and templ/htmx projects. When a frontend task touches pages, screens, dashboards, login, auth, or UI behavior, the workflow plan can point the agent at the matching starter-kit skill so edits stay in the owning app's frontend tree. -## Agent workflow examples +Skills are entry points into verified workflows, not a second copy of the documentation. They direct the agent to bounded docs sections, current project evidence, file-ownership policy, and validation appropriate to the task. + +## Agent Workflow Examples Agents should use Atlas tools together instead of reading the whole docs site or guessing from filenames. @@ -238,13 +253,15 @@ browser-logs app="app" limit=50 That gives the agent app/runtime identity, local URLs, recent logs, metrics labels, browser errors, and known operator resources before code changes begin. +The runtime evidence tools do not require the Lighthouse browser UI to be open. When Lighthouse-backed local evidence exists, Atlas can include its links or records; when logs, browser entries, routes, URLs, or metrics targets are absent, it reports the missing evidence instead of inventing it. + For human-readable versions of common evidence loops, see [Atlas Debug Recipes](/developer-tools/atlas-debug-recipes). `runtime-snapshot` and `debug-plan` are evidence tools. They report missing logs, URLs, routes, browser entries, metrics targets, or resource links instead of inventing values. `generated-file-policy` reports classification, preferred action, and ownership for generated files, app-owned files, app-specific files, migrations, frontend files, config, docs, and unknown paths. Projects can override ownership rules in `.goforj/atlas.json`. -## Daily use +## Daily Use Most users do not need to run Atlas commands every day. Once installed, your agent reads the local guidance files and, when configured, asks the MCP server for focused docs context. diff --git a/docs/developer-tools/forj-dev.md b/docs/developer-tools/forj-dev.md index ffbc3d3..41e6006 100644 --- a/docs/developer-tools/forj-dev.md +++ b/docs/developer-tools/forj-dev.md @@ -24,6 +24,10 @@ flowchart LR In a GoForj Project, this can bring up local dependencies, prepare the database, build the frontend, compile the App, start its Runtime, and watch the files that feed each step. You do not need to keep separate build, frontend, and server commands synchronized in different terminals. +::: warning Development only +`forj dev` is a local development supervisor. Do not run it as a production process manager or deploy its watcher lifecycle. Production supervisors should execute the built artifact, such as `./bin/app`, `./bin/app api`, `./bin/app worker`, or `./bin/app scheduler`. +::: + When a file changes, `forj dev` reruns only the affected work. It replaces the running App after a successful build. If the build fails, the last working Runtime stays up while the error remains visible in the transcript. Fix the error, save again, and the loop continues. ## Start the Development Loop @@ -237,7 +241,16 @@ dev: down_on_exit: true ``` -Startup first runs configured App bootstrap builds so pre-tasks can call built App commands. It then runs `dev.pre`, performs configured database setup and auto-migration, and runs any generated tasks deliberately ordered after migration. Finally, it builds App-owned SPAs, rebuilds their Apps, and starts persistent watcher and runtime processes. +For a modern `dev.apps` configuration whose setup tasks match GoForj's generated conventions, startup follows this order: + +1. Run conventional setup tasks that do not require an App binary, such as starting Docker Compose and waiting for its database. +2. Build each App-owned SPA. +3. Build the participating Apps once. +4. Prepare configured development databases and run auto-migration. +5. Run generated tasks that must follow migration, then rebuild when those tasks changed generated source. +6. Start the persistent watchers and App runtime processes. + +This ordering gives the migration step a current App binary while ensuring that embedded frontend assets are already present in that binary. If custom or legacy `dev.pre` tasks do not match the generated setup phases, GoForj preserves their historical ordering and may perform an earlier bootstrap build plus a post-setup rebuild. Keep binary-dependent custom setup explicit instead of relying on a generated task name to change its phase. For npm-backed starter kits, new Projects generate this dependency setup task: diff --git a/docs/developer-tools/wiring-recipes.md b/docs/developer-tools/wiring-recipes.md index fbf8d8f..696a9e6 100644 --- a/docs/developer-tools/wiring-recipes.md +++ b/docs/developer-tools/wiring-recipes.md @@ -27,6 +27,8 @@ For an additional app, replace `app/...` with the owning app's `app//...`. Use the most specific generated set that owns the surface. If a generated file is not present, the app probably does not have that component enabled. +The `inject_*_app.go` files are App-owned extension points. GoForj creates them with the App and make commands can update them, but normal Project regeneration preserves your edits. In contrast, `app/wire/app.go` and `app/wire/wire_gen.go` are framework-generated output and should not be edited. + ## Generated Resources When a resource has a make command, use it before editing provider sets by hand. The command creates the resource and updates the active App's generated wiring boundaries. @@ -75,6 +77,23 @@ The [controller verification workflow](/applications/controllers#verify-the-resu The controller can depend on an application service already provided by the app service set. If Wire cannot provide that service, add the service constructor to `app/wire/inject_services_app.go`. +The controller injector uses its own set rather than `appSet`: + + +```go +package wire + +import ( + "github.com/goforj/wire" + + "myapp/internal/users" +) + +var appHttpControllerSet = wire.NewSet( + users.NewController, +) +``` + Verify the result: ```bash @@ -88,7 +107,25 @@ The [command creation workflow](/applications/commands#create-a-command) shows t Command constructors should receive application services as parameters. They should not create repositories, managers, clients, or services themselves. -Commands also need to be exposed through the generated command collection. See [Commands](/applications/commands) for the command-specific registration path. +Commands need both an App-owned provider and an App-owned CLI field. `forj make:command` updates both locations. For a manually written command, edit both files: + + +```go +// app/wire/inject_cmd_app.go +var appCommandSet = wire.NewSet( + reports.NewReconcileCmd, +) +``` + + +```go +// app/commands.go +type Commands struct { + ReconcileCmd reports.ReconcileCmd `cmd:""` +} +``` + +The existing `NewCommands` constructor in `app/commands.go` must also accept the injected pointer and copy it into the collection. See [Commands](/applications/commands) for the complete registration path. ## Named Resource @@ -132,6 +169,7 @@ forj build ::: warning Common mistakes - Do not add constructors to `app/wire/wire_gen.go`; it is generated output. +- Do not edit `app/wire/app.go`; it is Framework-managed App assembly. - Do not register a controller in the service set when it belongs in the HTTP controller set. - Do not create dependencies inside commands or controllers when they should be constructor parameters. - Do not use package globals to avoid wiring a provider. diff --git a/docs/operations/lighthouse.md b/docs/operations/lighthouse.md index a9e4004..3d0c6b2 100644 --- a/docs/operations/lighthouse.md +++ b/docs/operations/lighthouse.md @@ -9,6 +9,12 @@ Lighthouse is GoForj's UI for inspecting running applications during development It brings inspects, logs, routes, schedules, queue state, cache, storage, and metrics-backed views into one operator workspace. + + +Instead of reconstructing a failure from several terminals, select the app and Runtime that produced it, follow its recent execution timeline, and move directly to the registered route, queue, schedule, cache, or storage resource involved. The workspace follows the components compiled into each App, so a focused worker and a full web app do not pretend to expose the same controls. + +Use Lighthouse when you need the fast, connected view. Keep logs, metrics, health checks, and Inspects independently useful so production diagnosis never depends on one UI. + ## Role Lighthouse should present already-useful operational data. @@ -90,6 +96,12 @@ Queue actions depend on the selected queue backend. The queue contract defines a Treat operator actions as production changes. Before retrying or deleting queue work, identify the app, process, queue, job, and driver capability; use application logs, metrics, and inspects to establish impact. A control that returns unsupported is a driver capability limit, not an empty queue. +## Browser Benchmarks + +Lighthouse includes a browser workflow for controlled HTTP, cache, queue, storage, and database comparisons. It discovers only the suites and configured resource instances available to the selected App, then reports throughput, latency percentiles, errors, driver details, and the system baseline together. + +Benchmarks create real load and can leave data behind after interruption or backend failure. Read [Performance Benchmarks](/operations/performance-benchmarks) before choosing a target, changing concurrency, or using results for a capacity decision. + ## Operational Workflow Use Lighthouse after the underlying signal has identified a problem: @@ -118,10 +130,12 @@ This order keeps Lighthouse a useful operator view without turning it into the o - Every replica has an unambiguous app, process role, and instance identity. - Connection and authentication warnings are collected with application logs. - A Lighthouse outage has a documented fallback using direct health, logs, metrics, and app commands. +- Browser benchmark access is limited to operators, and production runs require a reviewed target and load budget. ## Next Steps - [Inspects](/operations/inspects) - [Metrics](/operations/metrics) +- [Performance Benchmarks](/operations/performance-benchmarks) - [Environment Reference](/reference/env-vars#lighthouse-and-inspects) -- [Generated Extension Points](/core/code-generation#choose-a-safe-extension-point) +- [App Extension Points](/core/code-generation#choose-a-safe-extension-point) diff --git a/docs/public/design-system.css b/docs/public/design-system.css index f500244..fdaa91b 100644 --- a/docs/public/design-system.css +++ b/docs/public/design-system.css @@ -7358,3 +7358,15 @@ html:not(.dark) .gf-blog-visual { --gf-ink: #FFFFFF; --gf-ink-2: #A9A1B3; } +/* Atlas uses its source-owned product banner while the framework guide remains the preferred user path. */ +.vp-doc .gf-atlas-banner { + margin: 1.5rem 0 1.75rem; +} + +.vp-doc .gf-atlas-banner img { + display: block; + width: 100%; + border: 1px solid var(--vp-c-divider); + border-radius: 16px; + box-shadow: 0 18px 48px rgb(0 0 0 / 18%); +}