Skip to content

Contribution Guide

Luotsi is intended to stay boring to operate and boring to automate. Good contributions keep behavior explicit, validation obvious, and public docs aligned with the shipped workflow.

  • Branch from main for each focused change.
  • Keep commits and pull requests scoped to one behavior or one tightly related slice.
  • Update docs when command behavior, flags, artifacts, or operator UX changes.
  • Update docs/ first when you change maintained prose or reference content.
  • If the public website mirrors that topic, update the matching page under website/src/content/docs/docs/ in the same change.

When a change affects command output, artifacts, replay, or agent-facing behavior, keep the first output handoff obvious for both humans and agents. The core Luotsi loop is:

command -> structured output -> artifact root -> replay command -> next action

Use luotsi help output as the CLI-native source for that model. Normal commands return one JSON envelope, while inspect emits JSONL. After checking ok and the process exit code, command readers should look for data.recommended_next_action_command / data.recommendedNextActionCommand, data.recommended_next_action.command, focused packet evidence such as data.primary_failure.source_command or data.primaryFailure.sourceCommand, packet checklist commands such as data.triage_checklist[].command or data.triageChecklist[].command, ordered handoff arrays such as data.recommended_next_steps, data.next_actions, and data.suggested_commands, then artifacts.artifact_root as the fallback target for luotsi replay packet --artifacts <artifact-root>. Use command arrays such as data.commands, data.artifact_commands, and data.recommended_commands only when there is no artifact root to packetize.

Prefer luotsi replay open --artifacts <artifact-root> --dry-run when a human needs the primary failure, recommended next action, and follow-up commands without launching a browser. Use luotsi artifacts open <artifact-root> only when the generic artifact browser is the specific goal.

Use the pinned .NET SDK from global.json for source builds.

Run the normal safety net from the repository root:

Terminal window
dotnet build .\Luotsi.sln
dotnet test .\Luotsi.sln

If you only touched a narrow slice, run the focused test or command that proves that slice first, then fall back to the broader solution checks before merge.

If you changed the public website, also validate it from website/:

Terminal window
npm run check
npm run build

If you changed the Android helper, validate the helper build from Luotsi.ViewServer.Android:

Terminal window
.\gradlew.bat assembleDebug
  • Preserve the single JSON envelope contract for normal command mode.
  • Preserve JSONL streaming semantics for inspect and view sessions.
  • Prefer host-side orchestration over device-side complexity.
  • Keep Android support adb first unless there is a concrete reason not to.
  • Maintain artifact capture on device-facing failures.
  • Prefer injected fakes in tests over real devices or real adb.

When documentation needs a source of truth, prefer the owning implementation surface instead of copying behavior from stale notes.

  • docs/ for maintained repository prose and reference pages
  • website/src/content/docs/docs/ for the published public mirror of overlapping docs content
  • Luotsi.Cli/Cli/Help.cs for the public CLI command list and flags
  • Luotsi.Cli/Scenarios/ScenarioExecutor.cs and Luotsi.Cli/Scenarios/ScenarioValidator.cs for supported scenario actions and validation rules
  • Luotsi.ViewServer.Android/app/src/main/AndroidManifest.xml plus the helper Kotlin sources for Android helper behavior, permissions, and entry points

Keep Luotsi.Cli.Tests/TutorialDocumentationTests.cs green when you touch docs. It validates repository docs links, website docs links, and the Starlight sidebar slugs.

PRs should explain what changed, how it was validated, and whether the change affected the CLI contract, artifact set, or operator experience. If command output changed, attach representative JSON or artifact examples in the PR description.