diff --git a/extension/src/popup/styles.css b/extension/src/popup/styles.css
index 4d26e57..362e3ae 100644
--- a/extension/src/popup/styles.css
+++ b/extension/src/popup/styles.css
@@ -1256,3 +1256,23 @@ textarea {
.mode-card.active { border-color: #58a6ff; background: rgba(88,166,255,0.08); }
.mode-card-title { font-weight: 600; margin-bottom: 4px; font-size: 14px; }
.mode-card-blurb { color: #8b949e; font-size: 12px; margin: 0; line-height: 1.5; }
+
+/* --- Setup wizard probe banners (Step 2) --- */
+.banner { padding: 12px; border-radius: 6px; margin: 12px 0; font-size: 13px; }
+.banner-ok {
+ background: rgba(46,160,67,0.10);
+ border: 1px solid rgba(46,160,67,0.4);
+}
+.banner-warn {
+ background: rgba(218,54,51,0.08);
+ border: 1px solid rgba(218,54,51,0.4);
+}
+.banner strong { display: block; margin-bottom: 4px; }
+.banner p { margin: 6px 0; line-height: 1.5; color: #c9d1d9; }
+.banner code {
+ font-family: ui-monospace, SFMono-Regular, monospace;
+ font-size: 12px;
+ background: #21262d;
+ padding: 1px 5px;
+ border-radius: 3px;
+}
diff --git a/extension/src/setup/setup.ts b/extension/src/setup/setup.ts
index c32d626..fd3b076 100644
--- a/extension/src/setup/setup.ts
+++ b/extension/src/setup/setup.ts
@@ -7,6 +7,7 @@
/// Step 5: Finish (download reference image, push config to extension or copy JSON)
import { createGitHost, uint8ArrayToBase64 } from '../service-worker/git-host';
+import { probeVault } from './probe';
import type { VaultConfig } from '../shared/types';
// --- WASM module (loaded dynamically) ---
@@ -400,7 +401,55 @@ function attachStep1(): void {
// --- Step 2: Configure Connection ---
+function renderProbeBanner(): string {
+ const probe = state.vaultProbe;
+ if (!state.connectionTested || !probe) return '';
+ const meta = probe.lastCommit
+ ? `Last commit: ${escapeHtml(probe.lastCommit.sha)} by ${escapeHtml(probe.lastCommit.author)} on ${escapeHtml(probe.lastCommit.date.slice(0, 10))}.`
+ : '';
+ if (state.mode === 'new' && probe.exists) {
+ return `
+
+
⚠ This repository already contains a relicario vault.
+
${meta}
+
Creating a new vault here would overwrite the existing one and destroy all data inside .
+ To use this vault on this device, switch to attach mode instead.
+ If you really mean to start over, delete the repository via your git host's web UI and come back here.
+
+ switch to attach mode
+
+
`;
+ }
+ if (state.mode === 'attach' && !probe.exists) {
+ return `
+
+
No vault found in this repo.
+
Did you mean to create a new vault?
+
+ switch to new-vault mode
+
+
`;
+ }
+ if (state.mode === 'attach' && probe.exists) {
+ return `
+
+
✓ Existing vault found.
+
${meta}
+
Continue to attach this device.
+
`;
+ }
+ // mode = new, !exists
+ return `
+
+ ✓ Repo is empty — ready to create a new vault.
+
`;
+}
+
function renderStep2(): string {
+ const probe = state.vaultProbe;
+ const modeMismatch =
+ !!probe && ((state.mode === 'new' && probe.exists) || (state.mode === 'attach' && !probe.exists));
+ const nextDisabled = !state.connectionTested || !probe || modeMismatch;
return `
configure connection
@@ -420,9 +469,10 @@ function renderStep2(): string {
test connection
${state.connectionTested ? 'connected ' : ''}
+ ${renderProbeBanner()}
back
- next
+ next
`;
@@ -430,6 +480,8 @@ function renderStep2(): string {
function attachStep2(): void {
document.getElementById('test-btn')?.addEventListener('click', async () => {
+ state.connectionTested = false;
+ state.vaultProbe = null;
const hostUrl = state.hostType === 'github'
? 'https://api.github.com'
: (document.getElementById('host-url') as HTMLInputElement).value.trim();
@@ -456,8 +508,15 @@ function attachStep2(): void {
await host.listDir('');
state.connectionTested = true;
state.error = null;
+ try {
+ state.vaultProbe = await probeVault(host);
+ } catch (probeErr) {
+ state.vaultProbe = null;
+ state.error = `Could not check repo state: ${probeErr instanceof Error ? probeErr.message : String(probeErr)}`;
+ }
} catch (err: unknown) {
state.connectionTested = false;
+ state.vaultProbe = null;
state.error = `Connection failed: ${err instanceof Error ? err.message : String(err)}`;
}
render();
@@ -475,6 +534,13 @@ function attachStep2(): void {
state.error = null;
render();
});
+
+ document.getElementById('switch-mode-btn')?.addEventListener('click', (e) => {
+ const target = (e.currentTarget as HTMLElement).dataset.target as 'new' | 'attach';
+ state.mode = target;
+ state.error = null;
+ render();
+ });
}
// --- Step 3 (new-vault variant): Create Vault ---