Skip to content
Open

Dev #116

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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
38 changes: 19 additions & 19 deletions .cursor/mcp.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
"mcpServers": {
"task-master-ai": {
"command": "npx",
"args": ["-y", "task-master-ai"],
"env": {
"ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY_HERE",
"PERPLEXITY_API_KEY": "YOUR_PERPLEXITY_API_KEY_HERE",
"OPENAI_API_KEY": "YOUR_OPENAI_KEY_HERE",
"GOOGLE_API_KEY": "YOUR_GOOGLE_KEY_HERE",
"XAI_API_KEY": "YOUR_XAI_KEY_HERE",
"OPENROUTER_API_KEY": "YOUR_OPENROUTER_KEY_HERE",
"MISTRAL_API_KEY": "YOUR_MISTRAL_KEY_HERE",
"AZURE_OPENAI_API_KEY": "YOUR_AZURE_KEY_HERE",
"OLLAMA_API_KEY": "YOUR_OLLAMA_API_KEY_HERE"
}
}
}
}
{
"mcpServers": {
"task-master-ai": {
"command": "npx",
"args": ["-y", "task-master-ai"],
"env": {
"ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY_HERE",
"PERPLEXITY_API_KEY": "YOUR_PERPLEXITY_API_KEY_HERE",
"OPENAI_API_KEY": "YOUR_OPENAI_KEY_HERE",
"GOOGLE_API_KEY": "YOUR_GOOGLE_KEY_HERE",
"XAI_API_KEY": "YOUR_XAI_KEY_HERE",
"OPENROUTER_API_KEY": "YOUR_OPENROUTER_KEY_HERE",
"MISTRAL_API_KEY": "YOUR_MISTRAL_KEY_HERE",
"AZURE_OPENAI_API_KEY": "YOUR_AZURE_KEY_HERE",
"OLLAMA_API_KEY": "YOUR_OLLAMA_API_KEY_HERE"
}
}
}
}
13 changes: 4 additions & 9 deletions .github/lighthouse.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
module.exports = {
ci: {
collect: {
staticDistDir: "./dist",
staticDistDir: './dist',
numberOfRuns: 1,
settings: {
onlyCategories: ["seo", "performance"],
onlyCategories: ['seo', 'performance'],
},
},
assert: {
assertions: {
"categories:seo": ["error", { minScore: 0.9 }],
"categories:performance": ["warn", { minScore: 0.7 }],
'categories:seo': ['error', { minScore: 0.9 }],
'categories:performance': ['warn', { minScore: 0.7 }],
},
},
},
};





52 changes: 20 additions & 32 deletions .github/scripts/seo-check.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { readFile } from "node:fs/promises";
import path from "node:path";
import { readFile } from 'node:fs/promises';
import path from 'node:path';

import { JSDOM } from "jsdom";
import { JSDOM } from 'jsdom';

const REQUIRED_META = [
{ selector: 'meta[name="description"]', label: "description" },
{ selector: 'meta[property="og:title"]', label: "og:title" },
{ selector: 'meta[property="og:description"]', label: "og:description" },
{ selector: 'meta[property="og:image"]', label: "og:image" },
{ selector: 'meta[name="twitter:card"]', label: "twitter:card" },
{ selector: 'link[rel="canonical"]', label: "canonical" },
{ selector: 'meta[name="description"]', label: 'description' },
{ selector: 'meta[property="og:title"]', label: 'og:title' },
{ selector: 'meta[property="og:description"]', label: 'og:description' },
{ selector: 'meta[property="og:image"]', label: 'og:image' },
{ selector: 'meta[name="twitter:card"]', label: 'twitter:card' },
{ selector: 'link[rel="canonical"]', label: 'canonical' },
];

const DIST_DIR =
process.env.LANDING_DIST_DIR ?? path.resolve(process.cwd(), "dist");
const ENTRY_FILE = path.join(DIST_DIR, "index.html");
const DIST_DIR = process.env.LANDING_DIST_DIR ?? path.resolve(process.cwd(), 'dist');
const ENTRY_FILE = path.join(DIST_DIR, 'index.html');

