suparank 1.3.3 → 1.3.4

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.
@@ -205,7 +205,16 @@ async function handleSaveContent(args) {
205
205
  const wordCountOk = targetWordCount ? wordCount >= targetWordCount * 0.95 : true
206
206
  const shortfall = targetWordCount ? targetWordCount - wordCount : 0
207
207
 
208
+ // Multi-article progress tracking
209
+ const totalExpected = workflow?.settings?.article_count || 1
210
+ const savedCount = sessionState.articles.length
211
+ const remaining = totalExpected - savedCount
212
+ const isMultiArticle = totalExpected > 1
213
+
208
214
  log(`Word count check: ${wordCount} words (target: ${targetWordCount}, ok: ${wordCountOk})`)
215
+ if (isMultiArticle) {
216
+ log(`Multi-article progress: ${savedCount}/${totalExpected} saved, ${remaining} remaining`)
217
+ }
209
218
 
210
219
  // Find next step info
211
220
  const imageStep = workflow?.steps?.find(s => s.action === 'generate_images')
@@ -261,13 +270,28 @@ Please EXPAND the content before publishing.
261
270
  ` : ''}
262
271
  ${!meta_description ? '**Warning:** Meta description is missing. Add it for better SEO.\n' : ''}
263
272
  ${articlesListSection}${categoriesSection}
264
- ## Next Step${includeImages && imageStep ? ': Generate Images' : ': Ready to Publish or Continue'}
273
+ ${isMultiArticle && remaining > 0 ? `## ⚠️ MULTI-ARTICLE WORKFLOW: ${remaining} Article(s) Remaining
274
+
275
+ **Progress:** ${savedCount} of ${totalExpected} articles saved.
276
+
277
+ **NEXT ACTION REQUIRED:**
278
+ 1. Create article ${savedCount + 1} of ${totalExpected} using topic from content calendar
279
+ 2. Call \`content_write\` or write the article directly
280
+ 3. Call \`save_content\` to save it
281
+
282
+ ⛔ Do NOT publish until all ${totalExpected} articles are saved!
283
+ ` : ''}${isMultiArticle && remaining <= 0 ? `## ✅ ALL ${totalExpected} ARTICLES SAVED!
284
+
285
+ All articles in your batch are complete. Ready to publish.
286
+
287
+ **Next:** Call \`publish_content\` to publish all ${savedCount} articles.
288
+ ` : ''}${!isMultiArticle ? `## Next Step${includeImages && imageStep ? ': Generate Images' : ': Ready to Publish or Continue'}
265
289
  ${includeImages && imageStep ? `Generate **${totalImages} images** (1 cover + ${totalImages - 1} inline images).
266
290
 
267
291
  Call \`generate_image\` ${totalImages} times with prompts based on your article sections.` : `You can:
268
292
  - **Add more articles**: Continue creating content (each save_content adds to the batch)
269
293
  - **Publish all**: Call \`publish_content\` to publish all ${sessionState.articles.length} article(s)
270
- - **View session**: Call \`get_session\` to see all saved articles`}`
294
+ - **View session**: Call \`get_session\` to see all saved articles`}` : ''}`
271
295
  }]
272
296
  }
273
297
  }
@@ -465,6 +489,11 @@ function handleGetSession() {
465
489
  return sum + (a.imageUrl ? 1 : 0) + (a.inlineImages?.length || 0)
466
490
  }, 0)
467
491
 
492
+ // Multi-article workflow progress
493
+ const expectedArticles = workflow?.settings?.article_count || 1
494
+ const isMultiArticle = expectedArticles > 1
495
+ const remainingArticles = expectedArticles - totalArticles
496
+
468
497
  const articlesSection = sessionState.articles.length > 0 ? `
469
498
  ## Saved Articles (${totalArticles} total)
470
499
 
@@ -494,16 +523,27 @@ No articles saved yet. Use \`save_content\` after writing an article.
494
523
  *This article is being edited. Call \`save_content\` to add it to the session.*
495
524
  ` : ''
496
525
 
526
+ // Multi-article progress section
527
+ const multiArticleProgress = isMultiArticle ? `
528
+ ## 📊 Multi-Article Workflow Progress
529
+ **Status:** ${totalArticles}/${expectedArticles} articles saved${remainingArticles > 0 ? ` (${remainingArticles} remaining)` : ' ✅ Complete!'}
530
+ ${remainingArticles > 0 ? `
531
+ ⚠️ **NEXT:** Create article ${totalArticles + 1} of ${expectedArticles} and save it.
532
+ ⛔ Do NOT publish until all ${expectedArticles} articles are saved.
533
+ ` : `
534
+ ✅ All articles saved! Ready to call \`publish_content\`.
535
+ `}` : ''
536
+
497
537
  return {
498
538
  content: [{
499
539
  type: 'text',
500
540
  text: `# Session State
501
541
 
502
542
  **Workflow:** ${workflow?.workflow_id || 'None active'}
503
- **Total Articles:** ${totalArticles}
543
+ **Total Articles:** ${totalArticles}${isMultiArticle ? ` / ${expectedArticles} expected` : ''}
504
544
  **Ready to Publish:** ${unpublishedArticles.length}
505
545
  **Already Published:** ${publishedArticles.length}
506
- ${articlesSection}${currentWorkingSection}
546
+ ${multiArticleProgress}${articlesSection}${currentWorkingSection}
507
547
  ## Current Working Images (${imagesGenerated}/${totalImagesNeeded})
508
548
  **Cover Image:** ${sessionState.imageUrl || 'Not generated'}
