import{_ as s,o as a,c as t,a2 as i}from"./chunks/framework.CJEbdX1t.js";const k=JSON.parse('{"title":"Development Setup","description":"","frontmatter":{},"headers":[],"relativePath":"contributing/development.md","filePath":"contributing/development.md"}'),n={name:"contributing/development.md"};function d(l,e,r,h,o,p){return a(),t("div",null,[...e[0]||(e[0]=[i(`<h1 id="development-setup" tabindex="-1">Development Setup <a class="header-anchor" href="#development-setup" aria-label="Permalink to &quot;Development Setup&quot;">​</a></h1><p>Get Specwright running locally for development.</p><h2 id="prerequisites" tabindex="-1">Prerequisites <a class="header-anchor" href="#prerequisites" aria-label="Permalink to &quot;Prerequisites&quot;">​</a></h2><ul><li>Python 3.12+</li><li><a href="https://docs.astral.sh/uv/" target="_blank" rel="noreferrer">uv</a> (package manager)</li><li>Node.js 18+ (for the frontend)</li><li>Git</li></ul><h2 id="clone-and-install" tabindex="-1">Clone and Install <a class="header-anchor" href="#clone-and-install" aria-label="Permalink to &quot;Clone and Install&quot;">​</a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> clone</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> git@github.com:Gerner-Ventures/gv-exp-specwright.git</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> gv-exp-specwright</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Install all dependencies (backend + frontend)</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">make</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> install</span></span></code></pre></div><p>This runs:</p><ul><li><code>uv sync --extra dev</code> — Python dependencies including dev extras</li><li><code>cd frontend &amp;&amp; npm ci</code> — Frontend dependencies</li></ul><h2 id="environment-variables" tabindex="-1">Environment Variables <a class="header-anchor" href="#environment-variables" aria-label="Permalink to &quot;Environment Variables&quot;">​</a></h2><p>Copy the example env file and fill in your values:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cp</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .env.example</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .env</span></span></code></pre></div><p>Required for basic development:</p><table tabindex="0"><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody><tr><td><code>GH_APP_ID</code></td><td>GitHub App ID</td></tr><tr><td><code>GH_PRIVATE_KEY</code></td><td>GitHub App private key (PEM format)</td></tr><tr><td><code>GH_WEBHOOK_SECRET</code></td><td>GitHub App webhook secret</td></tr><tr><td><code>GH_INSTALLATION_ID</code></td><td>GitHub App installation ID</td></tr><tr><td><code>ANTHROPIC_API_KEY</code></td><td>Claude API key for agent runtime</td></tr></tbody></table><p>Optional:</p><table tabindex="0"><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody><tr><td><code>GITHUB_TOKEN</code></td><td>GitHub PAT for ticket sync via GitHub Issues</td></tr><tr><td><code>JIRA_HOST</code></td><td>Jira instance hostname</td></tr><tr><td><code>JIRA_EMAIL</code></td><td>Jira service account email</td></tr><tr><td><code>JIRA_API_TOKEN</code></td><td>Jira API token</td></tr><tr><td><code>LINEAR_API_KEY</code></td><td>Linear API key</td></tr><tr><td><code>LOG_LEVEL</code></td><td>Logging level (default: <code>info</code>)</td></tr></tbody></table><h2 id="running-locally" tabindex="-1">Running Locally <a class="header-anchor" href="#running-locally" aria-label="Permalink to &quot;Running Locally&quot;">​</a></h2><h3 id="backend-only" tabindex="-1">Backend Only <a class="header-anchor" href="#backend-only" aria-label="Permalink to &quot;Backend Only&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># With Doppler secrets</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">make</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Without secrets (no auth, limited features)</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">make</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev-no-auth</span></span></code></pre></div><p>The FastAPI server runs at <code>http://localhost:3000</code> with auto-reload.</p><h3 id="frontend-only" tabindex="-1">Frontend Only <a class="header-anchor" href="#frontend-only" aria-label="Permalink to &quot;Frontend Only&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">make</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev-frontend</span></span></code></pre></div><p>Vite HMR server at <code>http://localhost:5173</code>.</p><h3 id="both-recommended" tabindex="-1">Both (recommended) <a class="header-anchor" href="#both-recommended" aria-label="Permalink to &quot;Both (recommended)&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">make</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span></code></pre></div><p>The FastAPI server serves the Vue SPA and handles API routes.</p><h2 id="kubernetes-dev-environment" tabindex="-1">Kubernetes Dev Environment <a class="header-anchor" href="#kubernetes-dev-environment" aria-label="Permalink to &quot;Kubernetes Dev Environment&quot;">​</a></h2><p>For testing against real GitHub webhooks and ticket systems, use the DevSpace-based dev environment:</p><h3 id="additional-prerequisites" tabindex="-1">Additional Prerequisites <a class="header-anchor" href="#additional-prerequisites" aria-label="Permalink to &quot;Additional Prerequisites&quot;">​</a></h3><ul><li><a href="https://docs.docker.com/get-docker/" target="_blank" rel="noreferrer">Docker</a></li><li><a href="https://devspace.sh/docs/getting-started/installation" target="_blank" rel="noreferrer">DevSpace CLI</a> (v6+)</li><li><a href="https://docs.doppler.com/docs/cli" target="_blank" rel="noreferrer">Doppler CLI</a></li><li><a href="https://docs.digitalocean.com/reference/doctl/" target="_blank" rel="noreferrer">doctl</a></li></ul><h3 id="one-time-setup" tabindex="-1">One-Time Setup <a class="header-anchor" href="#one-time-setup" aria-label="Permalink to &quot;One-Time Setup&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">doppler</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> login</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">doctl</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> auth</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">doctl</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> registry</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> login</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">doctl</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> kubernetes</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> cluster</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> kubeconfig</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> save</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> gv-shared</span></span></code></pre></div><h3 id="usage" tabindex="-1">Usage <a class="header-anchor" href="#usage" aria-label="Permalink to &quot;Usage&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> DEVSPACE_USERNAME</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">your-name</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Full dev mode</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">devspace</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># → http://localhost:3000 (port-forwarded)</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># → https://your-name.specwright.gernerventures.com (ingress)</span></span></code></pre></div><p>File changes in <code>src/</code>, <code>templates/</code>, and <code>static/</code> sync into the pod and uvicorn auto-reloads.</p><h3 id="useful-devspace-commands" tabindex="-1">Useful DevSpace Commands <a class="header-anchor" href="#useful-devspace-commands" aria-label="Permalink to &quot;Useful DevSpace Commands&quot;">​</a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">devspace</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> logs</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">             # tail pod logs</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">devspace</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> sync-secrets</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">     # re-sync Doppler secrets</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">devspace</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> sync-trigger</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">     # manually run reverse sync cron</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">devspace</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> purge</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">                # tear down dev environment</span></span></code></pre></div><h2 id="make-commands" tabindex="-1">Make Commands <a class="header-anchor" href="#make-commands" aria-label="Permalink to &quot;Make Commands&quot;">​</a></h2><p>Run <code>make help</code> for the full list. Key commands:</p><table tabindex="0"><thead><tr><th>Command</th><th>Description</th></tr></thead><tbody><tr><td><code>make install</code></td><td>Install all dependencies</td></tr><tr><td><code>make dev</code></td><td>Run dev server with Doppler secrets</td></tr><tr><td><code>make test</code></td><td>Run Python tests</td></tr><tr><td><code>make lint</code></td><td>Lint backend + frontend</td></tr><tr><td><code>make format</code></td><td>Auto-fix Python lint errors</td></tr><tr><td><code>make typecheck</code></td><td>Run mypy + vue-tsc</td></tr><tr><td><code>make build</code></td><td>Build Vue SPA</td></tr><tr><td><code>make build-docker</code></td><td>Build production Docker image</td></tr><tr><td><code>make docs-dev</code></td><td>Run docs site dev server</td></tr><tr><td><code>make docs-build</code></td><td>Build docs site</td></tr></tbody></table>`,39)])])}const u=s(n,[["render",d]]);export{k as __pageData,u as default};