async function loadDom() {
try {
const markup = await readFile(ENTRY_FILE, "utf-8");
const markup = await readFile(ENTRY_FILE, 'utf-8');
return new JSDOM(markup);
} catch (error) {
console.error(`Failed to read ${ENTRY_FILE}. Did you run pnpm landing:build?`);
Expand All @@ -28,32 +27,26 @@ async function loadDom() {

function validateMeta(dom: JSDOM) {
const head = dom.window.document.head;
const missing = REQUIRED_META.filter(
(meta) => head.querySelector(meta.selector) === null,
);
const missing = REQUIRED_META.filter((meta) => head.querySelector(meta.selector) === null);

if (missing.length > 0) {
throw new Error(
`Missing required meta tags:\n- ${missing
.map((meta) => meta.label)
.join("\n- ")}`,
`Missing required meta tags:\n- ${missing.map((meta) => meta.label).join('\n- ')}`
);
}
}

function validateImages(dom: JSDOM) {
const images = Array.from(dom.window.document.querySelectorAll("img"));
const images = Array.from(dom.window.document.querySelectorAll('img'));
const withoutAlt = images.filter((img) => {
const alt = img.getAttribute("alt");
const alt = img.getAttribute('alt');
return !alt || alt.trim().length === 0;
});

if (withoutAlt.length > 0) {
const sample = withoutAlt
.slice(0, 5)
.map((img) => img.getAttribute("src") ?? "unknown src");
const sample = withoutAlt.slice(0, 5).map((img) => img.getAttribute('src') ?? 'unknown src');
throw new Error(
`Found ${withoutAlt.length} <img> tags without alt text. Sample: ${sample.join(", ")}`,
`Found ${withoutAlt.length} <img> tags without alt text. Sample: ${sample.join(', ')}`
);
}
}
Expand All @@ -63,16 +56,11 @@ async function main() {
validateMeta(dom);
validateImages(dom);

console.log("✅ SEO metadata and image alt text validated.");
console.log('✅ SEO metadata and image alt text validated.');
}

main().catch((error) => {
console.error("❌ SEO validation failed.");
console.error('❌ SEO validation failed.');
console.error(error instanceof Error ? error.message : error);
process.exit(1);
});





6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ reports/

# Task files
# tasks.json
# tasks/
# tasks/

# Windows reserved device names (prevent Git errors)
nul
NUL
9 changes: 4 additions & 5 deletions .precommitrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"mode": "fast",
"runLint": true,
"runTypecheck": false,
"runTests": false
"mode": "fast",
"runLint": true,
"runTypecheck": false,
"runTests": false
}

38 changes: 17 additions & 21 deletions .swcrc
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
{
"$schema": "https://swc.rs/schema.json",
"env": { "targets": "defaults" },
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false
},
"transform": {
"react": {
"runtime": "automatic",
"refresh": true
}
}
},
"module": { "type": "es6" },
"sourceMaps": true
"$schema": "https://swc.rs/schema.json",
"env": { "targets": "defaults" },
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false
},
"transform": {
"react": {
"runtime": "automatic",
"refresh": true
}
}
},
"module": { "type": "es6" },
"sourceMaps": true
}