509
549
  **Inline Images:** ${sessionState.inlineImages.length > 0 ? sessionState.inlineImages.map((url, i) => `\n ${i+1}. ${url.substring(0, 60)}...`).join('') : 'None'}
@@ -428,13 +428,22 @@ TRIGGERS - Use when user says:
428
428
  - "make content about..."
429
429
  - any request involving writing/creating/generating articles or blog posts
430
430
 
431
+ SINGLE ARTICLE (count=1): Creates, saves, and publishes 1 article automatically.
432
+
433
+ MULTIPLE ARTICLES (count>1): Creates a workflow with N separate article steps.
434
+ - Each article MUST be written and saved with save_content
435
+ - Progress tracked: "Article 1 of 5", "Article 2 of 5", etc.
436
+ - get_session shows "3/5 articles saved"
437
+ - Do NOT publish until ALL articles are saved
438
+ - After all saved, call publish_content to publish batch
439
+
431
440
  WORKFLOW (automatic 4-phase):
432
- 1. RESEARCH: Keywords, SEO strategy, content structure
433
- 2. CREATION: Outline, write full article, save to session
434
- 3. OPTIMIZATION: Quality check, GEO optimization for AI search
435
- 4. PUBLISHING: Generate images, publish to WordPress/Ghost
441
+ 1. RESEARCH: Keywords, SEO strategy, content calendar
442
+ 2. CREATION: (write + save) × N articles
443
+ 3. OPTIMIZATION: Quality check, GEO optimization
444
+ 4. PUBLISHING: Generate images, publish all to CMS
436
445
 
437
- OUTCOME: Complete article written, optimized, and published to CMS.`,
446
+ OUTCOME: Complete article(s) written, optimized, and published to CMS.`,
438
447
  inputSchema: {
439
448
  type: 'object',
440
449
  properties: {
@@ -291,14 +291,20 @@ Use format: [IMAGE: description of what image should show]` : '**Note:** Images
291
291
  store: 'outline'
292
292
  })
293
293
 
294
- // Step: Write Content
295
- stepNum++
296
- steps.push({
297
- step: stepNum,
298
- type: 'llm_execute',
299
- action: 'content_write',
300
- instruction: `Write the COMPLETE article following your outline.
294
+ // Step: Write Content (generates N steps for N articles)
295
+ for (let articleIndex = 0; articleIndex < count; articleIndex++) {
296
+ const articleNum = articleIndex + 1
297
+ const isFirstArticle = articleIndex === 0
298
+ const isLastArticle = articleIndex === count - 1
301
299
 
300
+ stepNum++
301
+ steps.push({
302
+ step: stepNum,
303
+ type: 'llm_execute',
304
+ action: 'content_write',
305
+ instruction: `${count > 1 ? `## 📝 ARTICLE ${articleNum} OF ${count}\n\n` : ''}Write the COMPLETE article following your outline.
306
+ ${count > 1 && !isFirstArticle ? `\n**Progress:** ${articleIndex} article(s) already saved. Now creating article ${articleNum}.` : ''}
307
+ ${count > 1 ? `**Topic:** Use topic #${articleNum} from your content calendar.\n` : ''}
302
308
  **MANDATORY WORD COUNT: ${targetWordCount} WORDS MINIMUM**
303
309
  This is a strict requirement from the project settings.
304
310
  The article will be REJECTED if under ${targetWordCount} words.
@@ -323,16 +329,19 @@ ${shouldGenerateImages ? '- Image placeholders: [IMAGE: description] where image
323
329
  - FAQ section with 5-8 Q&As (detailed answers, not one-liners)
324
330
  - Strong conclusion with clear CTA
325
331
 
326
- **After writing ${targetWordCount}+ words, call 'save_content' with:**
332
+ **MANDATORY: After writing ${targetWordCount}+ words, call 'save_content' with:**
327
333
  - title: Your SEO-optimized title
328
334
  - content: The full article (markdown)
329
335
  - keywords: Array of target keywords
330
336
  - meta_description: Your 150-160 char meta description
331
337
 
332
338
  STOP! Before calling save_content, verify you have ${targetWordCount}+ words.
333
- Count the words. If under ${targetWordCount}, ADD MORE CONTENT.`,
334
- store: 'article'
335
- })
339
+ Count the words. If under ${targetWordCount}, ADD MORE CONTENT.
340
+ ${count > 1 && !isLastArticle ? `\n⚠️ After saving this article, you MUST continue with article ${articleNum + 1} of ${count}. Do NOT publish until all ${count} articles are saved.` : ''}
341
+ ${count > 1 && isLastArticle ? `\n✅ This is the LAST article (${articleNum} of ${count}). After saving, all articles will be ready for publishing.` : ''}`,
342
+ store: `article${count > 1 ? `_${articleNum}` : ''}`
343
+ })
344
+ }
336
345
 
337
346
  // ═══════════════════════════════════════════════════════════
338
347
  // OPTIMIZATION PHASE
@@ -490,6 +499,7 @@ Call 'publish_content' tool - it will automatically use:
490
499
  niche: niche
491
500
  },
492
501
  settings: {
502
+ article_count: count, // Track expected article count for progress
493
503
  target_word_count: targetWordCount,
494
504
  reading_level: readingLevel,
495
505
  reading_level_display: readingLevelDisplay,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suparank",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "AI-powered SEO content creation MCP - generate and publish optimized blog posts with your AI assistant",
5
5
  "type": "module",
6
6
  "bin": {