create-hq 5.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/deps.d.ts +2 -2
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +138 -29
- package/dist/deps.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +16 -26
- package/dist/scaffold.js.map +1 -1
- package/dist/ui.js +1 -1
- package/package.json +3 -6
- package/template/.claude/CLAUDE.md +0 -202
- package/template/.claude/commands/checkpoint.md +0 -127
- package/template/.claude/commands/cleanup.md +0 -307
- package/template/.claude/commands/execute-task.md +0 -440
- package/template/.claude/commands/exit-plan.md +0 -41
- package/template/.claude/commands/handoff.md +0 -97
- package/template/.claude/commands/learn.md +0 -218
- package/template/.claude/commands/metrics.md +0 -118
- package/template/.claude/commands/newworker.md +0 -162
- package/template/.claude/commands/nexttask.md +0 -67
- package/template/.claude/commands/prd.md +0 -238
- package/template/.claude/commands/reanchor.md +0 -51
- package/template/.claude/commands/remember.md +0 -126
- package/template/.claude/commands/run-project.md +0 -348
- package/template/.claude/commands/run.md +0 -110
- package/template/.claude/commands/search-reindex.md +0 -62
- package/template/.claude/commands/search.md +0 -100
- package/template/.claude/commands/setup.md +0 -381
- package/template/.claude/scripts/pure-ralph-loop.ps1 +0 -312
- package/template/.claude/scripts/pure-ralph-loop.sh +0 -859
- package/template/CHANGELOG.md +0 -220
- package/template/LICENSE +0 -21
- package/template/MIGRATION.md +0 -259
- package/template/README.md +0 -368
- package/template/data/journal/.gitkeep +0 -0
- package/template/docs/images/ascii-banner-options.md +0 -122
- package/template/docs/images/hq-banner.svg +0 -105
- package/template/knowledge/Ralph/01-overview.md +0 -71
- package/template/knowledge/Ralph/02-core-concepts.md +0 -114
- package/template/knowledge/Ralph/03-how-ralph-works.md +0 -184
- package/template/knowledge/Ralph/04-back-pressure.md +0 -222
- package/template/knowledge/Ralph/05-specifications.md +0 -210
- package/template/knowledge/Ralph/06-agents-md.md +0 -222
- package/template/knowledge/Ralph/07-implementation.md +0 -316
- package/template/knowledge/Ralph/08-economics.md +0 -182
- package/template/knowledge/Ralph/09-resources.md +0 -145
- package/template/knowledge/Ralph/10-claude-code-workflow.md +0 -212
- package/template/knowledge/Ralph/11-team-training-guide.md +0 -383
- package/template/knowledge/Ralph/README.md +0 -40
- package/template/knowledge/ai-security-framework/CONTRIBUTING.md +0 -139
- package/template/knowledge/ai-security-framework/GLOSSARY.md +0 -176
- package/template/knowledge/ai-security-framework/LICENSE +0 -21
- package/template/knowledge/ai-security-framework/QUICK-START.md +0 -172
- package/template/knowledge/ai-security-framework/README.md +0 -232
- package/template/knowledge/ai-security-framework/checklists/browser-security.md +0 -301
- package/template/knowledge/ai-security-framework/checklists/credential-isolation.md +0 -322
- package/template/knowledge/ai-security-framework/checklists/incident-response.md +0 -288
- package/template/knowledge/ai-security-framework/checklists/pre-flight.md +0 -249
- package/template/knowledge/ai-security-framework/checklists/weekly-audit.md +0 -159
- package/template/knowledge/ai-security-framework/configs/audit-logging.md +0 -372
- package/template/knowledge/ai-security-framework/configs/kill-switches.md +0 -354
- package/template/knowledge/ai-security-framework/docs/01-core-principles.md +0 -256
- package/template/knowledge/ai-security-framework/docs/02-threat-landscape.md +0 -326
- package/template/knowledge/ai-security-framework/docs/03-security-posture.md +0 -250
- package/template/knowledge/ai-security-framework/templates/agents-security.md +0 -233
- package/template/knowledge/design-styles/README.md +0 -42
- package/template/knowledge/design-styles/american-industrial.md +0 -136
- package/template/knowledge/design-styles/ethereal-abstract.md +0 -133
- package/template/knowledge/design-styles/liminal-portal.md +0 -111
- package/template/knowledge/design-styles/swipes/american-industrial/G-3m4YPW0AADdu2.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G-JJlt5WwAABK3K.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G-JJmj5W0AEbJ-7.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G59fgNuXkAAKLJQ (1).jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G59fgNuXkAAKLJQ.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G7fVkn3WEAAM-ST.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G8ECO5JWEAIksyn.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G9-3GQSWoAA8eqZ.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G9xEOqrXkAEZRcs.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G_MVeJrXQAA8sx4.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G_RSkmGXkAAgAVZ.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/README.md +0 -31
- package/template/knowledge/design-styles/swipes/american-industrial/qyqtg7Dq.png +0 -0
- package/template/knowledge/dev-team/README.md +0 -35
- package/template/knowledge/dev-team/patterns/README.md +0 -34
- package/template/knowledge/dev-team/patterns/frontend/react-best-practices.md +0 -178
- package/template/knowledge/dev-team/troubleshooting/README.md +0 -31
- package/template/knowledge/dev-team/workflows/README.md +0 -49
- package/template/knowledge/hq/checkpoint-schema.json +0 -51
- package/template/knowledge/hq/index-md-spec.md +0 -74
- package/template/knowledge/hq/thread-schema.md +0 -153
- package/template/knowledge/hq-core/checkpoint-schema.json +0 -51
- package/template/knowledge/hq-core/index-md-spec.md +0 -74
- package/template/knowledge/hq-core/thread-schema.md +0 -153
- package/template/knowledge/loom/README.md +0 -51
- package/template/knowledge/loom/architecture.md +0 -125
- package/template/knowledge/loom/code-style.md +0 -169
- package/template/knowledge/loom/llm-proxy.md +0 -132
- package/template/knowledge/loom/state-machine.md +0 -131
- package/template/knowledge/loom/thread-system.md +0 -117
- package/template/knowledge/loom/tools.md +0 -94
- package/template/knowledge/loom/weaver.md +0 -96
- package/template/knowledge/loom/web-frontend.md +0 -131
- package/template/knowledge/projects/README.md +0 -72
- package/template/knowledge/projects/templates/README.template.md +0 -28
- package/template/knowledge/workers/README.md +0 -195
- package/template/knowledge/workers/ralph-loop-pattern.md +0 -157
- package/template/knowledge/workers/skill-schema.md +0 -182
- package/template/knowledge/workers/state-machine.md +0 -102
- package/template/knowledge/workers/templates/base-worker.yaml +0 -73
- package/template/knowledge/workers/templates/code-worker.yaml +0 -85
- package/template/knowledge/workers/templates/skill.yaml +0 -49
- package/template/knowledge/workers/templates/social-worker.yaml +0 -70
- package/template/modules/examples/full-manifest.yaml +0 -92
- package/template/modules/examples/minimal.yaml +0 -14
- package/template/modules/modules.yaml +0 -59
- package/template/projects/.gitkeep +0 -0
- package/template/projects/incorporate-workers-into-pure-ralph/prd.json +0 -88
- package/template/projects/pure-ralph-branch-isolation/README.md +0 -114
- package/template/projects/pure-ralph-branch-isolation/prd.json +0 -123
- package/template/projects/purist-ralph-loop/README.md +0 -148
- package/template/projects/purist-ralph-loop/prd.json +0 -135
- package/template/projects/ralph-test/prd.json +0 -50
- package/template/prompts/pure-ralph-base.md +0 -551
- package/template/settings/.gitkeep +0 -0
- package/template/settings/pure-ralph.json +0 -42
- package/template/social-content/drafts/INDEX.md +0 -21
- package/template/social-content/drafts/linkedin/.gitkeep +0 -1
- package/template/social-content/drafts/x/.gitkeep +0 -1
- package/template/social-content/images/.gitkeep +0 -1
- package/template/starter-projects/code-worker/README.md +0 -97
- package/template/starter-projects/code-worker/prd.json +0 -45
- package/template/starter-projects/personal-assistant/README.md +0 -42
- package/template/starter-projects/personal-assistant/prd.json +0 -43
- package/template/starter-projects/social-media/README.md +0 -60
- package/template/starter-projects/social-media/prd.json +0 -43
- package/template/workers/content-brand/README.md +0 -59
- package/template/workers/content-brand/skills/messaging-alignment.md +0 -91
- package/template/workers/content-brand/skills/tone-check.md +0 -76
- package/template/workers/content-brand/skills/voice-analysis.md +0 -68
- package/template/workers/content-brand/worker.yaml +0 -81
- package/template/workers/content-legal/README.md +0 -80
- package/template/workers/content-legal/skills/claim-substantiation.md +0 -150
- package/template/workers/content-legal/skills/compliance-scan.md +0 -123
- package/template/workers/content-legal/skills/disclaimer-check.md +0 -146
- package/template/workers/content-legal/worker.yaml +0 -118
- package/template/workers/content-product/README.md +0 -77
- package/template/workers/content-product/skills/claim-verification.md +0 -96
- package/template/workers/content-product/skills/feature-accuracy.md +0 -117
- package/template/workers/content-product/skills/stats-check.md +0 -128
- package/template/workers/content-product/worker.yaml +0 -97
- package/template/workers/content-sales/README.md +0 -70
- package/template/workers/content-sales/skills/conversion-analysis.md +0 -96
- package/template/workers/content-sales/skills/cta-audit.md +0 -107
- package/template/workers/content-sales/skills/value-prop-check.md +0 -114
- package/template/workers/content-sales/worker.yaml +0 -93
- package/template/workers/content-shared/cli.ts +0 -242
- package/template/workers/content-shared/index.ts +0 -234
- package/template/workers/content-shared/lib/accuracy-analyzer.ts +0 -661
- package/template/workers/content-shared/lib/analyze.ts +0 -370
- package/template/workers/content-shared/lib/brand-analyzer.ts +0 -526
- package/template/workers/content-shared/lib/cms-integration.ts +0 -446
- package/template/workers/content-shared/lib/compliance-analyzer.ts +0 -655
- package/template/workers/content-shared/lib/conversion-analyzer.ts +0 -555
- package/template/workers/content-shared/lib/github-integration.ts +0 -582
- package/template/workers/content-shared/lib/output.ts +0 -373
- package/template/workers/content-shared/lib/parser.ts +0 -771
- package/template/workers/content-shared/lib/priority.ts +0 -439
- package/template/workers/content-shared/lib/recommendations.ts +0 -512
- package/template/workers/content-shared/lib/reporter.ts +0 -749
- package/template/workers/content-shared/lib/restructure.ts +0 -664
- package/template/workers/content-shared/lib/scorer.ts +0 -140
- package/template/workers/content-shared/lib/types.ts +0 -227
- package/template/workers/content-shared/lib/variants.ts +0 -595
- package/template/workers/content-shared/package.json +0 -51
- package/template/workers/content-shared/pnpm-lock.yaml +0 -39
- package/template/workers/content-shared/test/sample-page.json +0 -115
- package/template/workers/content-shared/tsconfig.json +0 -20
- package/template/workers/dev-team/README.md +0 -166
- package/template/workers/dev-team/_template.yaml +0 -70
- package/template/workers/dev-team/architect/package.json +0 -27
- package/template/workers/dev-team/architect/skills/api-design.md +0 -89
- package/template/workers/dev-team/architect/skills/refactor-plan.md +0 -96
- package/template/workers/dev-team/architect/skills/system-design.md +0 -100
- package/template/workers/dev-team/architect/src/index.ts +0 -49
- package/template/workers/dev-team/architect/src/mcp-server.ts +0 -122
- package/template/workers/dev-team/architect/src/skills/api-design.ts +0 -316
- package/template/workers/dev-team/architect/src/skills/refactor-plan.ts +0 -264
- package/template/workers/dev-team/architect/src/skills/system-design.ts +0 -212
- package/template/workers/dev-team/architect/tsconfig.json +0 -19
- package/template/workers/dev-team/architect/worker.yaml +0 -128
- package/template/workers/dev-team/backend-dev/package-lock.json +0 -1252
- package/template/workers/dev-team/backend-dev/package.json +0 -27
- package/template/workers/dev-team/backend-dev/skills/implement-endpoint.md +0 -70
- package/template/workers/dev-team/backend-dev/skills/implement-service.md +0 -62
- package/template/workers/dev-team/backend-dev/src/index.ts +0 -51
- package/template/workers/dev-team/backend-dev/src/mcp-server.ts +0 -109
- package/template/workers/dev-team/backend-dev/src/skills/implement-endpoint.ts +0 -122
- package/template/workers/dev-team/backend-dev/src/skills/implement-service.ts +0 -126
- package/template/workers/dev-team/backend-dev/tsconfig.json +0 -19
- package/template/workers/dev-team/backend-dev/worker.yaml +0 -128
- package/template/workers/dev-team/code-reviewer/package-lock.json +0 -1080
- package/template/workers/dev-team/code-reviewer/package.json +0 -24
- package/template/workers/dev-team/code-reviewer/skills/merge-to-production.md +0 -61
- package/template/workers/dev-team/code-reviewer/skills/merge-to-staging.md +0 -54
- package/template/workers/dev-team/code-reviewer/skills/request-changes.md +0 -63
- package/template/workers/dev-team/code-reviewer/skills/review-pr.md +0 -77
- package/template/workers/dev-team/code-reviewer/src/index.ts +0 -56
- package/template/workers/dev-team/code-reviewer/src/mcp-server.ts +0 -101
- package/template/workers/dev-team/code-reviewer/tsconfig.json +0 -19
- package/template/workers/dev-team/code-reviewer/worker.yaml +0 -90
- package/template/workers/dev-team/database-dev/package.json +0 -22
- package/template/workers/dev-team/database-dev/skills/create-schema.md +0 -48
- package/template/workers/dev-team/database-dev/src/index.ts +0 -50
- package/template/workers/dev-team/database-dev/src/mcp-server.ts +0 -76
- package/template/workers/dev-team/database-dev/tsconfig.json +0 -18
- package/template/workers/dev-team/database-dev/worker.yaml +0 -90
- package/template/workers/dev-team/frontend-dev/package.json +0 -22
- package/template/workers/dev-team/frontend-dev/skills/create-component.md +0 -26
- package/template/workers/dev-team/frontend-dev/src/index.ts +0 -50
- package/template/workers/dev-team/frontend-dev/src/mcp-server.ts +0 -77
- package/template/workers/dev-team/frontend-dev/tsconfig.json +0 -18
- package/template/workers/dev-team/frontend-dev/worker.yaml +0 -132
- package/template/workers/dev-team/infra-dev/package.json +0 -24
- package/template/workers/dev-team/infra-dev/skills/add-monitoring.md +0 -73
- package/template/workers/dev-team/infra-dev/skills/configure-deployment.md +0 -80
- package/template/workers/dev-team/infra-dev/skills/create-dockerfile.md +0 -62
- package/template/workers/dev-team/infra-dev/skills/setup-cicd.md +0 -63
- package/template/workers/dev-team/infra-dev/src/index.ts +0 -55
- package/template/workers/dev-team/infra-dev/src/mcp-server.ts +0 -82
- package/template/workers/dev-team/infra-dev/tsconfig.json +0 -19
- package/template/workers/dev-team/infra-dev/worker.yaml +0 -92
- package/template/workers/dev-team/knowledge-curator/package.json +0 -24
- package/template/workers/dev-team/knowledge-curator/skills/curate-troubleshooting.md +0 -63
- package/template/workers/dev-team/knowledge-curator/skills/process-learnings.md +0 -61
- package/template/workers/dev-team/knowledge-curator/skills/sync-documentation.md +0 -76
- package/template/workers/dev-team/knowledge-curator/skills/update-patterns.md +0 -63
- package/template/workers/dev-team/knowledge-curator/src/index.ts +0 -53
- package/template/workers/dev-team/knowledge-curator/src/mcp-server.ts +0 -92
- package/template/workers/dev-team/knowledge-curator/tsconfig.json +0 -19
- package/template/workers/dev-team/knowledge-curator/worker.yaml +0 -80
- package/template/workers/dev-team/motion-designer/package.json +0 -22
- package/template/workers/dev-team/motion-designer/skills/add-animation.md +0 -25
- package/template/workers/dev-team/motion-designer/skills/generate-image.md +0 -36
- package/template/workers/dev-team/motion-designer/src/index.ts +0 -63
- package/template/workers/dev-team/motion-designer/src/mcp-server.ts +0 -79
- package/template/workers/dev-team/motion-designer/tsconfig.json +0 -18
- package/template/workers/dev-team/motion-designer/worker.yaml +0 -84
- package/template/workers/dev-team/product-planner/queue.json +0 -4
- package/template/workers/dev-team/product-planner/worker.yaml +0 -220
- package/template/workers/dev-team/project-manager/package-lock.json +0 -1252
- package/template/workers/dev-team/project-manager/package.json +0 -27
- package/template/workers/dev-team/project-manager/skills/create-prd.md +0 -66
- package/template/workers/dev-team/project-manager/skills/next-issue.md +0 -51
- package/template/workers/dev-team/project-manager/skills/project-status.md +0 -59
- package/template/workers/dev-team/project-manager/skills/update-learnings.md +0 -65
- package/template/workers/dev-team/project-manager/src/index.ts +0 -54
- package/template/workers/dev-team/project-manager/src/mcp-server.ts +0 -207
- package/template/workers/dev-team/project-manager/src/skills/create-prd.ts +0 -86
- package/template/workers/dev-team/project-manager/src/skills/next-issue.ts +0 -137
- package/template/workers/dev-team/project-manager/src/skills/project-status.ts +0 -131
- package/template/workers/dev-team/project-manager/src/skills/update-learnings.ts +0 -94
- package/template/workers/dev-team/project-manager/tsconfig.json +0 -19
- package/template/workers/dev-team/project-manager/worker.yaml +0 -96
- package/template/workers/dev-team/qa-tester/package.json +0 -24
- package/template/workers/dev-team/qa-tester/skills/create-demo-account.md +0 -36
- package/template/workers/dev-team/qa-tester/skills/run-tests.md +0 -36
- package/template/workers/dev-team/qa-tester/skills/write-test.md +0 -27
- package/template/workers/dev-team/qa-tester/src/index.ts +0 -61
- package/template/workers/dev-team/qa-tester/src/mcp-server.ts +0 -88
- package/template/workers/dev-team/qa-tester/tsconfig.json +0 -18
- package/template/workers/dev-team/qa-tester/worker.yaml +0 -116
- package/template/workers/dev-team/task-executor/package-lock.json +0 -1252
- package/template/workers/dev-team/task-executor/package.json +0 -27
- package/template/workers/dev-team/task-executor/skills/analyze-issue.md +0 -101
- package/template/workers/dev-team/task-executor/skills/execute.md +0 -133
- package/template/workers/dev-team/task-executor/skills/report-learnings.md +0 -106
- package/template/workers/dev-team/task-executor/skills/validate-completion.md +0 -121
- package/template/workers/dev-team/task-executor/src/index.ts +0 -54
- package/template/workers/dev-team/task-executor/src/mcp-server.ts +0 -139
- package/template/workers/dev-team/task-executor/src/skills/analyze-issue.ts +0 -219
- package/template/workers/dev-team/task-executor/src/skills/execute.ts +0 -132
- package/template/workers/dev-team/task-executor/src/skills/report-learnings.ts +0 -119
- package/template/workers/dev-team/task-executor/src/skills/validate-completion.ts +0 -142
- package/template/workers/dev-team/task-executor/tsconfig.json +0 -19
- package/template/workers/dev-team/task-executor/worker.yaml +0 -110
- package/template/workers/registry.yaml +0 -171
- package/template/workers/security-scanner/README.md +0 -73
- package/template/workers/security-scanner/skills/pre-deploy-check.md +0 -205
- package/template/workers/security-scanner/worker.yaml +0 -26
- package/template/workspace/checkpoints/.gitkeep +0 -0
- package/template/workspace/content-ideas/inbox.jsonl +0 -0
- package/template/workspace/drafts/.gitkeep +0 -0
- package/template/workspace/learnings/.gitkeep +0 -3
- package/template/workspace/orchestrator/.gitkeep +0 -0
- package/template/workspace/ralph-test/COMPLETE.md +0 -18
- package/template/workspace/ralph-test/hello.txt +0 -2
- package/template/workspace/reports/.gitkeep +0 -0
- package/template/workspace/scratch/.gitkeep +0 -0
- package/template/workspace/threads/.gitkeep +0 -3
|
@@ -1,664 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Section Restructuring Analyzer (US-014)
|
|
3
|
-
* Suggests page structure improvements based on templates and best practices
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { PageContent, ContentSection } from './types.js';
|
|
7
|
-
|
|
8
|
-
// ============================================
|
|
9
|
-
// Types
|
|
10
|
-
// ============================================
|
|
11
|
-
|
|
12
|
-
export type SectionAction = 'add' | 'remove' | 'move' | 'merge' | 'split';
|
|
13
|
-
|
|
14
|
-
export interface SectionRecommendation {
|
|
15
|
-
action: SectionAction;
|
|
16
|
-
sectionId?: string;
|
|
17
|
-
newPosition?: number;
|
|
18
|
-
rationale: string;
|
|
19
|
-
suggestedContent?: PageSection;
|
|
20
|
-
priority: 'high' | 'medium' | 'low';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface PageSection {
|
|
24
|
-
id: string;
|
|
25
|
-
type: ContentSection['type'];
|
|
26
|
-
heading?: string;
|
|
27
|
-
description?: string;
|
|
28
|
-
purpose: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface StructureAnalysis {
|
|
32
|
-
pageSlug: string;
|
|
33
|
-
templateUsed: string;
|
|
34
|
-
currentSections: string[];
|
|
35
|
-
missingSections: string[];
|
|
36
|
-
redundantSections: string[];
|
|
37
|
-
orderIssues: string[];
|
|
38
|
-
recommendations: SectionRecommendation[];
|
|
39
|
-
structureScore: number;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export type PageTemplate = 'product' | 'solution' | 'landing' | 'about' | 'pricing' | 'blog' | 'case-study';
|
|
43
|
-
|
|
44
|
-
// ============================================
|
|
45
|
-
// Page Templates
|
|
46
|
-
// ============================================
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Standard page templates defining optimal section order
|
|
50
|
-
*/
|
|
51
|
-
export const PAGE_TEMPLATES: Record<PageTemplate, string[]> = {
|
|
52
|
-
product: ['hero', 'problem', 'solution', 'features', 'proof', 'pricing', 'faq', 'cta'],
|
|
53
|
-
solution: ['hero', 'pain-points', 'how-it-works', 'benefits', 'features', 'case-study', 'cta'],
|
|
54
|
-
landing: ['hero', 'value-prop', 'features', 'testimonials', 'social-proof', 'faq', 'cta'],
|
|
55
|
-
about: ['hero', 'mission', 'story', 'team', 'values', 'contact'],
|
|
56
|
-
pricing: ['hero', 'plans', 'comparison', 'features', 'faq', 'cta'],
|
|
57
|
-
blog: ['header', 'content', 'author', 'related', 'cta'],
|
|
58
|
-
'case-study': ['hero', 'challenge', 'solution', 'results', 'testimonial', 'cta'],
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Section type to template section mapping
|
|
63
|
-
*/
|
|
64
|
-
const SECTION_TYPE_MAP: Record<ContentSection['type'], string[]> = {
|
|
65
|
-
hero: ['hero'],
|
|
66
|
-
features: ['features', 'benefits', 'value-prop'],
|
|
67
|
-
testimonials: ['testimonials', 'proof', 'social-proof', 'case-study'],
|
|
68
|
-
pricing: ['pricing', 'plans', 'comparison'],
|
|
69
|
-
cta: ['cta'],
|
|
70
|
-
content: ['content', 'story', 'mission', 'values', 'how-it-works', 'solution', 'problem', 'pain-points', 'challenge', 'results'],
|
|
71
|
-
footer: ['footer', 'contact'],
|
|
72
|
-
header: ['header'],
|
|
73
|
-
other: [],
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Recommended section content for common section types
|
|
78
|
-
*/
|
|
79
|
-
export const SECTION_TEMPLATES: Record<string, PageSection> = {
|
|
80
|
-
hero: {
|
|
81
|
-
id: 'hero',
|
|
82
|
-
type: 'hero',
|
|
83
|
-
heading: 'Headline that captures your unique value proposition',
|
|
84
|
-
description: 'Supporting text that expands on the headline with specific benefits',
|
|
85
|
-
purpose: 'Immediately communicate what you offer and why it matters',
|
|
86
|
-
},
|
|
87
|
-
problem: {
|
|
88
|
-
id: 'problem',
|
|
89
|
-
type: 'content',
|
|
90
|
-
heading: 'The Challenge You Face',
|
|
91
|
-
description: 'Describe the pain points your target audience experiences',
|
|
92
|
-
purpose: 'Create resonance by articulating the problem better than the reader can',
|
|
93
|
-
},
|
|
94
|
-
solution: {
|
|
95
|
-
id: 'solution',
|
|
96
|
-
type: 'content',
|
|
97
|
-
heading: 'How We Help',
|
|
98
|
-
description: 'Explain your approach to solving the problem',
|
|
99
|
-
purpose: 'Position your product/service as the answer to their challenge',
|
|
100
|
-
},
|
|
101
|
-
features: {
|
|
102
|
-
id: 'features',
|
|
103
|
-
type: 'features',
|
|
104
|
-
heading: 'Key Features',
|
|
105
|
-
description: 'List of 3-6 core features with brief descriptions',
|
|
106
|
-
purpose: 'Show the specific capabilities that deliver value',
|
|
107
|
-
},
|
|
108
|
-
benefits: {
|
|
109
|
-
id: 'benefits',
|
|
110
|
-
type: 'features',
|
|
111
|
-
heading: 'Benefits',
|
|
112
|
-
description: 'Outcomes and results customers achieve',
|
|
113
|
-
purpose: 'Translate features into tangible value for the customer',
|
|
114
|
-
},
|
|
115
|
-
proof: {
|
|
116
|
-
id: 'proof',
|
|
117
|
-
type: 'testimonials',
|
|
118
|
-
heading: 'Trusted By',
|
|
119
|
-
description: 'Customer testimonials, logos, case study snippets',
|
|
120
|
-
purpose: 'Build credibility through social proof and third-party validation',
|
|
121
|
-
},
|
|
122
|
-
testimonials: {
|
|
123
|
-
id: 'testimonials',
|
|
124
|
-
type: 'testimonials',
|
|
125
|
-
heading: 'What Our Customers Say',
|
|
126
|
-
description: 'Direct quotes from satisfied customers',
|
|
127
|
-
purpose: 'Let customers tell your story in their own words',
|
|
128
|
-
},
|
|
129
|
-
faq: {
|
|
130
|
-
id: 'faq',
|
|
131
|
-
type: 'content',
|
|
132
|
-
heading: 'Frequently Asked Questions',
|
|
133
|
-
description: 'Common questions and clear answers',
|
|
134
|
-
purpose: 'Address objections and provide additional information',
|
|
135
|
-
},
|
|
136
|
-
cta: {
|
|
137
|
-
id: 'cta',
|
|
138
|
-
type: 'cta',
|
|
139
|
-
heading: 'Ready to Get Started?',
|
|
140
|
-
description: 'Clear call to action with next steps',
|
|
141
|
-
purpose: 'Convert interest into action with a compelling offer',
|
|
142
|
-
},
|
|
143
|
-
pricing: {
|
|
144
|
-
id: 'pricing',
|
|
145
|
-
type: 'pricing',
|
|
146
|
-
heading: 'Simple, Transparent Pricing',
|
|
147
|
-
description: 'Clear pricing tiers with feature breakdown',
|
|
148
|
-
purpose: 'Make the purchase decision easy with clear options',
|
|
149
|
-
},
|
|
150
|
-
'how-it-works': {
|
|
151
|
-
id: 'how-it-works',
|
|
152
|
-
type: 'content',
|
|
153
|
-
heading: 'How It Works',
|
|
154
|
-
description: '3-5 step process explaining the customer journey',
|
|
155
|
-
purpose: 'Demystify the product/service and reduce perceived complexity',
|
|
156
|
-
},
|
|
157
|
-
'case-study': {
|
|
158
|
-
id: 'case-study',
|
|
159
|
-
type: 'content',
|
|
160
|
-
heading: 'Success Story',
|
|
161
|
-
description: 'Detailed customer success narrative',
|
|
162
|
-
purpose: 'Demonstrate real-world results and build credibility',
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
// ============================================
|
|
167
|
-
// Template Detection
|
|
168
|
-
// ============================================
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Infer the most likely template for a page based on its sections
|
|
172
|
-
*/
|
|
173
|
-
export function inferTemplate(page: PageContent): PageTemplate {
|
|
174
|
-
const sectionTypes = page.sections.map(s => s.type);
|
|
175
|
-
const sectionHeadings = page.sections.map(s => (s.heading ?? '').toLowerCase());
|
|
176
|
-
|
|
177
|
-
// Check for pricing page indicators
|
|
178
|
-
if (sectionTypes.includes('pricing') || sectionHeadings.some(h => h.includes('pricing') || h.includes('plans'))) {
|
|
179
|
-
return 'pricing';
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Check for about page indicators
|
|
183
|
-
if (sectionHeadings.some(h => h.includes('mission') || h.includes('team') || h.includes('story') || h.includes('about'))) {
|
|
184
|
-
return 'about';
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Check for case study indicators
|
|
188
|
-
if (sectionHeadings.some(h => h.includes('challenge') || h.includes('results') || h.includes('case study'))) {
|
|
189
|
-
return 'case-study';
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Check for blog indicators
|
|
193
|
-
if (sectionHeadings.some(h => h.includes('author') || h.includes('related posts'))) {
|
|
194
|
-
return 'blog';
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Check for solution vs product page
|
|
198
|
-
if (sectionHeadings.some(h => h.includes('pain') || h.includes('how it works') || h.includes('benefits'))) {
|
|
199
|
-
return 'solution';
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Check for testimonials heavy pages (landing)
|
|
203
|
-
if (sectionTypes.filter(t => t === 'testimonials').length >= 2) {
|
|
204
|
-
return 'landing';
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Default to product page
|
|
208
|
-
return 'product';
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// ============================================
|
|
212
|
-
// Structure Analysis
|
|
213
|
-
// ============================================
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Analyze page structure against templates
|
|
217
|
-
*/
|
|
218
|
-
export function analyzeStructure(page: PageContent, template?: PageTemplate): StructureAnalysis {
|
|
219
|
-
const inferredTemplate = template ?? inferTemplate(page);
|
|
220
|
-
const templateSections = PAGE_TEMPLATES[inferredTemplate];
|
|
221
|
-
const currentSections = extractSectionIdentifiers(page);
|
|
222
|
-
|
|
223
|
-
// Find missing sections
|
|
224
|
-
const missingSections = findMissingSections(currentSections, templateSections);
|
|
225
|
-
|
|
226
|
-
// Find redundant sections
|
|
227
|
-
const redundantSections = findRedundantSections(page, templateSections);
|
|
228
|
-
|
|
229
|
-
// Check section ordering
|
|
230
|
-
const orderIssues = checkSectionOrder(currentSections, templateSections);
|
|
231
|
-
|
|
232
|
-
// Generate recommendations
|
|
233
|
-
const recommendations = generateStructureRecommendations(
|
|
234
|
-
page,
|
|
235
|
-
inferredTemplate,
|
|
236
|
-
missingSections,
|
|
237
|
-
redundantSections,
|
|
238
|
-
orderIssues
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
// Calculate structure score
|
|
242
|
-
const structureScore = calculateStructureScore(
|
|
243
|
-
currentSections.length,
|
|
244
|
-
templateSections.length,
|
|
245
|
-
missingSections.length,
|
|
246
|
-
redundantSections.length,
|
|
247
|
-
orderIssues.length
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
return {
|
|
251
|
-
pageSlug: extractSlug(page.url),
|
|
252
|
-
templateUsed: inferredTemplate,
|
|
253
|
-
currentSections,
|
|
254
|
-
missingSections,
|
|
255
|
-
redundantSections,
|
|
256
|
-
orderIssues,
|
|
257
|
-
recommendations,
|
|
258
|
-
structureScore,
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Extract section identifiers from page
|
|
264
|
-
*/
|
|
265
|
-
function extractSectionIdentifiers(page: PageContent): string[] {
|
|
266
|
-
return page.sections.map(section => {
|
|
267
|
-
// First, try to match section type to template sections
|
|
268
|
-
const mappedSections = SECTION_TYPE_MAP[section.type];
|
|
269
|
-
if (mappedSections.length > 0) {
|
|
270
|
-
// Check if heading gives more specific info
|
|
271
|
-
const headingLower = (section.heading ?? '').toLowerCase();
|
|
272
|
-
for (const mapped of mappedSections) {
|
|
273
|
-
if (headingLower.includes(mapped.replace('-', ' '))) {
|
|
274
|
-
return mapped;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return mappedSections[0];
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Fall back to section type
|
|
281
|
-
return section.type;
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Find sections that should be present but aren't
|
|
287
|
-
*/
|
|
288
|
-
function findMissingSections(current: string[], template: string[]): string[] {
|
|
289
|
-
const missing: string[] = [];
|
|
290
|
-
|
|
291
|
-
for (const templateSection of template) {
|
|
292
|
-
// Check if any current section matches this template section
|
|
293
|
-
const hasMatch = current.some(c => sectionMatches(c, templateSection));
|
|
294
|
-
if (!hasMatch) {
|
|
295
|
-
missing.push(templateSection);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return missing;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Check if a current section matches a template section
|
|
304
|
-
*/
|
|
305
|
-
function sectionMatches(current: string, template: string): boolean {
|
|
306
|
-
// Direct match
|
|
307
|
-
if (current === template) return true;
|
|
308
|
-
|
|
309
|
-
// Check type mappings
|
|
310
|
-
for (const [type, mappings] of Object.entries(SECTION_TYPE_MAP)) {
|
|
311
|
-
if (mappings.includes(current) && mappings.includes(template)) {
|
|
312
|
-
return true;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// Related sections
|
|
317
|
-
const relatedPairs: [string, string][] = [
|
|
318
|
-
['features', 'benefits'],
|
|
319
|
-
['proof', 'testimonials'],
|
|
320
|
-
['solution', 'how-it-works'],
|
|
321
|
-
['problem', 'pain-points'],
|
|
322
|
-
];
|
|
323
|
-
|
|
324
|
-
for (const [a, b] of relatedPairs) {
|
|
325
|
-
if ((current === a && template === b) || (current === b && template === a)) {
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Find sections that may be redundant
|
|
335
|
-
*/
|
|
336
|
-
function findRedundantSections(page: PageContent, template: string[]): string[] {
|
|
337
|
-
const redundant: string[] = [];
|
|
338
|
-
const sectionCounts: Record<string, number> = {};
|
|
339
|
-
|
|
340
|
-
for (const section of page.sections) {
|
|
341
|
-
const type = section.type;
|
|
342
|
-
sectionCounts[type] = (sectionCounts[type] ?? 0) + 1;
|
|
343
|
-
|
|
344
|
-
// Multiple sections of same type (except content)
|
|
345
|
-
if (sectionCounts[type] > 1 && type !== 'content') {
|
|
346
|
-
redundant.push(`${type} (duplicate #${sectionCounts[type]})`);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Check for sections not in template
|
|
351
|
-
for (const section of page.sections) {
|
|
352
|
-
const identifiers = [section.type, section.id, (section.heading ?? '').toLowerCase()];
|
|
353
|
-
const inTemplate = identifiers.some(id =>
|
|
354
|
-
template.some(t => sectionMatches(id, t))
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
if (!inTemplate && section.type !== 'content' && section.type !== 'other') {
|
|
358
|
-
if (!redundant.includes(section.id)) {
|
|
359
|
-
redundant.push(section.id);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return redundant;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Check if sections are in optimal order
|
|
369
|
-
*/
|
|
370
|
-
function checkSectionOrder(current: string[], template: string[]): string[] {
|
|
371
|
-
const issues: string[] = [];
|
|
372
|
-
|
|
373
|
-
// Map current sections to their template positions
|
|
374
|
-
const positions: { section: string; currentPos: number; templatePos: number }[] = [];
|
|
375
|
-
|
|
376
|
-
for (let i = 0; i < current.length; i++) {
|
|
377
|
-
const templateIndex = template.findIndex(t => sectionMatches(current[i], t));
|
|
378
|
-
if (templateIndex !== -1) {
|
|
379
|
-
positions.push({
|
|
380
|
-
section: current[i],
|
|
381
|
-
currentPos: i,
|
|
382
|
-
templatePos: templateIndex,
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Check for out-of-order sections
|
|
388
|
-
for (let i = 0; i < positions.length - 1; i++) {
|
|
389
|
-
if (positions[i].templatePos > positions[i + 1].templatePos) {
|
|
390
|
-
issues.push(`"${positions[i].section}" should come after "${positions[i + 1].section}"`);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// Check for hero not being first
|
|
395
|
-
const heroIndex = current.findIndex(s => sectionMatches(s, 'hero'));
|
|
396
|
-
if (heroIndex > 0) {
|
|
397
|
-
issues.push('Hero section should be at the top of the page');
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Check for CTA not being last (for pages that should end with CTA)
|
|
401
|
-
const ctaIndex = current.findIndex(s => sectionMatches(s, 'cta'));
|
|
402
|
-
if (ctaIndex !== -1 && ctaIndex < current.length - 2) {
|
|
403
|
-
issues.push('CTA section should be near the bottom of the page');
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return issues;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// ============================================
|
|
410
|
-
// Recommendation Generation
|
|
411
|
-
// ============================================
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Generate structure recommendations
|
|
415
|
-
*/
|
|
416
|
-
function generateStructureRecommendations(
|
|
417
|
-
page: PageContent,
|
|
418
|
-
template: PageTemplate,
|
|
419
|
-
missing: string[],
|
|
420
|
-
redundant: string[],
|
|
421
|
-
orderIssues: string[]
|
|
422
|
-
): SectionRecommendation[] {
|
|
423
|
-
const recommendations: SectionRecommendation[] = [];
|
|
424
|
-
const templateSections = PAGE_TEMPLATES[template];
|
|
425
|
-
|
|
426
|
-
// Recommendations for missing sections
|
|
427
|
-
for (const section of missing) {
|
|
428
|
-
const sectionTemplate = SECTION_TEMPLATES[section];
|
|
429
|
-
const priority = getMissingSectionPriority(section);
|
|
430
|
-
|
|
431
|
-
recommendations.push({
|
|
432
|
-
action: 'add',
|
|
433
|
-
newPosition: templateSections.indexOf(section),
|
|
434
|
-
rationale: `Add a "${section}" section to follow ${template} page best practices`,
|
|
435
|
-
suggestedContent: sectionTemplate,
|
|
436
|
-
priority,
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Recommendations for redundant sections
|
|
441
|
-
for (const section of redundant) {
|
|
442
|
-
// Only suggest removal for truly redundant (not just extra content)
|
|
443
|
-
if (section.includes('duplicate')) {
|
|
444
|
-
recommendations.push({
|
|
445
|
-
action: 'merge',
|
|
446
|
-
sectionId: section.split(' ')[0],
|
|
447
|
-
rationale: `Consider merging duplicate ${section.split(' ')[0]} sections for clarity`,
|
|
448
|
-
priority: 'low',
|
|
449
|
-
});
|
|
450
|
-
} else {
|
|
451
|
-
recommendations.push({
|
|
452
|
-
action: 'remove',
|
|
453
|
-
sectionId: section,
|
|
454
|
-
rationale: `Section "${section}" may not be needed for this page type`,
|
|
455
|
-
priority: 'low',
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Recommendations for order issues
|
|
461
|
-
for (const issue of orderIssues) {
|
|
462
|
-
recommendations.push({
|
|
463
|
-
action: 'move',
|
|
464
|
-
rationale: issue,
|
|
465
|
-
priority: 'medium',
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
// Sort by priority
|
|
470
|
-
const priorityOrder: Record<SectionRecommendation['priority'], number> = {
|
|
471
|
-
high: 0,
|
|
472
|
-
medium: 1,
|
|
473
|
-
low: 2,
|
|
474
|
-
};
|
|
475
|
-
recommendations.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
|
|
476
|
-
|
|
477
|
-
return recommendations;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Determine priority for missing section
|
|
482
|
-
*/
|
|
483
|
-
function getMissingSectionPriority(section: string): 'high' | 'medium' | 'low' {
|
|
484
|
-
// Critical sections
|
|
485
|
-
if (['hero', 'cta', 'value-prop'].includes(section)) {
|
|
486
|
-
return 'high';
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Important sections
|
|
490
|
-
if (['features', 'benefits', 'proof', 'how-it-works'].includes(section)) {
|
|
491
|
-
return 'medium';
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// Nice to have
|
|
495
|
-
return 'low';
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
* Suggest new sections to add
|
|
500
|
-
*/
|
|
501
|
-
export function suggestNewSections(page: PageContent, template: PageTemplate): SectionRecommendation[] {
|
|
502
|
-
const analysis = analyzeStructure(page, template);
|
|
503
|
-
return analysis.recommendations.filter(r => r.action === 'add');
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Suggest section reordering
|
|
508
|
-
*/
|
|
509
|
-
export function suggestReorder(page: PageContent, template: PageTemplate): SectionRecommendation[] {
|
|
510
|
-
const analysis = analyzeStructure(page, template);
|
|
511
|
-
return analysis.recommendations.filter(r => r.action === 'move');
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// ============================================
|
|
515
|
-
// Score Calculation
|
|
516
|
-
// ============================================
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Calculate structure score (0-100)
|
|
520
|
-
*/
|
|
521
|
-
function calculateStructureScore(
|
|
522
|
-
currentCount: number,
|
|
523
|
-
templateCount: number,
|
|
524
|
-
missingCount: number,
|
|
525
|
-
redundantCount: number,
|
|
526
|
-
orderIssueCount: number
|
|
527
|
-
): number {
|
|
528
|
-
let score = 100;
|
|
529
|
-
|
|
530
|
-
// Deduct for missing sections (more impact for critical ones)
|
|
531
|
-
score -= missingCount * 10;
|
|
532
|
-
|
|
533
|
-
// Deduct for redundant sections (minor impact)
|
|
534
|
-
score -= redundantCount * 5;
|
|
535
|
-
|
|
536
|
-
// Deduct for ordering issues
|
|
537
|
-
score -= orderIssueCount * 8;
|
|
538
|
-
|
|
539
|
-
// Bonus for comprehensive coverage
|
|
540
|
-
if (currentCount >= templateCount * 0.8) {
|
|
541
|
-
score += 5;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
return Math.max(0, Math.min(100, score));
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// ============================================
|
|
548
|
-
// Utility Functions
|
|
549
|
-
// ============================================
|
|
550
|
-
|
|
551
|
-
function extractSlug(url: string): string {
|
|
552
|
-
let slug = url.replace(/^https?:\/\/[^\/]+/, '');
|
|
553
|
-
slug = slug.replace(/^\/+|\/+$/g, '');
|
|
554
|
-
return slug || 'home';
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// ============================================
|
|
558
|
-
// Formatting
|
|
559
|
-
// ============================================
|
|
560
|
-
|
|
561
|
-
/**
|
|
562
|
-
* Format structure analysis as markdown
|
|
563
|
-
*/
|
|
564
|
-
export function formatStructureAnalysisMarkdown(analysis: StructureAnalysis): string {
|
|
565
|
-
const lines: string[] = [
|
|
566
|
-
`# Structure Analysis: ${analysis.pageSlug}`,
|
|
567
|
-
'',
|
|
568
|
-
`**Template Used:** ${analysis.templateUsed}`,
|
|
569
|
-
`**Structure Score:** ${analysis.structureScore}/100`,
|
|
570
|
-
'',
|
|
571
|
-
];
|
|
572
|
-
|
|
573
|
-
// Current sections
|
|
574
|
-
lines.push('## Current Sections');
|
|
575
|
-
lines.push(analysis.currentSections.map((s, i) => `${i + 1}. ${s}`).join('\n'));
|
|
576
|
-
lines.push('');
|
|
577
|
-
|
|
578
|
-
// Missing sections
|
|
579
|
-
if (analysis.missingSections.length > 0) {
|
|
580
|
-
lines.push('## Missing Sections');
|
|
581
|
-
lines.push(analysis.missingSections.map(s => `- ${s}`).join('\n'));
|
|
582
|
-
lines.push('');
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// Redundant sections
|
|
586
|
-
if (analysis.redundantSections.length > 0) {
|
|
587
|
-
lines.push('## Potentially Redundant');
|
|
588
|
-
lines.push(analysis.redundantSections.map(s => `- ${s}`).join('\n'));
|
|
589
|
-
lines.push('');
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// Order issues
|
|
593
|
-
if (analysis.orderIssues.length > 0) {
|
|
594
|
-
lines.push('## Ordering Issues');
|
|
595
|
-
lines.push(analysis.orderIssues.map(s => `- ${s}`).join('\n'));
|
|
596
|
-
lines.push('');
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// Recommendations
|
|
600
|
-
if (analysis.recommendations.length > 0) {
|
|
601
|
-
lines.push('## Recommendations');
|
|
602
|
-
lines.push('');
|
|
603
|
-
|
|
604
|
-
for (const rec of analysis.recommendations) {
|
|
605
|
-
const priorityBadge = rec.priority === 'high' ? '[!]' : rec.priority === 'medium' ? '[*]' : '[-]';
|
|
606
|
-
lines.push(`${priorityBadge} **${rec.action.toUpperCase()}**${rec.sectionId ? ` (${rec.sectionId})` : ''}`);
|
|
607
|
-
lines.push(` ${rec.rationale}`);
|
|
608
|
-
|
|
609
|
-
if (rec.suggestedContent) {
|
|
610
|
-
lines.push(` - Purpose: ${rec.suggestedContent.purpose}`);
|
|
611
|
-
if (rec.suggestedContent.heading) {
|
|
612
|
-
lines.push(` - Suggested heading: "${rec.suggestedContent.heading}"`);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
lines.push('');
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
return lines.join('\n');
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
/**
|
|
623
|
-
* Format as brief summary
|
|
624
|
-
*/
|
|
625
|
-
export function formatStructureSummary(analysis: StructureAnalysis): string {
|
|
626
|
-
const status = analysis.structureScore >= 80 ? 'Good' :
|
|
627
|
-
analysis.structureScore >= 60 ? 'Needs Work' : 'Poor';
|
|
628
|
-
|
|
629
|
-
return `${analysis.pageSlug}: ${status} (${analysis.structureScore}/100) - ${analysis.recommendations.length} recommendations`;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// ============================================
|
|
633
|
-
// Batch Processing
|
|
634
|
-
// ============================================
|
|
635
|
-
|
|
636
|
-
/**
|
|
637
|
-
* Analyze structure for multiple pages
|
|
638
|
-
*/
|
|
639
|
-
export function analyzeStructureForPages(
|
|
640
|
-
pages: PageContent[],
|
|
641
|
-
templates?: Record<string, PageTemplate>
|
|
642
|
-
): StructureAnalysis[] {
|
|
643
|
-
return pages.map(page => {
|
|
644
|
-
const slug = extractSlug(page.url);
|
|
645
|
-
const template = templates?.[slug];
|
|
646
|
-
return analyzeStructure(page, template);
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
/**
|
|
651
|
-
* Get pages sorted by structure score
|
|
652
|
-
*/
|
|
653
|
-
export function sortByStructureScore(analyses: StructureAnalysis[], ascending = true): StructureAnalysis[] {
|
|
654
|
-
return [...analyses].sort((a, b) =>
|
|
655
|
-
ascending ? a.structureScore - b.structureScore : b.structureScore - a.structureScore
|
|
656
|
-
);
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* Get pages needing structure improvements
|
|
661
|
-
*/
|
|
662
|
-
export function getPagesNeedingWork(analyses: StructureAnalysis[], threshold = 70): StructureAnalysis[] {
|
|
663
|
-
return analyses.filter(a => a.structureScore < threshold);
|
|
664
|
-
}
|