Files
archify/docs/start.html
T
0853a80500 fix(site): preserve language across navigation (#159)
* fix(site): preserve language across navigation

* docs: use official-style Star History chart (#156)

* fix(site): make language and navigation state deterministic

* test(site): isolate serialized browser integration

* fix(site): migrate legacy language preferences

---------

Co-authored-by: tt-a1i <53142663+tt-a1i@users.noreply.github.com>
Co-authored-by: tt-a1i <2801884530@qq.com>
2026-08-29 02:45:35 +08:00

471 lines
39 KiB
HTML
Generated
Raw 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 — From Artifact to First Diagram</title>
<meta name="description" content="Install Archify, copy one bounded prompt, and create a verifiable technical diagram without sending repository or diagram content to this page.">
<meta name="theme-color" content="#eff2f1">
<meta property="og:type" content="website">
<meta property="og:title" content="Archify Start — One bounded prompt to a verifiable diagram">
<meta property="og:description" content="Choose a technical question, install Archify, and copy an exact prompt backed by a verified example.">
<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="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28'><polygon points='14,2 26,8 26,20 14,26 2,20 2,8' fill='%23083344' stroke='%2322d3ee' stroke-width='1.5'/><circle cx='14' cy='15' r='2.5' fill='%2322d3ee'/></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; }
/* 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); }
.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">
<span class="nav-logo-text">Archify</span>
<span class="nav-logo-path">/ 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="From a real artifact to your own" data-zh="从真实成品到你自己的图">From a real artifact to your own</p>
<h1><span data-en="One install." data-zh="一次安装,">One install.</span><span class="title-gap" aria-hidden="true"> </span><em data-en="One bounded prompt." data-zh="一段有边界的提示词。">One bounded prompt.</em></h1>
</div>
<div>
<p class="lead-copy" data-en="Choose the technical question closest to the artifact you saw. Copy a tested starting prompt, then let your coding agent inspect the real repository before it draws." data-zh="选择最接近你刚才所看成品的技术问题。复制一段经过验证的起始提示词,再让编码智能体先检查真实仓库,然后作图。">Choose the technical question closest to the artifact you saw. Copy a tested starting prompt, then let your coding agent inspect the real repository before it draws.</p>
<div class="trust-line" data-en="No repository content or diagram data is sent to this page." data-zh="这个页面不会接收仓库内容或图表数据。">No repository content or diagram data is sent to this page.</div>
</div>
</header>
<section class="type-shell" aria-labelledby="type-label">
<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="Architecture" data-zh="架构图">Architecture</button>
<button class="type-tab" type="button" role="tab" data-type="workflow" data-en="Workflow" data-zh="工作流">Workflow</button>
<button class="type-tab" type="button" role="tab" data-type="sequence" data-en="Sequence" data-zh="时序图">Sequence</button>
<button class="type-tab" type="button" role="tab" data-type="dataflow" data-en="Data flow" data-zh="数据流">Data flow</button>
<button class="type-tab" type="button" role="tab" data-type="lifecycle" data-en="Lifecycle" data-zh="生命周期">Lifecycle</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, or OpenCode. The switcher gives each one the same checked Skill and zero-dependency renderers—no vendor-specific fork." data-zh="选择 Cursor、Codex、Claude Code 或 OpenCode。切换器为每个 Agent 提供同一份经过检查的 Skill 与零依赖渲染器,不维护厂商专属分叉。">Choose Cursor, Codex, Claude Code, or OpenCode. 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>
</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="Raven is supported through a manual ZIP installation, not a generated agent-switcher command. Extract archify.zip into ~/.raven/workspace/skills, which yields ~/.raven/workspace/skills/archify." data-zh="Raven 采用 ZIP 手动安装,不使用 Agent 切换器生成命令。将 archify.zip 解压到 ~/.raven/workspace/skills,解压后会得到 ~/.raven/workspace/skills/archify。">Raven is supported through a manual ZIP installation, not a generated agent-switcher command. Extract archify.zip into ~/.raven/workspace/skills, which yields ~/.raven/workspace/skills/archify.</p>
<p class="secondary-note" data-en="The Start link carries only your agent, language, diagram type, 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, 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 v2.16.0-dev.0 · development · self-contained HTML · typed JSON source" data-zh="Archify v2.16.0-dev.0 · 开发版 · 独立 HTML · 类型化 JSON 源">Archify v2.16.0-dev.0 · 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">{"architecture":{"id":"system-overview","type":"architecture","proof":"web-app","presentation":{"preset":"classic","motion":"static","views":"optional"},"en":{"title":"System overview","question":"What exists, who owns it, and how is it connected?","summary":"A bounded map of core components, external dependencies, primary paths, and trust boundaries.","useWhen":"Onboarding, design reviews, repository orientation, or explaining a service landscape.","avoidWhen":"The audience needs exact call order, state transitions, or row-level data lineage.","include":["8–12 core components","one primary path","external dependencies","trust boundaries"],"prompt":"Analyze this repository, then use Archify to create a high-level architecture diagram. Show 8–12 core runtime components, one primary request or data path, external dependencies, ownership or trust boundaries, and put supporting detail in cards instead of adding more edges."},"zh":{"title":"系统总览","question":"系统里有什么、归谁负责、彼此如何连接?","summary":"用一张有边界的图展示核心组件、外部依赖、主路径和信任边界。","useWhen":"适合新人上手、方案评审、仓库梳理和服务全景说明。","avoidWhen":"如果重点是精确调用顺序、状态流转或字段级血缘,请换其他配方。","include":["8–12 个核心组件","一条主路径","外部依赖","归属或信任边界"],"prompt":"分析这个仓库,然后用 Archify 生成高层系统架构图。展示 8–12 个核心运行时组件、一条主要请求或数据路径、外部依赖、归属或信任边界;支持性细节放进卡片,不要继续堆连线。"}},"workflow":{"id":"agent-tool-call","type":"workflow","proof":"agent-tool-call","presentation":{"preset":"signal-flow","motion":"trace","views":"recommended"},"en":{"title":"Agent tool-call loop","question":"How does an agent plan, get permission, act, recover, and report?","summary":"A lane-based agent loop with policy gates, tool execution, exception recovery, evidence, and final response.","useWhen":"Explaining agent runtimes, MCP/tool orchestration, approvals, retries, or observability.","avoidWhen":"The goal is only to show static agent components or exact API message timing.","include":["request and planning","policy or approval gate","tool execution","exception and evidence paths"],"prompt":"Use Archify workflow mode to explain this agent tool-call loop. Separate user surface, agent runtime, policy boundary, exception handling, tool execution, and observability into lanes. Make the successful path primary and show approval, retry, blocked, and evidence paths explicitly."},"zh":{"title":"智能体工具调用","question":"智能体如何规划、获批、执行、恢复并汇报?","summary":"用泳道表达策略门、工具执行、异常恢复、证据和最终回复。","useWhen":"适合解释 Agent Runtime、MCP/工具编排、审批、重试和可观测性。","avoidWhen":"如果只想看静态组件,或重点是精确 API 消息时序,请换其他配方。","include":["请求与规划","策略或审批门","工具执行","异常与证据路径"],"prompt":"用 Archify 工作流模式解释这段智能体工具调用。把用户界面、Agent Runtime、策略边界、异常处理、工具执行和可观测性分成泳道;突出成功主路径,并明确展示审批、重试、阻塞和证据路径。"}},"sequence":{"id":"api-request","type":"sequence","proof":"cache-miss","presentation":{"preset":"classic","motion":"trace","views":"optional"},"en":{"title":"API request chain","question":"Who calls whom, in what order, and what returns?","summary":"A time-ordered request path with authentication, cache fallback, persistence, return traffic, and async trace.","useWhen":"API documentation, debugging request latency, auth reviews, or explaining cache fallback.","avoidWhen":"Order is unimportant and the audience only needs the stable service topology.","include":["callers and callees","request and return messages","fallback or error path","async side effects"],"prompt":"Use Archify sequence mode to show this request from caller to final response. Include authentication, cache hit or miss, persistence fallback, return messages, and asynchronous trace or event emission. Keep message labels short and order unambiguous."},"zh":{"title":"API 请求链","question":"谁调用谁、顺序如何、最终返回什么?","summary":"按时间展示鉴权、缓存回退、持久化、返回流量和异步追踪。","useWhen":"适合 API 文档、请求耗时排查、鉴权评审和缓存回退说明。","avoidWhen":"如果顺序不重要,受众只需要稳定的服务拓扑,请用架构图。","include":["调用方与被调用方","请求与返回消息","回退或错误路径","异步副作用"],"prompt":"用 Archify 时序模式展示从调用方到最终响应的完整请求。包含鉴权、缓存命中或未命中、持久化回退、返回消息,以及异步 Trace 或事件上报;消息标签保持简短,顺序必须明确。"}},"dataflow":{"id":"event-stream","type":"dataflow","proof":"event-stream","presentation":{"preset":"signal-flow","motion":"trace","views":"recommended"},"en":{"title":"Event-stream topology","question":"Which events move through which topics, processors, groups, and failure paths?","summary":"A stream map of producers, topics, ordered processors, consumer groups, state, replay, and DLQ.","useWhen":"Kafka/event-platform design, stream processing reviews, ownership, replay, and failure handling.","avoidWhen":"Topic names, consumer groups, and delivery semantics are not known—use a generic workflow instead.","include":["producers and event names","topics and ordering","processors and consumer groups","state, replay, and DLQ"],"prompt":"Use Archify dataflow mode to draw this event-stream topology. Name producers, events, topics, ordered processors, consumer groups, state stores, replay paths, and the DLQ. Show ownership and delivery semantics only when supported by evidence."},"zh":{"title":"事件流拓扑","question":"哪些事件经过哪些 Topic、处理器、消费者组和失败路径?","summary":"展示生产者、Topic、有序处理器、消费者组、状态、重放和 DLQ。","useWhen":"适合 Kafka/事件平台设计、流处理评审、归属、重放和失败处理。","avoidWhen":"如果 Topic、消费者组和投递语义都不清楚,请先用通用工作流,不要编造事件拓扑。","include":["生产者与事件名","Topic 与顺序","处理器与消费者组","状态、重放与 DLQ"],"prompt":"用 Archify 数据流模式绘制这段事件流拓扑。命名生产者、事件、Topic、有序处理器、消费者组、状态存储、重放路径和 DLQ;只有在证据充分时才标注归属和投递语义。"}},"lifecycle":{"id":"object-lifecycle","type":"lifecycle","proof":"agent-run","presentation":{"preset":"classic","motion":"trace","views":"optional"},"en":{"title":"Object lifecycle","question":"Which states exist, what events move between them, and how does it end?","summary":"A state model with active work, waits, retries, cancellation, failure, and explicit terminal outcomes.","useWhen":"Tasks, orders, tickets, subscriptions, jobs, agent runs, or any durable object with status.","avoidWhen":"The object has no durable state and the real question is participant interaction over time.","include":["start and active states","event-labelled transitions","wait and retry states","all terminal outcomes"],"prompt":"Use Archify lifecycle mode to model this object. Separate main progress, waiting or interruption states, and terminal outcomes. Label transitions with events, include retry, cancellation, timeout, success, and failure where real, and never hide an ending."},"zh":{"title":"对象生命周期","question":"有哪些状态、什么事件触发流转、最终如何结束?","summary":"展示执行、等待、重试、取消、失败以及明确终态的状态模型。","useWhen":"适合任务、订单、工单、订阅、作业、Agent Run 等带持久状态的对象。","avoidWhen":"对象没有持久状态,真正问题是参与者随时间的交互时,请使用时序图。","include":["开始与执行态","带事件的转换","等待与重试态","所有终态"],"prompt":"用 Archify 生命周期模式建模这个对象。分开主进度、等待或中断状态和终态;用事件标注转换,并在真实存在时展示重试、取消、超时、成功和失败,不能隐藏任何结束方式。"}}}</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']);
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 type = KNOWN_TYPES.has(requestedType) ? requestedType : 'architecture';
var agent = KNOWN_AGENTS.has(requestedAgent) ? requestedAgent : 'codex';
var source = KNOWN_SOURCES.has(requestedSource) ? requestedSource : 'direct';
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);
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 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;
});
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 = copy.prompt;
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()
+ '\n\n然后在目标仓库中让 ' + agentName + ' 执行:\n' + DATA[type][language].prompt;
}
return 'Install Archify for ' + agentName + ':\n' + installCommand.textContent.trim()
+ '\n\nThen, in your target repository, ask ' + agentName + ':\n' + DATA[type][language].prompt;
}
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-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(DATA[type][language].prompt, '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>