88 changes: 44 additions & 44 deletions .taskmaster/config.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
{
"models": {
"main": {
"provider": "anthropic",
"modelId": "claude-3-7-sonnet-20250219",
"maxTokens": 120000,
"temperature": 0.2
},
"research": {
"provider": "perplexity",
"modelId": "sonar-pro",
"maxTokens": 8700,
"temperature": 0.1
},
"fallback": {
"provider": "anthropic",
"modelId": "claude-3-7-sonnet-20250219",
"maxTokens": 120000,
"temperature": 0.2
}
},
"global": {
"logLevel": "info",
"debug": false,
"defaultNumTasks": 10,
"defaultSubtasks": 5,
"defaultPriority": "medium",
"projectName": "Taskmaster",
"ollamaBaseURL": "http://localhost:11434/api",
"bedrockBaseURL": "https://bedrock.us-east-1.amazonaws.com",
"responseLanguage": "English",
"enableCodebaseAnalysis": true,
"defaultTag": "master",
"azureOpenaiBaseURL": "https://your-endpoint.openai.azure.com/",
"userId": "1234567890"
},
"claudeCode": {},
"codexCli": {},
"grokCli": {
"timeout": 120000,
"workingDirectory": null,
"defaultModel": "grok-4-latest"
}
}
{
"models": {
"main": {
"provider": "anthropic",
"modelId": "claude-3-7-sonnet-20250219",
"maxTokens": 120000,
"temperature": 0.2
},
"research": {
"provider": "perplexity",
"modelId": "sonar-pro",
"maxTokens": 8700,
"temperature": 0.1
},
"fallback": {
"provider": "anthropic",
"modelId": "claude-3-7-sonnet-20250219",
"maxTokens": 120000,
"temperature": 0.2
}
},
"global": {
"logLevel": "info",
"debug": false,
"defaultNumTasks": 10,
"defaultSubtasks": 5,
"defaultPriority": "medium",
"projectName": "Taskmaster",
"ollamaBaseURL": "http://localhost:11434/api",
"bedrockBaseURL": "https://bedrock.us-east-1.amazonaws.com",
"responseLanguage": "English",
"enableCodebaseAnalysis": true,
"defaultTag": "master",
"azureOpenaiBaseURL": "https://your-endpoint.openai.azure.com/",
"userId": "1234567890"
},
"claudeCode": {},
"codexCli": {},
"grokCli": {
"timeout": 120000,
"workingDirectory": null,
"defaultModel": "grok-4-latest"
}
}
12 changes: 6 additions & 6 deletions .taskmaster/state.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"currentTag": "master",
"lastSwitched": "2025-11-13T01:34:10.316Z",
"branchTagMapping": {},
"migrationNoticeShown": false
}
{
"currentTag": "master",
"lastSwitched": "2025-11-13T01:34:10.316Z",
"branchTagMapping": {},
"migrationNoticeShown": false
}
64 changes: 32 additions & 32 deletions .taskmaster/tasks/tasks.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
{
"master": {
"tasks": [
{
"id": 1,
"title": "Fix gradient hero text and marquee alignment",
"description": "Adjust the ConnectAnythingHero component so the gradient headline renders without clipping and the 3D marquee background stays centered.",
"details": "",
"testStrategy": "",
"status": "done",
"dependencies": [],
"priority": "high",
"subtasks": [
{
"id": 1,
"title": "Gather component context and diagnose clipping",
"description": "Inspect ConnectAnythingHero and AnimatedGradientText implementations to identify why the headline baseline is clipped.",
"details": "",
"status": "done",
"dependencies": [],
"parentTaskId": 1
}
]
}
],
"metadata": {
"created": "2025-11-13T01:34:28.015Z",
"description": "Default tasks context",
"updated": "2025-11-13T01:38:35.934Z"
}
}
}
{
"master": {
"tasks": [
{
"id": 1,
"title": "Fix gradient hero text and marquee alignment",
"description": "Adjust the ConnectAnythingHero component so the gradient headline renders without clipping and the 3D marquee background stays centered.",
"details": "",
"testStrategy": "",
"status": "done",
"dependencies": [],
"priority": "high",
"subtasks": [
{
"id": 1,
"title": "Gather component context and diagnose clipping",
"description": "Inspect ConnectAnythingHero and AnimatedGradientText implementations to identify why the headline baseline is clipped.",
"details": "",
"status": "done",
"dependencies": [],
"parentTaskId": 1
}
]
}
],
"metadata": {
"created": "2025-11-13T01:34:28.015Z",
"description": "Default tasks context",
"updated": "2025-11-13T01:38:35.934Z"
}
}
}
Loading