diff --git a/docs/content/_index.ko.md b/docs/content/_index.ko.md
@@ -13,6 +13,29 @@ cta_start = "시작하기"
cta_github = "GitHub에서 보기"
install_pick = "설치 방법"
install_note = "릴리스마다 체크섬이 붙은 타르볼도 함께 나갑니다 — x86_64·ARM64 리눅스, Apple Silicon macOS."
+install_prompt_label = "에이전트에게 줄 프롬프트 복사"
+install_prompt = """
+Set up sqzass in this project.
+
+Install it — it is not on crates.io, so `cargo install sqzass` fails:
+ curl -fsSL https://sqzass.sqzer.com/install.sh | sh
+ # from source: cargo install --git https://github.com/sqzer-x/sqzass
+
+Then scaffold and build:
+ sqzass init .
+ sqzass build -i .
+
+Things you cannot infer from the file tree: front matter is TOML fenced with
++++, not YAML; internal links are @/section/page.md, the source path rather
+than the URL, and images use root-absolute paths instead; broken references
+stop the build on purpose and there is no flag to downgrade them.
+
+Runtime messages are Korean but the error identifiers (SQZASS_E_CONFIG,
+SQZASS_E_CONTENT, ...) and doctor check names are ASCII and stable — match on
+those. --json works on every command and prints one object to stdout.
+
+The long version is at https://sqzass.sqzer.com/agent.md
+"""
bento_label = "왜 sqzass인가"
diff --git a/docs/content/_index.md b/docs/content/_index.md
@@ -13,6 +13,29 @@ cta_start = "Get started"
cta_github = "View on GitHub"
install_pick = "Install with"
install_note = "Every release also ships tarballs with checksums — Linux on x86_64 and ARM64, and Apple-silicon macOS."
+install_prompt_label = "Copy prompt for your agent"
+install_prompt = """
+Set up sqzass in this project.
+
+Install it — it is not on crates.io, so `cargo install sqzass` fails:
+ curl -fsSL https://sqzass.sqzer.com/install.sh | sh
+ # from source: cargo install --git https://github.com/sqzer-x/sqzass
+
+Then scaffold and build:
+ sqzass init .
+ sqzass build -i .
+
+Things you cannot infer from the file tree: front matter is TOML fenced with
++++, not YAML; internal links are @/section/page.md, the source path rather
+than the URL, and images use root-absolute paths instead; broken references
+stop the build on purpose and there is no flag to downgrade them.
+
+Runtime messages are Korean but the error identifiers (SQZASS_E_CONFIG,
+SQZASS_E_CONTENT, ...) and doctor check names are ASCII and stable — match on
+those. --json works on every command and prints one object to stdout.
+
+The long version is at https://sqzass.sqzer.com/agent.md
+"""
bento_label = "Why sqzass"
diff --git a/docs/content/start/installation.ko.md b/docs/content/start/installation.ko.md
@@ -41,6 +41,23 @@ yay -S sqzass # paru도, 클론해서 makepkg -si도 됩니다
`sqzass-bin`은 만들지 않았습니다. Arch에서 Rust 도구를 소스에서 빌드하는 건
정상이고, 패키지가 둘이면 어느 쪽이 최신인지 묻는 일만 생깁니다.
+## 코딩 에이전트로
+
+이걸 에이전트에 붙여 넣으면 추측 없이 끝냅니다.
+
+```
+Set up sqzass in this project.
+Read https://sqzass.sqzer.com/agent.md first — it covers the install (sqzass is
+not on crates.io), the TOML front matter, how @/ links resolve, and the error
+identifiers to match on.
+```
+
+[`/agent.md`](/agent.md)이 긴 쪽입니다. 같은 설치 명령과, 파일 트리만 봐서는
+알 수 없는 규칙들과, exit code 표가 들어 있습니다. 이 파일이 있는 이유는
+"정적 사이트 생성기를 붙여 줘"라는 말을 들은 에이전트가 그냥 두면
+`cargo install sqzass`부터 시도하기 때문입니다 — 그건 실패합니다. sqzass는
+git이나 릴리스 타르볼에서 설치합니다.
+
## 소스에서 빌드
```bash
diff --git a/docs/content/start/installation.md b/docs/content/start/installation.md
@@ -41,6 +41,23 @@ yay -S sqzass # or paru, or makepkg -si on a clone
There is no `sqzass-bin`. Building a Rust tool from source is normal on Arch,
and two packages would only raise the question of which one is current.
+## With a coding agent
+
+Paste this at an agent and it has enough to finish without guessing:
+
+```
+Set up sqzass in this project.
+Read https://sqzass.sqzer.com/agent.md first — it covers the install (sqzass is
+not on crates.io), the TOML front matter, how @/ links resolve, and the error
+identifiers to match on.
+```
+
+[`/agent.md`](/agent.md) is the long version: the same install commands, the
+rules that are not guessable from a file tree, and the exit-code table. It exists
+because an agent asked to "add a static site generator" will otherwise reach for
+`cargo install sqzass`, which fails — sqzass is installed from git or a release
+tarball.
+
## From source
```bash
diff --git a/docs/static/agent.md b/docs/static/agent.md
@@ -0,0 +1,80 @@
+# Set up sqzass in this project
+
+sqzass is a static site generator: markdown in, a directory of HTML out. One
+binary, no runtime — no Node, no Python, no system libraries.
+
+## 1. Install
+
+It is **not on crates.io**. `cargo install sqzass` will fail.
+
+```bash
+curl -fsSL https://sqzass.sqzer.com/install.sh | sh
+# with Rust: cargo install --git https://github.com/sqzer-x/sqzass
+# on Arch: yay -S sqzass
+```
+
+## 2. Scaffold and build
+
+`init` writes three files and refuses to run where a `sqzass.toml` already
+exists, so it cannot half-overwrite a site that is already there.
+
+```bash
+sqzass init . # sqzass.toml, content/_index.md, templates/page.html
+sqzass build -i . # writes public/
+sqzass serve -i . # live reload on http://127.0.0.1:3000
+```
+
+Two config keys are required: `title` and `base_url`. Everything else has a
+default.
+
+## 3. Rules you cannot infer from the file tree
+
+- Front matter is **TOML fenced with `+++`**, not YAML with `---`. `title` is
+ the only required field.
+- Internal links are `@/section/page.md` — the *source path* under `content/`,
+ not the URL. The build rewrites it and resolves it to the reader's language.
+- Images are different: use a root-absolute path, ``. `@/`
+ resolves against pages only, so `@/images/x.png` stops the build.
+- Translations sit beside each other: `page.md` and `page.ko.md`.
+- `page.content` is already HTML in templates, so it needs `| safe`. Templates
+ autoescape by default and reading an undefined value is an error.
+
+## 4. Errors are deliberate
+
+An unresolved link, a template that does not exist, two pages claiming one URL,
+a misspelled key in `sqzass.toml` or in front matter — each one stops the build
+and names the file and line. There is no flag to downgrade any of them to a
+warning. Fix the cause.
+
+## 5. Reading the output as a program
+
+Runtime messages are in Korean. The identifiers are not: error codes and
+`doctor` check names are ASCII and stable, so match on those rather than on
+message text.
+
+| Exit | Identifier | |
+|---|---|---|
+| `0` | | Success. |
+| `1` | `SQZASS_E` | Unclassified failure. |
+| `2` | | Bad command line (clap's code, not ours). |
+| `3` | `SQZASS_E_CONFIG` | `sqzass.toml`. |
+| `4` | `SQZASS_E_CONTENT` | Anything under `content/`. |
+| `5` | `SQZASS_E_TEMPLATE` | `templates/`, `i18n/`, or a missing asset. |
+| `6` | `SQZASS_E_IO` | Reading or writing failed. |
+| `7` | | `doctor` found something at or above `--fail-on`. |
+
+`--json` works on every command and prints one object to stdout — on failure
+too, so a script reads one pipe.
+
+```console
+$ sqzass build -i . --json
+{"ok":true,"output":"public","pages":1}
+
+$ sqzass doctor -i . --json
+{"findings":[{"check":"base-url","file":"sqzass.toml","message":"…","severity":"warn"}],"gated":1,"ok":false}
+```
+
+## Full documentation
+
+<https://sqzass.sqzer.com> — and <https://sqzass.sqzer.com/llms.txt> is a flat
+list of every page with its description.
diff --git a/docs/static/css/landing.css b/docs/static/css/landing.css
@@ -425,6 +425,29 @@ main { display: block; }
.install:has(#inst-3:checked) .pick-panel:nth-child(3) { visibility: visible; opacity: 1; }
.install-note { margin: 0.7rem 0 0; font-size: 0.82rem; color: var(--muted); }
+/* 설치 카드보다 조용해야 한다. 대부분의 방문자는 셸에 붙여 넣지 에이전트에
+ 붙여 넣지 않으므로, 있는 걸 알아볼 수는 있되 먼저 눈에 들어오면 안 된다. */
+.install-agent { margin: 0.55rem 0 0; }
+.agent-copy {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.34rem;
+ white-space: nowrap;
+ padding: 0.34rem 0.66rem;
+ border: 1px solid var(--line);
+ border-radius: 999px;
+ background: transparent;
+ color: var(--muted);
+ font: inherit;
+ font-size: 0.78rem;
+ line-height: 1.2;
+ cursor: pointer;
+ transition: color 0.15s, border-color 0.15s;
+}
+.agent-copy:hover { color: var(--ink); border-color: var(--ink-3); }
+.agent-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
+.agent-copy.is-done { color: var(--accent-ink); border-color: rgba(255, 140, 90, 0.55); }
+.agent-copy svg { flex: none; }
.pick-panel > code {
font-family: var(--mono);
diff --git a/docs/static/js/landing.js b/docs/static/js/landing.js
@@ -16,16 +16,24 @@
}
/* 설치 한 줄 복사 */
- document.querySelectorAll(".inst-copy").forEach(function (btn) {
+ /* 복사 버튼은 클래스가 아니라 data-copy-text로 찾는다. 클래스로 찾으면 새
+ 버튼마다 아이콘 전용 스타일(.inst-copy는 2rem 정사각형)을 같이 받게 된다. */
+ document.querySelectorAll("[data-copy-text]").forEach(function (btn) {
var label = btn.getAttribute("aria-label");
+ /* 글자를 달고 있는 버튼은 그 글자가 바뀌어야 눌린 걸 안다. 아이콘만 있는
+ 버튼은 aria-label만 바꾼다 — 볼 게 없으니 들릴 것이라도 바뀌어야 한다. */
+ var text = btn.querySelector(".copy-label");
+ var was = text ? text.textContent : null;
btn.addEventListener("click", function () {
if (!navigator.clipboard) return;
navigator.clipboard.writeText(btn.getAttribute("data-copy-text") || "").then(function () {
btn.classList.add("is-done");
- btn.setAttribute("aria-label", btn.getAttribute("data-copied"));
+ if (label) btn.setAttribute("aria-label", btn.getAttribute("data-copied"));
+ if (text) text.textContent = btn.getAttribute("data-copied");
setTimeout(function () {
btn.classList.remove("is-done");
- btn.setAttribute("aria-label", label);
+ if (label) btn.setAttribute("aria-label", label);
+ if (text) text.textContent = was;
}, 1600);
});
});
diff --git a/docs/templates/landing.html b/docs/templates/landing.html
@@ -111,7 +111,18 @@
{%- endfor %}
</div>
</fieldset>
+ {#- 에이전트용 프롬프트. 설치 명령과 나란히 놓지 않고 카드 밖에 따로 둔다 —
+ 붙여 넣을 곳이 셸이 아니라 다른 도구라, 같은 탭에 섞으면 어느 쪽이
+ 어디로 가는 것인지 흐려진다. #}
<p class="install-note" data-reveal>{{ page.extra.install_note }}</p>
+ <p class="install-agent" data-reveal>
+ <button class="agent-copy" type="button"
+ data-copy-text="{{ page.extra.install_prompt }}"
+ data-copied="{{ t("copied") }}">
+ <svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>
+ <span class="copy-label">{{ page.extra.install_prompt_label }}</span>
+ </button>
+ </p>
<div class="lede" data-reveal>
{{ page.content | safe }}
</div>
|