Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
syntaqxAgents in any harness coordinate through one inbox, the merge queue lands only what an attempt itself tested, and workspaces have Insights. Each session keeps the coordination updates that concern it (session_updates, migration 0038): claims, releases, hand-offs and expiries, overlaps, dependency changes, decisions, integration results and sessions starting and ending, about the issues and pull requests it is on or tied to, or every one while it is on nothing yet; never its own start, end or claims. An update is written in the same batch as the change it announces, guarded so it exists only once the change is made, with an id derived from the change, so a retry or two requests at once deliver it once; a blocker clearing and queue results follow their change under a key that names it. get_session's `updates` lists up to 100, oldest first, and reading never clears them; record_session_entries' `acknowledge` clears exact IDs for that session only and says how many were its (`acknowledged`). The CLI has `g1t session updates` and `g1t session acknowledge ID --note` (the decision note and the acknowledgement in one idempotent call, `--session` over G1T_SESSION), and those and `heartbeat` say which files the working copy changed (git status; G1T_TOUCH=0 turns it off), so overlapping edits are noticed whichever harness makes them; a pair of sessions is told again when another file in common joins. The Claude Code hooks fetch the inbox in the background, show it at every prompt and before tools when it changes or every two minutes, refresh after an acknowledgement, and never acknowledge. The AGENTS.md snippet, the skills, MCP's instructions and llms.txt say the same steps for every harness: scope claims (Scope, Interfaces, Depends on, Checks), proceed on complementary work, agree ownership before overlapping edits, record public summaries and evidence, never private reasoning. Claims resolve ownership in one statement, so simultaneous claims by one session converge. The merge queue: every attempt has its own id and branch (0037); a claimed build, an accepted build, a report and a callback each check their attempt; a dispatch registers its runs first and Actions fails the dispatch when it cannot; an attempt is decided only by its own runs (and other tools' statuses set after it was claimed), never an earlier attempt's or the pull request's own on the same commit (0040 keeps what it built and how many runs it registered); landing re-reads the rules, honours a bypass asked for when queued (0039), checks no predecessor remains, carries the exact tested commit to Git's compare-and-swap, records publication intent that fences removal, closing, drafting and changing base, resumes after a crash, and a publisher that lost a race no longer undoes the winner's landing; a retried attempt's branch is deleted; an entry whose branch or pull request is gone leaves the queue with a note instead of blocking those behind it; diagnosis rebuilds exactly what was tested and names a failing combination, not a proven cause. A session's page shows what awaits its agent as the coordination feed does. Workspace Insights (/:owner/-/insights): delivery metrics across a workspace's readable repositories (work service delivery_insights). Deploy Work migrations 0037 to 0040 first (the pipeline does), then Repos and Actions before Work, and the site with Work. Checked: cargo test for g1t-work (143), g1t-repos (311), g1t-actions-service (108), g1t-api (201), g1t (149), g1t-rules (72), g1t-contracts (306) and wasm32 builds; cargo check --workspace; the conformance suite against freshly built API and Work Workers (5, none skipped); the Claude Code hooks (49); the site's typecheck, tests (919) and a production build; the deploy tool's 92 tests; the docs build; and two unscripted local rehearsals in which two concurrent agents, given only a task and AGENTS.md, found each other, agreed a split and made complementary edits.

README.md

g1t/detect

Says what a g1t.page build of the checkout would find, without building or deploying anything: the same rules g1t/deploy builds with.

steps:
  - uses: actions/checkout@v5
  - id: detect
    uses: g1t/detect@v1
  - if: steps.detect.outputs.kind == 'none'
    run: echo "::error::Nothing here would be served."
  - if: steps.detect.outputs.framework == 'hugo'
    run: echo "A Hugo site, served from ${{ steps.detect.outputs.output-dir }}"
  - if: steps.detect.outputs.install != ''
    run: ${{ steps.detect.outputs.install }}
yaml

Inputs

InputDefault
root-dirThe checkoutWhere the project is in the checkout.
build-commandNoneA build command of your own, as g1t/deploy takes it.
output-dirNoneAn output folder of your own, as g1t/deploy takes it.
build-asautoWhat it is built as: auto, static, workers or docker (Container), as g1t/deploy takes it.
dockerfileNoneA Dockerfile's path of your own, as g1t/deploy takes it.

Outputs

Output
kindworkers (a wrangler.jsonc, wrangler.json or wrangler.toml, a framework's Cloudflare adapter, or a Node.js server run as a Worker), static (a site a build writes), html (the files as they are), container (a server that is not run as a Worker, a framework set up to need a server, or a Dockerfile with nothing else to serve) or none (nothing to serve).
frameworkThe framework it is built with, from the table below; node for a Node.js server run as a Worker; for a container without one, dockerfile, or the server g1t writes a Dockerfile for (node, django, flask, fastapi, python, go, rails, rack, laravel, php). Empty when there is none.
dockerfileA container's own Dockerfile, relative to the project. Empty when g1t writes one, and for anything that is not a container.
portThe port a container listens on: its Dockerfile's EXPOSE, else 8080.
entryFor a Node.js server run as a Worker, the file that starts it, relative to the project. Empty for anything else.
installHow dependencies are installed, from the lockfile: npm ci, pnpm install --frozen-lockfile, and so on, and bundle install for Jekyll. Empty when there is nothing to install.
buildWhat builds it: your command, the package's build script (npm run build), the framework's own command, or wrangler deploy --dry-run for Workers. Empty when nothing does.
output-dirThe folder served, relative to the project (. for the project itself): yours, a Workers project's assets directory, the folder the framework writes, or the first of dist, build, out, public, _site, .output/public that exists. Empty when a build has yet to write it, as for a Cloudflare adapter's Worker.

When kind is none, the step's log says what to change or add, such as a Dockerfile. Docker deployments has the order in which a project's kind is decided.

Frameworks

frameworkFound byServes
vite, vite-react, vite-vue, vite-svelte, vite-solid, vite-preactvite, and the framework's Vite plugindist, or build.outDir
astroastrodist, or outDir; a Worker with @astrojs/cloudflare
nextjsnextout with output: 'export'; a Worker with @opennextjs/cloudflare and a wrangler.jsonc
sveltekit@sveltejs/kitbuild with adapter-static; a Worker with adapter-cloudflare
nuxtnuxt.output/public, from nuxi generate
react-router, remix@react-router/dev, @remix-run/devbuild/client with ssr: false
gatsbygatsbypublic
docusaurus@docusaurus/corebuild
eleventy@11ty/eleventy_site
angular@angular/core and angular.jsondist/<project>/browser
create-react-appreact-scriptsbuild
hugohugo.toml, or Hugo's config.tomlpublic
jekyll_config.yml and a Gemfile_site
mdbookbook.tomlbook

What deploys has each one's build command. Your build-command and output-dir win over what is detected.

It runs g1t-runner detect, found or downloaded as g1t/deploy finds it.