@telepat/ideon 0.1.31 → 0.1.32

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/README.md CHANGED
@@ -24,6 +24,7 @@ Built for marketers, founders, and lean teams who need to ship high-quality cont
24
24
  - **Write once, publish everywhere** — One idea turns into article, blog, newsletter, X, LinkedIn, and Reddit posts in a single run. Your article anchors the campaign. Everything else promotes it.
25
25
  - **Style and intent control** — 13 styles × 13 intents. Every output shares one consistent voice across every channel.
26
26
  - **Research-backed links** — Ideon browses the web and inserts contextual external links like a human writer would. No manual research.
27
+ - **SEO-optimized output** — On-page SEO, E-E-A-T credibility signals, and fact density baked into the writing pipeline. Content built to rank in both traditional search and AI-generated summaries.
27
28
  - **Any model via OpenRouter** — Plug in Claude, GPT-4, or any supported model. Switch without changing your workflow.
28
29
  - **Writing guide-driven** — Prompt composition grounded in proven writing principles compiled from real advice. No generic AI filler.
29
30
  - **Code-driven efficiency** — Deterministic pipeline code handles orchestration. You pay for tokens only when drafting prose.
package/README.zh-CN.md CHANGED
@@ -24,6 +24,7 @@ Ideon 是一款 AI 内容写作工具,可将一个想法转化为多格式、
24
24
  - **写一次,处处发布** — 一次运行将一个创意转化为文章、博客、新闻通讯、X、LinkedIn 和 Reddit 帖子。文章是核心,其余均为推广内容。
25
25
  - **风格与意图控制** — 13 种风格 × 13 种意图。所有输出共享同一种一致的声音。
26
26
  - **研究支撑的链接** — Ideon 浏览网络并像人类作者一样插入与上下文相关的外部链接。无需手动研究。
27
+ - **SEO 优化输出** — 页面 SEO、E-E-A-T 可信度信号和事实密度已融入写作流水线。生成的内容针对传统搜索和 AI 生成摘要进行了排名优化。
27
28
  - **通过 OpenRouter 接入任何模型** — 接入 Claude、GPT-4 或任何支持的模型。无需更改工作流程即可切换。
28
29
  - **写作指南驱动** — 提示词组合基于经过实践检验的写作原则汇编而成。没有通用 AI 套话。
29
30
  - **代码驱动的高效率** — 确定性流水线代码处理编排。您只需在起草正文时支付 token 费用。
package/dist/ideon.js CHANGED
@@ -1428,7 +1428,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
1428
1428
  // package.json
