Files
archify/scripts/start-template.html

523 lines
34 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Archify Start — Describe It, Then See It</title>
<meta name="description" content="Create a verifiable technical diagram directly from a plain-language description, pasted Mermaid, or a repository. No repository is required.">
<meta name="theme-color" content="#eff2f1">
<meta property="og:type" content="website">
<meta property="og:title" content="Archify Start — Describe it, then see it">
<meta property="og:description" content="Start with a plain-language description, pasted Mermaid, or real code. No repository is required.">
<meta property="og:url" content="https://tt-a1i.github.io/archify/start.html">
<meta property="og:image" content="https://tt-a1i.github.io/archify/assets/archify-social-preview.png">
<link rel="icon" type="image/svg+xml" href="assets/archify-mark.svg">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,400;0,9..144,500;1,9..144,400&family=Inter:wght@400;450;500;600&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/site-navigation.css">
<style>
:root {
/* Drafted-sheet palette — shared with the project page */
--paper:#eff2f1; --paper-raised:#f8faf9;
--ink:#15181b; --ink-soft:#363c41; --muted:#60686d; --dim:#929a9e;
--line:rgba(20,23,26,0.14); --line-hi:rgba(20,23,26,0.3);
--accent:#e14a0e; --accent-soft:rgba(225,74,14,0.08);
--plate:#0f1216;
--emerald:#047857;
--font-display:'Fraunces','Songti SC','STSong',Georgia,serif;
--font-body:'Inter',-apple-system,BlinkMacSystemFont,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
--font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
--ease-out:cubic-bezier(.22,1,.36,1);
}
*,*::before,*::after { margin:0; padding:0; box-sizing:border-box; }
html { scroll-behavior:smooth; }
body {
font-family:var(--font-body);
-webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
background:var(--paper); color:var(--ink); min-height:100vh; overflow-x:hidden;
}
body::after {
content:''; position:fixed; inset:0; z-index:1000; pointer-events:none;
opacity:.05; mix-blend-mode:multiply;
background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}
::selection { background:rgba(225,74,14,.18); color:var(--ink); }
a { color:inherit; }
button { font:inherit; }
:focus-visible { outline:2px solid var(--accent); outline-offset:3px; border-radius:4px; }
.grid-bg {
position:fixed; inset:0; z-index:0; pointer-events:none;
background-image:linear-gradient(rgba(20,23,26,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(20,23,26,.045) 1px,transparent 1px);
background-size:56px 56px;
-webkit-mask-image:radial-gradient(ellipse 95% 62% at 50% -6%, black 12%, transparent 75%);
mask-image:radial-gradient(ellipse 95% 62% at 50% -6%, black 12%, transparent 75%);
}
main { position:relative; z-index:1; width:min(1120px,calc(100% - 3rem)); margin:0 auto; padding:10rem 0 4rem; }
/* LEAD */
.lead { display:grid; grid-template-columns:minmax(0,1.5fr) minmax(260px,.65fr); gap:4rem; align-items:end; margin-bottom:3.5rem; }
.lead-label { display:flex; align-items:center; gap:.875rem; margin-bottom:1.5rem; font-family:var(--font-mono); font-size:.625rem; font-weight:500; letter-spacing:.2em; color:var(--muted); text-transform:uppercase; }
.lead-label::before { content:''; width:2.75rem; height:1px; background:var(--line-hi); }
h1 { max-width:780px; font-family:var(--font-display); font-optical-sizing:auto; font-size:clamp(2.5rem,5vw,4.25rem); font-weight:400; line-height:1.06; letter-spacing:-.028em; color:var(--ink); text-wrap:balance; }
h1 em { font-style:italic; color:var(--accent); }
html[lang^="zh"] .title-gap { display:none; }
.lead-copy { color:var(--muted); font-size:.9375rem; line-height:1.72; text-wrap:pretty; }
.trust-line { display:flex; gap:.6rem; align-items:flex-start; margin-top:1.125rem; color:var(--emerald); font-family:var(--font-mono); font-size:.6875rem; line-height:1.65; }
.trust-line::before { content:'✓'; flex:0 0 auto; }
/* INPUT PATH — make the no-repository path explicit before diagram choices */
.input-paths { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.625rem; margin-bottom:1.25rem; }
.input-path {
min-height:72px; padding:.85rem 1rem; text-align:left;
border:1px solid var(--line); border-radius:10px; background:var(--paper);
color:var(--muted); cursor:pointer; transition:all .18s var(--ease-out);
}
.input-path:hover { color:var(--ink); border-color:var(--line-hi); }
.input-path strong { display:block; margin-bottom:.3rem; color:inherit; font-size:.8125rem; font-weight:600; }
.input-path span { display:block; font-size:.6875rem; line-height:1.5; }
.input-path[aria-selected="true"] { border-color:var(--accent); background:var(--accent-soft); color:var(--ink); box-shadow:inset 3px 0 0 var(--accent); }
/* TYPE TABS */
.type-shell { margin-bottom:var(--bento-gap,14px); padding:1.25rem 1.5rem 1.5rem; border:1px solid var(--line-hi); border-radius:14px; background:var(--paper-raised); }
.type-label { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem; color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.16em; text-transform:uppercase; }
.type-label strong { color:var(--accent); font-weight:600; }
.type-tabs { display:grid; grid-template-columns:repeat(5,1fr); gap:1px; border:1px solid var(--line); border-radius:10px; overflow:hidden; background:var(--line); }
.type-tab {
min-height:52px;
border:0;
background:var(--paper-raised);
color:var(--muted);
cursor:pointer;
font-family:var(--font-mono); font-size:.6875rem; font-weight:500; letter-spacing:.06em;
transition:background .18s var(--ease-out),color .18s var(--ease-out);
}
.type-tab:hover { background:var(--paper); color:var(--ink); }
.type-tab[aria-selected="true"] { background:var(--ink); color:var(--paper); }
/* WORKBENCH — two paper cards */
.workbench { display:grid; grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr); gap:14px; align-items:stretch; }
.panel { min-width:0; padding:2.25rem 2.5rem; border:1px solid var(--line-hi); border-radius:14px; background:var(--paper-raised); }
.panel-kicker { display:flex; align-items:center; gap:.875rem; margin-bottom:1.5rem; color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.16em; text-transform:uppercase; }
.panel-kicker b { font-family:var(--font-display); font-style:italic; font-optical-sizing:auto; font-weight:400; font-size:1.375rem; color:var(--accent); }
.panel h2 { margin-bottom:.625rem; font-family:var(--font-display); font-optical-sizing:auto; font-size:1.5rem; font-weight:500; letter-spacing:-.02em; color:var(--ink); }
.panel-intro { min-height:3.9rem; margin-bottom:1.5rem; color:var(--muted); font-size:.8125rem; line-height:1.7; text-wrap:pretty; }
.agent-picker { margin-bottom:1.25rem; }
.agent-picker-head { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:.75rem; color:var(--muted); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.1em; text-transform:uppercase; line-height:1.45; }
.agent-picker-head strong { color:var(--emerald); font-weight:600; }
.agent-tabs { display:flex; flex-wrap:wrap; gap:.45rem; }
.agent-tab {
min-height:44px;
padding:.55rem .85rem;
border:1px solid var(--line-hi);
border-radius:8px;
background:transparent;
color:var(--muted);
cursor:pointer;
font-family:var(--font-mono); font-size:.625rem; font-weight:500; letter-spacing:.06em;
transition:all .18s var(--ease-out);
}
.agent-tab:hover { color:var(--ink); border-color:var(--ink); }
.agent-tab[aria-selected="true"] { color:var(--paper); border-color:var(--ink); background:var(--ink); }
/* COMMAND BLOCKS — dark plate on paper, like the project page install strip */
.command-block { margin-top:.875rem; border:1px solid var(--ink); border-radius:10px; overflow:hidden; background:var(--plate); }
.command-bar { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:.6rem .875rem; border-bottom:1px solid rgba(232,237,242,.1); color:#7d8894; font-family:var(--font-mono); font-size:.5625rem; text-transform:uppercase; letter-spacing:.14em; }
.copy-button { border:0; background:transparent; color:var(--accent); cursor:pointer; font-family:var(--font-mono); font-size:.5625rem; font-weight:600; text-transform:uppercase; letter-spacing:.12em; transition:color .18s var(--ease-out); }
.copy-button:hover { color:#ff7a3d; }
pre { margin:0; padding:.9rem 1rem; overflow:auto; color:#e8edf2; font:500 .6875rem/1.7 var(--font-mono); white-space:pre-wrap; overflow-wrap:anywhere; }
.secondary-note { margin:1rem 0 0; padding:.9rem 1rem; border:1px solid var(--line); border-radius:10px; background:var(--paper); color:var(--muted); font-size:.75rem; line-height:1.7; }
.question { margin-bottom:1rem; color:var(--ink-soft); font-size:.9375rem; font-weight:500; line-height:1.6; }
.include-list { display:flex; flex-wrap:wrap; gap:.45rem; margin-bottom:1.25rem; list-style:none; }
.include-list li { padding:.35rem .65rem; border:1px solid var(--line); border-radius:999px; color:var(--muted); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.06em; background:var(--paper); }
.prompt-box { min-height:172px; padding:1.15rem 1.25rem; border:1px solid rgba(225,74,14,.3); border-radius:10px; background:var(--accent-soft); color:var(--ink-soft); font-family:var(--font-mono); font-size:.75rem; line-height:1.8; white-space:pre-wrap; }
.actions { display:flex; align-items:center; flex-wrap:wrap; gap:.625rem; margin-top:1.25rem; }
.action { min-height:44px; display:inline-flex; align-items:center; justify-content:center; padding:.65rem 1.05rem; border:1px solid var(--line-hi); border-radius:8px; background:transparent; color:var(--ink-soft); font:500 .8125rem var(--font-body); text-decoration:none; cursor:pointer; transition:all .2s var(--ease-out); }
.action:hover { color:var(--ink); border-color:var(--ink); }
.action-primary { border-color:var(--ink); background:var(--ink); color:var(--paper); }
.action-primary:hover { background:var(--accent); border-color:var(--accent); color:var(--paper); }
.proof-meta { margin-top:1.1rem; color:var(--dim); font-family:var(--font-mono); font-size:.5625rem; letter-spacing:.08em; line-height:1.65; text-transform:uppercase; }
.page-footer { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-top:3.5rem; padding-top:1.5rem; border-top:1px solid var(--line); color:var(--dim); font-family:var(--font-mono); font-size:.625rem; letter-spacing:.04em; }
.page-footer a { color:var(--muted); text-decoration:none; transition:color .18s var(--ease-out); }
.page-footer a:hover { color:var(--ink); }
#copy-status { min-height:1.1rem; color:var(--emerald); }
/* ENTRANCE — one quiet rise on load */
@keyframes rise { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:none; } }
.lead, .type-shell, .workbench { animation:rise .7s var(--ease-out) both; }
.type-shell { animation-delay:.08s; }
.workbench { animation-delay:.16s; }
@media (max-width:840px) {
main { width:min(100% - 2rem,720px); padding-top:8rem; }
.lead { grid-template-columns:1fr; gap:1.5rem; margin-bottom:2.5rem; }
.workbench { grid-template-columns:1fr; }
.type-tabs { grid-template-columns:repeat(2,1fr); }
.input-paths { grid-template-columns:1fr; }
.type-tab:last-child { grid-column:1 / -1; }
}
@media (max-width:560px) {
main { width:calc(100% - 1.5rem); padding-top:7rem; }
h1 { font-size:2.2rem; }
.panel { padding:1.5rem 1.25rem; }
.type-shell { padding:1rem 1rem 1.25rem; }
.type-tabs { grid-template-columns:1fr; }
.type-tab:last-child { grid-column:auto; }
.page-footer { align-items:flex-start; flex-direction:column; }
}
@media (prefers-reduced-motion:reduce) {
html { scroll-behavior:auto; }
.lead, .type-shell, .workbench { animation:none; }
}
</style>
</head>
<body>
<div class="grid-bg" aria-hidden="true"></div>
<nav class="site-nav" aria-label="Primary navigation">
<a class="nav-logo" href="./" aria-label="Archify project page">
<img class="nav-logo-text brand-lockup" src="assets/archify-lockup-light.svg" alt="Archify" width="117" height="32">
<span class="nav-logo-path" data-en="/ start" data-zh="/ 快速上手">/ start</span>
</a>
<div class="nav-right">
<a class="nav-link" href="guide.html" data-en="Guide" data-zh="场景指南">Guide</a>
<a class="nav-link" href="gallery.html" data-en="Proof Lab" data-zh="验证作品集">Proof Lab</a>
<a class="nav-link" href="start.html" aria-current="page" data-en="Start" data-zh="快速上手">Start</a>
<a class="nav-link" href="https://github.com/tt-a1i/archify" target="_blank" rel="noopener">GitHub</a>
<button class="btn-lang" id="language" type="button" aria-label="Switch language">中文</button>
<a class="btn btn-primary nav-cta" href="#install" data-en="Install Skill" data-zh="安装技能">Install Skill</a>
</div>
</nav>
<main>
<header class="lead">
<div>
<p class="lead-label" data-en="Start with words, Mermaid, or code" data-zh="从描述、Mermaid 或代码开始">Start with words, Mermaid, or code</p>
<h1><span data-en="Describe it." data-zh="直接说,">Describe it.</span><span class="title-gap" aria-hidden="true"> </span><em data-en="Archify maps it." data-zh="Archify 就能画。">Archify maps it.</em></h1>
</div>
<div>
<p class="lead-copy" data-en="No repository is required. Describe a system or flow in a normal agent chat and Archify will turn it into a checked, interactive diagram. If code exists, the same skill can inspect it for evidence." data-zh="不需要绑定代码库。在任意 Agent 对话里用自然语言描述系统或流程,Archify 就会把它变成经过校验的交互图;如果有代码,也可以再让它读取仓库作为证据。">No repository is required. Describe a system or flow in a normal agent chat and Archify will turn it into a checked, interactive diagram. If code exists, the same skill can inspect it for evidence.</p>
<div class="trust-line" data-en="Your description is enough to make the first diagram." data-zh="只有一段描述,也足够画出第一张图。">Your description is enough to make the first diagram.</div>
</div>
</header>
<section class="type-shell" aria-labelledby="type-label">
<p class="type-label"><span data-en="Choose how to start" data-zh="选择如何开始">Choose how to start</span><strong data-en="Repository optional" data-zh="代码库可选">Repository optional</strong></p>
<div class="input-paths" role="tablist" aria-label="Input source">
<button class="input-path" type="button" role="tab" data-input="description"><strong data-en="Just describe it" data-zh="直接描述">直接描述</strong><span data-en="Start in any chat. No files or repository needed." data-zh="在任意对话里开始,不需要文件或代码库。">Start in any chat. No files or repository needed.</span></button>
<button class="input-path" type="button" role="tab" data-input="repository"><strong data-en="Use a repository" data-zh="从代码库开始">Use a repository</strong><span data-en="Let the agent inspect code when source evidence matters." data-zh="需要源码证据时,再让 Agent 检查代码。">Let the agent inspect code when source evidence matters.</span></button>
</div>
<p class="type-label" id="type-label"><span data-en="Choose the question shape" data-zh="选择问题形态">Choose the question shape</span><strong data-en="5 typed renderers" data-zh="5 种类型化渲染器">5 typed renderers</strong></p>
<div class="type-tabs" role="tablist" aria-label="Diagram type">
<button class="type-tab" type="button" role="tab" data-type="architecture" data-en="[[DIAGRAM_TYPE_ARCHITECTURE_EN]]" data-zh="[[DIAGRAM_TYPE_ARCHITECTURE_ZH]]">[[DIAGRAM_TYPE_ARCHITECTURE_EN]]</button>
<button class="type-tab" type="button" role="tab" data-type="workflow" data-en="[[DIAGRAM_TYPE_WORKFLOW_EN]]" data-zh="[[DIAGRAM_TYPE_WORKFLOW_ZH]]">[[DIAGRAM_TYPE_WORKFLOW_EN]]</button>
<button class="type-tab" type="button" role="tab" data-type="sequence" data-en="[[DIAGRAM_TYPE_SEQUENCE_EN]]" data-zh="[[DIAGRAM_TYPE_SEQUENCE_ZH]]">[[DIAGRAM_TYPE_SEQUENCE_EN]]</button>
<button class="type-tab" type="button" role="tab" data-type="dataflow" data-en="[[DIAGRAM_TYPE_DATAFLOW_EN]]" data-zh="[[DIAGRAM_TYPE_DATAFLOW_ZH]]">[[DIAGRAM_TYPE_DATAFLOW_EN]]</button>
<button class="type-tab" type="button" role="tab" data-type="lifecycle" data-en="[[DIAGRAM_TYPE_LIFECYCLE_EN]]" data-zh="[[DIAGRAM_TYPE_LIFECYCLE_ZH]]">[[DIAGRAM_TYPE_LIFECYCLE_EN]]</button>
</div>
</section>
<section class="workbench" aria-label="Archify quick start">
<article class="panel" id="install">
<div class="panel-kicker"><b>01</b><span data-en="Install the skill" data-zh="安装 Skill">Install the skill</span></div>
<h2 data-en="Keep the tool local." data-zh="让工具留在本地。">Keep the tool local.</h2>
<p class="panel-intro" data-en="Choose Cursor, Codex, Claude Code, OpenCode, or GitHub Copilot. The switcher gives each one the same checked Skill and zero-dependency renderers—no vendor-specific fork." data-zh="选择 Cursor、Codex、Claude Code、OpenCode 或 GitHub Copilot。切换器为每个 Agent 提供同一份经过检查的 Skill 与零依赖渲染器,不维护厂商专属分叉。">Choose Cursor, Codex, Claude Code, OpenCode, or GitHub Copilot. The switcher gives each one the same checked Skill and zero-dependency renderers—no vendor-specific fork.</p>
<div class="agent-picker">
<p class="agent-picker-head"><span data-en="Choose your coding agent" data-zh="选择你的编码 Agent">Choose your coding agent</span><strong id="agent-state">Codex · same Skill</strong></p>
<div class="agent-tabs" role="tablist" aria-label="Coding agent">
<button class="agent-tab" type="button" role="tab" data-agent="cursor">Cursor</button>
<button class="agent-tab" type="button" role="tab" data-agent="codex">Codex</button>
<button class="agent-tab" type="button" role="tab" data-agent="claude-code">Claude Code</button>
<button class="agent-tab" type="button" role="tab" data-agent="opencode">OpenCode</button>
<button class="agent-tab" type="button" role="tab" data-agent="github-copilot">GitHub Copilot</button>
</div>
</div>
<div class="command-block">
<div class="command-bar"><span data-en="Global install" data-zh="全局安装">Global install</span><button class="copy-button" type="button" data-copy-source="install-command" data-en="Copy" data-zh="复制">Copy</button></div>
<pre id="install-command">npx -y skills add tt-a1i/archify --skill archify --agent codex --global --copy --yes</pre>
</div>
<div class="command-block">
<div class="command-bar"><span data-en="This repository only" data-zh="仅安装到当前仓库">This repository only</span><button class="copy-button" type="button" data-copy-source="project-command" data-en="Copy" data-zh="复制">Copy</button></div>
<pre id="project-command">npx -y skills add tt-a1i/archify --skill archify --agent codex --copy --yes</pre>
</div>
<p class="secondary-note" data-en="The Start link carries only your agent, language, diagram type, input mode, and a coarse source label. Journey events stay in this browser session and are never sent by Archify. No repository path, title, node, relationship, or source JSON is recorded." data-zh="Start 链接只携带 Agent、语言、图表类型、输入模式和粗粒度来源标签。转化步骤只保存在当前浏览器会话中,Archify 不会发送这些数据,也不会记录仓库路径、标题、节点、关系或源 JSON。">The Start link carries only your agent, language, diagram type, input mode, and a coarse source label. Journey events stay in this browser session and are never sent by Archify. No repository path, title, node, relationship, or source JSON is recorded.</p>
</article>
<article class="panel" aria-live="polite">
<div class="panel-kicker"><b>02</b><span data-en="Ask one bounded question" data-zh="只问一个有边界的问题">Ask one bounded question</span></div>
<h2 id="recipe-title">System overview</h2>
<p class="question" id="recipe-question"></p>
<ul class="include-list" id="include-list" aria-label="Required evidence"></ul>
<p class="prompt-box" id="recipe-prompt"></p>
<div class="actions">
<button class="action action-primary" id="copy-starter" type="button" data-en="Copy install + prompt" data-zh="复制安装命令 + 提示词">Copy install + prompt</button>
<button class="action" id="copy-prompt" type="button" data-en="Prompt only" data-zh="仅复制提示词">Prompt only</button>
<a class="action" id="proof-link" href="gallery.html" data-en="Open verified proof ↗" data-zh="打开验证成品 ↗">Open verified proof ↗</a>
<a class="action" href="guide.html" data-en="Need another recipe?" data-zh="需要其他配方?">Need another recipe?</a>
</div>
<p class="proof-meta" id="proof-meta"></p>
</article>
</section>
<footer class="page-footer">
<span data-en="Archify v[[ARCHIFY_VERSION]] · development · self-contained HTML · typed JSON source" data-zh="Archify v[[ARCHIFY_VERSION]] · 开发版 · 独立 HTML · 类型化 JSON 源">Archify v[[ARCHIFY_VERSION]] · development · self-contained HTML · typed JSON source</span>
<span id="copy-status" role="status" aria-live="polite"></span>
<a href="https://github.com/tt-a1i/archify" data-en="View source on GitHub ↗" data-zh="在 GitHub 查看源码 ↗">View source on GitHub ↗</a>
</footer>
</main>
<script id="start-data" type="application/json">[[START_JSON]]</script>
<script src="assets/site-language.js"></script>
<script>
(function () {
'use strict';
var DATA = JSON.parse(document.getElementById('start-data').textContent);
var KNOWN_TYPES = new Set(['architecture', 'workflow', 'sequence', 'dataflow', 'lifecycle']);
var KNOWN_AGENTS = new Set(['cursor', 'codex', 'claude-code', 'opencode', 'github-copilot']);
var KNOWN_INPUTS = new Set(['description', 'repository']);
var KNOWN_SOURCES = new Set(['artifact', 'gallery', 'readme', 'direct']);
var EVENT_KEY = 'archify.start.events.v1';
var params = new URLSearchParams(window.location.search);
var requestedType = params.get('type');
var requestedAgent = params.get('agent');
var requestedSource = params.get('source');
var requestedInput = params.get('input');
var type = KNOWN_TYPES.has(requestedType) ? requestedType : 'architecture';
var agent = KNOWN_AGENTS.has(requestedAgent) ? requestedAgent : 'codex';
var source = KNOWN_SOURCES.has(requestedSource) ? requestedSource : 'direct';
var input = KNOWN_INPUTS.has(requestedInput) ? requestedInput : 'description';
var language = ArchifySiteLanguage.read();
var title = document.getElementById('recipe-title');
var question = document.getElementById('recipe-question');
var prompt = document.getElementById('recipe-prompt');
var includeList = document.getElementById('include-list');
var proofLink = document.getElementById('proof-link');
var proofMeta = document.getElementById('proof-meta');
var copyStatus = document.getElementById('copy-status');
var languageButton = document.getElementById('language');
var agentState = document.getElementById('agent-state');
var installCommand = document.getElementById('install-command');
var projectCommand = document.getElementById('project-command');
function copyForElement(element) {
return language === 'zh' ? element.dataset.zh : element.dataset.en;
}
function updateStaticCopy() {
document.documentElement.lang = language === 'zh' ? 'zh-CN' : 'en';
document.querySelectorAll('[data-en][data-zh]').forEach(function (element) {
element.textContent = copyForElement(element);
});
languageButton.textContent = language === 'zh' ? 'EN' : '中文';
languageButton.setAttribute('aria-label', language === 'zh' ? 'Switch to English' : '切换到中文');
}
function updateUrl() {
var next = new URL(window.location.href);
next.searchParams.set('type', type);
next.searchParams.set('agent', agent);
next.searchParams.delete('lang');
next.searchParams.set('source', source);
next.searchParams.set('input', input);
history.replaceState(null, '', next.pathname + next.search + next.hash);
}
function recordStep(step) {
var detail = {
schemaVersion: 1,
step: step,
source: source,
type: type,
agent: agent,
language: language
};
try {
var events = JSON.parse(sessionStorage.getItem(EVENT_KEY) || '[]');
if (!Array.isArray(events)) events = [];
events.push(detail);
sessionStorage.setItem(EVENT_KEY, JSON.stringify(events.slice(-24)));
} catch (_) {}
try { window.dispatchEvent(new CustomEvent('archify:start-funnel', { detail: detail })); } catch (_) {}
}
window.ArchifyStartMetrics = {
snapshot: function () {
try {
var events = JSON.parse(sessionStorage.getItem(EVENT_KEY) || '[]');
return Array.isArray(events) ? events.slice() : [];
} catch (_) { return []; }
}
};
function currentPrompt() {
return input === 'description'
? DATA[type][language].descriptionPrompt
: DATA[type][language].repositoryPrompt;
}
function render() {
language = ArchifySiteLanguage.write(language);
var recipe = DATA[type];
var copy = recipe[language];
updateStaticCopy();
document.querySelectorAll('[data-type]').forEach(function (button) {
var active = button.dataset.type === type;
button.setAttribute('aria-selected', String(active));
button.tabIndex = active ? 0 : -1;
});
document.querySelectorAll('[data-agent]').forEach(function (button) {
var active = button.dataset.agent === agent;
button.setAttribute('aria-selected', String(active));
button.tabIndex = active ? 0 : -1;
});
document.querySelectorAll('[data-input]').forEach(function (button) {
var active = button.dataset.input === input;
button.setAttribute('aria-selected', String(active));
button.tabIndex = active ? 0 : -1;
});
var agentName = document.querySelector('[data-agent="' + agent + '"]').textContent;
agentState.textContent = agentName + (language === 'zh' ? ' · 同一份 Skill' : ' · same Skill');
installCommand.textContent = 'npx -y skills add tt-a1i/archify --skill archify --agent ' + agent + ' --global --copy --yes';
projectCommand.textContent = 'npx -y skills add tt-a1i/archify --skill archify --agent ' + agent + ' --copy --yes';
title.textContent = copy.title;
question.textContent = copy.question;
prompt.textContent = currentPrompt();
includeList.replaceChildren.apply(includeList, copy.include.map(function (item) {
var entry = document.createElement('li');
entry.textContent = item;
return entry;
}));
proofLink.href = 'gallery.html#proof-' + encodeURIComponent(recipe.proof);
proofMeta.textContent = language === 'zh'
? '验证成品 · ' + recipe.presentation.preset + ' · ' + recipe.presentation.motion
: 'Verified proof · ' + recipe.presentation.preset + ' · ' + recipe.presentation.motion;
copyStatus.textContent = '';
updateUrl();
}
function fallbackCopy(text) {
var area = document.createElement('textarea');
area.value = text;
area.setAttribute('readonly', '');
area.style.position = 'fixed';
area.style.opacity = '0';
document.body.appendChild(area);
area.select();
var ok = document.execCommand('copy');
area.remove();
if (!ok) throw new Error('copy failed');
}
function starterText() {
var agentName = document.querySelector('[data-agent="' + agent + '"]').textContent;
if (language === 'zh') {
return '为 ' + agentName + ' 安装 Archify:\n' + installCommand.textContent.trim()
+ (input === 'description' ? '\n\n然后在任意新对话中直接告诉 ' : '\n\n然后在目标仓库中让 ') + agentName + ':\n' + currentPrompt();
}
return 'Install Archify for ' + agentName + ':\n' + installCommand.textContent.trim()
+ (input === 'description' ? '\n\nThen start any new chat and tell ' : '\n\nThen, in your target repository, ask ') + agentName + ':\n' + currentPrompt();
}
async function copyText(text, step) {
try {
if (navigator.clipboard && window.isSecureContext) await navigator.clipboard.writeText(text);
else fallbackCopy(text);
if (step) recordStep(step);
copyStatus.textContent = language === 'zh' ? '已复制到剪贴板。' : 'Copied to clipboard.';
} catch (_) {
copyStatus.textContent = language === 'zh' ? '复制失败,请手动选择文本。' : 'Copy failed. Select the text manually.';
}
}
document.querySelectorAll('[data-type]').forEach(function (button) {
button.addEventListener('click', function () {
type = button.dataset.type;
render();
});
button.addEventListener('keydown', function (event) {
var buttons = Array.from(document.querySelectorAll('[data-type]'));
var index = buttons.indexOf(button);
if (event.key === 'ArrowRight' || event.key === 'ArrowDown') index = (index + 1) % buttons.length;
else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') index = (index - 1 + buttons.length) % buttons.length;
else if (event.key === 'Home') index = 0;
else if (event.key === 'End') index = buttons.length - 1;
else return;
event.preventDefault();
buttons[index].click();
buttons[index].focus();
});
});
document.querySelectorAll('[data-agent]').forEach(function (button) {
button.addEventListener('click', function () {
agent = button.dataset.agent;
render();
});
button.addEventListener('keydown', function (event) {
var buttons = Array.from(document.querySelectorAll('[data-agent]'));
var index = buttons.indexOf(button);
if (event.key === 'ArrowRight' || event.key === 'ArrowDown') index = (index + 1) % buttons.length;
else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') index = (index - 1 + buttons.length) % buttons.length;
else if (event.key === 'Home') index = 0;
else if (event.key === 'End') index = buttons.length - 1;
else return;
event.preventDefault();
buttons[index].click();
buttons[index].focus();
});
});
document.querySelectorAll('[data-input]').forEach(function (button) {
button.addEventListener('click', function () {
input = button.dataset.input;
render();
});
button.addEventListener('keydown', function (event) {
var buttons = Array.from(document.querySelectorAll('[data-input]'));
var index = buttons.indexOf(button);
if (event.key === 'ArrowRight' || event.key === 'ArrowDown') index = (index + 1) % buttons.length;
else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') index = (index - 1 + buttons.length) % buttons.length;
else if (event.key === 'Home') index = 0;
else if (event.key === 'End') index = buttons.length - 1;
else return;
event.preventDefault();
buttons[index].click();
buttons[index].focus();
});
});
document.querySelectorAll('[data-copy-source]').forEach(function (button) {
button.addEventListener('click', function () {
var step = button.dataset.copySource === 'install-command' ? 'global_install_copy' : 'project_install_copy';
copyText(document.getElementById(button.dataset.copySource).textContent.trim(), step);
});
});
document.getElementById('copy-prompt').addEventListener('click', function () {
copyText(currentPrompt(), 'prompt_copy');
});
document.getElementById('copy-starter').addEventListener('click', function () {
copyText(starterText(), 'starter_copy');
});
proofLink.addEventListener('click', function () { recordStep('proof_open'); });
languageButton.addEventListener('click', function () {
language = language === 'zh' ? 'en' : 'zh';
render();
});
render();
recordStep('start_view');
})();
</script>
</body>
</html>