Replace the bulky hero installers with a compact platform switcher, wrapping command, and copy action
Hop-State: A_06FN6S8S3T184C0AS6MXQ08 Hop-Proposal: R_06FN6S5PSBAXTT4CDRPQS0R Hop-Task: T_06FN6N560GHE00H1ACBKR8G Hop-Attempt: AT_06FN6N560G6CPSCDTN8C48R
This commit is contained in:
@@ -305,6 +305,72 @@
|
|||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function copyToClipboard(value) {
|
||||||
|
if (navigator.clipboard?.writeText) {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(value);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
// Fall back for browsers that block clipboard access outside a secure context.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const input = document.createElement('textarea');
|
||||||
|
input.value = value;
|
||||||
|
input.setAttribute('readonly', '');
|
||||||
|
input.style.position = 'fixed';
|
||||||
|
input.style.opacity = '0';
|
||||||
|
document.body.append(input);
|
||||||
|
input.select();
|
||||||
|
input.setSelectionRange(0, value.length);
|
||||||
|
const copied = document.execCommand('copy');
|
||||||
|
input.remove();
|
||||||
|
return copied;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindInstallationSwitchers() {
|
||||||
|
for (const switcher of document.querySelectorAll('.hop-agent-install-shell')) {
|
||||||
|
if (switcher.dataset.hopInstallBound === 'true') continue;
|
||||||
|
switcher.dataset.hopInstallBound = 'true';
|
||||||
|
const buttons = [...switcher.querySelectorAll('[data-hop-install-command]')];
|
||||||
|
const output = switcher.querySelector('[data-hop-install-command-output]');
|
||||||
|
const copyButton = switcher.querySelector('[data-hop-copy]');
|
||||||
|
const status = copyButton ? document.getElementById(copyButton.getAttribute('aria-describedby')) : null;
|
||||||
|
for (const button of buttons) {
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
for (const option of buttons) option.setAttribute('aria-pressed', String(option === button));
|
||||||
|
if (output) output.textContent = button.dataset.hopInstallCommand;
|
||||||
|
if (copyButton) copyButton.setAttribute('aria-label', `Copy ${button.dataset.hopInstallPlatform} installation command`);
|
||||||
|
if (status) status.textContent = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindInstallationCopyButtons() {
|
||||||
|
for (const button of document.querySelectorAll('[data-hop-copy]')) {
|
||||||
|
if (button.dataset.hopCopyBound === 'true') continue;
|
||||||
|
button.dataset.hopCopyBound = 'true';
|
||||||
|
button.addEventListener('click', async () => {
|
||||||
|
const command = button.closest('.hop-agent-install-command')?.querySelector('code')?.textContent?.trim();
|
||||||
|
const status = document.getElementById(button.getAttribute('aria-describedby'));
|
||||||
|
if (!command) return;
|
||||||
|
|
||||||
|
button.disabled = true;
|
||||||
|
button.textContent = 'Copying…';
|
||||||
|
const copied = await copyToClipboard(command);
|
||||||
|
button.disabled = false;
|
||||||
|
button.textContent = copied ? 'Copied' : 'Retry';
|
||||||
|
if (status) status.textContent = copied ? 'Command copied to clipboard.' : 'Could not copy automatically. Select the command and copy it.';
|
||||||
|
|
||||||
|
window.setTimeout(() => {
|
||||||
|
button.textContent = 'Copy';
|
||||||
|
if (status) status.textContent = '';
|
||||||
|
}, 2400);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function replaceBrandImages() {
|
function replaceBrandImages() {
|
||||||
const upstreamBrandAsset = /\/img\/(?:avatar_default\.png|logo\.png|logo\.svg)(?:\?.*)?$/;
|
const upstreamBrandAsset = /\/img\/(?:avatar_default\.png|logo\.png|logo\.svg)(?:\?.*)?$/;
|
||||||
for (const image of document.querySelectorAll('img[src]')) {
|
for (const image of document.querySelectorAll('img[src]')) {
|
||||||
@@ -322,6 +388,8 @@
|
|||||||
addPromptsNavigation();
|
addPromptsNavigation();
|
||||||
addWorkflowSummary();
|
addWorkflowSummary();
|
||||||
renderPromptPage();
|
renderPromptPage();
|
||||||
|
bindInstallationSwitchers();
|
||||||
|
bindInstallationCopyButtons();
|
||||||
const title = replacePhrases(document.title);
|
const title = replacePhrases(document.title);
|
||||||
if (title !== document.title) document.title = title;
|
if (title !== document.title) document.title = title;
|
||||||
document.documentElement.dataset.hopNative = 'true';
|
document.documentElement.dataset.hopNative = 'true';
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/hop-home.css?v=4">
|
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/hop-home.css?v=4">
|
||||||
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/hop-prompts.css?v=1">
|
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/hop-prompts.css?v=1">
|
||||||
<script src="{{AssetUrlPrefix}}/js/hop-native.js?v=9"></script>
|
<script src="{{AssetUrlPrefix}}/js/hop-native.js?v=10"></script>
|
||||||
|
|||||||
@@ -242,37 +242,121 @@
|
|||||||
font-weight: 550;
|
font-weight: 550;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-install {
|
.hop-agent-installs {
|
||||||
|
border-top: 1px solid var(--color-secondary);
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
max-width: 100%;
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-heading {
|
||||||
|
align-items: baseline;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-shell {
|
||||||
|
border: 1px solid var(--color-secondary);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
margin-top: 0.7rem;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-tabs {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-tab {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-radius: calc(var(--border-radius) - 2px);
|
||||||
|
color: var(--color-text-light-2);
|
||||||
|
cursor: pointer;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 0.55rem 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-tab[aria-pressed="true"] {
|
||||||
|
background: color-mix(in srgb, var(--color-primary) 18%, transparent);
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-tab:focus-visible {
|
||||||
|
outline: 2px solid var(--color-primary);
|
||||||
|
outline-offset: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-command {
|
||||||
|
align-items: center;
|
||||||
|
background: color-mix(in srgb, var(--color-secondary) 42%, transparent);
|
||||||
border-top: 1px solid var(--color-secondary);
|
border-top: 1px solid var(--color-secondary);
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: clamp(3rem, 7vw, 6rem);
|
gap: 0.75rem;
|
||||||
grid-template-columns: minmax(220px, 0.7fr) minmax(0, 1.3fr);
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
margin-top: clamp(3.5rem, 5vw, 5rem);
|
min-width: 0;
|
||||||
padding-top: clamp(2.25rem, 3.5vw, 3.5rem);
|
padding: 0.75rem 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-install-copy h2 {
|
.hop-agent-copy-button {
|
||||||
font-size: clamp(2.2rem, 4vw, 3.6rem);
|
background: transparent;
|
||||||
|
border: 1px solid var(--color-secondary);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: var(--color-text);
|
||||||
|
cursor: pointer;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.78rem;
|
||||||
font-weight: 650;
|
font-weight: 650;
|
||||||
letter-spacing: -0.045em;
|
line-height: 1;
|
||||||
line-height: 1.04;
|
padding: 0.5rem 0.65rem;
|
||||||
margin-top: 0.9rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-install-copy > p:last-of-type {
|
.hop-agent-copy-button:hover {
|
||||||
color: var(--color-text-light-2) !important;
|
background: color-mix(in srgb, var(--color-primary) 16%, transparent);
|
||||||
font-size: 1rem;
|
}
|
||||||
line-height: 1.6;
|
|
||||||
margin-top: 1.2rem !important;
|
.hop-agent-copy-button:focus-visible {
|
||||||
max-width: 42ch;
|
outline: 2px solid var(--color-primary);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-command code {
|
||||||
|
color: var(--color-text);
|
||||||
|
display: block;
|
||||||
|
font-family: var(--fonts-monospace);
|
||||||
|
font-size: clamp(0.72rem, 1.12vw, 0.84rem);
|
||||||
|
line-height: 1.45;
|
||||||
|
min-width: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-copy-status {
|
||||||
|
color: var(--color-text-light-2);
|
||||||
|
display: block;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-top: 0.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hop-agent-copy-status:empty {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-repo-link {
|
.hop-agent-repo-link {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
font-weight: 650;
|
font-size: 0.84rem;
|
||||||
|
font-weight: 600;
|
||||||
gap: 0.45rem;
|
gap: 0.45rem;
|
||||||
margin-top: 1.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-repo-link::after {
|
.hop-agent-repo-link::after {
|
||||||
@@ -280,29 +364,6 @@
|
|||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-install-list {
|
|
||||||
border-top: 1px solid var(--color-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hop-agent-install-command {
|
|
||||||
border-bottom: 1px solid var(--color-secondary);
|
|
||||||
padding: 1.45rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hop-agent-install-command code {
|
|
||||||
background: color-mix(in srgb, var(--color-secondary) 42%, transparent);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
color: var(--color-text);
|
|
||||||
display: block;
|
|
||||||
font-family: var(--fonts-monospace);
|
|
||||||
font-size: clamp(0.78rem, 1.35vw, 0.94rem);
|
|
||||||
line-height: 1.55;
|
|
||||||
margin-top: 0.85rem;
|
|
||||||
overflow-x: auto;
|
|
||||||
padding: 0.85rem 1rem;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hop-agent-finish {
|
.hop-agent-finish {
|
||||||
align-items: end;
|
align-items: end;
|
||||||
border-top: 1px solid var(--color-secondary);
|
border-top: 1px solid var(--color-secondary);
|
||||||
@@ -345,10 +406,6 @@
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-install {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hop-agent-flow .hop-agent-section-heading {
|
.hop-agent-flow .hop-agent-section-heading {
|
||||||
max-width: 620px;
|
max-width: 620px;
|
||||||
}
|
}
|
||||||
@@ -454,9 +511,14 @@
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hop-agent-install-command code {
|
.hop-agent-install-heading {
|
||||||
font-size: 0.76rem;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hop-agent-install-command {
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<main id="hop-main" tabindex="-1" role="main" aria-label="Hop, agent-first version control" class="page-content hop-agent-home">
|
<main id="hop-main" tabindex="-1" role="main" aria-label="Hop, agent-first version control" class="page-content hop-agent-home">
|
||||||
@@ -474,6 +536,23 @@
|
|||||||
<a class="ui basic button" href="#why-hop">Why use Hop?</a>
|
<a class="ui basic button" href="#why-hop">Why use Hop?</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hop-agent-installs" aria-label="Install Hop">
|
||||||
|
<div class="hop-agent-install-heading">
|
||||||
|
<p class="hop-agent-label">Install Hop</p>
|
||||||
|
<a class="hop-agent-repo-link" href="https://githop.xyz/GnosysLabs/Hop" target="_blank" rel="noreferrer">Repository</a>
|
||||||
|
</div>
|
||||||
|
<div class="hop-agent-install-shell">
|
||||||
|
<div class="hop-agent-install-tabs" role="group" aria-label="Installation platform">
|
||||||
|
<button class="hop-agent-install-tab" type="button" aria-pressed="true" data-hop-install-command="curl -fsSL https://githop.xyz/GnosysLabs/Hop/raw/branch/main/scripts/install.sh | sh" data-hop-install-platform="macOS and Linux">macOS + Linux</button>
|
||||||
|
<button class="hop-agent-install-tab" type="button" aria-pressed="false" data-hop-install-command="irm https://githop.xyz/GnosysLabs/Hop/raw/branch/main/scripts/install.ps1 | iex" data-hop-install-platform="Windows PowerShell">Windows</button>
|
||||||
|
</div>
|
||||||
|
<div class="hop-agent-install-command">
|
||||||
|
<code data-hop-install-command-output>curl -fsSL https://githop.xyz/GnosysLabs/Hop/raw/branch/main/scripts/install.sh | sh</code>
|
||||||
|
<button class="hop-agent-copy-button" type="button" data-hop-copy aria-label="Copy macOS and Linux installation command" aria-describedby="hop-install-status">Copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="hop-agent-copy-status" id="hop-install-status" role="status" aria-live="polite"></span>
|
||||||
|
</div>
|
||||||
<p class="hop-agent-note">Git stays underneath for compatibility. The mechanics disappear from your workflow.</p>
|
<p class="hop-agent-note">Git stays underneath for compatibility. The mechanics disappear from your workflow.</p>
|
||||||
</div>
|
</div>
|
||||||
<figure class="hop-agent-mascot">
|
<figure class="hop-agent-mascot">
|
||||||
@@ -534,25 +613,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="hop-agent-install" id="install-hop" aria-labelledby="hop-agent-install-title">
|
|
||||||
<div class="hop-agent-install-copy">
|
|
||||||
<p class="hop-agent-label">Install Hop</p>
|
|
||||||
<h2 id="hop-agent-install-title">One install. No Git busywork.</h2>
|
|
||||||
<p>Install the Hop CLI, then tell your agents what to build. Hop handles isolated workspaces, checkpoints, reconciliation, and landing.</p>
|
|
||||||
<a class="hop-agent-repo-link" href="https://githop.xyz/GnosysLabs/Hop" target="_blank" rel="noreferrer">Official Hop repository</a>
|
|
||||||
</div>
|
|
||||||
<div class="hop-agent-install-list" aria-label="Hop installation commands">
|
|
||||||
<div class="hop-agent-install-command">
|
|
||||||
<p class="hop-agent-label">macOS and Linux</p>
|
|
||||||
<code>curl -fsSL https://githop.xyz/GnosysLabs/Hop/raw/branch/main/scripts/install.sh | sh</code>
|
|
||||||
</div>
|
|
||||||
<div class="hop-agent-install-command">
|
|
||||||
<p class="hop-agent-label">Windows PowerShell</p>
|
|
||||||
<code>irm https://githop.xyz/GnosysLabs/Hop/raw/branch/main/scripts/install.ps1 | iex</code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="hop-agent-finish" aria-labelledby="hop-agent-finish-title">
|
<section class="hop-agent-finish" aria-labelledby="hop-agent-finish-title">
|
||||||
<div>
|
<div>
|
||||||
<h2 id="hop-agent-finish-title">Git compatibility without Git busywork.</h2>
|
<h2 id="hop-agent-finish-title">Git compatibility without Git busywork.</h2>
|
||||||
|
|||||||
Reference in New Issue
Block a user