Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The initial playground includes:
- Distinct, accessible syntax palettes for light and dark color modes
- Compiler-style diagnostics with source selection, code frames, expected values, help, and related locations
- Safe SVG image preview, expanded dialog, and download
- User-selected provider icon stores with searchable AWS, Google Cloud, Azure, and tool artwork

Authentication, persistence, collaboration, and paid themes remain outside this delivery. Cloudflare configuration targets the `stack-web` Worker and publishes the combined Vite and VitePress output as static assets.

Expand Down
70 changes: 5 additions & 65 deletions docs/.vitepress/theme/components/ProviderCatalog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import catalogData from "../data/provider-catalogs.json"

type Locale = "en" | "ja" | "zh" | "ko"
type CatalogIcon = (typeof catalogData.providers)[number]["icons"][number]
type CatalogSource = (typeof catalogData.providers)[number]["source"] & { id: string }

const props = defineProps<{ locale: Locale }>()
const pageSize = 100
Expand All @@ -20,17 +19,14 @@ const labels = {
en: {
allCategories: "All categories",
allProviders: "All providers",
commandIntro: "Download, import, and render",
commandIntro: "Import this provider",
category: "Category",
copy: "Copy",
copied: "Copied",
download: "Download ZIP",
guidelines: "Guidelines",
hash: "Expected SHA-256",
kind: "Kind",
noResults: "No icon IDs match these filters.",
officialPage: "Official download page",
primaryArchive: "Primary archive",
product: "Product",
results: "results",
search: "Search ID, product, or category",
Expand All @@ -41,17 +37,14 @@ const labels = {
ja: {
allCategories: "すべてのcategory",
allProviders: "すべてのprovider",
commandIntro: "Download・import・render",
commandIntro: "このproviderをimport",
category: "Category",
copy: "コピー",
copied: "コピー済み",
download: "ZIPをdownload",
guidelines: "Guideline",
hash: "期待するSHA-256",
kind: "Kind",
noResults: "条件に一致するicon IDはありません。",
officialPage: "公式download page",
primaryArchive: "Primary archive",
product: "Product",
results: "件",
search: "ID、product、categoryを検索",
Expand All @@ -62,17 +55,14 @@ const labels = {
zh: {
allCategories: "所有分类",
allProviders: "所有提供商",
commandIntro: "下载、导入并渲染",
commandIntro: "导入此服务商",
category: "分类",
copy: "复制",
copied: "已复制",
download: "下载 ZIP",
guidelines: "使用指南",
hash: "预期 SHA-256",
kind: "类型",
noResults: "没有符合筛选条件的图标 ID。",
officialPage: "官方下载页面",
primaryArchive: "主压缩包",
product: "产品",
results: "项结果",
search: "搜索 ID、产品或分类",
Expand All @@ -83,17 +73,14 @@ const labels = {
ko: {
allCategories: "모든 카테고리",
allProviders: "모든 제공자",
commandIntro: "다운로드, import, render",
commandIntro: "이 제공자 가져오기",
category: "카테고리",
copy: "복사",
copied: "복사됨",
download: "ZIP 다운로드",
guidelines: "사용 지침",
hash: "예상 SHA-256",
kind: "종류",
noResults: "필터와 일치하는 아이콘 ID가 없습니다.",
officialPage: "공식 다운로드 페이지",
primaryArchive: "Primary archive",
product: "제품",
results: "개 결과",
search: "ID, 제품 또는 카테고리 검색",
Expand All @@ -103,46 +90,14 @@ const labels = {
},
} as const

const archiveFilenames: Record<string, Record<string, string>> = {
aws: { primary: "aws-icons.zip" },
gcp: {
primary: "gcp-core-products-icons.zip",
categories: "gcp-category-icons.zip",
},
azure: { primary: "azure-icons.zip" },
"simple-icons": { primary: "simple-icons-16.29.0.zip" },
}

const text = computed(() => labels[props.locale])
const selectedProvider = computed(() =>
catalogData.providers.find((item) => item.id === provider.value),
)
const selectedProviderSources = computed<CatalogSource[]>(() => {
const item = selectedProvider.value
if (!item) return []
return [
{ ...item.source, id: "primary" },
...item.additionalSources.map((source) => ({ ...source, id: source.id })),
]
})
const selectedProviderCommands = computed(() => {
const item = selectedProvider.value
if (!item) return ""

const filenames = archiveFilenames[item.id]
const lines = selectedProviderSources.value.map(
(source) => `$ curl -fL "${source.archiveUrl}" -o ${filenames[source.id]}`,
)
const importLines = [`$ stack icons import ${item.id} ./${filenames.primary} \\`]
for (const source of item.additionalSources) {
importLines.push(` --source ${source.id}=./${filenames[source.id]} \\`)
}
importLines.push(` --accept-terms -o .stack-icons/${item.id}`)
lines.push(
importLines.join("\n"),
`$ stack render architecture.stack --provider-pack .stack-icons/${item.id} -o architecture.svg`,
)
return lines.join("\n")
return `$ stack icons import ${item.id} --accept-terms`
})
const allIcons = computed(() =>
catalogData.providers.flatMap((item) =>
Expand Down Expand Up @@ -225,21 +180,6 @@ onBeforeUnmount(() => window.clearTimeout(copyTimer))
{{ text.terms }}
</a>
</div>
<div class="stack-provider-setup__sources">
<article v-for="sourceItem in selectedProviderSources" :key="sourceItem.id">
<strong>
{{ sourceItem.id === "primary" ? text.primaryArchive : sourceItem.id }}
</strong>
<span>{{ sourceItem.release }}</span>
<a :href="sourceItem.archiveUrl" rel="noreferrer" target="_blank">
{{ text.download }}
</a>
<small>
{{ text.hash }}
<code>{{ sourceItem.archiveSha256.replace("sha256:", "") }}</code>
</small>
</article>
</div>
<p>{{ text.commandIntro }}</p>
<pre tabindex="0"><code>{{ selectedProviderCommands }}</code></pre>
</section>
Expand Down
115 changes: 71 additions & 44 deletions docs/guide/provider-icons.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
# Provider icons

Stack supports a provider-neutral core icon catalog without setup. AWS, Google Cloud, Azure, and common developer or collaboration artwork is available through user-imported provider packs. The searchable catalog below is public metadata, but Stack does not host or redistribute the vendor SVG files.
Stack includes a provider-neutral core icon catalog. AWS, Google Cloud, Azure, and common developer and collaboration artwork are available through provider packs stored in your user-managed icon store.

## Available provider catalog

The audited catalog contains 1,051 IDs: 305 AWS Architecture Icons, all 19 Google Cloud core-product and 26 category icons, 639 Azure service icons after exact-byte deduplication, and 62 curated tool icons. Search or filter the complete list without loading any SVG bytes. Results are shown 100 at a time so the page remains usable on smaller devices.
The audited catalog contains 1,051 IDs: 305 AWS Architecture Icons, 45 Google Cloud product and category icons, 639 Azure service icons, and 62 curated tool icons. The tool catalog includes GitHub, GitHub Actions, Notion, Linear, Atlassian, Jira, Confluence, Docker, Kubernetes, Terraform, Datadog, Grafana, Sentry, and more.

<ProviderCatalog locale="en" />

Every imported manifest records the official product name, every contributing source release and archive hash, terms URL, review date, permitted output categories, and non-endorsement notice. Curated tool records also retain the rights owner's brand source and guideline links. A provider pack adds only artwork; the authored node `kind` still controls its semantic styling and layout.

## Why artwork is not hosted
Select a provider card to see its import command, then search or filter the complete catalog. Results are shown 100 at a time for comfortable use on smaller devices.

The reviewed vendor guidance permits particular diagram and documentation uses, but does not clearly grant Stack permission to repackage every SVG byte in its website, npm package, WebAssembly module, or native binary. Static Documentation therefore shows searchable catalog metadata, provenance, and exact IDs without copying vendor artwork.

The curated tool archive comes from [Simple Icons](https://simpleicons.org/). Its CC0 distribution does not imply that every underlying brand mark is CC0, so inclusion is not permission or endorsement. Follow the per-icon source and guideline links shown above before use.
<ProviderCatalog locale="en" />

After you load a pack, the Playground shows its actual icons from your selected local files. It creates browser-local image URLs only after Engine validation and does not inject the SVG as page HTML. Review the linked provider terms before using or distributing a generated diagram.
A provider pack supplies artwork. The node `kind` in Stack source continues to control semantic styling and layout.

## Create a local pack
## Quick start

Select an AWS, Google Cloud, Azure, or Simple Icons card above to see its exact audited download URL, expected SHA-256, and complete `curl` → `stack icons import` → `stack render` commands. The CLI rejects an archive if its bytes no longer match the reviewed hash.
Import each provider used by a diagram once. `--accept-terms` records your confirmation that you reviewed the linked provider and brand terms.

```sh
$ stack icons list aws s3
$ stack icons list simple-icons github
$ stack icons import gcp --accept-terms
$ stack icons import simple-icons --accept-terms
$ stack render architecture.stack -o architecture.svg
```

Use `aws`, `gcp`, `azure`, or `simple-icons`. Google Cloud requires both official archives shown when its card is selected. The importer reads the files downloaded by `curl`; it does not fetch or upload them itself. It verifies every complete archive, reads only reviewed paths, removes active content, preserves colors and geometry, and creates `manifest.json`, `NOTICE.md`, and `assets/*.svg`.
The CLI downloads the audited official archives, verifies their complete SHA-256 hashes, sanitizes the selected SVGs, and writes each processed provider pack to the shared icon store. Google Cloud product and category artwork is imported together by the single `gcp` command.

## Use a pack in Playground
## Use provider icons in CLI

Open **Icons**, choose one pack's `manifest.json` and every declared file in `assets/`, then search the loaded local catalog and copy an ID into source:

```stack
stack 1.0

diagram "Storage" {
node files "Amazon S3" {
kind storage
icon "aws:s3"
}
}
```

The selected files stay in the current browser tab. The Playground does not upload, fetch, or persist the pack, so reloads require another selection. Use **Notice** beside the SVG download when a rendered diagram embeds provider artwork.

The Playground accepts an already processed pack, not a raw provider ZIP. Raw-archive verification and safe SVG processing remain in the CLI so browser code does not duplicate that security boundary.

## Use a pack in CLI

A single Stack file can use multiple providers. For example, this diagram uses Cloud Run from the Google Cloud pack and GitHub from the Simple Icons pack:
A Stack file can use multiple providers. This example combines Cloud Run from Google Cloud with GitHub from Simple Icons:

```stack
stack 1.0
Expand All @@ -72,20 +48,71 @@ diagram "Deploy from GitHub to Cloud Run" {
}
```

After importing both packs with the commands shown in their catalog cards, repeat `--provider-pack` when rendering:
After both imports, the standard render command discovers both packs:

```sh
$ stack render architecture.stack -o architecture.svg --notice architecture.NOTICE.md
```

## Shared icon store

The default icon store is `$XDG_CONFIG_HOME/stack/icons`. When `XDG_CONFIG_HOME` is unset, Stack uses `$HOME/.config/stack/icons`.

```text
icons/
aws/
gcp/
azure/
simple-icons/
```

Set a different shared location in `$XDG_CONFIG_HOME/stack/config.yaml` with an absolute path:

```yaml
default_icons_path: /absolute/path/to/stack-icons
```

The configured location is used by both `stack icons import` and `stack render`.

## Use provider icons in Playground

Open **Icons**, choose the `stack/icons` folder, and the Playground loads every recognized provider directory in that store. Search the loaded artwork and select an item to copy its ID into Stack source.

The selected packs are processed in the current browser tab. When a rendered diagram contains provider artwork, **Notice** beside the SVG download provides the source, terms, and used-icon record.

## Keep icons with a project

Use `-o` to place imported packs in a project directory that can be committed with the repository:

```sh
$ stack icons import gcp --accept-terms -o .stack-icons
$ stack icons import simple-icons --accept-terms -o .stack-icons
```

Pass that icon-store root with `--provider-pack` when rendering:

```sh
$ stack render architecture.stack \
--provider-pack .stack-icons/gcp \
--provider-pack .stack-icons/simple-icons \
--provider-pack .stack-icons \
-o architecture.svg \
--notice architecture.NOTICE.md
```

The CLI validates each bounded pack before rendering and records the exact used icons and source archives in the notice sidecar.
## Find icon IDs

Search the catalog from the CLI or on this page:

```sh
$ stack icons list
$ stack icons list aws s3
$ stack icons list azure database
$ stack icons list simple-icons github
```

The CLI output contains `ID`, `PRODUCT`, `CATEGORY`, and recommended `KIND` columns. Namespaced IDs such as `gcp:cloud-run` and `simple-icons:github` select artwork from the corresponding pack.

## Offline behavior
## Verification, terms, and notices

CLI authoring and SVG generation work fully offline after the CLI and any desired provider archives are on the device. Installing the CLI or obtaining a new official archive may require a connection.
The CLI catalog pins each official HTTPS archive URL, release, complete archive SHA-256, allowlisted entry path, terms URL, and review date. Import applies bounded archive and SVG sizes, sanitizes active and external SVG content, and writes each pack atomically.

The Web Playground also formats, checks, and renders locally after its JavaScript and WebAssembly have loaded. It has no server rendering dependency and provider files never leave the browser. The current website is not an installed offline app, however, so a cold start without a network connection is not guaranteed.
Each pack includes `NOTICE.md`. `stack render --notice <PATH>` writes the exact pack revisions, source releases, terms URLs, attribution, non-endorsement text, and used icon IDs for a rendered artifact. The catalog links each provider's official source and terms, plus brand sources and guidelines for curated Simple Icons marks.
Loading