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
32 changes: 19 additions & 13 deletions .github/workflows/generate-llms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ name: Generate LLMs files

on:
workflow_dispatch:
inputs:
environment:
description: 'Environment'
required: true
default: 'dev'
type: choice
options:
- dev
- prod

permissions:
contents: write
Expand All @@ -23,27 +32,24 @@ jobs:
- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Copy prod env file
- name: Copy env file
run: |
echo "${{ secrets.ENV_PROD }}" | base64 -d > .env
if [ "${{ inputs.environment }}" = "prod" ]; then
echo "${{ secrets.ENV_PROD }}" | base64 -d > .env
else
echo "${{ secrets.ENV_DEV }}" | base64 -d > .env
fi
rm -f .env.local

- name: Generate llms.txt
run: node scripts/generate-llms.mjs
env:
LLMS_MODE: curated

- name: Generate llms-full.txt
run: node scripts/generate-llms.mjs
env:
LLMS_MODE: full
- name: Generate llms-full-pages
run: yarn generate:llms:pages

- name: Commit and push generated files
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add public/keepsimple_/
if ! git diff --cached --quiet; then
git commit -m "chore: regenerate llms files"
git commit -m "chore: regenerate llms pages"
git push
fi
fi
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"scripts": {
"dev": "cross-env NODE_ENV=development APP_ENV=local next dev -p 3005",
"build": "cross-env NODE_ENV=production APP_ENV=prod next build",
"generate:llms": "cross-env LLMS_MODE=curated node scripts/generate-llms.mjs",
"generate:llms:full": "cross-env LLMS_MODE=full node scripts/generate-llms.mjs",
"generate:llms": "cross-env LLMS_MODE=curated ts-node --compiler-options '{\"module\":\"commonjs\",\"target\":\"es2020\"}' scripts/generate-llms.ts",
"generate:llms:full": "cross-env LLMS_MODE=full ts-node --compiler-options '{\"module\":\"commonjs\",\"target\":\"es2020\"}' scripts/generate-llms.ts",
"generate:llms:pages": "ts-node --compiler-options '{\"module\":\"commonjs\",\"target\":\"es2020\"}' scripts/generate-llms-pages.ts",
"start": "cross-env NODE_ENV=production APP_ENV=production yarn build && next start -p 4033",
"start:staging": "cross-env NODE_ENV=production APP_ENV=staging next start -p 3005",
"build:staging": "cross-env NODE_ENV=production APP_ENV=staging next build",
Expand Down
212 changes: 208 additions & 4 deletions public/keepsimple_/llms-full.txt

Large diffs are not rendered by default.

48 changes: 44 additions & 4 deletions public/keepsimple_/llms.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
# KeepSimple
> Practical resources and articles from KeepSimple.
# Keep Simple | Cognitive Science & UX Leadership
> Elevate your leadership with applied cognitive science. Explore behavioral psychology and cognitive frameworks designed for modern managers.

## Pages & Resources
- [Home](https://keepsimple.io/): KeepSimple home page.
- [Slug](https://keepsimple.io/[page]): No description available.
- [Articles](https://keepsimple.io/articles): Browse all KeepSimple articles and categories.
- [Articles Slug](https://keepsimple.io/articles/[page]): No description available.
- [Articles All About User Stories Brand New](https://keepsimple.io/articles/all-about-user-stories-brand-new): This article describes how to write user stories. The author uses real-world example based on the real feature developed for a major online platform.
- [Articles Career Path Of A Manager And A Few Universal Tips](https://keepsimple.io/articles/career-path-of-a-manager-and-a-few-universal-tips): The article summarizes what was described in all previous articles and what are the possible ways of a project manager's career development.
- [Articles Overengineering And Demo Readiness](https://keepsimple.io/articles/overengineering_and_demo_readiness): How to solve overengineering issues in engineering teams, and how to always be ready for important DEMOs and milestones.
- [Articles Philosophies Methodologies And Frameworks](https://keepsimple.io/articles/philosophies-methodologies-and-frameworks): The article describes the fundamental differences between project management philosophies, methodologies, and frameworks.
- [Articles Scrum Framework Artifacts Rituals And Roles](https://keepsimple.io/articles/scrum-framework-artifacts-rituals-and-roles): This article describes all SCRUM Framework artifacts, rituals, and roles, including nuanced details such as the definition of Done, Increment, and others.
- [Articles Software Development Life Cycles](https://keepsimple.io/articles/software-development-life-cycles): The article describes all actual software development life cycles (SDLCs), in particular Predictive, Iterative, Incremental, and Agile.
- [Articles Summarize Like Your Job Depends On It](https://keepsimple.io/articles/summarize-like-your-job-depends-on-it): The article describes the importance of summarization, making quality executive summaries and its impact on career.
- [Articles Technical Components Of The Project](https://keepsimple.io/articles/technical-components-of-the-project): A brief introduction of the main technical components and terms used in the infrastructure of any software project
- [Articles What Is A Project](https://keepsimple.io/articles/what-is-a-project): The article describes what can be considered as a project.
- [Articles Why Study Management](https://keepsimple.io/articles/why-study-management): This article describes the importance of management and why everyone should study management basics regardless of their specialty and interests.
- [Auth](https://keepsimple.io/auth): Authentication page for KeepSimple.
- [Company Management](https://keepsimple.io/company-management): Explore company management resources.
- [Contributors](https://keepsimple.io/contributors): Meet the KeepSimple contributors.
Expand All @@ -18,5 +28,35 @@
- [Tools Longevity Protocol Habits Supplements](https://keepsimple.io/tools/longevity-protocol/habits/supplements): No description available.
- [Tools Longevity Protocol Habits Workout](https://keepsimple.io/tools/longevity-protocol/habits/workout): No description available.
- [Tools Longevity Protocol Results](https://keepsimple.io/tools/longevity-protocol/results): No description available.
- [Uxcore Slug](https://keepsimple.io/uxcore/[slug]): No description available.
- [See All Articles](https://keepsimple.io/articles): Browse all KeepSimple articles and categories.
- [Auth](https://keepsimple.io/auth)
- [Certificate](https://keepsimple.io/user/[userId]/certificate)
- [User Profile](https://keepsimple.io/user/username)
- [Uxcat](https://keepsimple.io/uxcat): First of its kind online test to measure and increase self-awareness
- [Ongoing](https://keepsimple.io/uxcat/ongoing): First of its kind online test to measure and increase self-awareness
- [Start Test](https://keepsimple.io/uxcat/start-test): First of its kind online test to measure and increase self-awareness
- [Test Result](https://keepsimple.io/uxcat/test-result): First of its kind online test to measure and increase self-awareness
- [Why our company has reputation issue?](https://keepsimple.io/uxcg/why-our-company-is-having-reputation-issue): The following 7 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why users aren't happy with product quality?](https://keepsimple.io/uxcg/why-our-users-are-not-happy-with-product): The following 12 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why users don't use requested features?](https://keepsimple.io/uxcg/why-users-do-not-use-requested-features): The following 13 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why did we fail to create the right product associations in the market?](https://keepsimple.io/uxcg/we-could-not-create-needed-associations-on-the-market): The following 12 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why do users complain about product updates?](https://keepsimple.io/uxcg/why-users-complain-about-product-updates): The following 7 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why didn’t our product meet user expectations?](https://keepsimple.io/uxcg/why-our-product-did-not-meet-user-expectations): The following 6 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why don’t users like the product anymore?](https://keepsimple.io/uxcg/why-dont-users-like-the-product-anymore): The following 9 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why are users so sensitive to product changes?](https://keepsimple.io/uxcg/why-users-so-sensitive-to-product-changes): The following 10 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why do our users find our communication overwhelming?](https://keepsimple.io/uxcg/users-find-our-communication-overwhelming): The following 6 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [Why do users complain about the quality of our support?](https://keepsimple.io/uxcg/users-do-not-like-our-customer-support): The following 7 cognitive biases can address this issue. Find the reason and learn how to secure your team's and company's future. Free and only at UX Core.
- [See All UXCG](https://keepsimple.io/uxcg): An extensive knowledge base containing over 1,000 practical examples of applying cognitive biases in business - from idea generation to product launch
- [Availability heuristics](https://keepsimple.io/uxcore/1-availability-heuristics): Explore Availability Heuristics Bias in our UX Core project. Learn how this cognitive bias influences decision-making in product management and HR for free.
- [Attentional bias](https://keepsimple.io/uxcore/2-attentional-bias): Discover attentional bias – a cognitive quirk shaping human focus. Learn how to leverage it in UX and HR for better decision-making. Explore at UX Core.
- [Illusory truth effect](https://keepsimple.io/uxcore/3-illusory-truth-effect): "Elevate your management skills with an understanding of the illusory truth effect! Explore practical applications in HR and product management at UX Core."
- [Mere-exposure effect](https://keepsimple.io/uxcore/4-mere-exposure-effect): Learn how to utilize this bias in software development, applications, product management, and HR activities. Explore all this and more for free, only at UX Core
- [Context effect](https://keepsimple.io/uxcore/5-context-effect): Learn how to use Context Effect in software development, team, and company management. Hands-on examples of use and a lot more for free, only at UX Core project
- [ Cue-dependent forgetting](https://keepsimple.io/uxcore/6-cue-dependent-forgetting): Explore Cue-Dependent Forgetting: Uncover how memory retrieval cues affect information recall. Learn its impact on UX and HR strategies for free at UX Core.
- [Mood-congruent memory bias](https://keepsimple.io/uxcore/7-mood-congruent-memory-bias): Harness Mood-Congruent Memory Bias: Enhance user experiences and HR practices by understanding how emotions influence memory recall. Explore insights at UX Core
- [Frequency illusion](https://keepsimple.io/uxcore/8-frequency-illusion): Master Frequency Illusion Bias: Elevate UX and HR techniques through strategic utilization of cognitive biases. Learn practical applications at UX Core for free
- [Empathy gap](https://keepsimple.io/uxcore/9-empathy-gap): Discover how the empathy gap can be used when developing a product or working in HR team. Harness cognitive bias for improved decision-making. Free at UX Core.
- [Omission bias](https://keepsimple.io/uxcore/10-omission-bias): Explore omission bias: a cognitive inclination to favor inaction over action. Learn how to address it in product management and HR strategies. #UXCore
- [See All UXCore](https://keepsimple.io/uxcore): Apply UX cognitive biases and behavioral patterns to improve product management and team leadership.
- [Uxcore Api](https://keepsimple.io/uxcore-api): Here is the list of all available API details, including the ability to fetch data about all cognitive biases on the project.
- [Uxcp](https://keepsimple.io/uxcp): This tool helps to create a Persona using cognitive biases for sales, marketing, other business teams, and educational purposes.
176 changes: 176 additions & 0 deletions scripts/generate-llms-pages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import * as dotenv from 'dotenv';
import * as fs from 'fs/promises';
import * as http from 'http';
import * as https from 'https';
import * as path from 'path';

dotenv.config({ path: path.join(process.cwd(), '.env'), override: true });
dotenv.config({ path: path.join(process.cwd(), '.env.local'), override: true });

const PUBLIC_DIR = path.join(process.cwd(), 'public');
const OUTPUT_DIR = path.join(
PUBLIC_DIR,
'keepsimple_',
'llms-full-pages',
'article',
);
const SITE_BASE_URL = (
process.env.NEXT_PUBLIC_DOMAIN || 'https://keepsimple.io'
).replace(/\/+$/, '');

const STRAPI_BASE =
process.env.STRAPI_URL || process.env.NEXT_PUBLIC_STRAPI || '';

// ─────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────

const stripHtml = (value: any): string =>
String(value || '')
.replace(/<[^>]*>/g, ' ')
.replace(/&nbsp;/g, ' ')
.replace(/&amp;/g, '&')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&quot;/g, '"')
.replace(/\s+/g, ' ')
.trim();

function getJson(url: string): Promise<any> {
return new Promise((resolve, reject) => {
const client = url.startsWith('https://') ? https : http;
const req = client.request(url, { method: 'GET' }, res => {
const status = res.statusCode ?? 0;
let raw = '';
res.setEncoding('utf8');
res.on('data', (chunk: string) => {
raw += chunk;
});
res.on('end', () => {
if (status < 200 || status >= 300) {
reject(new Error(`HTTP ${status} for ${url}`));
return;
}
try {
resolve(JSON.parse(raw));
} catch (err) {
reject(
new Error(`Invalid JSON for ${url}: ${(err as Error).message}`),
);
}
});
});
req.on('error', reject);
req.end();
});
}

async function strapiGet(endpoint: string): Promise<any> {
const url = `${STRAPI_BASE}/api/${endpoint}`;
return getJson(url);
}

// ─────────────────────────────────────────────
// Fetch all articles with content
// ─────────────────────────────────────────────

async function fetchArticles(): Promise<any[]> {
try {
const data = await strapiGet(
'articles?locale=en&pagination[pageSize]=1000&populate=*',
);
return data?.data || [];
} catch (error: any) {
console.log(
`[strapi] failed to fetch articles: ${error?.message || error}`,
);
return [];
}
}

// ─────────────────────────────────────────────
// Build markdown for a single article
// ─────────────────────────────────────────────

function buildArticleMarkdown(attributes: any, slug: string): string {
const title = attributes?.title || slug;
const description = stripHtml(
attributes?.seoDescription || attributes?.shortDescription || '',
);
const url = `${SITE_BASE_URL}/articles/${slug}`;

const lines: string[] = [];
lines.push(`# ${title}`);
lines.push(`- URL: ${url}`);
if (description) {
lines.push(`- Description: ${description}`);
}
lines.push('');
return lines.join('\n');
}

// ─────────────────────────────────────────────
// Main
// ─────────────────────────────────────────────

async function main(): Promise<void> {
console.log('=== generate-llms-pages.ts ===\n');

if (!STRAPI_BASE) {
console.error(
'[error] STRAPI_URL or NEXT_PUBLIC_STRAPI must be set in .env',
);
process.exit(1);
}

console.log('[step 1] Fetching articles from Strapi...');
const records = await fetchArticles();
console.log(` found ${records.length} articles\n`);

if (!records.length) {
console.log('[done] no articles to write');
return;
}

await fs.mkdir(OUTPUT_DIR, { recursive: true });

let written = 0;
let skipped = 0;

console.log('[step 2] Writing markdown pages...\n');
for (const record of records) {
const attributes = record?.attributes || {};
const slug = String(attributes?.newUrl || '')
.replace(/^\/+/, '')
.replace(/\/+$/, '');

if (!slug) {
skipped++;
continue;
}

const markdown = buildArticleMarkdown(attributes, slug);
const filePath = path.join(OUTPUT_DIR, `${slug}.md`);

try {
await fs.writeFile(filePath, markdown, 'utf8');
console.log(` ✓ ${slug}`);
written++;
} catch (error: any) {
console.log(` ✗ ${slug}: ${error?.message || error}`);
skipped++;
}
}

console.log(`\nSuccessfully wrote ${written} article pages to ${OUTPUT_DIR}`);
if (skipped > 0) {
console.log(`Skipped ${skipped} articles (no slug or write error)`);
}
}

main().catch(error => {
console.error(
`[fatal] generate-llms-pages failed: ${(error as Error).message || error}`,
);
process.exit(1);
});
Loading
Loading