1429
1429
  var package_default = {
1430
1430
  name: "@telepat/ideon",
1431
- version: "0.1.31",
1431
+ version: "0.1.32",
1432
1432
  description: "CLI for generating rich articles and images from ideas.",
1433
1433
  type: "module",
1434
1434
  repository: {
@@ -2064,6 +2064,9 @@ function intentToGuidePath(intent) {
2064
2064
  function styleToGuidePath(style) {
2065
2065
  return `writing-guide/styles/${style}.md`;
2066
2066
  }
2067
+ function seoGuidePath(name) {
2068
+ return `writing-guide/seo/${name}.md`;
2069
+ }
2067
2070
  function dedupe(items) {
2068
2071
  return Array.from(new Set(items));
2069
2072
  }
@@ -2079,6 +2082,7 @@ function buildPrimaryPlanGuideInstruction(intent, contentType) {
2079
2082
  "writing-guide/references/headline-writing-systems.md",
2080
2083
  "writing-guide/references/ideation-and-credibility-systems.md",
2081
2084
  "writing-guide/references/content-frameworks.md",
2085
+ seoGuidePath("on-page-essentials"),
2082
2086
  intentToGuidePath(intent),
2083
2087
  formatToGuidePath(contentType)
2084
2088
  ];
@@ -2098,6 +2102,9 @@ function buildArticleSectionGuideInstruction(style, intent, contentType) {
2098
2102
  "writing-guide/references/prose-quality-checks.md",
2099
2103
  "writing-guide/references/readability-and-pace.md",
2100
2104
  "writing-guide/references/skimmability-patterns.md",
2105
+ seoGuidePath("on-page-essentials"),
2106
+ seoGuidePath("eeat-signals"),
2107
+ seoGuidePath("fact-density"),
2101
2108
  styleToGuidePath(style),
2102
2109
  intentToGuidePath(intent),
2103
2110
  formatToGuidePath(contentType)
@@ -2445,9 +2452,9 @@ function buildLongFormPlanMessages(idea, options) {
2445
2452
  "",
2446
2453
  "Requirements:",
2447
2454
  "- The content should feel authoritative, practical, and clearly structured for scanning and deep reading.",
2448
- "- Generate a memorable title and a sharp subtitle that promise a concrete benefit, mechanism, or outcome.",
2455
+ "- Generate a memorable title (under 60 characters) that leads with the primary entity. Include a sharp subtitle that promises a concrete benefit, mechanism, or outcome.",
2449
2456
  "- The slug must be lowercase kebab-case and publication-ready.",
2450
- "- The description should work as a concise meta description and align with the shared content plan.",
2457
+ "- The description should work as a concise meta description (120-160 characters), include the primary entity, and align with the shared content plan.",
2451
2458
  `- Plan ${sectionCounts.label} strong sections with distinct focus areas and logical progression (no repetitive section intent).`,
2452
2459
  "- Frame section titles to reflect likely search intent or practical reader questions when appropriate.",
2453
2460
  "- Each section description should name the mechanism, evidence type, or practical action that makes the section useful.",
@@ -2468,7 +2475,7 @@ function buildLongFormPlanMessages(idea, options) {
2468
2475
  `- contentType: set to "${options.contentType}" exactly`,
2469
2476
  "- title: string",
2470
2477
  "- subtitle: string",
2471
- "- keywords: array of 3 to 8 strings",
2478
+ "- keywords: array of 3 to 8 specific, non-generic strings representing primary entities and search topics (not exact-match duplicates of heading text)",
2472
2479
  "- slug: string in lowercase kebab-case",
2473
2480
  "- description: string",
2474
2481
  "- introBrief: string",
@@ -2615,6 +2622,30 @@ async function planPrimaryContent({
2615
2622
  return shortFormPlanSchema.parse(data);
2616
2623
  }
2617
2624
  });
2625
+ if (!dryRun) {
2626
+ const seoWarnings = [];
2627
+ if (basePlan.title && basePlan.title.length > 60) {
2628
+ seoWarnings.push(`Title is ${basePlan.title.length} chars (recommended: under 60 for search display safety)`);
2629
+ }
2630
+ if (basePlan.description) {
2631
+ if (basePlan.description.length < 120) {
2632
+ seoWarnings.push(`Description is ${basePlan.description.length} chars (recommended: 120-160 for meta description effectiveness)`);
2633
+ } else if (basePlan.description.length > 160) {
2634
+ seoWarnings.push(`Description is ${basePlan.description.length} chars (recommended: 120-160 for meta description effectiveness)`);
2635
+ }
2636
+ }
2637
+ if (isLongForm) {
2638
+ const longPlan = basePlan;
2639
+ const headings = longPlan.sections.map((s) => s.title.toLowerCase());
2640
+ const duplicateKeywords = longPlan.keywords.filter((kw) => headings.includes(kw.toLowerCase()));
2641
+ if (duplicateKeywords.length > 0) {
2642
+ seoWarnings.push(`Keywords duplicate heading text: ${duplicateKeywords.join(", ")} (consider using semantic variants)`);
2643
+ }
2644
+ }
2645
+ for (const warning of seoWarnings) {
2646
+ console.warn(`[seo] ${warning}`);
2647
+ }
2648
+ }
2618
2649
  const normalizedSlug = slugify(basePlan.slug || basePlan.title);
2619
2650
  const uniqueSlug = await resolveUniqueSlug(markdownOutputDir, normalizedSlug);
2620
2651
  if (isLongForm) {
@@ -2949,7 +2980,8 @@ function buildSectionMessages(plan, section, articleSoFar, style, intent, conten
2949
2980
  "Requirements:",
2950
2981
  `- ${paragraphCount} paragraphs.`,
2951
2982
  `- Target length: about ${sectionTargetWords} words.`,
2952
- "- Be concrete and specific.",
2983
+ "- Be concrete and specific. Support key claims with statistics, data points, or authoritative citations.",
2984
+ "- Include at least one practical insight that sounds like first-hand practitioner experience.",
2953
2985
  "- Continue naturally from the article draft so far without rehashing prior sections.",
2954
2986
  "- Use short Markdown lists only if they materially improve clarity."
2955
2987
  ].join("\n")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telepat/ideon",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "CLI for generating rich articles and images from ideas.",
5
5
  "type": "module",
6
6
  "repository": {