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
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<script lang="ts">
import CopyButton from './CopyButton.svelte';
import { features } from '$lib/site';
import { capabilities } from '$lib/site';
</script>

<section id="features" class="scroll-target border-t border-ink-800">
<section id="capabilities" class="scroll-target border-t border-ink-800">
<div class="container-site py-12 sm:py-20 lg:py-24">
<div class="max-w-2xl">
<h2 class="font-sans font-semibold text-title text-ink-50">{features.title}</h2>
<h2 class="font-sans font-semibold text-title text-ink-50">{capabilities.title}</h2>
<p class="mt-3 text-[0.9375rem] leading-relaxed text-ink-300 sm:text-[1.0625rem]">
{features.lead}
{capabilities.lead}
</p>
</div>

<div class="mt-8 grid gap-3 sm:mt-10 sm:gap-6 sm:grid-cols-2 lg:grid-cols-3">
{#each features.items as item (item.id)}
{#each capabilities.items as item (item.id)}
<div class="flex flex-col justify-between rounded-xs border border-ink-800 bg-ink-900/30 p-4 sm:p-5 transition-colors duration-150 hover:border-ink-700">
<div>
<h3 class="font-sans text-base font-semibold text-ink-50">{item.title}</h3>
Expand Down
3 changes: 3 additions & 0 deletions src/lib/components/Hero.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<h1 class="font-sans font-semibold text-hero text-ink-50">
{site.headline}
</h1>
<p class="mt-2 text-[1rem] font-medium text-ink-400 sm:text-[1.0625rem]">
{site.subheadline}
</p>
<p class="mt-4 text-[0.9375rem] leading-relaxed text-ink-300 sm:mt-5 sm:text-[1.0625rem]">
{site.description}
</p>
Expand Down
106 changes: 106 additions & 0 deletions src/lib/components/PillarsSection.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<script lang="ts">
import CopyButton from './CopyButton.svelte';
import { pillars } from '$lib/site';

let active = $state(0);
</script>

<section id="workflows" class="scroll-target border-t border-ink-800">
<div class="container-site py-12 sm:py-20 lg:py-24">
<div class="max-w-2xl">
<h2 class="font-sans font-semibold text-title text-ink-50">Who is WrightKit for?</h2>
<p class="mt-3 text-[0.9375rem] leading-relaxed text-ink-300 sm:text-[1.0625rem]">
WrightKit supports three established Workshop development workflows. Pick the one closest to
how you work.
</p>
</div>

<!-- Tab strip -->
<div class="mt-8 sm:mt-10 flex gap-1 border-b border-ink-800" role="tablist">
{#each pillars as pillar, i (pillar.id)}
<button
role="tab"
aria-selected={active === i}
aria-controls="pillar-panel-{pillar.id}"
id="pillar-tab-{pillar.id}"
class="relative px-4 py-2.5 text-sm font-medium transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-400 focus-visible:ring-offset-2 focus-visible:ring-offset-ink-950
{active === i
? 'text-ink-50 after:absolute after:inset-x-0 after:-bottom-px after:h-px after:bg-accent-400'
: 'text-ink-400 hover:text-ink-200'}"
onclick={() => (active = i)}
>
{pillar.label}
</button>
{/each}
</div>

<!-- Panels -->
{#each pillars as pillar, i (pillar.id)}
<div
id="pillar-panel-{pillar.id}"
role="tabpanel"
aria-labelledby="pillar-tab-{pillar.id}"
hidden={active !== i}
class="mt-6 sm:mt-8"
>
<div class="grid gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,0.9fr)] lg:gap-12">
<!-- Left: copy -->
<div class="min-w-0">
<h3 class="font-sans text-xl font-semibold text-ink-50 sm:text-2xl">
{pillar.headline}
</h3>
<p class="mt-3 text-[0.9375rem] leading-relaxed text-ink-300 sm:mt-4 sm:text-[1.0625rem]">
{pillar.body}
</p>

<!-- Capability list -->
<ul class="mt-5 sm:mt-6 space-y-2">
{#each pillar.capabilities as cap}
<li class="flex items-start gap-2.5 text-[0.875rem] leading-relaxed text-ink-300">
<span
class="mt-[0.2em] shrink-0 h-4 w-4 rounded-full bg-accent-500/20 flex items-center justify-center"
aria-hidden="true"
>
<svg
width="8"
height="8"
viewBox="0 0 8 8"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.5 4L3.16667 5.66667L6.5 2.33333"
stroke="currentColor"
stroke-width="1.2"
stroke-linecap="round"
stroke-linejoin="round"
class="text-accent-400"
/>
</svg>
</span>
{cap}
</li>
{/each}
</ul>
</div>

<!-- Right: command snippet -->
<div class="min-w-0 lg:pt-1">
<div class="rounded-xs border border-ink-800 bg-ink-900/60 overflow-hidden">
<div class="flex items-center gap-2 border-b border-ink-800 px-3 py-2 sm:px-4">
<span class="text-[0.6875rem] font-mono text-ink-500 select-none">$</span>
<div class="min-w-0 flex-1 overflow-hidden">
<code class="block truncate font-mono text-xs text-ink-200">{pillar.command}</code>
</div>
<CopyButton text={pillar.command} label="Copy" variant="inline" />
</div>
<p class="px-3 py-2.5 text-[0.75rem] leading-relaxed text-ink-500 sm:px-4">
{pillar.commandCaption}
</p>
</div>
</div>
</div>
</div>
{/each}
</div>
</section>
72 changes: 64 additions & 8 deletions src/lib/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ export const site = {
product: 'Wright',
brand: 'WrightKit',
url: 'https://wrightkit.dev',
tagline: 'Tooling-first ecosystem for Overwatch Workshop',
headline: 'Tooling for the Overwatch Workshop.',
tagline: 'Tooling for Overwatch Workshop development',
headline: 'Tooling for Overwatch Workshop development.',
subheadline: 'Native Workshop, OverPy / OSTW, and AI agents.',
description:
'WrightKit is an open-source ecosystem of tools for Overwatch Workshop development. Wright, its primary product, is a standalone Rust toolchain for linting, static analysis, semantic inspection, and compilation — for developers, CI, and AI agents.',
'WrightKit is an open-source tooling ecosystem for Overwatch Workshop development. Whether you work in native Workshop text, OverPy, OSTW, or use AI coding agents — Wright provides linting, static analysis, semantic inspection, validated source editing, and language services.',
github: 'https://github.com/wrightkit/wright',
org: 'https://github.com/wrightkit',
releases: 'https://github.com/wrightkit/wright/releases',
Expand All @@ -36,10 +37,10 @@ export interface NavItem {

export const nav = [
{ label: 'Install', href: '#install' },
{ label: 'Features', href: '#features' },
{ label: 'Workflows', href: '#workflows' },
{ label: 'Capabilities', href: '#capabilities' },
{ label: 'Compatibility', href: '#compatibility' },
{ label: 'Ecosystem', href: '#ecosystem' },
{ label: 'Agents', href: '#agents' },
{ label: 'GitHub', href: site.org, external: true }
] satisfies readonly NavItem[];

Expand All @@ -66,6 +67,61 @@ export const terminal = [
{ prompt: '', text: '✓ compiled 12 rules, 4 subroutines (0.018s)' }
] as const;

/**
* Three primary developer entry points.
* Capability claims trace to current wright/workshop-rs/opy-rs/del-rs/workshop-agent evidence.
*/
export const pillars = [
{
id: 'workshop',
anchor: 'workflows',
label: 'Native Workshop',
headline: 'Parse, inspect, lint, and transform raw Workshop scripts.',
body: 'Workshop text is the canonical interoperability boundary. WrightKit treats it as a first-class source form — not only as compiler output. Parse, validate, check, analyze, and emit Workshop projects with full catalog awareness.',
capabilities: [
'Parse and validate Workshop text against the live action/value catalog',
'Static analysis and lint rules with stable diagnostic codes',
'Semantic inspection: rules, variables, subroutines, control flow',
'Deterministic re-emission for diffs, CI, and round-trip verification',
'Source-span diagnostics in terminal and machine-readable JSON'
],
command: 'wright lint src/main.workshop',
commandCaption: 'Lint native Workshop text with stable diagnostic codes.'
},
{
id: 'opy',
anchor: 'workflows',
label: 'OverPy & OSTW',
headline: 'Modern tooling for OverPy and OSTW projects.',
body: 'OverPy (OPY) and DeltinScript (OSTW) are widely-used languages for Workshop development. WrightKit provides source-aware tooling — checking, linting, semantic analysis, and compilation where supported — for existing projects without replacing upstream implementations.',
capabilities: [
'OverPy frontend: preprocessor, macros, declarations, expressions, settings blocks',
'Corpus-evidenced semantic frontend, verified against a pinned OverPy oracle',
'OPY → Workshop compilation (supported), Workshop → OPY (in development)',
'DEL/OSTW-compatible frontend in development (del-rs)',
'Language server hover, definition, references, and rename (wright-lsp)'
],
command: 'wright check src/hero.opy',
commandCaption: 'Check an OverPy source file with exact source-span diagnostics.'
},
{
id: 'agents',
anchor: 'workflows',
label: 'AI Agents',
headline: 'Semantic understanding and validated edits for coding agents.',
body: 'Workshop projects are hard for agents to reason about: the action/value catalog is large, semantics are non-obvious, and mistakes can silently break behavior. WrightKit gives agents the same structured interfaces developers use — no scraped logs or brittle regexes.',
capabilities: [
'Semantic inspection APIs: rules, symbols, dependencies, control-flow graphs',
'Machine-readable diagnostics with stable codes, severity levels, and source spans',
'Validated source editing that agents can verify before applying',
'workshop-agent: deterministic CLI tools and engineering knowledge for agent harnesses',
'Non-interactive installer for CI and agent containers'
],
command: 'wright analyze src/hero.opy --format json',
commandCaption: 'Structured program analysis for programmatic consumption.'
}
] as const;

export const install = {
title: 'Install Wright',
lead: 'Standalone wright and wright-lsp binaries for macOS (Apple Silicon & Intel), Linux (x86_64), and Windows (x86_64). Zero runtime dependencies — no Node.js, .NET, or external interpreters required.',
Expand Down Expand Up @@ -130,9 +186,9 @@ export const install = {
}
} as const;

export const features = {
title: 'Features',
lead: 'Developer tooling — linting, diagnostics, semantic queries, editor assistance, and safe source transformations — as first-class product surfaces.',
export const capabilities = {
title: 'Shared Capabilities',
lead: 'The same tooling foundation — linting, diagnostics, semantic inspection, language services, and agent APIs — applies across all supported source forms.',
items: [
{
id: 'lint',
Expand Down
8 changes: 4 additions & 4 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import Hero from '$lib/components/Hero.svelte';
import InstallSection from '$lib/components/InstallSection.svelte';
import FeaturesSection from '$lib/components/FeaturesSection.svelte';
import PillarsSection from '$lib/components/PillarsSection.svelte';
import CapabilitiesSection from '$lib/components/CapabilitiesSection.svelte';
import CompatibilitySection from '$lib/components/CompatibilitySection.svelte';
import EcosystemSection from '$lib/components/EcosystemSection.svelte';
import AgentsSection from '$lib/components/AgentsSection.svelte';
import OpenSourceSection from '$lib/components/OpenSourceSection.svelte';
import { site } from '$lib/site';
</script>
Expand All @@ -23,8 +23,8 @@

<Hero />
<InstallSection />
<FeaturesSection />
<PillarsSection />
<CapabilitiesSection />
<CompatibilitySection />
<EcosystemSection />
<AgentsSection />
<OpenSourceSection />