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
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,14 @@ The extension card should appear with no errors. For HMR-rebuild during active d

### Load from `.zip` (without source code)

```bash
cd extension
npm run zip # builds and creates worktrace-extension.zip
```
Download `worktrace-extension.zip` from the [latest GitHub Release](https://github.com/BODMAT/worktrace/releases/latest), then:

Then in Chrome:

1. Unzip `worktrace-extension.zip` to any folder
1. Unzip to any folder
2. Open `chrome://extensions` → **Developer mode** → **Load unpacked**
3. Select the unzipped folder

No `.env` needed — the production dashboard URL and OAuth client ID are baked into the release build.

## Verifying it works

1. **Dashboard** — відкрий `http://localhost:3000`, натисни "Sign in with Google" → має відкритись `/dashboard` з даними.
Expand Down
2 changes: 1 addition & 1 deletion dashboard/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default async function DashboardLayout({
</main>
<footer className="relative z-10 flex items-center justify-center border-t border-border bg-bg/95 px-6 py-3 backdrop-blur">
<a
href="https://github.com/BODMAT/worktrace"
href="https://github.com/BODMAT/worktrace/releases"
target="_blank"
rel="noopener noreferrer"
className="text-[10px] font-bold tracking-widest text-muted transition-colors hover:text-cyan"
Expand Down
25 changes: 21 additions & 4 deletions dashboard/components/smooth-scroll.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
"use client";

import { ReactLenis } from "lenis/react";
import { useEffect } from "react";
import { usePathname } from "next/navigation";
import { ReactLenis, useLenis } from "lenis/react";
import type { LenisOptions } from "lenis";

const OPTIONS: LenisOptions = {
duration: 1.4, // inertia length in seconds
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // expo ease-out
duration: 1.4,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
smoothWheel: true,
};

function LenisResizer() {
const lenis = useLenis();
const pathname = usePathname();
useEffect(() => {
lenis?.scrollTo(0, { immediate: true });
lenis?.resize();
}, [lenis, pathname]);
return null;
}

export function SmoothScroll({ children }: { children: React.ReactNode }) {
return <ReactLenis root options={OPTIONS}>{children}</ReactLenis>;
return (
<ReactLenis root options={OPTIONS}>
<LenisResizer />
{children}
</ReactLenis>
);
}
21 changes: 5 additions & 16 deletions extension/.env.example
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
# ─── Dashboard URL ─────────────────────────────────────────────────────────────
# Local dev: http://localhost:3000
# Production: your Vercel deployment URL (e.g. https://worktrace-ecru.vercel.app)
VITE_DASHBOARD_URL="http://localhost:3000"
# Optional overrides — production defaults are hardcoded in background/index.ts
# Only needed for local development against a different dashboard instance.

# ─── Google OAuth ──────────────────────────────────────────────────────────────
# https://console.cloud.google.com → APIs & Services → Credentials
# → "+ CREATE CREDENTIALS" → "OAuth 2.0 Client ID"
# Application type: Chrome Extension
# Application ID: your unpacked extension ID from chrome://extensions
# → copy the generated Client ID here (same value as GOOGLE_CLIENT_ID in dashboard/.env)
VITE_GOOGLE_CLIENT_ID=""

# ─── Dev mode ───────────────────────────────────────────────────────────────────
# true → "Sign in" bypasses Google OAuth and stores a fake JWT (for local UI testing)
# false → real Google OAuth flow (requires valid VITE_GOOGLE_CLIENT_ID + GCC setup)
VITE_DEV_MODE="false"
# VITE_DASHBOARD_URL="http://localhost:3000" # defaults to https://worktrace-ecru.vercel.app
# VITE_GOOGLE_CLIENT_ID="" # defaults to the production OAuth client ID
# VITE_DEV_MODE="true" # true = bypass Google OAuth (UI testing only)
32 changes: 18 additions & 14 deletions extension/src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import {
} from "./session";
import { initSync, flush, getStatus } from "./sync";

const DASHBOARD_URL = import.meta.env.VITE_DASHBOARD_URL as string;
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID as string;
const DASHBOARD_URL = (import.meta.env.VITE_DASHBOARD_URL as string | undefined)
?? "https://worktrace-ecru.vercel.app";
const GOOGLE_CLIENT_ID = (import.meta.env.VITE_GOOGLE_CLIENT_ID as string | undefined)
?? "574196284059-4go0qqvqvbpjla25hmbp9hc2h3qtvcqi.apps.googleusercontent.com";
const DEV_MODE = import.meta.env.VITE_DEV_MODE === "true";
const EXPIRY_BUFFER_MS = 60_000;

Expand Down Expand Up @@ -475,18 +477,20 @@ chrome.runtime.onMessage.addListener(
}

if (message.type === "NOTE_ADD") {
getSession().then((session) => {
if (!session || session.pausedAt !== null) return;
const event: PendingEvent = {
url: `worktrace://note/${crypto.randomUUID()}`,
title: message.text.slice(0, 80) || "Note",
content: message.text,
tags: ["note", ...message.tags],
timestamp: new Date().toISOString(),
};
void enqueuePending(event);
});
return false;
getSession().then(async (session) => {
if (session && session.pausedAt === null) {
const event: PendingEvent = {
url: `worktrace://note/${crypto.randomUUID()}`,
title: message.text.slice(0, 80) || "Note",
content: message.text,
tags: ["note", ...message.tags],
timestamp: new Date().toISOString(),
};
await enqueuePending(event);
}
sendResponse({ success: true });
}).catch(() => sendResponse({ success: true }));
return true;
}

// ─── Sync messages ───────────────────────────────────────────────────────
Expand Down
1 change: 1 addition & 0 deletions extension/src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import pkg from "../package.json" with { type: "json" };
export default defineManifest({
manifest_version: 3,
name: "WorkTrace",
key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSo1/6UBVPUowjH+mwCmWB30I85MGpNqEvf/uDMQqPcC/+VK7iXahcqQcT1xXo3W/6tXeHVWuDfFslkKw6NZSFrlF7+4AUfl2JPKh4Rd/K5iAnM4BoTKQGx9v6wlR1RYIEgGQ+/nDyc7w1zAI+2oNsrUf+Uw10xDWzDR9fFDntpSgnq/ogR3ojrnnlJdbHIqjYIhdbF832I8Cu1+pMPo/BYbEE9/GFUnV7oNTQARF6Z46w4FZXmD5OLHQPBiAnXqO0u4FM2mKT7BjR64jgYtPhbvwJxYtx8BJPNyfukXq3wwVn7Is9a2iHaYaRg2GB6BSwXmG71sgJHvyHUuSRSlVQIDAQAB",
version: pkg.version,
description: "Capture dev session context for AI-generated reports.",
icons: {
Expand Down
Loading