booth: label every field in the publish form (0.99.0)

audited the Booth as a new publisher: the onboarding is good, but the publish
form was placeholder-only — and Kind (codex) + Launch command (codex --yolo)
come pre-filled, so their placeholders never show, leaving those two technical
fields with no visible label.

- added a persistent label above every field (Class name, Tags, Description,
  Kind, Visibility, Launch command) + clearer example placeholders
- a one-line hint explains the two technical fields
- verified live (throwaway account, cleaned up): all six labels render, form
  reads cleanly
- changelog entry (0.99) added with the bump
This commit is contained in:
artheru 2026-06-10 15:19:04 +08:00
parent 9c1aa73742
commit 80d7140d1f
5 changed files with 28 additions and 9 deletions

View File

@ -17,7 +17,7 @@
@media (prefers-reduced-motion: reduce) { .app-loading-gem { animation: none; transform: rotate(45deg); } }
</style>
<meta name="description" content="amerc is the agent mercenary tavern — hire, run, publish, and remotely deliver AI agents across software boundaries. No infrastructure, just skills." />
<meta name="version" content="0.98.0-apiconsole" />
<meta name="version" content="0.99.0-boothform" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/app-192.png" type="image/png" sizes="192x192" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />

View File

@ -1,6 +1,6 @@
{
"name": "amerc-site",
"version": "0.98.0-apiconsole",
"version": "0.99.0-boothform",
"private": true,
"type": "module",
"scripts": {

View File

@ -323,14 +323,27 @@ export function BoothDashboard({ auth, setRoute }) {
<div className="ap-booth-grid">
<form className="ap-publish" onSubmit={publishClass}>
<h4 className="ap-h4">Publish an agent class</h4>
<input placeholder="class name" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} required />
<input placeholder="tags (comma): backend, model" value={form.tags} onChange={(e) => setForm({ ...form, tags: e.target.value })} />
<textarea placeholder="description" value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
<label className="ap-pub-field"><span>Class name</span>
<input placeholder="e.g. Backend Helper" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} required />
</label>
<label className="ap-pub-field"><span>Tags</span>
<input placeholder="comma-separated: backend, model" value={form.tags} onChange={(e) => setForm({ ...form, tags: e.target.value })} />
</label>
<label className="ap-pub-field"><span>Description</span>
<textarea placeholder="What does it do for users?" value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
</label>
<div className="ap-row">
<input placeholder="kind (codex)" value={form.kind} onChange={(e) => setForm({ ...form, kind: e.target.value })} />
<label className="ap-pub-field"><span>Kind</span>
<input placeholder="codex" value={form.kind} onChange={(e) => setForm({ ...form, kind: e.target.value })} />
</label>
<label className="ap-pub-field"><span>Visibility</span>
<select value={form.visibility} onChange={(e) => setForm({ ...form, visibility: e.target.value })}><option value="public">public</option><option value="private">private publish</option></select>
</label>
</div>
<input placeholder="launch command" value={form.command} onChange={(e) => setForm({ ...form, command: e.target.value })} />
<label className="ap-pub-field"><span>Launch command</span>
<input placeholder="codex --yolo" value={form.command} onChange={(e) => setForm({ ...form, command: e.target.value })} />
</label>
<p className="ap-hint">Kind is your agent's runtime; the launch command is how your broker starts it.</p>
<button className="px-action px-auth-submit" type="submit">Publish class</button>
</form>
<div className="ap-mine">

View File

@ -10,7 +10,7 @@ import { api } from './api.js';
const Menu = ({ size = 20 }) => (<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true"><line x1="3" y1="6" x2="21" y2="6" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="18" x2="21" y2="18" /></svg>);
const X = ({ size = 20 }) => (<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></svg>);
const RELEASE = '0.98.0-apiconsole';
const RELEASE = '0.99.0-boothform';
const NAV = [
{ id: 'home', label: 'Tavern' },
@ -476,6 +476,7 @@ function StatusPage() {
}
const CHANGELOG = [
{ v: '0.99', date: 'Jun 2026', title: 'Clearer publish form', notes: ['The Booth publish form now labels every field, so the pre-filled Kind and Launch command are no longer ambiguous'] },
{ v: '0.98', date: 'Jun 2026', title: 'Live API console', notes: ['The home-page API peek now shows the response status and timing, with a run button to re-fetch'] },
{ v: '0.97', date: 'Jun 2026', title: 'Clearer sign-in', notes: ['The join form now uses plain labels (Email, Password) and a clear Log in button'] },
{ v: '0.96', date: 'Jun 2026', title: 'Hero fits the fold', notes: ['The tagline, calls-to-action and live stats now sit above the fold on laptop screens'] },

View File

@ -1565,3 +1565,8 @@ button {
.hf-peek-run { background: none; border: 1px solid #2a4a5c; color: #7fd9ea; border-radius: 6px; padding: 3px 10px; font-size: 11px; cursor: pointer; font-family: inherit; flex: 0 0 auto; }
.hf-peek-run:hover:not(:disabled) { background: rgba(39, 216, 255, 0.1); color: #cfeff7; }
.hf-peek-run:disabled { opacity: 0.5; cursor: default; }
/* booth publish form: labelled fields (0.99) */
.ap-pub-field { display: flex; flex-direction: column; gap: 4px; }
.ap-pub-field > span { font-size: 11px; color: #8a7bb0; letter-spacing: 0.3px; }
.ap-row .ap-pub-field { flex: 1; }