Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

Merge 919fdf4250c015a4f2ca589827bacb98e5d4083f into 1d10bcf54df8a53b04114256cd7ce04be30cf401

Diffinery authored 2 parents 1d10bcf919fdf4commit 2637c142699887599067fdbc267f53849970f0d6Browse files
1 file changed+35−44
modifiedapps/diffinery/src/web/agent-setup.tsx+35−44View file
@@ -100,31 +100,29 @@
100100
101101 const TokenRow: FC<{ c: AppContext; base: string; t: AgentSetupToken }> = ({ base, t, c }) => {
102102 const soon = Date.parse(t.expiresAt) - Date.now() < 14 * 86400_000;
103+ // A list row rather than a table row: on a phone the buttons wrap below the token's details.
103104 return (
104- <tr>
105- <td>
106- <b>{t.name}</b>
107- <div class="small muted mono">{t.prefix}…</div>
108- </td>
109- <td class={soon ? "warn" : ""}>
110- {date(t.expiresAt)}
111- <div class="small muted">created {date(t.createdAt)}</div>
112- </td>
113- <td class="small">{t.lastUsedAt ? <Time at={t.lastUsedAt} /> : <span class="muted">never</span>}</td>
114- <td style="text-align:right;white-space:nowrap">
105+ <li style="flex-wrap:wrap;align-items:center">
106+ <div class="grow" style="min-width:200px">
107+ <b>{t.name}</b> <span class="small muted mono">{t.prefix}…</span>
108+ <div class="small muted">
109+ <span class={soon ? "warn" : ""}>Expires {date(t.expiresAt)}</span> · created {date(t.createdAt)} · {t.lastUsedAt ? <>last used <Time at={t.lastUsedAt} /></> : "never used"}
110+ </div>
111+ </div>
112+ <div class="row" style="gap:6px">
115113 <Form action={`${base}/tokens/${t.id}/renew`} t={csrfToken(c)} class="inline">
116114 <button class="btn sm" title={`Keep this token working for ${AGENT_SETUP_DAYS} days from today; nothing to paste again`}>
117115 Renew
118116 </button>
119- </Form>{" "}
117+ </Form>
120118 <Form action={`${base}/tokens/${t.id}/regenerate`} t={csrfToken(c)} class="inline" confirm="Revoke this token and make a new one? Sessions using it stop working until you paste the new one.">
121119 <button class="btn sm">Revoke and regenerate</button>
122- </Form>{" "}
120+ </Form>
123121 <Form action={`${base}/tokens/${t.id}/revoke`} t={csrfToken(c)} class="inline" confirm="Revoke this token? Environments using it stop working.">
124122 <button class="btn sm danger">Revoke</button>
125123 </Form>
126- </td>
127- </tr>
124+ </div>
125+ </li>
128126 );
129127 };
130128
@@ -176,37 +174,30 @@
176174 </p>
177175 )}
178176 {tokens.length ? (
179- <table class="tbl mb">
180- <thead>
181- <tr>
182- <th>Token</th>
183- <th>Expires</th>
184- <th>Last used</th>
185- <th />
186- </tr>
187- </thead>
188- <tbody>
189- {tokens.map((k) => (
190- <TokenRow c={c} base={base} t={k} />
191- ))}
192- </tbody>
193- </table>
177+ <ul class="list mb" style="border:1px solid var(--border2);border-radius:7px">
178+ {tokens.map((k) => (
179+ <TokenRow c={c} base={base} t={k} />
180+ ))}
181+ </ul>
194182 ) : null}
195- <Form action={`${base}/generate`} t={t} class="row" style="align-items:flex-end">
196- <div class="field grow m0">
197- <label for="tname">Label</label>
198- <input id="tname" name="name" type="text" maxlength={100} value={defaultTokenName()} />
199- <div class="hint">Shown in the token list and in audit logs, so you can tell environments apart.</div>
183+ {/* The button lines up with the input, and drops below it where both don't fit. */}
184+ <Form action={`${base}/generate`} t={t} class="field m0">
185+ <label for="tname">Label</label>
186+ <div class="row">
187+ <input id="tname" name="name" type="text" maxlength={100} value={defaultTokenName()} style="flex:1 1 240px;width:auto;min-width:0" />
188+ <button class="btn primary">{tokens.length ? "Generate another token" : "Generate agent token"}</button>
200189 </div>
201- <button class="btn primary">{tokens.length ? "Generate another token" : "Generate agent token"}</button>
190+ <div class="hint">Shown in the token list and in audit logs, so you can tell environments apart.</div>
202191 </Form>
203192 {active ? (
204- <Form action={`${base}/merge`} t={t} class="row mt" style="align-items:center">
205- <KCheckbox name="mayMerge" checked={agentMayMerge(active)} label="Can merge pull requests" />
206- <button class="btn sm">Save</button>
207- <span class="hint" style="margin:0">
193+ <Form action={`${base}/merge`} t={t} class="mt">
194+ <div class="row">
195+ <KCheckbox name="mayMerge" checked={agentMayMerge(active)} label="Can merge pull requests" />
196+ <button class="btn sm">Save</button>
197+ </div>
198+ <p class="small muted" style="margin:6px 0 0">
208199 It merges, or turns on auto-merge, only once a person approved the pull request's latest commit and every rule of the branch is met. A change to a workflow file always needs a person to merge.
209- </span>
200+ </p>
210201 </Form>
211202 ) : null}
212203 </div>
@@ -218,7 +209,7 @@
218209 </div>
219210 <div class="body">
220211 <Paste value={host} />
221- <p class="small muted mt">
212+ <p class="small muted mt" style="margin-bottom:0">
222213 The domain the environment must reach (the container registry is on it too). In Claude Code, set <b>Network access</b> to <b>Custom</b>, add it under <b>Allowed domains</b> and keep <b>Also include default list of common package managers</b> ticked; or choose <b>Full</b>. The default <b>Trusted</b> level
223214 doesn't include it.
224215 </p>
@@ -231,7 +222,7 @@
231222 </div>
232223 <div class="body">
233224 <Paste value={script} />
234- <p class="small muted mt">
225+ <p class="small muted mt" style="margin-bottom:0">
235226 Installs the <code>diffinery</code> CLI on PATH, makes git and gh use the token from the environment (it never writes the token to disk or prints it), clones {slug} unless it's there (into <code>/home/user/{repo.name}</code> in Claude Code; set <code>DIFFINERY_NO_CLONE=1</code> to skip), then checks that
236227 everything works and reports to the Check below. Safe to run every session, and quick once the CLI is installed. <a href={`/${slug}/agent-setup.sh`}>Read the script</a>.
237228 </p>
@@ -244,7 +235,7 @@
244235 </div>
245236 <div class="body">
246237 <Paste value={env} copy={!!created} id="agent-env" />
247- <p class="small muted mt">
238+ <p class="small muted mt" style="margin-bottom:0">
248239 {created
249240 ? "Paste these lines as they are. The token is in two of them: the CLI and git read DIFFINERY_TOKEN, gh reads GH_ENTERPRISE_TOKEN, and GH_HOST points gh at Diffinery."
250241 : tokens.length