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
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ <h2 data-i18n="settingsTitle"></h2>
<svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="m6.4 5 5.6 5.6L17.6 5 19 6.4 13.4 12l5.6 5.6-1.4 1.4-5.6-5.6L6.4 19 5 17.6 10.6 12 5 6.4z"/></svg>
</button>
</div>
<div class="set-row">
<label data-i18n="tourLabel"></label>
<button class="btn-replay-tour" id="btn-replay-tour" type="button" data-i18n="tourReplayBtn"></button>
</div>
<div class="set-row">
<label data-i18n="theme"></label>
<div class="theme-picker" id="theme-picker">
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "afkode",
"private": true,
"version": "0.8.13",
"version": "0.8.14",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "afkode"
version = "0.8.13"
version = "0.8.14"
description = "In-game overlay to supervise AI coding agents while you play"
authors = ["Omar Hernandez"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "AFKode",
"version": "0.8.13",
"version": "0.8.14",
"identifier": "app.afkode.overlay",
"build": {
"beforeDevCommand": "npm run dev",
Expand Down
116 changes: 112 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { CommandBlocks } from "./blocks";
import { WebKitDeadKeyAddon } from "./xtermDeadKeyAddon";
import { MODEL_EXTS } from "./modelExts";
import type { ModelPreview } from "./modelPreview";
import { startTour, type TourStep } from "./tour";

// ── Themes ────────────────────────────────────────────────

Expand Down Expand Up @@ -357,6 +358,20 @@ const I18N: Record<Lang, Record<string, string>> = {
restoreAsk: "Preguntar",
restoreNever: "Nunca",
restoreNote: "Reabre tus pestaΓ±as (orden, nombres, colores y carpetas). Las pestaΓ±as de Claude ofrecen retomar la conversaciΓ³n anterior.",
tourLabel: "Recorrido guiado",
tourReplayBtn: "Ver el recorrido",
tourSkip: "Saltar",
tourNext: "Siguiente",
tourDone: "Listo",
tourStepOf: "Paso {i} de {n}",
tourStep1Title: "Abre una nueva pestaΓ±a",
tourStep1Body: "El botΓ³n + lanza Claude Code, OpenCode, Codex o PowerShell en la carpeta que elijas.",
tourStep2Title: "Tu terminal",
tourStep2Body: "ConPTY con render por GPU: colores completos y apps interactivas con impacto mΓ­nimo en tus FPS.",
tourStep3Title: "Vista previa de archivos",
tourStep3Body: "Al abrir un archivo se muestra aquΓ­: cΓ³digo, imΓ‘genes e incluso modelos 3D (.glb, .gltf, .obj, .stl).",
tourStep4Title: "BΓΊsqueda global",
tourStep4Body: "Pulsa Ctrl+K en cualquier momento para saltar a archivos, comandos o sesiones.",
restoreBannerText: "ΒΏRestaurar tu ΓΊltima sesiΓ³n? ({n} pestaΓ±as)",
restoreBtn: "Restaurar",
resumeQuestion: "ΒΏRetomar la conversaciΓ³n anterior?",
Expand Down Expand Up @@ -484,6 +499,20 @@ const I18N: Record<Lang, Record<string, string>> = {
restoreAsk: "Ask",
restoreNever: "Never",
restoreNote: "Reopens your tabs (order, names, colors and folders). Claude tabs offer to resume the previous conversation.",
tourLabel: "Guided tour",
tourReplayBtn: "Take the tour",
tourSkip: "Skip",
tourNext: "Next",
tourDone: "Done",
tourStepOf: "Step {i} of {n}",
tourStep1Title: "Open a new tab",
tourStep1Body: "The + button launches Claude Code, OpenCode, Codex, or PowerShell in a folder you pick.",
tourStep2Title: "Your terminal",
tourStep2Body: "ConPTY with GPU rendering: full colors and interactive apps with minimal impact on your FPS.",
tourStep3Title: "File preview",
tourStep3Body: "Open a file and it shows up here: code, images, and even 3D models (.glb, .gltf, .obj, .stl).",
tourStep4Title: "Global search",
tourStep4Body: "Press Ctrl+K anytime to jump to files, commands, or sessions.",
restoreBannerText: "Restore your last session? ({n} tabs)",
restoreBtn: "Restore",
resumeQuestion: "Resume previous conversation?",
Expand Down Expand Up @@ -611,6 +640,20 @@ const I18N: Record<Lang, Record<string, string>> = {
restoreAsk: "Demander",
restoreNever: "Jamais",
restoreNote: "Rouvre vos onglets (ordre, noms, couleurs et dossiers). Les onglets Claude proposent de reprendre la conversation prΓ©cΓ©dente.",
tourLabel: "Visite guidΓ©e",
tourReplayBtn: "Revoir la visite",
tourSkip: "Passer",
tourNext: "Suivant",
tourDone: "TerminΓ©",
tourStepOf: "Γ‰tape {i} sur {n}",
tourStep1Title: "Ouvrez un nouvel onglet",
tourStep1Body: "Le bouton + lance Claude Code, OpenCode, Codex ou PowerShell dans le dossier de votre choix.",
tourStep2Title: "Votre terminal",
tourStep2Body: "ConPTY avec rendu GPU : couleurs complètes et applications interactives, impact minimal sur vos FPS.",
tourStep3Title: "AperΓ§u des fichiers",
tourStep3Body: "Ouvrez un fichier et il s'affiche ici : code, images et mΓͺme modΓ¨les 3D (.glb, .gltf, .obj, .stl).",
tourStep4Title: "Recherche globale",
tourStep4Body: "Appuyez sur Ctrl+K Γ  tout moment pour accΓ©der aux fichiers, commandes ou sessions.",
restoreBannerText: "Restaurer votre dernière session ? ({n} onglets)",
restoreBtn: "Restaurer",
resumeQuestion: "Reprendre la conversation prΓ©cΓ©dente ?",
Expand Down Expand Up @@ -738,6 +781,20 @@ const I18N: Record<Lang, Record<string, string>> = {
restoreAsk: "Chiedi",
restoreNever: "Mai",
restoreNote: "Riapre le tue schede (ordine, nomi, colori e cartelle). Le schede Claude offrono di riprendere la conversazione precedente.",
tourLabel: "Visita guidata",
tourReplayBtn: "Rivedi la visita",
tourSkip: "Salta",
tourNext: "Avanti",
tourDone: "Fine",
tourStepOf: "Passo {i} di {n}",
tourStep1Title: "Apri una nuova scheda",
tourStep1Body: "Il pulsante + avvia Claude Code, OpenCode, Codex o PowerShell nella cartella che scegli.",
tourStep2Title: "Il tuo terminale",
tourStep2Body: "ConPTY con rendering GPU: colori completi e app interattive con impatto minimo sugli FPS.",
tourStep3Title: "Anteprima file",
tourStep3Body: "Apri un file e viene mostrato qui: codice, immagini e persino modelli 3D (.glb, .gltf, .obj, .stl).",
tourStep4Title: "Ricerca globale",
tourStep4Body: "Premi Ctrl+K in qualsiasi momento per saltare a file, comandi o sessioni.",
restoreBannerText: "Ripristinare l'ultima sessione? ({n} schede)",
restoreBtn: "Ripristina",
resumeQuestion: "Riprendere la conversazione precedente?",
Expand Down Expand Up @@ -2597,6 +2654,55 @@ wireSwitch("#chk-hooks", "hooks");
wireSwitch("#chk-matchmode", "matchMode");
wireSwitch("#chk-aisearch", "aiSearch");

// ── Onboarding tour ───────────────────────────────────────

function buildTourSteps(): TourStep[] {
const previewModal = $("#file-preview-modal");
const wasOpen = previewModal.classList.contains("open");
return [
{
selector: "#btn-new-tab",
title: t("tourStep1Title"),
body: t("tourStep1Body"),
},
{
selector: "#terminals",
title: t("tourStep2Title"),
body: t("tourStep2Body"),
},
{
selector: "#file-preview-modal",
title: t("tourStep3Title"),
body: t("tourStep3Body"),
onEnter: () => previewModal.classList.add("open"),
onLeave: () => {
if (!wasOpen) previewModal.classList.remove("open");
},
},
{
selector: "#btn-global-search",
title: t("tourStep4Title"),
body: t("tourStep4Body"),
},
];
}

function tourLabels() {
return {
skip: t("tourSkip"),
next: t("tourNext"),
done: t("tourDone"),
stepOf: (i: number, n: number) => t("tourStepOf").replace("{i}", String(i)).replace("{n}", String(n)),
};
}

function replayTour() {
$("#settings-modal").classList.add("hidden");
startTour(buildTourSteps(), tourLabels(), () => {});
}

$<HTMLButtonElement>("#btn-replay-tour").addEventListener("click", replayTour);

const selRestore = $<HTMLSelectElement>("#sel-restore");
selRestore.value = settings.restore;
selRestore.addEventListener("change", () => {
Expand Down Expand Up @@ -3594,8 +3700,10 @@ refreshCliButtons().then(() => {
}
});

// First run: show the help card once so the user discovers the features.
if (!localStorage.getItem("help-seen")) {
helpModal.classList.remove("hidden");
localStorage.setItem("help-seen", "1");
// First run: walk the user through the core UI once. The static help
// card (still reachable any time via the help button) stays available
// as reference material afterward.
if (!localStorage.getItem("tour-seen")) {
localStorage.setItem("tour-seen", "1");
startTour(buildTourSteps(), tourLabels(), () => {});
}
81 changes: 81 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1685,3 +1685,84 @@ kbd {
.hidden {
display: none !important;
}

/* ── Onboarding tour ───────────────────────────────────── */

.btn-replay-tour {
padding: 6px 12px;
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 7px;
background: rgba(255, 255, 255, 0.05);
color: var(--text);
font-size: 12px;
cursor: pointer;
}
.btn-replay-tour:hover {
border-color: var(--accent);
color: var(--accent);
}

.tour-overlay {
position: fixed;
inset: 0;
z-index: 300;
animation: fade-in 0.15s ease;
}

.tour-spot {
position: fixed;
border-radius: 8px;
border: 2px solid var(--accent);
box-shadow:
0 0 0 9999px rgba(10, 11, 15, 0.72),
0 0 12px 1px var(--accent-glow);
transition:
left 0.25s ease,
top 0.25s ease,
width 0.25s ease,
height 0.25s ease;
pointer-events: none;
}

.tour-tip {
position: fixed;
width: min(320px, 90vw);
padding: 14px 16px 12px;
background: rgb(var(--bar-rgb));
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
transition:
left 0.25s ease,
top 0.25s ease;
}

.tour-tip-step {
font-size: 11px;
color: var(--text-dim);
margin-bottom: 2px;
}

.tour-tip-title {
margin: 0 0 6px;
font-size: 14px;
color: var(--text-bright);
}

.tour-tip-body {
margin: 0 0 12px;
font-size: 12.5px;
line-height: 1.5;
color: var(--text);
}

.tour-tip-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}

.tour-tip-actions .ask-btn.ok {
border-color: var(--accent);
color: var(--accent);
}
Loading
Loading