@telepat/ideon 0.1.19 → 0.1.21
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/ideon.js
CHANGED
|
@@ -1362,7 +1362,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
1362
1362
|
// package.json
|
|
1363
1363
|
var package_default = {
|
|
1364
1364
|
name: "@telepat/ideon",
|
|
1365
|
-
version: "0.1.
|
|
1365
|
+
version: "0.1.21",
|
|
1366
1366
|
description: "CLI for generating rich articles and images from ideas.",
|
|
1367
1367
|
type: "module",
|
|
1368
1368
|
repository: {
|
|
@@ -1883,7 +1883,7 @@ function toExpressionPreview(expression, maxLength = 60) {
|
|
|
1883
1883
|
// src/llm/prompts/writingFramework.ts
|
|
1884
1884
|
function buildRunContextDirective(contentTypes) {
|
|
1885
1885
|
const normalizedTypes = contentTypes.length > 0 ? contentTypes.join(", ") : "article";
|
|
1886
|
-
return `Run context: requested content types are ${normalizedTypes}. Keep output aligned with this distribution plan, maintain one shared content
|
|
1886
|
+
return `Run context: requested content types are ${normalizedTypes}. Keep output aligned with this distribution plan, maintain one shared content plan, and adapt structure per channel without duplicating article-only scaffolding.`;
|
|
1887
1887
|
}
|
|
1888
1888
|
var TARGET_LENGTH_TIERS = {
|
|
1889
1889
|
small: {
|
|
@@ -2012,9 +2012,9 @@ function buildArticleSectionGuideInstruction(style, intent, contentType) {
|
|
|
2012
2012
|
formatToGuidePath(contentType)
|
|
2013
2013
|
]);
|
|
2014
2014
|
}
|
|
2015
|
-
function
|
|
2015
|
+
function buildContentPlanGuideInstruction(intent, primaryContentType, secondaryContentTypes) {
|
|
2016
2016
|
return buildGuideBundle([
|
|
2017
|
-
"writing-guide/references/multi-channel-
|
|
2017
|
+
"writing-guide/references/multi-channel-plan-strategy.md",
|
|
2018
2018
|
"writing-guide/references/content-frameworks.md",
|
|
2019
2019
|
"writing-guide/references/target-length-guidance.md",
|
|
2020
2020
|
intentToGuidePath(intent),
|
|
@@ -2034,8 +2034,8 @@ function buildChannelContentGuideInstruction(style, intent, contentType) {
|
|
|
2034
2034
|
]);
|
|
2035
2035
|
}
|
|
2036
2036
|
|
|
2037
|
-
// src/llm/prompts/
|
|
2038
|
-
var
|
|
2037
|
+
// src/llm/prompts/contentPlan.ts
|
|
2038
|
+
var contentPlanSchema = {
|
|
2039
2039
|
type: "object",
|
|
2040
2040
|
additionalProperties: false,
|
|
2041
2041
|
required: [
|
|
@@ -2069,15 +2069,15 @@ var contentBriefSchema = {
|
|
|
2069
2069
|
secondaryContentStrategy: { type: "string" }
|
|
2070
2070
|
}
|
|
2071
2071
|
};
|
|
2072
|
-
function
|
|
2072
|
+
function buildContentPlanMessages(idea, options) {
|
|
2073
2073
|
const audienceSeed = options.targetAudienceHint?.trim() || "A general, non-specific audience.";
|
|
2074
2074
|
const hasSecondaryContentTypes = options.secondaryContentTypes.length > 0;
|
|
2075
2075
|
const systemInstruction = [
|
|
2076
2076
|
"You are a senior editorial strategist.",
|
|
2077
|
-
"Produce a shared content
|
|
2078
|
-
|
|
2077
|
+
"Produce a shared content plan that can guide all requested content types in this run.",
|
|
2078
|
+
buildContentPlanGuideInstruction(options.intent, options.primaryContentType, options.secondaryContentTypes),
|
|
2079
2079
|
buildRunContextDirective([options.primaryContentType, ...options.secondaryContentTypes]),
|
|
2080
|
-
"The
|
|
2080
|
+
"The plan must be specific, concrete, and directly usable by writers without extra clarification.",
|
|
2081
2081
|
"This run has one explicit primary output and optional secondary outputs that should promote or incite interest in the primary while remaining independently valuable.",
|
|
2082
2082
|
"Return only the requested JSON."
|
|
2083
2083
|
].join(" ");
|
|
@@ -2089,7 +2089,7 @@ function buildContentBriefMessages(idea, options) {
|
|
|
2089
2089
|
{
|
|
2090
2090
|
role: "user",
|
|
2091
2091
|
content: [
|
|
2092
|
-
"Create a shared content
|
|
2092
|
+
"Create a shared content plan from this idea:",
|
|
2093
2093
|
idea,
|
|
2094
2094
|
"",
|
|
2095
2095
|
`Audience seed (optional user guidance): ${audienceSeed}`,
|
|
@@ -2112,7 +2112,7 @@ function buildContentBriefMessages(idea, options) {
|
|
|
2112
2112
|
];
|
|
2113
2113
|
}
|
|
2114
2114
|
|
|
2115
|
-
// src/types/
|
|
2115
|
+
// src/types/contentPlanSchema.ts
|
|
2116
2116
|
import { z as z4 } from "zod";
|
|
2117
2117
|
var secondaryTypeSentinelValues = /* @__PURE__ */ new Set([
|
|
2118
2118
|
"none",
|
|
@@ -2123,7 +2123,7 @@ var secondaryTypeSentinelValues = /* @__PURE__ */ new Set([
|
|
|
2123
2123
|
"no secondary content",
|
|
2124
2124
|
"no secondary outputs"
|
|
2125
2125
|
]);
|
|
2126
|
-
var
|
|
2126
|
+
var contentPlanSchema2 = z4.object({
|
|
2127
2127
|
title: z4.string().min(8),
|
|
2128
2128
|
description: z4.string().min(40),
|
|
2129
2129
|
targetAudience: z4.string().min(10),
|
|
@@ -2133,12 +2133,12 @@ var contentBriefSchema2 = z4.object({
|
|
|
2133
2133
|
primaryContentType: z4.string().min(2),
|
|
2134
2134
|
secondaryContentTypes: z4.array(z4.string().min(2)).max(10).transform((values) => values.map((value2) => value2.trim()).filter((value2) => value2.length > 0).filter((value2) => !secondaryTypeSentinelValues.has(value2.toLowerCase()))),
|
|
2135
2135
|
secondaryContentStrategy: z4.string()
|
|
2136
|
-
}).superRefine((
|
|
2137
|
-
const hasSecondaryTargets =
|
|
2136
|
+
}).superRefine((plan, ctx) => {
|
|
2137
|
+
const hasSecondaryTargets = plan.secondaryContentTypes.length > 0;
|
|
2138
2138
|
if (!hasSecondaryTargets) {
|
|
2139
2139
|
return;
|
|
2140
2140
|
}
|
|
2141
|
-
if (
|
|
2141
|
+
if (plan.secondaryContentStrategy.trim().length < 20) {
|
|
2142
2142
|
ctx.addIssue({
|
|
2143
2143
|
code: z4.ZodIssueCode.too_small,
|
|
2144
2144
|
minimum: 20,
|
|
@@ -2151,9 +2151,9 @@ var contentBriefSchema2 = z4.object({
|
|
|
2151
2151
|
}
|
|
2152
2152
|
});
|
|
2153
2153
|
|
|
2154
|
-
// src/generation/
|
|
2155
|
-
var
|
|
2156
|
-
async function
|
|
2154
|
+
// src/generation/planContentPlan.ts
|
|
2155
|
+
var SHARED_PLAN_MAX_TOKENS = 8e3;
|
|
2156
|
+
async function planContentPlan({
|
|
2157
2157
|
idea,
|
|
2158
2158
|
targetAudienceHint,
|
|
2159
2159
|
settings,
|
|
@@ -2163,37 +2163,37 @@ async function planContentBrief({
|
|
|
2163
2163
|
onInteraction
|
|
2164
2164
|
}) {
|
|
2165
2165
|
if (dryRun || !openRouter) {
|
|
2166
|
-
return
|
|
2166
|
+
return buildDryRunContentPlan(idea, targetAudienceHint);
|
|
2167
2167
|
}
|
|
2168
|
-
const
|
|
2168
|
+
const sharedPlanSettings = {
|
|
2169
2169
|
...settings,
|
|
2170
2170
|
modelSettings: {
|
|
2171
2171
|
...settings.modelSettings,
|
|
2172
|
-
maxTokens: Math.max(settings.modelSettings.maxTokens,
|
|
2172
|
+
maxTokens: Math.max(settings.modelSettings.maxTokens, SHARED_PLAN_MAX_TOKENS)
|
|
2173
2173
|
}
|
|
2174
2174
|
};
|
|
2175
2175
|
return await openRouter.requestStructured({
|
|
2176
|
-
schemaName: "
|
|
2177
|
-
schema:
|
|
2178
|
-
messages:
|
|
2176
|
+
schemaName: "content_plan",
|
|
2177
|
+
schema: contentPlanSchema,
|
|
2178
|
+
messages: buildContentPlanMessages(idea, {
|
|
2179
2179
|
intent: settings.intent,
|
|
2180
2180
|
targetAudienceHint,
|
|
2181
2181
|
primaryContentType: settings.contentTargets.find((target) => target.role === "primary")?.contentType ?? "article",
|
|
2182
2182
|
secondaryContentTypes: settings.contentTargets.filter((target) => target.role === "secondary").map((target) => target.contentType)
|
|
2183
2183
|
}),
|
|
2184
|
-
settings:
|
|
2184
|
+
settings: sharedPlanSettings,
|
|
2185
2185
|
interactionContext: {
|
|
2186
|
-
stageId: "shared-
|
|
2187
|
-
operationId: "shared-
|
|
2186
|
+
stageId: "shared-plan",
|
|
2187
|
+
operationId: "shared-plan:content-plan"
|
|
2188
2188
|
},
|
|
2189
2189
|
onInteraction,
|
|
2190
2190
|
onMetrics: onLlmMetrics,
|
|
2191
2191
|
parse(data) {
|
|
2192
|
-
return
|
|
2192
|
+
return contentPlanSchema2.parse(data);
|
|
2193
2193
|
}
|
|
2194
2194
|
});
|
|
2195
2195
|
}
|
|
2196
|
-
function
|
|
2196
|
+
function buildDryRunContentPlan(idea, targetAudienceHint) {
|
|
2197
2197
|
const normalizedIdea = idea.trim();
|
|
2198
2198
|
const normalizedAudience = targetAudienceHint?.trim();
|
|
2199
2199
|
const targetAudience = normalizedAudience && normalizedAudience.length > 0 ? `Audience seed: ${normalizedAudience}. Extend this profile with specific motivations, constraints, and context tied to ${normalizedIdea}.` : "A broad, general audience of curious professionals and creators seeking practical, applicable insight.";
|
|
@@ -2215,7 +2215,7 @@ function buildDryRunContentBrief(idea, targetAudienceHint) {
|
|
|
2215
2215
|
}
|
|
2216
2216
|
function deriveTitleFromIdea(idea) {
|
|
2217
2217
|
if (!idea) {
|
|
2218
|
-
return "Generated Content
|
|
2218
|
+
return "Generated Content Plan";
|
|
2219
2219
|
}
|
|
2220
2220
|
return idea.split(/\s+/).slice(0, 8).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
2221
2221
|
}
|
|
@@ -2284,9 +2284,10 @@ function buildArticlePlanJsonSchema(targetLengthWords) {
|
|
|
2284
2284
|
items: {
|
|
2285
2285
|
type: "object",
|
|
2286
2286
|
additionalProperties: false,
|
|
2287
|
-
required: ["description"],
|
|
2287
|
+
required: ["description", "anchorAfterSection"],
|
|
2288
2288
|
properties: {
|
|
2289
|
-
description: { type: "string" }
|
|
2289
|
+
description: { type: "string" },
|
|
2290
|
+
anchorAfterSection: { type: "number", minimum: 1 }
|
|
2290
2291
|
}
|
|
2291
2292
|
}
|
|
2292
2293
|
}
|
|
@@ -2317,21 +2318,22 @@ function buildArticlePlanMessages(idea, options) {
|
|
|
2317
2318
|
"- The article should feel authoritative, practical, and clearly structured for scanning and deep reading.",
|
|
2318
2319
|
"- Generate a memorable title and a sharp subtitle that promise a concrete benefit, mechanism, or outcome.",
|
|
2319
2320
|
"- The slug must be lowercase kebab-case and publication-ready.",
|
|
2320
|
-
"- The description should work as a concise meta description and align with the shared content
|
|
2321
|
+
"- The description should work as a concise meta description and align with the shared content plan.",
|
|
2321
2322
|
`- Plan ${sectionCounts.label} strong sections with distinct focus areas and logical progression (no repetitive section intent).`,
|
|
2322
2323
|
"- Frame section titles to reflect likely search intent or practical reader questions when appropriate.",
|
|
2323
2324
|
"- Each section description should name the mechanism, evidence type, or practical action that makes the section useful.",
|
|
2324
2325
|
"- Sections are article-only structure and must not be treated as requirements for non-article channels.",
|
|
2325
2326
|
"- Include a cover image description and 2 to 3 inline image descriptions.",
|
|
2327
|
+
"- Each inline image must specify which section it follows (anchorAfterSection, 1-based index). Choose sections where visual reinforcement adds the most value.",
|
|
2328
|
+
"- Image descriptions should capture the general concept and mood \u2014 the exact text-to-image prompt will be refined later using the actual section content.",
|
|
2326
2329
|
"- Image descriptions must be concrete and contextual, not generic stock-photo phrasing.",
|
|
2327
|
-
"- Do not include section placement for inline images \u2014 placement is determined automatically after writing.",
|
|
2328
2330
|
"",
|
|
2329
|
-
"Shared content
|
|
2330
|
-
`- description: ${options.
|
|
2331
|
-
`- targetAudience: ${options.
|
|
2332
|
-
`- corePromise: ${options.
|
|
2333
|
-
`- keyPoints: ${options.
|
|
2334
|
-
`- voiceNotes: ${options.
|
|
2331
|
+
"Shared content plan context:",
|
|
2332
|
+
`- description: ${options.contentPlan.description}`,
|
|
2333
|
+
`- targetAudience: ${options.contentPlan.targetAudience}`,
|
|
2334
|
+
`- corePromise: ${options.contentPlan.corePromise}`,
|
|
2335
|
+
`- keyPoints: ${options.contentPlan.keyPoints.join(" | ")}`,
|
|
2336
|
+
`- voiceNotes: ${options.contentPlan.voiceNotes}`,
|
|
2335
2337
|
"",
|
|
2336
2338
|
"Return JSON with all required fields:",
|
|
2337
2339
|
"- title: string",
|
|
@@ -2343,7 +2345,7 @@ function buildArticlePlanMessages(idea, options) {
|
|
|
2343
2345
|
"- outroBrief: string",
|
|
2344
2346
|
`- sections: array of ${sectionCounts.label} objects, each with title and description strings`,
|
|
2345
2347
|
"- coverImageDescription: string",
|
|
2346
|
-
"- inlineImages: array of 2 to 3 objects, each with a description string
|
|
2348
|
+
"- inlineImages: array of 2 to 3 objects, each with a description string and an anchorAfterSection number (1-based section index)",
|
|
2347
2349
|
"",
|
|
2348
2350
|
"Do not omit any required fields. Return strict JSON only."
|
|
2349
2351
|
].join("\n")
|
|
@@ -2358,7 +2360,8 @@ var articleSectionPlanSchema = z5.object({
|
|
|
2358
2360
|
description: z5.string().min(1)
|
|
2359
2361
|
});
|
|
2360
2362
|
var inlineImagePlanSchema = z5.object({
|
|
2361
|
-
description: z5.string().min(1)
|
|
2363
|
+
description: z5.string().min(1),
|
|
2364
|
+
anchorAfterSection: z5.number().int().min(1)
|
|
2362
2365
|
});
|
|
2363
2366
|
var articlePlanSchema = z5.object({
|
|
2364
2367
|
title: z5.string().min(1),
|
|
@@ -2379,7 +2382,7 @@ var imagePromptResultSchema = z5.object({
|
|
|
2379
2382
|
// src/generation/planArticle.ts
|
|
2380
2383
|
async function planArticle({
|
|
2381
2384
|
idea,
|
|
2382
|
-
|
|
2385
|
+
contentPlan,
|
|
2383
2386
|
settings,
|
|
2384
2387
|
markdownOutputDir,
|
|
2385
2388
|
openRouter,
|
|
@@ -2387,13 +2390,13 @@ async function planArticle({
|
|
|
2387
2390
|
onLlmMetrics,
|
|
2388
2391
|
onInteraction
|
|
2389
2392
|
}) {
|
|
2390
|
-
const basePlan = dryRun || !openRouter ? buildDryRunPlan(idea,
|
|
2393
|
+
const basePlan = dryRun || !openRouter ? buildDryRunPlan(idea, contentPlan) : await openRouter.requestStructured({
|
|
2391
2394
|
schemaName: "article_plan",
|
|
2392
2395
|
schema: buildArticlePlanJsonSchema(settings.targetLength),
|
|
2393
2396
|
messages: buildArticlePlanMessages(idea, {
|
|
2394
2397
|
intent: settings.intent,
|
|
2395
2398
|
contentTypes: settings.contentTargets.map((target) => target.contentType),
|
|
2396
|
-
|
|
2399
|
+
contentPlan,
|
|
2397
2400
|
targetLength: settings.targetLength
|
|
2398
2401
|
}),
|
|
2399
2402
|
settings,
|
|
@@ -2409,21 +2412,25 @@ async function planArticle({
|
|
|
2409
2412
|
});
|
|
2410
2413
|
const normalizedSlug = slugify(basePlan.slug || basePlan.title);
|
|
2411
2414
|
const uniqueSlug = await resolveUniqueSlug(markdownOutputDir, normalizedSlug);
|
|
2415
|
+
const sectionCount = basePlan.sections.length;
|
|
2412
2416
|
return {
|
|
2413
2417
|
...basePlan,
|
|
2414
2418
|
slug: uniqueSlug,
|
|
2415
2419
|
keywords: basePlan.keywords.slice(0, 8),
|
|
2416
|
-
inlineImages: basePlan.inlineImages.slice(0, 3)
|
|
2420
|
+
inlineImages: basePlan.inlineImages.slice(0, 3).map((img) => ({
|
|
2421
|
+
...img,
|
|
2422
|
+
anchorAfterSection: Math.max(1, Math.min(sectionCount, img.anchorAfterSection))
|
|
2423
|
+
}))
|
|
2417
2424
|
};
|
|
2418
2425
|
}
|
|
2419
|
-
function buildDryRunPlan(idea,
|
|
2426
|
+
function buildDryRunPlan(idea, contentPlan) {
|
|
2420
2427
|
const title = idea.trim().split(/\s+/).slice(0, 7).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
2421
2428
|
return {
|
|
2422
2429
|
title,
|
|
2423
2430
|
subtitle: "A practical editorial blueprint for turning a good idea into a strong article",
|
|
2424
2431
|
keywords: ["writing", "editorial workflow", "ai tools", "content strategy"],
|
|
2425
2432
|
slug: slugify(title),
|
|
2426
|
-
description:
|
|
2433
|
+
description: contentPlan.description,
|
|
2427
2434
|
introBrief: "Frame the tension between having ideas and actually shaping them into useful published work.",
|
|
2428
2435
|
outroBrief: "End by emphasizing disciplined workflows, taste, and iteration.",
|
|
2429
2436
|
sections: [
|
|
@@ -2451,10 +2458,12 @@ function buildDryRunPlan(idea, contentBrief) {
|
|
|
2451
2458
|
coverImageDescription: "A refined editorial workspace with notebooks, sketches, and glowing structured outlines, cinematic but minimal.",
|
|
2452
2459
|
inlineImages: [
|
|
2453
2460
|
{
|
|
2454
|
-
description: "A rough idea evolving into a structured article outline on a desk full of notes."
|
|
2461
|
+
description: "A rough idea evolving into a structured article outline on a desk full of notes.",
|
|
2462
|
+
anchorAfterSection: 2
|
|
2455
2463
|
},
|
|
2456
2464
|
{
|
|
2457
|
-
description: "A collaborative editorial scene where human judgment and AI suggestions coexist."
|
|
2465
|
+
description: "A collaborative editorial scene where human judgment and AI suggestions coexist.",
|
|
2466
|
+
anchorAfterSection: 4
|
|
2458
2467
|
}
|
|
2459
2468
|
]
|
|
2460
2469
|
};
|
|
@@ -2506,16 +2515,16 @@ function buildSingleShotContentMessages(options) {
|
|
|
2506
2515
|
`Primary content type: ${options.primaryContentType}`,
|
|
2507
2516
|
`Output index: ${options.outputIndex} of ${options.outputCountForType}`,
|
|
2508
2517
|
"",
|
|
2509
|
-
"Shared content
|
|
2510
|
-
`- title: ${options.
|
|
2511
|
-
`- description: ${options.
|
|
2512
|
-
`- targetAudience: ${options.
|
|
2513
|
-
`- corePromise: ${options.
|
|
2514
|
-
`- keyPoints: ${options.
|
|
2515
|
-
`- voiceNotes: ${options.
|
|
2516
|
-
`- primaryContentType: ${options.
|
|
2517
|
-
`- secondaryContentTypes: ${options.
|
|
2518
|
-
`- secondaryContentStrategy: ${options.
|
|
2518
|
+
"Shared content plan (must guide this output):",
|
|
2519
|
+
`- title: ${options.contentPlan.title}`,
|
|
2520
|
+
`- description: ${options.contentPlan.description}`,
|
|
2521
|
+
`- targetAudience: ${options.contentPlan.targetAudience}`,
|
|
2522
|
+
`- corePromise: ${options.contentPlan.corePromise}`,
|
|
2523
|
+
`- keyPoints: ${options.contentPlan.keyPoints.join(" | ")}`,
|
|
2524
|
+
`- voiceNotes: ${options.contentPlan.voiceNotes}`,
|
|
2525
|
+
`- primaryContentType: ${options.contentPlan.primaryContentType}`,
|
|
2526
|
+
`- secondaryContentTypes: ${options.contentPlan.secondaryContentTypes.join(" | ") || "none"}`,
|
|
2527
|
+
`- secondaryContentStrategy: ${options.contentPlan.secondaryContentStrategy}`,
|
|
2519
2528
|
"",
|
|
2520
2529
|
articleContext,
|
|
2521
2530
|
"",
|
|
@@ -2539,7 +2548,7 @@ async function writeSingleShotContent({
|
|
|
2539
2548
|
outputIndex,
|
|
2540
2549
|
outputCountForType,
|
|
2541
2550
|
articleReferenceMarkdown,
|
|
2542
|
-
|
|
2551
|
+
contentPlan,
|
|
2543
2552
|
settings,
|
|
2544
2553
|
openRouter,
|
|
2545
2554
|
dryRun,
|
|
@@ -2554,7 +2563,7 @@ async function writeSingleShotContent({
|
|
|
2554
2563
|
primaryContentType,
|
|
2555
2564
|
outputIndex,
|
|
2556
2565
|
outputCountForType,
|
|
2557
|
-
|
|
2566
|
+
contentPlan,
|
|
2558
2567
|
articleReferenceMarkdown
|
|
2559
2568
|
});
|
|
2560
2569
|
}
|
|
@@ -2568,7 +2577,7 @@ async function writeSingleShotContent({
|
|
|
2568
2577
|
intent,
|
|
2569
2578
|
outputIndex,
|
|
2570
2579
|
outputCountForType,
|
|
2571
|
-
|
|
2580
|
+
contentPlan,
|
|
2572
2581
|
articleReferenceMarkdown,
|
|
2573
2582
|
targetLength: settings.targetLength
|
|
2574
2583
|
}),
|
|
@@ -2590,7 +2599,7 @@ function buildDryRunContent(options) {
|
|
|
2590
2599
|
`Variant: ${options.outputIndex}/${options.outputCountForType}`,
|
|
2591
2600
|
`Role: ${options.role}`,
|
|
2592
2601
|
`Primary content type: ${options.primaryContentType}`,
|
|
2593
|
-
`Shared
|
|
2602
|
+
`Shared plan: ${options.contentPlan.description}`,
|
|
2594
2603
|
anchorNote,
|
|
2595
2604
|
"",
|
|
2596
2605
|
"This is a dry-run placeholder for single-prompt channel generation."
|
|
@@ -2956,24 +2965,8 @@ function sumKnownCosts(values) {
|
|
|
2956
2965
|
|
|
2957
2966
|
// src/images/renderImages.ts
|
|
2958
2967
|
var MIN_IMAGE_BYTES = 1024;
|
|
2959
|
-
function
|
|
2968
|
+
function buildImageSlots(plan, sections, options) {
|
|
2960
2969
|
const sectionCount = sections.length;
|
|
2961
|
-
let defaultInlineCount;
|
|
2962
|
-
if (sectionCount <= 3) {
|
|
2963
|
-
defaultInlineCount = 0;
|
|
2964
|
-
} else if (sectionCount <= 6) {
|
|
2965
|
-
defaultInlineCount = 1;
|
|
2966
|
-
} else {
|
|
2967
|
-
defaultInlineCount = 2;
|
|
2968
|
-
}
|
|
2969
|
-
const availableInlineCount = Math.min(defaultInlineCount, plan.inlineImages.length, sectionCount);
|
|
2970
|
-
let inlineCount;
|
|
2971
|
-
const maxImages = options?.maxImages;
|
|
2972
|
-
if (maxImages !== void 0 && maxImages >= 1) {
|
|
2973
|
-
inlineCount = Math.min(availableInlineCount, Math.max(0, maxImages - 1));
|
|
2974
|
-
} else {
|
|
2975
|
-
inlineCount = availableInlineCount;
|
|
2976
|
-
}
|
|
2977
2970
|
const slots = [
|
|
2978
2971
|
{
|
|
2979
2972
|
id: "cover",
|
|
@@ -2983,17 +2976,22 @@ function selectImageSlots(plan, sections, options) {
|
|
|
2983
2976
|
anchorAfterSection: null
|
|
2984
2977
|
}
|
|
2985
2978
|
];
|
|
2979
|
+
let inlineCount = plan.inlineImages.length;
|
|
2980
|
+
const maxImages = options?.maxImages;
|
|
2981
|
+
if (maxImages !== void 0 && maxImages >= 1) {
|
|
2982
|
+
inlineCount = Math.min(inlineCount, Math.max(0, maxImages - 1));
|
|
2983
|
+
}
|
|
2986
2984
|
for (let i = 0; i < inlineCount; i++) {
|
|
2987
|
-
const
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2985
|
+
const img = plan.inlineImages[i];
|
|
2986
|
+
if (!img) {
|
|
2987
|
+
continue;
|
|
2988
|
+
}
|
|
2991
2989
|
slots.push({
|
|
2992
2990
|
id: `inline-${i + 1}`,
|
|
2993
2991
|
kind: "inline",
|
|
2994
2992
|
prompt: "",
|
|
2995
|
-
description:
|
|
2996
|
-
anchorAfterSection
|
|
2993
|
+
description: img.description,
|
|
2994
|
+
anchorAfterSection: Math.max(1, Math.min(sectionCount, img.anchorAfterSection))
|
|
2997
2995
|
});
|
|
2998
2996
|
}
|
|
2999
2997
|
return slots;
|
|
@@ -3718,10 +3716,12 @@ ${body.join("\n").trim()}
|
|
|
3718
3716
|
}
|
|
3719
3717
|
|
|
3720
3718
|
// src/pipeline/sessionStore.ts
|
|
3719
|
+
import { createHash } from "crypto";
|
|
3721
3720
|
import { mkdir as mkdir4, readFile as readFile5, rm as rm2, writeFile as writeFile5 } from "fs/promises";
|
|
3722
3721
|
import path7 from "path";
|
|
3722
|
+
import envPaths3 from "env-paths";
|
|
3723
3723
|
import { z as z6 } from "zod";
|
|
3724
|
-
var STAGE_IDS = ["shared-
|
|
3724
|
+
var STAGE_IDS = ["shared-plan", "planning", "sections", "image-prompts", "images", "output", "links"];
|
|
3725
3725
|
var generatedArticleSectionSchema = z6.object({
|
|
3726
3726
|
title: z6.string().min(1),
|
|
3727
3727
|
body: z6.string().min(1)
|
|
@@ -3760,7 +3760,8 @@ var pipelineArtifactSummarySchema = z6.object({
|
|
|
3760
3760
|
markdownPath: z6.string().min(1),
|
|
3761
3761
|
assetDir: z6.string().min(1),
|
|
3762
3762
|
analyticsPath: z6.string().min(1).default("unknown.analytics.json"),
|
|
3763
|
-
interactionsPath: z6.string().min(1).default("unknown.interactions.json")
|
|
3763
|
+
interactionsPath: z6.string().min(1).default("unknown.interactions.json"),
|
|
3764
|
+
planPath: z6.string().min(1).nullable().default(null)
|
|
3764
3765
|
});
|
|
3765
3766
|
var resolvedPathsSchema = z6.object({
|
|
3766
3767
|
markdownOutputDir: z6.string().min(1),
|
|
@@ -3780,7 +3781,7 @@ var writeSessionStateSchema = z6.object({
|
|
|
3780
3781
|
lastCompletedStage: z6.enum(STAGE_IDS).nullable(),
|
|
3781
3782
|
failedStage: z6.enum(STAGE_IDS).nullable(),
|
|
3782
3783
|
errorMessage: z6.string().nullable(),
|
|
3783
|
-
|
|
3784
|
+
contentPlan: contentPlanSchema2.nullable().default(null),
|
|
3784
3785
|
plan: articlePlanSchema.nullable(),
|
|
3785
3786
|
text: z6.object({
|
|
3786
3787
|
intro: z6.string().min(1),
|
|
@@ -3795,12 +3796,20 @@ var writeSessionStateSchema = z6.object({
|
|
|
3795
3796
|
links: z6.array(linksResultSchema).nullable().default(null),
|
|
3796
3797
|
artifact: pipelineArtifactSummarySchema.nullable()
|
|
3797
3798
|
});
|
|
3799
|
+
var ideonPaths3 = envPaths3("ideon", { suffix: "" });
|
|
3800
|
+
var sessionsDir = path7.join(ideonPaths3.config, "sessions");
|
|
3801
|
+
function hashProjectPath(workingDir) {
|
|
3802
|
+
return createHash("sha256").update(path7.resolve(workingDir)).digest("hex").slice(0, 16);
|
|
3803
|
+
}
|
|
3798
3804
|
function resolveWriteRoot(workingDir) {
|
|
3799
|
-
return path7.join(
|
|
3805
|
+
return path7.join(sessionsDir, hashProjectPath(workingDir));
|
|
3800
3806
|
}
|
|
3801
3807
|
function resolveStateFilePath(workingDir) {
|
|
3802
3808
|
return path7.join(resolveWriteRoot(workingDir), "state.json");
|
|
3803
3809
|
}
|
|
3810
|
+
function resolveLegacyStatePath(workingDir) {
|
|
3811
|
+
return path7.join(workingDir, ".ideon", "write", "state.json");
|
|
3812
|
+
}
|
|
3804
3813
|
async function startFreshWriteSession(seed, workingDir = process.cwd()) {
|
|
3805
3814
|
const writeRoot = resolveWriteRoot(workingDir);
|
|
3806
3815
|
await rm2(writeRoot, { recursive: true, force: true });
|
|
@@ -3820,7 +3829,7 @@ async function startFreshWriteSession(seed, workingDir = process.cwd()) {
|
|
|
3820
3829
|
lastCompletedStage: null,
|
|
3821
3830
|
failedStage: null,
|
|
3822
3831
|
errorMessage: null,
|
|
3823
|
-
|
|
3832
|
+
contentPlan: null,
|
|
3824
3833
|
plan: null,
|
|
3825
3834
|
text: null,
|
|
3826
3835
|
imagePrompts: null,
|
|
@@ -3836,6 +3845,17 @@ async function loadWriteSession(workingDir = process.cwd()) {
|
|
|
3836
3845
|
try {
|
|
3837
3846
|
const raw = await readFile5(statePath, "utf8");
|
|
3838
3847
|
return writeSessionStateSchema.parse(JSON.parse(raw));
|
|
3848
|
+
} catch (error) {
|
|
3849
|
+
if (!isNotFoundError(error)) {
|
|
3850
|
+
throw error;
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
const legacyPath = resolveLegacyStatePath(workingDir);
|
|
3854
|
+
try {
|
|
3855
|
+
const raw = await readFile5(legacyPath, "utf8");
|
|
3856
|
+
const state = writeSessionStateSchema.parse(JSON.parse(raw));
|
|
3857
|
+
await saveWriteSession(state, workingDir);
|
|
3858
|
+
return state;
|
|
3839
3859
|
} catch (error) {
|
|
3840
3860
|
if (isNotFoundError(error)) {
|
|
3841
3861
|
return null;
|
|
@@ -3857,7 +3877,7 @@ async function saveWriteSession(state, workingDir = process.cwd()) {
|
|
|
3857
3877
|
async function patchWriteSession(patch, workingDir = process.cwd()) {
|
|
3858
3878
|
const existing = await loadWriteSession(workingDir);
|
|
3859
3879
|
if (!existing) {
|
|
3860
|
-
throw new Error("No active write session found
|
|
3880
|
+
throw new Error("No active write session found. Start a fresh write first.");
|
|
3861
3881
|
}
|
|
3862
3882
|
const has = (key) => Object.hasOwn(patch, key);
|
|
3863
3883
|
const merged = {
|
|
@@ -3867,7 +3887,7 @@ async function patchWriteSession(patch, workingDir = process.cwd()) {
|
|
|
3867
3887
|
lastCompletedStage: has("lastCompletedStage") ? patch.lastCompletedStage ?? null : existing.lastCompletedStage,
|
|
3868
3888
|
failedStage: has("failedStage") ? patch.failedStage ?? null : existing.failedStage,
|
|
3869
3889
|
errorMessage: has("errorMessage") ? patch.errorMessage ?? null : existing.errorMessage,
|
|
3870
|
-
|
|
3890
|
+
contentPlan: has("contentPlan") ? patch.contentPlan ?? null : existing.contentPlan,
|
|
3871
3891
|
plan: has("plan") ? patch.plan ?? null : existing.plan,
|
|
3872
3892
|
text: has("text") ? patch.text ?? null : existing.text,
|
|
3873
3893
|
imagePrompts: has("imagePrompts") ? patch.imagePrompts ?? null : existing.imagePrompts,
|
|
@@ -3889,8 +3909,8 @@ function createInitialStages(options = { isArticlePrimary: true }) {
|
|
|
3889
3909
|
const sectionsDetail = options.isArticlePrimary ? "Waiting for the approved article plan." : "Waiting for primary content generation to begin.";
|
|
3890
3910
|
return [
|
|
3891
3911
|
{
|
|
3892
|
-
id: "shared-
|
|
3893
|
-
title: "Planning Shared
|
|
3912
|
+
id: "shared-plan",
|
|
3913
|
+
title: "Planning Shared Plan",
|
|
3894
3914
|
status: "running",
|
|
3895
3915
|
detail: "Generating explicit cross-channel content guidance."
|
|
3896
3916
|
},
|
|
@@ -3953,7 +3973,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
3953
3973
|
const stageTracking = /* @__PURE__ */ new Map();
|
|
3954
3974
|
const stageRetryState = /* @__PURE__ */ new Map();
|
|
3955
3975
|
const llmOperationRetryState = /* @__PURE__ */ new Map();
|
|
3956
|
-
stageTracking.set("shared-
|
|
3976
|
+
stageTracking.set("shared-plan", {
|
|
3957
3977
|
startedAtMs: runStartedAtMs,
|
|
3958
3978
|
endedAtMs: null,
|
|
3959
3979
|
retries: 0,
|
|
@@ -4017,7 +4037,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4017
4037
|
} else {
|
|
4018
4038
|
const existing = await loadWriteSession(workingDir);
|
|
4019
4039
|
if (!existing) {
|
|
4020
|
-
throw new Error("No resumable write session found
|
|
4040
|
+
throw new Error("No resumable write session found. Start a fresh write first.");
|
|
4021
4041
|
}
|
|
4022
4042
|
if (existing.status === "completed") {
|
|
4023
4043
|
}
|
|
@@ -4033,24 +4053,24 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4033
4053
|
replicateApiKey: requireSecret(input.config.secrets.replicateApiToken, "Replicate API token"),
|
|
4034
4054
|
openrouterModel: input.config.settings.model
|
|
4035
4055
|
});
|
|
4036
|
-
let
|
|
4056
|
+
let contentPlan = writeSession.contentPlan;
|
|
4037
4057
|
let plan = writeSession.plan;
|
|
4038
4058
|
let text = writeSession.text;
|
|
4039
4059
|
let imagePrompts = writeSession.imagePrompts ?? writeSession.imageArtifacts?.imagePrompts ?? null;
|
|
4040
4060
|
let imageArtifacts = writeSession.imageArtifacts;
|
|
4041
4061
|
let linksResult = writeSession.links;
|
|
4042
4062
|
let primaryMarkdownTemplate = null;
|
|
4043
|
-
if (
|
|
4044
|
-
markStageCompleted(stageTracking, "shared-
|
|
4063
|
+
if (contentPlan) {
|
|
4064
|
+
markStageCompleted(stageTracking, "shared-plan");
|
|
4045
4065
|
stages[0] = {
|
|
4046
4066
|
...stages[0],
|
|
4047
4067
|
status: "succeeded",
|
|
4048
|
-
detail: "Reused saved shared
|
|
4049
|
-
summary:
|
|
4050
|
-
stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-
|
|
4068
|
+
detail: "Reused saved shared plan from cached session.",
|
|
4069
|
+
summary: contentPlan.title,
|
|
4070
|
+
stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-plan")
|
|
4051
4071
|
};
|
|
4052
4072
|
} else {
|
|
4053
|
-
|
|
4073
|
+
contentPlan = await planContentPlan({
|
|
4054
4074
|
idea: input.idea,
|
|
4055
4075
|
targetAudienceHint: input.targetAudienceHint,
|
|
4056
4076
|
settings: input.config.settings,
|
|
@@ -4060,24 +4080,24 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4060
4080
|
onLlmInteraction(interaction);
|
|
4061
4081
|
},
|
|
4062
4082
|
onLlmMetrics(metrics) {
|
|
4063
|
-
recordLlmMetrics(stageTracking, "shared-
|
|
4083
|
+
recordLlmMetrics(stageTracking, "shared-plan", metrics);
|
|
4064
4084
|
}
|
|
4065
4085
|
});
|
|
4066
|
-
markStageCompleted(stageTracking, "shared-
|
|
4086
|
+
markStageCompleted(stageTracking, "shared-plan");
|
|
4067
4087
|
stages[0] = {
|
|
4068
4088
|
...stages[0],
|
|
4069
4089
|
status: "succeeded",
|
|
4070
|
-
detail: "Shared
|
|
4071
|
-
summary:
|
|
4072
|
-
stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-
|
|
4090
|
+
detail: "Shared plan generated successfully.",
|
|
4091
|
+
summary: contentPlan.title,
|
|
4092
|
+
stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-plan")
|
|
4073
4093
|
};
|
|
4074
4094
|
writeSession = await patchWriteSession(
|
|
4075
4095
|
{
|
|
4076
4096
|
status: "running",
|
|
4077
|
-
lastCompletedStage: "shared-
|
|
4097
|
+
lastCompletedStage: "shared-plan",
|
|
4078
4098
|
failedStage: null,
|
|
4079
4099
|
errorMessage: null,
|
|
4080
|
-
|
|
4100
|
+
contentPlan
|
|
4081
4101
|
},
|
|
4082
4102
|
workingDir
|
|
4083
4103
|
);
|
|
@@ -4095,17 +4115,17 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4095
4115
|
stages[1] = {
|
|
4096
4116
|
...stages[1],
|
|
4097
4117
|
status: "succeeded",
|
|
4098
|
-
detail: "Reused saved plan from .
|
|
4118
|
+
detail: "Reused saved plan from cached session.",
|
|
4099
4119
|
summary: `${plan.title} \u2022 ${plan.slug} \u2022 ${plan.sections.length} sections \u2022 ${plan.inlineImages.length + 1} images`,
|
|
4100
4120
|
stageAnalytics: snapshotStageAnalytics(stageTracking, "planning")
|
|
4101
4121
|
};
|
|
4102
4122
|
} else {
|
|
4103
|
-
if (!
|
|
4104
|
-
throw new Error("Shared content
|
|
4123
|
+
if (!contentPlan) {
|
|
4124
|
+
throw new Error("Shared content plan is missing for article planning stage.");
|
|
4105
4125
|
}
|
|
4106
4126
|
plan = await planArticle({
|
|
4107
4127
|
idea: input.idea,
|
|
4108
|
-
|
|
4128
|
+
contentPlan,
|
|
4109
4129
|
settings: input.config.settings,
|
|
4110
4130
|
markdownOutputDir: writeSession.outputPaths.markdownOutputDir,
|
|
4111
4131
|
openRouter,
|
|
@@ -4131,7 +4151,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4131
4151
|
lastCompletedStage: "planning",
|
|
4132
4152
|
failedStage: null,
|
|
4133
4153
|
errorMessage: null,
|
|
4134
|
-
|
|
4154
|
+
contentPlan,
|
|
4135
4155
|
plan
|
|
4136
4156
|
},
|
|
4137
4157
|
workingDir
|
|
@@ -4150,12 +4170,12 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4150
4170
|
stages[2] = {
|
|
4151
4171
|
...stages[2],
|
|
4152
4172
|
status: "succeeded",
|
|
4153
|
-
detail: "Reused saved section drafts from .
|
|
4173
|
+
detail: "Reused saved section drafts from cached session.",
|
|
4154
4174
|
summary: `Intro + ${text.sections.length} sections + conclusion`,
|
|
4155
4175
|
items: (stages[2].items ?? []).map((item) => ({
|
|
4156
4176
|
...item,
|
|
4157
4177
|
status: "succeeded",
|
|
4158
|
-
detail: "Reused saved section draft from .
|
|
4178
|
+
detail: "Reused saved section draft from cached session."
|
|
4159
4179
|
})),
|
|
4160
4180
|
stageAnalytics: snapshotStageAnalytics(stageTracking, "sections")
|
|
4161
4181
|
};
|
|
@@ -4269,7 +4289,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4269
4289
|
stages[3] = {
|
|
4270
4290
|
...stages[3],
|
|
4271
4291
|
status: "succeeded",
|
|
4272
|
-
detail: "Reused saved image prompts from .
|
|
4292
|
+
detail: "Reused saved image prompts from cached session.",
|
|
4273
4293
|
summary: `${imagePrompts.length} prompts ready`,
|
|
4274
4294
|
stageAnalytics: snapshotStageAnalytics(stageTracking, "image-prompts")
|
|
4275
4295
|
};
|
|
@@ -4282,7 +4302,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4282
4302
|
options.onUpdate?.(cloneStages(stages));
|
|
4283
4303
|
} else {
|
|
4284
4304
|
imagePrompts = await expandImagePrompts({
|
|
4285
|
-
slots:
|
|
4305
|
+
slots: buildImageSlots(plan, text.sections, { maxImages: options.maxImages }),
|
|
4286
4306
|
planContext: plan,
|
|
4287
4307
|
sections: text.sections,
|
|
4288
4308
|
settings: input.config.settings,
|
|
@@ -4344,8 +4364,8 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4344
4364
|
);
|
|
4345
4365
|
}
|
|
4346
4366
|
} else {
|
|
4347
|
-
if (!
|
|
4348
|
-
throw new Error("Shared content
|
|
4367
|
+
if (!contentPlan) {
|
|
4368
|
+
throw new Error("Shared content plan is missing for primary content planning stage.");
|
|
4349
4369
|
}
|
|
4350
4370
|
stages[1] = {
|
|
4351
4371
|
...stages[1],
|
|
@@ -4379,7 +4399,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4379
4399
|
outputIndex: 1,
|
|
4380
4400
|
outputCountForType: 1,
|
|
4381
4401
|
articleReferenceMarkdown: void 0,
|
|
4382
|
-
|
|
4402
|
+
contentPlan,
|
|
4383
4403
|
settings: input.config.settings,
|
|
4384
4404
|
openRouter,
|
|
4385
4405
|
dryRun,
|
|
@@ -4405,7 +4425,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4405
4425
|
};
|
|
4406
4426
|
markStageStarted(stageTracking, "image-prompts");
|
|
4407
4427
|
options.onUpdate?.(cloneStages(stages));
|
|
4408
|
-
imagePrompts = [buildPrimaryCoverPrompt(
|
|
4428
|
+
imagePrompts = [buildPrimaryCoverPrompt(contentPlan, primaryTarget.contentType, primaryMarkdownTemplate)];
|
|
4409
4429
|
markStageCompleted(stageTracking, "image-prompts");
|
|
4410
4430
|
stages[3] = {
|
|
4411
4431
|
...stages[3],
|
|
@@ -4427,7 +4447,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4427
4447
|
};
|
|
4428
4448
|
options.onUpdate?.(cloneStages(stages));
|
|
4429
4449
|
}
|
|
4430
|
-
const baseSlug = plan?.slug ??
|
|
4450
|
+
const baseSlug = plan?.slug ?? resolveGenerationSlug(input.idea, contentPlan?.title);
|
|
4431
4451
|
const generationDir = path8.join(
|
|
4432
4452
|
writeSession.outputPaths.markdownOutputDir,
|
|
4433
4453
|
buildGenerationDirectoryName(baseSlug)
|
|
@@ -4445,6 +4465,10 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4445
4465
|
sourceJob: input.job
|
|
4446
4466
|
})
|
|
4447
4467
|
);
|
|
4468
|
+
const planPath = plan ? path8.join(generationDir, "plan.md") : null;
|
|
4469
|
+
if (plan && planPath) {
|
|
4470
|
+
await writeUtf8File(planPath, renderPlanMarkdown(plan));
|
|
4471
|
+
}
|
|
4448
4472
|
const primaryFilePrefix = toFilePrefix(primaryTarget.contentType);
|
|
4449
4473
|
const primaryMarkdownPath = path8.join(generationDir, `${primaryFilePrefix}-1.md`);
|
|
4450
4474
|
const sharedAssetDir = generationDir;
|
|
@@ -4454,7 +4478,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4454
4478
|
stages[4] = {
|
|
4455
4479
|
...stages[4],
|
|
4456
4480
|
status: "succeeded",
|
|
4457
|
-
detail: "Reused previously rendered images from .
|
|
4481
|
+
detail: "Reused previously rendered images from cached session.",
|
|
4458
4482
|
summary: sharedAssetDir,
|
|
4459
4483
|
stageAnalytics: snapshotStageAnalytics(stageTracking, "images")
|
|
4460
4484
|
};
|
|
@@ -4541,7 +4565,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4541
4565
|
stages[4] = {
|
|
4542
4566
|
...stages[4],
|
|
4543
4567
|
status: "succeeded",
|
|
4544
|
-
detail: "Reused previously rendered primary cover image from .
|
|
4568
|
+
detail: "Reused previously rendered primary cover image from cached session.",
|
|
4545
4569
|
summary: sharedAssetDir,
|
|
4546
4570
|
stageAnalytics: snapshotStageAnalytics(stageTracking, "images")
|
|
4547
4571
|
};
|
|
@@ -4613,7 +4637,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4613
4637
|
}
|
|
4614
4638
|
primaryMarkdownTemplate = applyPrimaryTitleHeading(
|
|
4615
4639
|
primaryMarkdownTemplate,
|
|
4616
|
-
|
|
4640
|
+
contentPlan.title || deriveTitleFromIdea2(input.idea)
|
|
4617
4641
|
);
|
|
4618
4642
|
}
|
|
4619
4643
|
const markdownPaths = [];
|
|
@@ -4643,8 +4667,8 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4643
4667
|
};
|
|
4644
4668
|
markStageStarted(stageTracking, "output");
|
|
4645
4669
|
options.onUpdate?.(cloneStages(stages));
|
|
4646
|
-
if (!
|
|
4647
|
-
throw new Error("Shared content
|
|
4670
|
+
if (!contentPlan) {
|
|
4671
|
+
throw new Error("Shared content plan is missing for output generation stage.");
|
|
4648
4672
|
}
|
|
4649
4673
|
for (const output of requestedOutputs) {
|
|
4650
4674
|
const itemId = toOutputItemId(output.filePrefix, output.index);
|
|
@@ -4679,7 +4703,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4679
4703
|
outputIndex: output.index,
|
|
4680
4704
|
outputCountForType: output.outputCountForType,
|
|
4681
4705
|
articleReferenceMarkdown: primaryMarkdownTemplate ?? void 0,
|
|
4682
|
-
|
|
4706
|
+
contentPlan,
|
|
4683
4707
|
settings: input.config.settings,
|
|
4684
4708
|
openRouter,
|
|
4685
4709
|
dryRun,
|
|
@@ -4824,7 +4848,7 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4824
4848
|
stages[6] = {
|
|
4825
4849
|
...stages[6],
|
|
4826
4850
|
status: "succeeded",
|
|
4827
|
-
detail: "Reused saved link metadata from .
|
|
4851
|
+
detail: "Reused saved link metadata from cached session.",
|
|
4828
4852
|
summary: `${resumedLinks.reduce((sum, item) => sum + item.links.length, 0)} links`,
|
|
4829
4853
|
items: (stages[6].items ?? []).map((item) => ({
|
|
4830
4854
|
...item,
|
|
@@ -4838,8 +4862,8 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4838
4862
|
const itemTracking = /* @__PURE__ */ new Map();
|
|
4839
4863
|
linksResult = await enrichLinks({
|
|
4840
4864
|
markdownFiles: eligibleOutputsForLinks,
|
|
4841
|
-
articleTitle: plan?.title ??
|
|
4842
|
-
articleDescription: plan?.description ??
|
|
4865
|
+
articleTitle: plan?.title ?? contentPlan.title ?? deriveTitleFromIdea2(input.idea),
|
|
4866
|
+
articleDescription: plan?.description ?? contentPlan.description,
|
|
4843
4867
|
openRouter,
|
|
4844
4868
|
settings: input.config.settings,
|
|
4845
4869
|
dryRun,
|
|
@@ -4952,8 +4976,8 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4952
4976
|
await writeJsonFile(interactionsPath, interactions);
|
|
4953
4977
|
const primaryMarkdownPathForArtifact = markdownPaths[0] ?? primaryMarkdownPath;
|
|
4954
4978
|
const artifact = {
|
|
4955
|
-
title: plan?.title ??
|
|
4956
|
-
slug: plan?.slug ??
|
|
4979
|
+
title: plan?.title ?? contentPlan.title ?? deriveTitleFromIdea2(input.idea),
|
|
4980
|
+
slug: plan?.slug ?? resolveGenerationSlug(input.idea, contentPlan?.title),
|
|
4957
4981
|
sectionCount: text?.sections.length ?? 0,
|
|
4958
4982
|
imageCount: imageArtifacts?.renderedImages.length ?? 0,
|
|
4959
4983
|
outputCount: markdownPaths.length,
|
|
@@ -4962,7 +4986,8 @@ async function runPipelineShell(input, options = {}) {
|
|
|
4962
4986
|
markdownPath: primaryMarkdownPathForArtifact,
|
|
4963
4987
|
assetDir: sharedAssetDir,
|
|
4964
4988
|
analyticsPath,
|
|
4965
|
-
interactionsPath
|
|
4989
|
+
interactionsPath,
|
|
4990
|
+
planPath
|
|
4966
4991
|
};
|
|
4967
4992
|
writeSession = await patchWriteSession(
|
|
4968
4993
|
{
|
|
@@ -5061,7 +5086,7 @@ function buildRunAnalytics({
|
|
|
5061
5086
|
linkEnrichmentCalls
|
|
5062
5087
|
}) {
|
|
5063
5088
|
const runEndedAtMs = Date.now();
|
|
5064
|
-
const orderedStageIds = ["shared-
|
|
5089
|
+
const orderedStageIds = ["shared-plan", "planning", "sections", "image-prompts", "images", "output", "links"];
|
|
5065
5090
|
const stages = orderedStageIds.map((stageId) => {
|
|
5066
5091
|
const tracked = stageTracking.get(stageId);
|
|
5067
5092
|
const startedAtMs = tracked?.startedAtMs ?? runEndedAtMs;
|
|
@@ -5278,7 +5303,7 @@ function getSecondaryTargets(contentTargets) {
|
|
|
5278
5303
|
count: target.count
|
|
5279
5304
|
}));
|
|
5280
5305
|
}
|
|
5281
|
-
function buildPrimaryCoverPrompt(
|
|
5306
|
+
function buildPrimaryCoverPrompt(contentPlan, primaryContentType, primaryMarkdown) {
|
|
5282
5307
|
const markdownExcerpt = primaryMarkdown.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
5283
5308
|
return {
|
|
5284
5309
|
id: "cover",
|
|
@@ -5287,10 +5312,10 @@ function buildPrimaryCoverPrompt(contentBrief, primaryContentType, primaryMarkdo
|
|
|
5287
5312
|
anchorAfterSection: null,
|
|
5288
5313
|
prompt: [
|
|
5289
5314
|
`Cover image for ${primaryContentType}.`,
|
|
5290
|
-
`Core angle: ${
|
|
5291
|
-
`Audience: ${
|
|
5292
|
-
`Promise: ${
|
|
5293
|
-
`Voice: ${
|
|
5315
|
+
`Core angle: ${contentPlan.description}`,
|
|
5316
|
+
`Audience: ${contentPlan.targetAudience}`,
|
|
5317
|
+
`Promise: ${contentPlan.corePromise}`,
|
|
5318
|
+
`Voice: ${contentPlan.voiceNotes}`,
|
|
5294
5319
|
`Primary excerpt: ${markdownExcerpt}`,
|
|
5295
5320
|
"Do not include any words, letters, numbers, logos, watermarks, or signage in the image."
|
|
5296
5321
|
].join(" ")
|
|
@@ -5325,8 +5350,18 @@ function deriveTitleFromIdea2(idea) {
|
|
|
5325
5350
|
}
|
|
5326
5351
|
return normalized.split(/\s+/).slice(0, 8).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
5327
5352
|
}
|
|
5328
|
-
function slugifyIdea(idea) {
|
|
5329
|
-
|
|
5353
|
+
function slugifyIdea(idea, maxLength) {
|
|
5354
|
+
const slug = idea.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "generated-content";
|
|
5355
|
+
if (maxLength !== void 0 && slug.length > maxLength) {
|
|
5356
|
+
return slug.slice(0, maxLength).replace(/-+$/, "");
|
|
5357
|
+
}
|
|
5358
|
+
return slug;
|
|
5359
|
+
}
|
|
5360
|
+
function resolveGenerationSlug(idea, planTitle) {
|
|
5361
|
+
if (planTitle) {
|
|
5362
|
+
return slugifyIdea(planTitle);
|
|
5363
|
+
}
|
|
5364
|
+
return slugifyIdea(idea, 80);
|
|
5330
5365
|
}
|
|
5331
5366
|
function buildRunJobDefinition(input) {
|
|
5332
5367
|
return {
|
|
@@ -5344,8 +5379,47 @@ function buildRunJobDefinition(input) {
|
|
|
5344
5379
|
}
|
|
5345
5380
|
};
|
|
5346
5381
|
}
|
|
5382
|
+
function renderPlanMarkdown(plan) {
|
|
5383
|
+
const yamlKeywords = plan.keywords.map((kw) => ` - "${kw}"`).join("\n");
|
|
5384
|
+
const sectionsRows = plan.sections.map((section, index) => `| ${index + 1} | ${section.title} | ${section.description} |`).join("\n");
|
|
5385
|
+
const inlineImageRows = plan.inlineImages.map((img, index) => `| Inline ${index + 1} | ${img.description} |`).join("\n");
|
|
5386
|
+
const imageRows = `| Cover | ${plan.coverImageDescription} |
|
|
5387
|
+
${inlineImageRows}`;
|
|
5388
|
+
return `---
|
|
5389
|
+
title: "${plan.title.replace(/"/g, '\\"')}"
|
|
5390
|
+
subtitle: "${plan.subtitle.replace(/"/g, '\\"')}"
|
|
5391
|
+
slug: "${plan.slug}"
|
|
5392
|
+
keywords:
|
|
5393
|
+
${yamlKeywords}
|
|
5394
|
+
---
|
|
5395
|
+
|
|
5396
|
+
## Description
|
|
5397
|
+
|
|
5398
|
+
${plan.description}
|
|
5399
|
+
|
|
5400
|
+
## Introduction Brief
|
|
5401
|
+
|
|
5402
|
+
${plan.introBrief}
|
|
5403
|
+
|
|
5404
|
+
## Sections
|
|
5405
|
+
|
|
5406
|
+
| # | Title | Description |
|
|
5407
|
+
|---|-------|-------------|
|
|
5408
|
+
${sectionsRows}
|
|
5409
|
+
|
|
5410
|
+
## Outro Brief
|
|
5411
|
+
|
|
5412
|
+
${plan.outroBrief}
|
|
5413
|
+
|
|
5414
|
+
## Image Plan
|
|
5415
|
+
|
|
5416
|
+
| Type | Description |
|
|
5417
|
+
|------|-------------|
|
|
5418
|
+
${imageRows}
|
|
5419
|
+
`;
|
|
5420
|
+
}
|
|
5347
5421
|
function asWriteStageId(stageId) {
|
|
5348
|
-
if (stageId === "shared-
|
|
5422
|
+
if (stageId === "shared-plan" || stageId === "planning" || stageId === "sections" || stageId === "image-prompts" || stageId === "images" || stageId === "output" || stageId === "links") {
|
|
5349
5423
|
return stageId;
|
|
5350
5424
|
}
|
|
5351
5425
|
return null;
|
|
@@ -6258,7 +6332,7 @@ async function startIdeonMcpServer() {
|
|
|
6258
6332
|
try {
|
|
6259
6333
|
const session = await loadWriteSession(cwd());
|
|
6260
6334
|
if (!session) {
|
|
6261
|
-
throw new ReportedError("No resumable write session found
|
|
6335
|
+
throw new ReportedError("No resumable write session found.");
|
|
6262
6336
|
}
|
|
6263
6337
|
if (session.status === "completed") {
|
|
6264
6338
|
throw new ReportedError("The last write session already completed.");
|
|
@@ -8269,7 +8343,7 @@ function renderShell({
|
|
|
8269
8343
|
const articleListElement = document.getElementById('articleList');
|
|
8270
8344
|
const themeToggleButton = document.getElementById('themeToggle');
|
|
8271
8345
|
const typeOrder = ['article', 'blog-post', 'x-thread', 'x-post', 'linkedin-post', 'reddit-post', 'newsletter'];
|
|
8272
|
-
const stageOrder = ['shared-
|
|
8346
|
+
const stageOrder = ['shared-plan', 'planning', 'sections', 'image-prompts', 'images', 'output', 'links'];
|
|
8273
8347
|
|
|
8274
8348
|
let currentGeneration = null;
|
|
8275
8349
|
let activeType = '';
|
|
@@ -8931,7 +9005,7 @@ function formatStageCost(costUsd, costSource) {
|
|
|
8931
9005
|
return costSource === "estimated" ? `~${formatted}` : formatted;
|
|
8932
9006
|
}
|
|
8933
9007
|
function formatStageId(stageId) {
|
|
8934
|
-
if (stageId === "shared-
|
|
9008
|
+
if (stageId === "shared-plan") return "shared-plan";
|
|
8935
9009
|
if (stageId === "planning") return "planning";
|
|
8936
9010
|
if (stageId === "sections") return "sections";
|
|
8937
9011
|
if (stageId === "image-prompts") return "image-prompts";
|
|
@@ -9829,7 +9903,7 @@ async function runWriteCommand(options) {
|
|
|
9829
9903
|
async function runWriteResumeCommand(options = {}) {
|
|
9830
9904
|
const session = await loadWriteSession();
|
|
9831
9905
|
if (!session) {
|
|
9832
|
-
throw new ReportedError("No resumable write session found
|
|
9906
|
+
throw new ReportedError("No resumable write session found. Run ideon write <idea> first.");
|
|
9833
9907
|
}
|
|
9834
9908
|
if (session.status === "completed") {
|
|
9835
9909
|
throw new ReportedError("The last write session already completed. Run ideon write <idea> to start fresh.");
|
|
@@ -10126,7 +10200,7 @@ async function runCli(argv) {
|
|
|
10126
10200
|
watch: options.watch
|
|
10127
10201
|
});
|
|
10128
10202
|
});
|
|
10129
|
-
const writeCommand = program.command("write").description("Generate one primary content output plus optional secondary outputs from a prompt or job file.").argument("[idea]", "Natural-language idea for the generation run").option("-i, --idea <idea>", "Natural-language idea for the generation run").option("--audience <description>", "Optional natural-language audience description for shared-
|
|
10203
|
+
const writeCommand = program.command("write").description("Generate one primary content output plus optional secondary outputs from a prompt or job file.").argument("[idea]", "Natural-language idea for the generation run").option("-i, --idea <idea>", "Natural-language idea for the generation run").option("--audience <description>", "Optional natural-language audience description for shared-plan targeting").option("-j, --job <path>", "Path to a JSON job definition").option("--primary <type=count>", "Required primary output target (for example: article=1 or x-post=1)").option("--secondary <type=count>", "Secondary output target, repeatable (for example: x-thread=3, linkedin-post=2)", collectOptionValue).option("--style <style>", "Writing style (academic, analytical, authoritative, conversational, empathetic, friendly, journalistic, minimalist, persuasive, playful, professional, storytelling, technical)").option("--intent <intent>", "Content intent (announcement, case-study, cornerstone, counterargument, critique-review, deep-dive-analysis, how-to-guide, interview-q-and-a, listicle, opinion-piece, personal-essay, roundup-curation, tutorial)").option("--length <size>", "Target length: small, medium, large, or a positive integer word count").option("--no-interactive", "Fail instead of prompting for missing input in TTY mode").option("--dry-run", "Run the pipeline shell without external API calls", false).option("--enrich-links", "Run link enrichment after markdown generation", false).option("--link <pair>", 'Custom link "expression->url", repeatable', collectOptionValue).option("--unlink <expression>", "Remove a custom link by expression, repeatable", collectOptionValue).option("--max-links <n>", "Max number of generated links", (v) => Number.parseInt(v, 10)).option("--max-images <n>", "Max total images including cover (1=cover only, 2=cover+1 inline, 3=cover+2 inline)", (v) => Number.parseInt(v, 10)).action(async (ideaArg, options) => {
|
|
10130
10204
|
await runWriteCommand({
|
|
10131
10205
|
idea: options.idea ?? ideaArg,
|
|
10132
10206
|
audience: options.audience,
|
|
@@ -10145,7 +10219,7 @@ async function runCli(argv) {
|
|
|
10145
10219
|
maxImages: options.maxImages
|
|
10146
10220
|
});
|
|
10147
10221
|
});
|
|
10148
|
-
writeCommand.command("resume").description("Resume the last failed or interrupted write session
|
|
10222
|
+
writeCommand.command("resume").description("Resume the last failed or interrupted write session.").option("--no-interactive", "Force plain non-interactive output even in TTY mode", false).option("--enrich-links", "Run link enrichment after markdown generation", false).option("--link <pair>", 'Custom link "expression->url", repeatable', collectOptionValue).option("--unlink <expression>", "Remove a custom link by expression, repeatable", collectOptionValue).option("--max-links <n>", "Max number of generated links", (v) => Number.parseInt(v, 10)).option("--max-images <n>", "Max total images including cover (1=cover only, 2=cover+1 inline, 3=cover+2 inline)", (v) => Number.parseInt(v, 10)).action(async (options) => {
|
|
10149
10223
|
await runWriteResumeCommand({
|
|
10150
10224
|
noInteractive: options.noInteractive,
|
|
10151
10225
|
enrichLinks: options.enrichLinks,
|
|
@@ -211,7 +211,7 @@ html body {
|
|
|
211
211
|
${t}-collapse,
|
|
212
212
|
${t}-edit,
|
|
213
213
|
${t}-copy
|
|
214
|
-
`]:{...fx(e),marginInlineStart:e.marginXXS},...A9(e),..._9(e),...B9(),"&-rtl":{direction:"rtl"}}}},L9=()=>({titleMarginTop:"1.2em",titleMarginBottom:"0.5em"}),T$=Xt("Typography",H9,L9),D9=e=>{const{prefixCls:t,"aria-label":o,className:a,style:l,direction:c,maxLength:f,autoSize:m=!0,value:h,onSave:p,onCancel:y,onEnd:b,component:v,enterIcon:$=u.createElement(M9,null)}=e,x=u.useRef(null),E=u.useRef(!1),C=u.useRef(null),[T,M]=u.useState(h);u.useEffect(()=>{M(h)},[h]),u.useEffect(()=>{if(x.current?.resizableTextArea){const{textArea:k}=x.current.resizableTextArea;k.focus();const{length:U}=k.value;k.setSelectionRange(U,U)}},[]);const w=({target:k})=>{M(k.value.replace(/[\n\r]/g,""))},N=()=>{E.current=!0},R=()=>{E.current=!1},_=({keyCode:k})=>{E.current||(C.current=k)},z=()=>{p(T.trim())},B=({keyCode:k,ctrlKey:U,altKey:F,metaKey:P,shiftKey:q})=>{C.current!==k||E.current||U||F||P||q||(k===er.ENTER?(z(),b?.()):k===er.ESC&&y())},H=()=>{z()},[I,L]=T$(t),V=W(t,`${t}-edit-content`,{[`${t}-rtl`]:c==="rtl",[`${t}-${v}`]:!!v},a,I,L);return u.createElement("div",{className:V,style:l},u.createElement(r9,{ref:x,maxLength:f,value:T,onChange:w,onKeyDown:_,onKeyUp:B,onCompositionStart:N,onCompositionEnd:R,onBlur:H,"aria-label":o,rows:1,autoSize:m}),$!==null?pa($,{className:`${t}-edit-content-confirm`}):null)},P9=(e,t)=>{let o=!1;const a=l=>{l.stopPropagation(),l.preventDefault(),l.clipboardData?.clearData(),l.clipboardData?.setData("text/plain",e),t&&l.clipboardData?.setData("text/html",e),o=!0};try{return document.addEventListener("copy",a,{capture:!0}),document.execCommand("copy"),o}catch{return!1}finally{document.removeEventListener("copy",a,{capture:!0})}},I9=async(e,t)=>{try{return t?await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([e],{type:"text/html"}),"text/plain":new Blob([e],{type:"text/plain"})})]):await navigator.clipboard.writeText(e),!0}catch{return!1}};async function j9(e,t){if(typeof e!="string")return!1;const o=t?.format==="text/html";return!!(await I9(e,o)||P9(e,o))}const V9=({copyConfig:e,children:t})=>{const[o,a]=u.useState(!1),[l,c]=u.useState(!1),f=u.useRef(null),m=()=>{f.current&&clearTimeout(f.current)},h={};e.format&&(h.format=e.format),u.useEffect(()=>m,[]);const p=Tt(async y=>{y?.preventDefault(),y?.stopPropagation(),c(!0);try{const b=typeof e.text=="function"?await e.text():e.text;await j9(b||E$(t,{skipEmpty:!0}).join("")||"",h),c(!1),a(!0),m(),f.current=setTimeout(()=>{a(!1)},3e3),e.onCopy?.(y)}catch(b){throw c(!1),b}});return{copied:o,copyLoading:l,onClick:p}};function tg(e,t){return u.useMemo(()=>{const o=!!e;return[o,{...t,...o&&typeof e=="object"?e:null}]},[e])}const F9=e=>{const t=u.useRef(void 0);return u.useEffect(()=>{t.current=e}),t.current},q9=(e,t,o)=>u.useMemo(()=>e===!0?{title:t??o}:u.isValidElement(e)?{title:e}:typeof e=="object"?{title:t??o,...e}:{title:e},[e,t,o]),M$=u.forwardRef((e,t)=>{const{prefixCls:o,component:a="article",className:l,rootClassName:c,children:f,direction:m,style:h,...p}=e,{getPrefixCls:y,direction:b,className:v,style:$}=cn("typography"),x=m??b,E=y("typography",o),[C,T]=T$(E),M=W(E,v,{[`${E}-rtl`]:x==="rtl"},l,c,C,T),w={...$,...h};return u.createElement(a,{className:M,style:w,ref:t,...p},f)});var U9={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"}}]},name:"copy",theme:"outlined"};function Up(){return Up=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Up.apply(this,arguments)}const G9=(e,t)=>u.createElement(Dt,Up({},e,{ref:t,icon:U9})),X9=u.forwardRef(G9),uC=e=>e===!1?[!1,!1]:E$(e);function ng(e,t,o){return e===!0||e===void 0?t:e||o&&t}function W9(e){const t=document.createElement("em");e.appendChild(t);const o=e.getBoundingClientRect(),a=t.getBoundingClientRect();return e.removeChild(t),o.left>a.left||a.right>o.right||o.top>a.top||a.bottom>o.bottom}const Qh=e=>["string","number"].includes(typeof e),Y9=e=>{const{prefixCls:t,copied:o,locale:a,iconOnly:l,tooltips:c,icon:f,tabIndex:m,onCopy:h,loading:p}=e,y=uC(c),b=uC(f),{copied:v,copy:$}=a??{},x=o?v:$,E=ng(y[o?1:0],x),C=typeof E=="string"?E:x;return u.createElement(dl,{title:E},u.createElement("button",{type:"button",className:W(`${t}-copy`,{[`${t}-copy-success`]:o,[`${t}-copy-icon-only`]:l}),onClick:h,"aria-label":C,tabIndex:m},o?ng(b[1],u.createElement(bz,null),!0):ng(b[0],p?u.createElement(Th,null):u.createElement(X9,null),!0)))},bu=u.forwardRef(({style:e,children:t},o)=>{const a=u.useRef(null);return u.useImperativeHandle(o,()=>({isExceed:()=>{const l=a.current;return l.scrollHeight>l.clientHeight},getHeight:()=>a.current.clientHeight})),u.createElement("span",{"aria-hidden":!0,ref:a,style:{position:"fixed",display:"block",left:0,top:0,pointerEvents:"none",backgroundColor:"rgba(255, 0, 0, 0.65)",...e}},t)}),K9=e=>e.reduce((t,o)=>t+(Qh(o)?String(o).length:1),0);function fC(e,t){let o=0;const a=[];for(let l=0;l<e.length;l+=1){if(o===t)return a;const c=e[l],m=Qh(c)?String(c).length:1,h=o+m;if(h>t){const p=t-o;return a.push(String(c).slice(0,p)),a}a.push(c),o=h}return e}const rg=0,og=1,ag=2,ig=3,dC=4,vu={display:"-webkit-box",overflow:"hidden",WebkitBoxOrient:"vertical"};function k9(e){const{enableMeasure:t,width:o,text:a,children:l,rows:c,expanded:f,miscDeps:m,onEllipsis:h}=e,p=u.useMemo(()=>br(a),[a]),y=u.useMemo(()=>K9(p),[a]),b=u.useMemo(()=>l(p,!1),[a]),[v,$]=u.useState(null),x=u.useRef(null),E=u.useRef(null),C=u.useRef(null),T=u.useRef(null),M=u.useRef(null),[w,N]=u.useState(!1),[R,_]=u.useState(rg),[z,B]=u.useState(0),[H,I]=u.useState(null);Lt(()=>{_(t&&o&&y?og:rg)},[o,a,c,t,p]),Lt(()=>{if(R===og){_(ag);const U=E.current&&getComputedStyle(E.current).whiteSpace;I(U)}else if(R===ag){const U=!!C.current?.isExceed();_(U?ig:dC),$(U?[0,y]:null),N(U);const F=C.current?.getHeight()||0,P=c===1?0:T.current?.getHeight()||0,q=M.current?.getHeight()||0,G=Math.max(F,P+q);B(G+1),h(U)}},[R]);const L=v?Math.ceil((v[0]+v[1])/2):0;Lt(()=>{const[U,F]=v||[0,0];if(U!==F){const q=(x.current?.getHeight()||0)>z;let G=L;F-U===1&&(G=q?U:F),$(q?[U,G]:[G,F])}},[v,L]);const V=u.useMemo(()=>{if(!t)return l(p,!1);if(R!==ig||!v||v[0]!==v[1]){const U=l(p,!1);return[dC,rg].includes(R)?U:u.createElement("span",{style:{...vu,WebkitLineClamp:c}},U)}return l(f?p:fC(p,v[0]),w)},[f,R,v,p].concat(sn(m))),k={width:o,margin:0,padding:0,whiteSpace:H==="nowrap"?"normal":"inherit"};return u.createElement(u.Fragment,null,V,R===ag&&u.createElement(u.Fragment,null,u.createElement(bu,{style:{...k,...vu,WebkitLineClamp:c},ref:C},b),u.createElement(bu,{style:{...k,...vu,WebkitLineClamp:c-1},ref:T},b),u.createElement(bu,{style:{...k,...vu,WebkitLineClamp:1},ref:M},l([],!0))),R===ig&&v&&v[0]!==v[1]&&u.createElement(bu,{style:{...k,top:400},ref:x},l(fC(p,L),!0)),R===og&&u.createElement("span",{style:{whiteSpace:"inherit"},ref:E}))}const Q9=({enableEllipsis:e,isEllipsis:t,open:o,children:a,tooltipProps:l})=>{if(!l?.title||!e)return a;const c=o&&t;return u.createElement(dl,{open:c,...l},a)};function Z9({mark:e,code:t,underline:o,delete:a,strong:l,keyboard:c,italic:f},m){let h=m;function p(y,b){b&&(h=u.createElement(y,{},h))}return p("strong",l),p("u",o),p("del",a),p("code",t),p("mark",e),p("kbd",c),p("i",f),h}const J9="...",mC=["delete","mark","code","underline","strong","keyboard","italic"],ff=u.forwardRef((e,t)=>{const{prefixCls:o,className:a,style:l,type:c,disabled:f,children:m,ellipsis:h,editable:p,copyable:y,component:b,title:v,onMouseEnter:$,onMouseLeave:x,...E}=e,{getPrefixCls:C,direction:T}=u.useContext(ut),[M]=ba("Text"),w=u.useRef(null),N=u.useRef(null),R=C("typography",o),_=Lr(E,mC),[z,B]=tg(p),[H,I]=yr(!1,B.editing),{triggerType:L=["icon"]}=B,V=je=>{je&&B.onStart?.(),I(je)},k=F9(H);Lt(()=>{!H&&k&&N.current?.focus()},[H]);const U=je=>{je?.preventDefault(),V(!0)},F=je=>{B.onChange?.(je),V(!1)},P=()=>{B.onCancel?.(),V(!1)},[q,G]=tg(y),{copied:Y,copyLoading:Z,onClick:A}=V9({copyConfig:G,children:m}),[D,K]=u.useState(!1),[Q,ee]=u.useState(!1),[ie,le]=u.useState(!1),[de,ye]=u.useState(!1),[ve,we]=u.useState(!0),[be,Se]=tg(h,{expandable:!1,symbol:je=>je?M?.collapse:M?.expand}),[me,he]=yr(Se.defaultExpanded||!1,Se.expanded),pe=be&&(!me||Se.expandable==="collapsible"),{rows:Pe=1}=Se,Le=u.useMemo(()=>pe&&(Se.suffix!==void 0||Se.onEllipsis||Se.expandable||z||q),[pe,Se,z,q]);Lt(()=>{be&&!Le&&(K(CS("webkitLineClamp")),ee(CS("textOverflow")))},[Le,be]);const[Ee,Xe]=u.useState(pe),Oe=u.useMemo(()=>Le?!1:Pe===1?Q:D,[Le,Q,D]);Lt(()=>{Xe(Oe&&pe)},[Oe,pe]);const Re=pe&&(Ee?de:ie),De=pe&&Pe===1&&Ee,Te=pe&&Pe>1&&Ee,et=(je,Fe)=>{he(Fe.expanded),Se.onExpand?.(je,Fe)},[it,ft]=u.useState(0),[Ue,dt]=u.useState(!1),[Me,xe]=u.useState(!1),Ae=({offsetWidth:je})=>{ft(je)},Ye=je=>{le(je),ie!==je&&Se.onEllipsis?.(je)};u.useEffect(()=>{const je=w.current;if(be&&Ee&&je){const Fe=W9(je);de!==Fe&&ye(Fe)}},[be,Ee,m,Te,ve,it]),u.useEffect(()=>{const je=w.current;if(typeof IntersectionObserver>"u"||!je||!Ee||!pe)return;const Fe=new IntersectionObserver(()=>{we(!!je.offsetParent)});return Fe.observe(je),()=>{Fe.disconnect()}},[Ee,pe]);const _e=q9(Se.tooltip,B.text,m),Ce=u.useMemo(()=>{if(!(!be||Ee))return[B.text,m,v,_e.title].find(Qh)},[be,Ee,v,_e.title,Re]);if(H)return u.createElement(D9,{value:B.text??(typeof m=="string"?m:""),onSave:F,onCancel:P,onEnd:B.onEnd,prefixCls:R,className:a,style:l,direction:T,component:b,maxLength:B.maxLength,autoSize:B.autoSize,enterIcon:B.enterIcon});const Ie=()=>{const{expandable:je,symbol:Fe}=Se;return je?u.createElement("button",{type:"button",key:"expand",className:`${R}-${me?"collapse":"expand"}`,onClick:ot=>et(ot,{expanded:!me}),"aria-label":me?M.collapse:M?.expand},typeof Fe=="function"?Fe(me):Fe):null},mt=()=>{if(!z)return;const{icon:je,tooltip:Fe,tabIndex:ot}=B,Pt=br(Fe)[0]||M?.edit,Wt=typeof Pt=="string"?Pt:"";return L.includes("icon")?u.createElement(dl,{key:"edit",title:Fe===!1?"":Pt},u.createElement("button",{type:"button",ref:N,className:`${R}-edit`,onClick:U,"aria-label":Wt,tabIndex:ot},je||u.createElement($9,{role:"button"}))):null},ke=()=>q?u.createElement(Y9,{key:"copy",...G,prefixCls:R,copied:Y,locale:M,onCopy:A,loading:Z,iconOnly:!vr(m)}):null,Ut=je=>{const Fe=je&&Ie(),ot=mt(),Pt=ke();return!Fe&&!ot&&!Pt?null:u.createElement("span",{key:"operations",className:`${R}-actions`,onMouseEnter:()=>dt(!0),onMouseLeave:()=>dt(!1)},Fe,ot,Pt)},bt=je=>[je&&!me&&u.createElement("span",{"aria-hidden":!0,key:"ellipsis"},J9),Se.suffix,Ut(je)];return u.createElement(wo,{onResize:Ae,disabled:!pe},je=>u.createElement(Q9,{tooltipProps:_e,enableEllipsis:pe,isEllipsis:Re,open:Me&&!Ue},u.createElement(M$,{onMouseEnter:Fe=>{xe(!0),$?.(Fe)},onMouseLeave:Fe=>{xe(!1),x?.(Fe)},className:W({[`${R}-${c}`]:c,[`${R}-disabled`]:f,[`${R}-ellipsis`]:be,[`${R}-ellipsis-single-line`]:De,[`${R}-ellipsis-multiple-line`]:Te,[`${R}-link`]:b==="a"},a),prefixCls:o,style:{...l,WebkitLineClamp:Te?Pe:void 0},component:b,ref:Hr(je,w,t),direction:T,onClick:L.includes("text")?U:void 0,"aria-label":Ce?.toString(),title:v,..._},u.createElement(k9,{enableMeasure:pe&&!Ee,text:m,rows:Pe,width:it,onEllipsis:Ye,expanded:me,miscDeps:[Y,me,Z,z,q,M].concat(sn(mC.map(Fe=>e[Fe])))},(Fe,ot)=>Z9(e,u.createElement(u.Fragment,null,Fe.length>0&&ot&&!me&&Ce?u.createElement("span",{key:"show-content","aria-hidden":!0},Fe):Fe,bt(ot)))))))}),e7=u.forwardRef((e,t)=>{const{ellipsis:o,rel:a,children:l,navigate:c,...f}=e,m={...f,rel:a===void 0&&f.target==="_blank"?"noopener noreferrer":a};return u.createElement(ff,{...m,ref:t,ellipsis:!!o,component:"a"},l)}),t7=u.forwardRef((e,t)=>{const{children:o,...a}=e;return u.createElement(ff,{ref:t,...a,component:"div"},o)}),n7=u.forwardRef((e,t)=>{const{ellipsis:o,children:a,...l}=e,c=u.useMemo(()=>o&&typeof o=="object"?Lr(o,["expandable","rows"]):o,[o]);return u.createElement(ff,{ref:t,...l,ellipsis:c,component:"span"},a)}),r7=[1,2,3,4,5],o7=u.forwardRef((e,t)=>{const{level:o=1,children:a,...l}=e,c=r7.includes(o)?`h${o}`:"h1";return u.createElement(ff,{ref:t,...l,component:c},a)}),Sn=M$;Sn.Text=n7;Sn.Link=e7;Sn.Title=o7;Sn.Paragraph=t7;var a7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M632 888H392c-4.4 0-8 3.6-8 8v32c0 17.7 14.3 32 32 32h192c17.7 0 32-14.3 32-32v-32c0-4.4-3.6-8-8-8zM512 64c-181.1 0-328 146.9-328 328 0 121.4 66 227.4 164 284.1V792c0 17.7 14.3 32 32 32h264c17.7 0 32-14.3 32-32V676.1c98-56.7 164-162.7 164-284.1 0-181.1-146.9-328-328-328zm127.9 549.8L604 634.6V752H420V634.6l-35.9-20.8C305.4 568.3 256 484.5 256 392c0-141.4 114.6-256 256-256s256 114.6 256 256c0 92.5-49.4 176.3-128.1 221.8z"}}]},name:"bulb",theme:"outlined"};function Gp(){return Gp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Gp.apply(this,arguments)}const i7=(e,t)=>u.createElement(Dt,Gp({},e,{ref:t,icon:a7})),l7=u.forwardRef(i7);var s7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm47.7-395.2l-25.4-5.9V348.6c38 5.2 61.5 29 65.5 58.2.5 4 3.9 6.9 7.9 6.9h44.9c4.7 0 8.4-4.1 8-8.8-6.1-62.3-57.4-102.3-125.9-109.2V263c0-4.4-3.6-8-8-8h-28.1c-4.4 0-8 3.6-8 8v33c-70.8 6.9-126.2 46-126.2 119 0 67.6 49.8 100.2 102.1 112.7l24.7 6.3v142.7c-44.2-5.9-69-29.5-74.1-61.3-.6-3.8-4-6.6-7.9-6.6H363c-4.7 0-8.4 4-8 8.7 4.5 55 46.2 105.6 135.2 112.1V761c0 4.4 3.6 8 8 8h28.4c4.4 0 8-3.6 8-8.1l-.2-31.7c78.3-6.9 134.3-48.8 134.3-124-.1-69.4-44.2-100.4-109-116.4zm-68.6-16.2c-5.6-1.6-10.3-3.1-15-5-33.8-12.2-49.5-31.9-49.5-57.3 0-36.3 27.5-57 64.5-61.7v124zM534.3 677V543.3c3.1.9 5.9 1.6 8.8 2.2 47.3 14.4 63.2 34.4 63.2 65.1 0 39.1-29.4 62.6-72 66.4z"}}]},name:"dollar",theme:"outlined"};function Xp(){return Xp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Xp.apply(this,arguments)}const c7=(e,t)=>u.createElement(Dt,Xp({},e,{ref:t,icon:s7})),u7=u.forwardRef(c7);var f7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.4 800.9c.2-.3.5-.6.7-.9C920.6 722.1 960 621.7 960 512s-39.4-210.1-104.8-288c-.2-.3-.5-.5-.7-.8-1.1-1.3-2.1-2.5-3.2-3.7-.4-.5-.8-.9-1.2-1.4l-4.1-4.7-.1-.1c-1.5-1.7-3.1-3.4-4.6-5.1l-.1-.1c-3.2-3.4-6.4-6.8-9.7-10.1l-.1-.1-4.8-4.8-.3-.3c-1.5-1.5-3-2.9-4.5-4.3-.5-.5-1-1-1.6-1.5-1-1-2-1.9-3-2.8-.3-.3-.7-.6-1-1C736.4 109.2 629.5 64 512 64s-224.4 45.2-304.3 119.2c-.3.3-.7.6-1 1-1 .9-2 1.9-3 2.9-.5.5-1 1-1.6 1.5-1.5 1.4-3 2.9-4.5 4.3l-.3.3-4.8 4.8-.1.1c-3.3 3.3-6.5 6.7-9.7 10.1l-.1.1c-1.6 1.7-3.1 3.4-4.6 5.1l-.1.1c-1.4 1.5-2.8 3.1-4.1 4.7-.4.5-.8.9-1.2 1.4-1.1 1.2-2.1 2.5-3.2 3.7-.2.3-.5.5-.7.8C103.4 301.9 64 402.3 64 512s39.4 210.1 104.8 288c.2.3.5.6.7.9l3.1 3.7c.4.5.8.9 1.2 1.4l4.1 4.7c0 .1.1.1.1.2 1.5 1.7 3 3.4 4.6 5l.1.1c3.2 3.4 6.4 6.8 9.6 10.1l.1.1c1.6 1.6 3.1 3.2 4.7 4.7l.3.3c3.3 3.3 6.7 6.5 10.1 9.6 80.1 74 187 119.2 304.5 119.2s224.4-45.2 304.3-119.2a300 300 0 0010-9.6l.3-.3c1.6-1.6 3.2-3.1 4.7-4.7l.1-.1c3.3-3.3 6.5-6.7 9.6-10.1l.1-.1c1.5-1.7 3.1-3.3 4.6-5 0-.1.1-.1.1-.2 1.4-1.5 2.8-3.1 4.1-4.7.4-.5.8-.9 1.2-1.4a99 99 0 003.3-3.7zm4.1-142.6c-13.8 32.6-32 62.8-54.2 90.2a444.07 444.07 0 00-81.5-55.9c11.6-46.9 18.8-98.4 20.7-152.6H887c-3 40.9-12.6 80.6-28.5 118.3zM887 484H743.5c-1.9-54.2-9.1-105.7-20.7-152.6 29.3-15.6 56.6-34.4 81.5-55.9A373.86 373.86 0 01887 484zM658.3 165.5c39.7 16.8 75.8 40 107.6 69.2a394.72 394.72 0 01-59.4 41.8c-15.7-45-35.8-84.1-59.2-115.4 3.7 1.4 7.4 2.9 11 4.4zm-90.6 700.6c-9.2 7.2-18.4 12.7-27.7 16.4V697a389.1 389.1 0 01115.7 26.2c-8.3 24.6-17.9 47.3-29 67.8-17.4 32.4-37.8 58.3-59 75.1zm59-633.1c11 20.6 20.7 43.3 29 67.8A389.1 389.1 0 01540 327V141.6c9.2 3.7 18.5 9.1 27.7 16.4 21.2 16.7 41.6 42.6 59 75zM540 640.9V540h147.5c-1.6 44.2-7.1 87.1-16.3 127.8l-.3 1.2A445.02 445.02 0 00540 640.9zm0-156.9V383.1c45.8-2.8 89.8-12.5 130.9-28.1l.3 1.2c9.2 40.7 14.7 83.5 16.3 127.8H540zm-56 56v100.9c-45.8 2.8-89.8 12.5-130.9 28.1l-.3-1.2c-9.2-40.7-14.7-83.5-16.3-127.8H484zm-147.5-56c1.6-44.2 7.1-87.1 16.3-127.8l.3-1.2c41.1 15.6 85 25.3 130.9 28.1V484H336.5zM484 697v185.4c-9.2-3.7-18.5-9.1-27.7-16.4-21.2-16.7-41.7-42.7-59.1-75.1-11-20.6-20.7-43.3-29-67.8 37.2-14.6 75.9-23.3 115.8-26.1zm0-370a389.1 389.1 0 01-115.7-26.2c8.3-24.6 17.9-47.3 29-67.8 17.4-32.4 37.8-58.4 59.1-75.1 9.2-7.2 18.4-12.7 27.7-16.4V327zM365.7 165.5c3.7-1.5 7.3-3 11-4.4-23.4 31.3-43.5 70.4-59.2 115.4-21-12-40.9-26-59.4-41.8 31.8-29.2 67.9-52.4 107.6-69.2zM165.5 365.7c13.8-32.6 32-62.8 54.2-90.2 24.9 21.5 52.2 40.3 81.5 55.9-11.6 46.9-18.8 98.4-20.7 152.6H137c3-40.9 12.6-80.6 28.5-118.3zM137 540h143.5c1.9 54.2 9.1 105.7 20.7 152.6a444.07 444.07 0 00-81.5 55.9A373.86 373.86 0 01137 540zm228.7 318.5c-39.7-16.8-75.8-40-107.6-69.2 18.5-15.8 38.4-29.7 59.4-41.8 15.7 45 35.8 84.1 59.2 115.4-3.7-1.4-7.4-2.9-11-4.4zm292.6 0c-3.7 1.5-7.3 3-11 4.4 23.4-31.3 43.5-70.4 59.2-115.4 21 12 40.9 26 59.4 41.8a373.81 373.81 0 01-107.6 69.2z"}}]},name:"global",theme:"outlined"};function Wp(){return Wp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Wp.apply(this,arguments)}const d7=(e,t)=>u.createElement(Dt,Wp({},e,{ref:t,icon:f7})),m7=u.forwardRef(d7);var g7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M847.7 112H176.3c-35.5 0-64.3 28.8-64.3 64.3v671.4c0 35.5 28.8 64.3 64.3 64.3h671.4c35.5 0 64.3-28.8 64.3-64.3V176.3c0-35.5-28.8-64.3-64.3-64.3zm0 736c-447.8-.1-671.7-.2-671.7-.3.1-447.8.2-671.7.3-671.7 447.8.1 671.7.2 671.7.3-.1 447.8-.2 671.7-.3 671.7zM230.6 411.9h118.7v381.8H230.6zm59.4-52.2c37.9 0 68.8-30.8 68.8-68.8a68.8 68.8 0 10-137.6 0c-.1 38 30.7 68.8 68.8 68.8zm252.3 245.1c0-49.8 9.5-98 71.2-98 60.8 0 61.7 56.9 61.7 101.2v185.7h118.6V584.3c0-102.8-22.2-181.9-142.3-181.9-57.7 0-96.4 31.7-112.3 61.7h-1.6v-52.2H423.7v381.8h118.6V604.8z"}}]},name:"linkedin",theme:"outlined"};function Yp(){return Yp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Yp.apply(this,arguments)}const p7=(e,t)=>u.createElement(Dt,Yp({},e,{ref:t,icon:g7})),h7=u.forwardRef(p7);var y7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"}}]},name:"mail",theme:"outlined"};function Kp(){return Kp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Kp.apply(this,arguments)}const b7=(e,t)=>u.createElement(Dt,Kp({},e,{ref:t,icon:y7})),v7=u.forwardRef(b7);var S7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"}}]},name:"menu",theme:"outlined"};function kp(){return kp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},kp.apply(this,arguments)}const C7=(e,t)=>u.createElement(Dt,kp({},e,{ref:t,icon:S7})),x7=u.forwardRef(C7);var E7={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M489.5 111.66c30.65-1.8 45.98 36.44 22.58 56.33A243.35 243.35 0 00426 354c0 134.76 109.24 244 244 244 72.58 0 139.9-31.83 186.01-86.08 19.87-23.38 58.07-8.1 56.34 22.53C900.4 745.82 725.15 912 512.5 912 291.31 912 112 732.69 112 511.5c0-211.39 164.29-386.02 374.2-399.65l.2-.01zm-81.15 79.75l-4.11 1.36C271.1 237.94 176 364.09 176 511.5 176 697.34 326.66 848 512.5 848c148.28 0 274.94-96.2 319.45-230.41l.63-1.93-.11.07a307.06 307.06 0 01-159.73 46.26L670 662c-170.1 0-308-137.9-308-308 0-58.6 16.48-114.54 46.27-162.47z"}}]},name:"moon",theme:"outlined"};function Qp(){return Qp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Qp.apply(this,arguments)}const $7=(e,t)=>u.createElement(Dt,Qp({},e,{ref:t,icon:E7})),w7=u.forwardRef($7);var T7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 254.3c-30.6 13.2-63.9 22.7-98.2 26.4a170.1 170.1 0 0075-94 336.64 336.64 0 01-108.2 41.2A170.1 170.1 0 00672 174c-94.5 0-170.5 76.6-170.5 170.6 0 13.2 1.6 26.4 4.2 39.1-141.5-7.4-267.7-75-351.6-178.5a169.32 169.32 0 00-23.2 86.1c0 59.2 30.1 111.4 76 142.1a172 172 0 01-77.1-21.7v2.1c0 82.9 58.6 151.6 136.7 167.4a180.6 180.6 0 01-44.9 5.8c-11.1 0-21.6-1.1-32.2-2.6C211 652 273.9 701.1 348.8 702.7c-58.6 45.9-132 72.9-211.7 72.9-14.3 0-27.5-.5-41.2-2.1C171.5 822 261.2 850 357.8 850 671.4 850 843 590.2 843 364.7c0-7.4 0-14.8-.5-22.2 33.2-24.3 62.3-54.4 85.5-88.2z"}}]},name:"twitter",theme:"outlined"};function Zp(){return Zp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Zp.apply(this,arguments)}const M7=(e,t)=>u.createElement(Dt,Zp({},e,{ref:t,icon:T7})),gC=u.forwardRef(M7);async function Zh(e){const t=await fetch(e);if(!t.ok){let o=`Request failed with status ${t.status}`;try{const a=await t.json();typeof a.error=="string"&&a.error.length>0&&(o=a.error)}catch{}throw new Error(o)}return t.json()}function R7(){return Zh("/api/bootstrap")}function N7(){return Zh("/api/articles")}function z7(e){return Zh(`/api/articles/${encodeURIComponent(e)}`)}const pC=["article","blog-post","x-thread","x-post","linkedin-post","reddit-post","newsletter"],hC=["shared-brief","planning","sections","image-prompts","images","output","links"];function R$(e){return e.reduce((t,o)=>{const a=o.contentType||"article",l=t[a]??[];return l.push(o),l.sort((c,f)=>c.index-f.index),t[a]=l,t},{})}function N$(e){return[...e].sort((t,o)=>{const a=pC.indexOf(t),l=pC.indexOf(o),c=a===-1?Number.MAX_SAFE_INTEGER:a,f=l===-1?Number.MAX_SAFE_INTEGER:l;return c!==f?c-f:t.localeCompare(o)})}function z$(e){const t=Array.isArray(e?.llmCalls)?e.llmCalls:[],o=Array.isArray(e?.t2iCalls)?e.t2iCalls:[],a=t.map((c,f)=>({id:`llm-${f}`,source:"llm",stageId:String(c.stageId||"unknown"),operationId:String(c.operationId||""),status:String(c.status||""),requestType:String(c.requestType||""),provider:String(c.provider||""),modelId:String(c.modelId||""),durationMs:Number(c.durationMs||0),raw:c})),l=o.map((c,f)=>({id:`t2i-${f}`,source:"t2i",stageId:String(c.stageId||"images"),operationId:String(c.operationId||""),status:String(c.status||""),requestType:"t2i",provider:String(c.provider||""),modelId:String(c.modelId||""),durationMs:Number(c.durationMs||0),raw:c}));return a.concat(l).sort((c,f)=>{const m=new Date(yC(c.raw)).getTime(),h=new Date(yC(f.raw)).getTime();return m!==h?m-h:c.id.localeCompare(f.id)})}function O7(e){const t=e.reduce((o,a)=>{const l=o[a.stageId]??[];return l.push(a),o[a.stageId]=l,o},{});return Object.keys(t).sort((o,a)=>{const l=hC.indexOf(o),c=hC.indexOf(a),f=l===-1?Number.MAX_SAFE_INTEGER:l,m=c===-1?Number.MAX_SAFE_INTEGER:c;return f!==m?f-m:o.localeCompare(a)}).map(o=>({stageId:o,items:t[o]??[]}))}function A7(e){if(e.source==="t2i"){const f=e.raw;return{promptText:String(f.prompt||""),responseText:f.errorMessage?`Error: ${f.errorMessage}`:"Image request completed. Inspect Full JSON for the resolved input payload."}}const t=e.raw,o=bC(t.requestBody),a=bC(t.responseBody),l=Array.isArray(o?.messages)?o.messages.map(f=>`[${String(f.role||"unknown")}]
|
|
214
|
+
`]:{...fx(e),marginInlineStart:e.marginXXS},...A9(e),..._9(e),...B9(),"&-rtl":{direction:"rtl"}}}},L9=()=>({titleMarginTop:"1.2em",titleMarginBottom:"0.5em"}),T$=Xt("Typography",H9,L9),D9=e=>{const{prefixCls:t,"aria-label":o,className:a,style:l,direction:c,maxLength:f,autoSize:m=!0,value:h,onSave:p,onCancel:y,onEnd:b,component:v,enterIcon:$=u.createElement(M9,null)}=e,x=u.useRef(null),E=u.useRef(!1),C=u.useRef(null),[T,M]=u.useState(h);u.useEffect(()=>{M(h)},[h]),u.useEffect(()=>{if(x.current?.resizableTextArea){const{textArea:k}=x.current.resizableTextArea;k.focus();const{length:U}=k.value;k.setSelectionRange(U,U)}},[]);const w=({target:k})=>{M(k.value.replace(/[\n\r]/g,""))},N=()=>{E.current=!0},R=()=>{E.current=!1},_=({keyCode:k})=>{E.current||(C.current=k)},z=()=>{p(T.trim())},B=({keyCode:k,ctrlKey:U,altKey:F,metaKey:P,shiftKey:q})=>{C.current!==k||E.current||U||F||P||q||(k===er.ENTER?(z(),b?.()):k===er.ESC&&y())},H=()=>{z()},[I,L]=T$(t),V=W(t,`${t}-edit-content`,{[`${t}-rtl`]:c==="rtl",[`${t}-${v}`]:!!v},a,I,L);return u.createElement("div",{className:V,style:l},u.createElement(r9,{ref:x,maxLength:f,value:T,onChange:w,onKeyDown:_,onKeyUp:B,onCompositionStart:N,onCompositionEnd:R,onBlur:H,"aria-label":o,rows:1,autoSize:m}),$!==null?pa($,{className:`${t}-edit-content-confirm`}):null)},P9=(e,t)=>{let o=!1;const a=l=>{l.stopPropagation(),l.preventDefault(),l.clipboardData?.clearData(),l.clipboardData?.setData("text/plain",e),t&&l.clipboardData?.setData("text/html",e),o=!0};try{return document.addEventListener("copy",a,{capture:!0}),document.execCommand("copy"),o}catch{return!1}finally{document.removeEventListener("copy",a,{capture:!0})}},I9=async(e,t)=>{try{return t?await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([e],{type:"text/html"}),"text/plain":new Blob([e],{type:"text/plain"})})]):await navigator.clipboard.writeText(e),!0}catch{return!1}};async function j9(e,t){if(typeof e!="string")return!1;const o=t?.format==="text/html";return!!(await I9(e,o)||P9(e,o))}const V9=({copyConfig:e,children:t})=>{const[o,a]=u.useState(!1),[l,c]=u.useState(!1),f=u.useRef(null),m=()=>{f.current&&clearTimeout(f.current)},h={};e.format&&(h.format=e.format),u.useEffect(()=>m,[]);const p=Tt(async y=>{y?.preventDefault(),y?.stopPropagation(),c(!0);try{const b=typeof e.text=="function"?await e.text():e.text;await j9(b||E$(t,{skipEmpty:!0}).join("")||"",h),c(!1),a(!0),m(),f.current=setTimeout(()=>{a(!1)},3e3),e.onCopy?.(y)}catch(b){throw c(!1),b}});return{copied:o,copyLoading:l,onClick:p}};function tg(e,t){return u.useMemo(()=>{const o=!!e;return[o,{...t,...o&&typeof e=="object"?e:null}]},[e])}const F9=e=>{const t=u.useRef(void 0);return u.useEffect(()=>{t.current=e}),t.current},q9=(e,t,o)=>u.useMemo(()=>e===!0?{title:t??o}:u.isValidElement(e)?{title:e}:typeof e=="object"?{title:t??o,...e}:{title:e},[e,t,o]),M$=u.forwardRef((e,t)=>{const{prefixCls:o,component:a="article",className:l,rootClassName:c,children:f,direction:m,style:h,...p}=e,{getPrefixCls:y,direction:b,className:v,style:$}=cn("typography"),x=m??b,E=y("typography",o),[C,T]=T$(E),M=W(E,v,{[`${E}-rtl`]:x==="rtl"},l,c,C,T),w={...$,...h};return u.createElement(a,{className:M,style:w,ref:t,...p},f)});var U9={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"}}]},name:"copy",theme:"outlined"};function Up(){return Up=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Up.apply(this,arguments)}const G9=(e,t)=>u.createElement(Dt,Up({},e,{ref:t,icon:U9})),X9=u.forwardRef(G9),uC=e=>e===!1?[!1,!1]:E$(e);function ng(e,t,o){return e===!0||e===void 0?t:e||o&&t}function W9(e){const t=document.createElement("em");e.appendChild(t);const o=e.getBoundingClientRect(),a=t.getBoundingClientRect();return e.removeChild(t),o.left>a.left||a.right>o.right||o.top>a.top||a.bottom>o.bottom}const Qh=e=>["string","number"].includes(typeof e),Y9=e=>{const{prefixCls:t,copied:o,locale:a,iconOnly:l,tooltips:c,icon:f,tabIndex:m,onCopy:h,loading:p}=e,y=uC(c),b=uC(f),{copied:v,copy:$}=a??{},x=o?v:$,E=ng(y[o?1:0],x),C=typeof E=="string"?E:x;return u.createElement(dl,{title:E},u.createElement("button",{type:"button",className:W(`${t}-copy`,{[`${t}-copy-success`]:o,[`${t}-copy-icon-only`]:l}),onClick:h,"aria-label":C,tabIndex:m},o?ng(b[1],u.createElement(bz,null),!0):ng(b[0],p?u.createElement(Th,null):u.createElement(X9,null),!0)))},bu=u.forwardRef(({style:e,children:t},o)=>{const a=u.useRef(null);return u.useImperativeHandle(o,()=>({isExceed:()=>{const l=a.current;return l.scrollHeight>l.clientHeight},getHeight:()=>a.current.clientHeight})),u.createElement("span",{"aria-hidden":!0,ref:a,style:{position:"fixed",display:"block",left:0,top:0,pointerEvents:"none",backgroundColor:"rgba(255, 0, 0, 0.65)",...e}},t)}),K9=e=>e.reduce((t,o)=>t+(Qh(o)?String(o).length:1),0);function fC(e,t){let o=0;const a=[];for(let l=0;l<e.length;l+=1){if(o===t)return a;const c=e[l],m=Qh(c)?String(c).length:1,h=o+m;if(h>t){const p=t-o;return a.push(String(c).slice(0,p)),a}a.push(c),o=h}return e}const rg=0,og=1,ag=2,ig=3,dC=4,vu={display:"-webkit-box",overflow:"hidden",WebkitBoxOrient:"vertical"};function k9(e){const{enableMeasure:t,width:o,text:a,children:l,rows:c,expanded:f,miscDeps:m,onEllipsis:h}=e,p=u.useMemo(()=>br(a),[a]),y=u.useMemo(()=>K9(p),[a]),b=u.useMemo(()=>l(p,!1),[a]),[v,$]=u.useState(null),x=u.useRef(null),E=u.useRef(null),C=u.useRef(null),T=u.useRef(null),M=u.useRef(null),[w,N]=u.useState(!1),[R,_]=u.useState(rg),[z,B]=u.useState(0),[H,I]=u.useState(null);Lt(()=>{_(t&&o&&y?og:rg)},[o,a,c,t,p]),Lt(()=>{if(R===og){_(ag);const U=E.current&&getComputedStyle(E.current).whiteSpace;I(U)}else if(R===ag){const U=!!C.current?.isExceed();_(U?ig:dC),$(U?[0,y]:null),N(U);const F=C.current?.getHeight()||0,P=c===1?0:T.current?.getHeight()||0,q=M.current?.getHeight()||0,G=Math.max(F,P+q);B(G+1),h(U)}},[R]);const L=v?Math.ceil((v[0]+v[1])/2):0;Lt(()=>{const[U,F]=v||[0,0];if(U!==F){const q=(x.current?.getHeight()||0)>z;let G=L;F-U===1&&(G=q?U:F),$(q?[U,G]:[G,F])}},[v,L]);const V=u.useMemo(()=>{if(!t)return l(p,!1);if(R!==ig||!v||v[0]!==v[1]){const U=l(p,!1);return[dC,rg].includes(R)?U:u.createElement("span",{style:{...vu,WebkitLineClamp:c}},U)}return l(f?p:fC(p,v[0]),w)},[f,R,v,p].concat(sn(m))),k={width:o,margin:0,padding:0,whiteSpace:H==="nowrap"?"normal":"inherit"};return u.createElement(u.Fragment,null,V,R===ag&&u.createElement(u.Fragment,null,u.createElement(bu,{style:{...k,...vu,WebkitLineClamp:c},ref:C},b),u.createElement(bu,{style:{...k,...vu,WebkitLineClamp:c-1},ref:T},b),u.createElement(bu,{style:{...k,...vu,WebkitLineClamp:1},ref:M},l([],!0))),R===ig&&v&&v[0]!==v[1]&&u.createElement(bu,{style:{...k,top:400},ref:x},l(fC(p,L),!0)),R===og&&u.createElement("span",{style:{whiteSpace:"inherit"},ref:E}))}const Q9=({enableEllipsis:e,isEllipsis:t,open:o,children:a,tooltipProps:l})=>{if(!l?.title||!e)return a;const c=o&&t;return u.createElement(dl,{open:c,...l},a)};function Z9({mark:e,code:t,underline:o,delete:a,strong:l,keyboard:c,italic:f},m){let h=m;function p(y,b){b&&(h=u.createElement(y,{},h))}return p("strong",l),p("u",o),p("del",a),p("code",t),p("mark",e),p("kbd",c),p("i",f),h}const J9="...",mC=["delete","mark","code","underline","strong","keyboard","italic"],ff=u.forwardRef((e,t)=>{const{prefixCls:o,className:a,style:l,type:c,disabled:f,children:m,ellipsis:h,editable:p,copyable:y,component:b,title:v,onMouseEnter:$,onMouseLeave:x,...E}=e,{getPrefixCls:C,direction:T}=u.useContext(ut),[M]=ba("Text"),w=u.useRef(null),N=u.useRef(null),R=C("typography",o),_=Lr(E,mC),[z,B]=tg(p),[H,I]=yr(!1,B.editing),{triggerType:L=["icon"]}=B,V=je=>{je&&B.onStart?.(),I(je)},k=F9(H);Lt(()=>{!H&&k&&N.current?.focus()},[H]);const U=je=>{je?.preventDefault(),V(!0)},F=je=>{B.onChange?.(je),V(!1)},P=()=>{B.onCancel?.(),V(!1)},[q,G]=tg(y),{copied:Y,copyLoading:Z,onClick:A}=V9({copyConfig:G,children:m}),[D,K]=u.useState(!1),[Q,ee]=u.useState(!1),[ie,le]=u.useState(!1),[de,ye]=u.useState(!1),[ve,we]=u.useState(!0),[be,Se]=tg(h,{expandable:!1,symbol:je=>je?M?.collapse:M?.expand}),[me,he]=yr(Se.defaultExpanded||!1,Se.expanded),pe=be&&(!me||Se.expandable==="collapsible"),{rows:Pe=1}=Se,Le=u.useMemo(()=>pe&&(Se.suffix!==void 0||Se.onEllipsis||Se.expandable||z||q),[pe,Se,z,q]);Lt(()=>{be&&!Le&&(K(CS("webkitLineClamp")),ee(CS("textOverflow")))},[Le,be]);const[Ee,Xe]=u.useState(pe),Oe=u.useMemo(()=>Le?!1:Pe===1?Q:D,[Le,Q,D]);Lt(()=>{Xe(Oe&&pe)},[Oe,pe]);const Re=pe&&(Ee?de:ie),De=pe&&Pe===1&&Ee,Te=pe&&Pe>1&&Ee,et=(je,Fe)=>{he(Fe.expanded),Se.onExpand?.(je,Fe)},[it,ft]=u.useState(0),[Ue,dt]=u.useState(!1),[Me,xe]=u.useState(!1),Ae=({offsetWidth:je})=>{ft(je)},Ye=je=>{le(je),ie!==je&&Se.onEllipsis?.(je)};u.useEffect(()=>{const je=w.current;if(be&&Ee&&je){const Fe=W9(je);de!==Fe&&ye(Fe)}},[be,Ee,m,Te,ve,it]),u.useEffect(()=>{const je=w.current;if(typeof IntersectionObserver>"u"||!je||!Ee||!pe)return;const Fe=new IntersectionObserver(()=>{we(!!je.offsetParent)});return Fe.observe(je),()=>{Fe.disconnect()}},[Ee,pe]);const _e=q9(Se.tooltip,B.text,m),Ce=u.useMemo(()=>{if(!(!be||Ee))return[B.text,m,v,_e.title].find(Qh)},[be,Ee,v,_e.title,Re]);if(H)return u.createElement(D9,{value:B.text??(typeof m=="string"?m:""),onSave:F,onCancel:P,onEnd:B.onEnd,prefixCls:R,className:a,style:l,direction:T,component:b,maxLength:B.maxLength,autoSize:B.autoSize,enterIcon:B.enterIcon});const Ie=()=>{const{expandable:je,symbol:Fe}=Se;return je?u.createElement("button",{type:"button",key:"expand",className:`${R}-${me?"collapse":"expand"}`,onClick:ot=>et(ot,{expanded:!me}),"aria-label":me?M.collapse:M?.expand},typeof Fe=="function"?Fe(me):Fe):null},mt=()=>{if(!z)return;const{icon:je,tooltip:Fe,tabIndex:ot}=B,Pt=br(Fe)[0]||M?.edit,Wt=typeof Pt=="string"?Pt:"";return L.includes("icon")?u.createElement(dl,{key:"edit",title:Fe===!1?"":Pt},u.createElement("button",{type:"button",ref:N,className:`${R}-edit`,onClick:U,"aria-label":Wt,tabIndex:ot},je||u.createElement($9,{role:"button"}))):null},ke=()=>q?u.createElement(Y9,{key:"copy",...G,prefixCls:R,copied:Y,locale:M,onCopy:A,loading:Z,iconOnly:!vr(m)}):null,Ut=je=>{const Fe=je&&Ie(),ot=mt(),Pt=ke();return!Fe&&!ot&&!Pt?null:u.createElement("span",{key:"operations",className:`${R}-actions`,onMouseEnter:()=>dt(!0),onMouseLeave:()=>dt(!1)},Fe,ot,Pt)},bt=je=>[je&&!me&&u.createElement("span",{"aria-hidden":!0,key:"ellipsis"},J9),Se.suffix,Ut(je)];return u.createElement(wo,{onResize:Ae,disabled:!pe},je=>u.createElement(Q9,{tooltipProps:_e,enableEllipsis:pe,isEllipsis:Re,open:Me&&!Ue},u.createElement(M$,{onMouseEnter:Fe=>{xe(!0),$?.(Fe)},onMouseLeave:Fe=>{xe(!1),x?.(Fe)},className:W({[`${R}-${c}`]:c,[`${R}-disabled`]:f,[`${R}-ellipsis`]:be,[`${R}-ellipsis-single-line`]:De,[`${R}-ellipsis-multiple-line`]:Te,[`${R}-link`]:b==="a"},a),prefixCls:o,style:{...l,WebkitLineClamp:Te?Pe:void 0},component:b,ref:Hr(je,w,t),direction:T,onClick:L.includes("text")?U:void 0,"aria-label":Ce?.toString(),title:v,..._},u.createElement(k9,{enableMeasure:pe&&!Ee,text:m,rows:Pe,width:it,onEllipsis:Ye,expanded:me,miscDeps:[Y,me,Z,z,q,M].concat(sn(mC.map(Fe=>e[Fe])))},(Fe,ot)=>Z9(e,u.createElement(u.Fragment,null,Fe.length>0&&ot&&!me&&Ce?u.createElement("span",{key:"show-content","aria-hidden":!0},Fe):Fe,bt(ot)))))))}),e7=u.forwardRef((e,t)=>{const{ellipsis:o,rel:a,children:l,navigate:c,...f}=e,m={...f,rel:a===void 0&&f.target==="_blank"?"noopener noreferrer":a};return u.createElement(ff,{...m,ref:t,ellipsis:!!o,component:"a"},l)}),t7=u.forwardRef((e,t)=>{const{children:o,...a}=e;return u.createElement(ff,{ref:t,...a,component:"div"},o)}),n7=u.forwardRef((e,t)=>{const{ellipsis:o,children:a,...l}=e,c=u.useMemo(()=>o&&typeof o=="object"?Lr(o,["expandable","rows"]):o,[o]);return u.createElement(ff,{ref:t,...l,ellipsis:c,component:"span"},a)}),r7=[1,2,3,4,5],o7=u.forwardRef((e,t)=>{const{level:o=1,children:a,...l}=e,c=r7.includes(o)?`h${o}`:"h1";return u.createElement(ff,{ref:t,...l,component:c},a)}),Sn=M$;Sn.Text=n7;Sn.Link=e7;Sn.Title=o7;Sn.Paragraph=t7;var a7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M632 888H392c-4.4 0-8 3.6-8 8v32c0 17.7 14.3 32 32 32h192c17.7 0 32-14.3 32-32v-32c0-4.4-3.6-8-8-8zM512 64c-181.1 0-328 146.9-328 328 0 121.4 66 227.4 164 284.1V792c0 17.7 14.3 32 32 32h264c17.7 0 32-14.3 32-32V676.1c98-56.7 164-162.7 164-284.1 0-181.1-146.9-328-328-328zm127.9 549.8L604 634.6V752H420V634.6l-35.9-20.8C305.4 568.3 256 484.5 256 392c0-141.4 114.6-256 256-256s256 114.6 256 256c0 92.5-49.4 176.3-128.1 221.8z"}}]},name:"bulb",theme:"outlined"};function Gp(){return Gp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Gp.apply(this,arguments)}const i7=(e,t)=>u.createElement(Dt,Gp({},e,{ref:t,icon:a7})),l7=u.forwardRef(i7);var s7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm47.7-395.2l-25.4-5.9V348.6c38 5.2 61.5 29 65.5 58.2.5 4 3.9 6.9 7.9 6.9h44.9c4.7 0 8.4-4.1 8-8.8-6.1-62.3-57.4-102.3-125.9-109.2V263c0-4.4-3.6-8-8-8h-28.1c-4.4 0-8 3.6-8 8v33c-70.8 6.9-126.2 46-126.2 119 0 67.6 49.8 100.2 102.1 112.7l24.7 6.3v142.7c-44.2-5.9-69-29.5-74.1-61.3-.6-3.8-4-6.6-7.9-6.6H363c-4.7 0-8.4 4-8 8.7 4.5 55 46.2 105.6 135.2 112.1V761c0 4.4 3.6 8 8 8h28.4c4.4 0 8-3.6 8-8.1l-.2-31.7c78.3-6.9 134.3-48.8 134.3-124-.1-69.4-44.2-100.4-109-116.4zm-68.6-16.2c-5.6-1.6-10.3-3.1-15-5-33.8-12.2-49.5-31.9-49.5-57.3 0-36.3 27.5-57 64.5-61.7v124zM534.3 677V543.3c3.1.9 5.9 1.6 8.8 2.2 47.3 14.4 63.2 34.4 63.2 65.1 0 39.1-29.4 62.6-72 66.4z"}}]},name:"dollar",theme:"outlined"};function Xp(){return Xp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Xp.apply(this,arguments)}const c7=(e,t)=>u.createElement(Dt,Xp({},e,{ref:t,icon:s7})),u7=u.forwardRef(c7);var f7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.4 800.9c.2-.3.5-.6.7-.9C920.6 722.1 960 621.7 960 512s-39.4-210.1-104.8-288c-.2-.3-.5-.5-.7-.8-1.1-1.3-2.1-2.5-3.2-3.7-.4-.5-.8-.9-1.2-1.4l-4.1-4.7-.1-.1c-1.5-1.7-3.1-3.4-4.6-5.1l-.1-.1c-3.2-3.4-6.4-6.8-9.7-10.1l-.1-.1-4.8-4.8-.3-.3c-1.5-1.5-3-2.9-4.5-4.3-.5-.5-1-1-1.6-1.5-1-1-2-1.9-3-2.8-.3-.3-.7-.6-1-1C736.4 109.2 629.5 64 512 64s-224.4 45.2-304.3 119.2c-.3.3-.7.6-1 1-1 .9-2 1.9-3 2.9-.5.5-1 1-1.6 1.5-1.5 1.4-3 2.9-4.5 4.3l-.3.3-4.8 4.8-.1.1c-3.3 3.3-6.5 6.7-9.7 10.1l-.1.1c-1.6 1.7-3.1 3.4-4.6 5.1l-.1.1c-1.4 1.5-2.8 3.1-4.1 4.7-.4.5-.8.9-1.2 1.4-1.1 1.2-2.1 2.5-3.2 3.7-.2.3-.5.5-.7.8C103.4 301.9 64 402.3 64 512s39.4 210.1 104.8 288c.2.3.5.6.7.9l3.1 3.7c.4.5.8.9 1.2 1.4l4.1 4.7c0 .1.1.1.1.2 1.5 1.7 3 3.4 4.6 5l.1.1c3.2 3.4 6.4 6.8 9.6 10.1l.1.1c1.6 1.6 3.1 3.2 4.7 4.7l.3.3c3.3 3.3 6.7 6.5 10.1 9.6 80.1 74 187 119.2 304.5 119.2s224.4-45.2 304.3-119.2a300 300 0 0010-9.6l.3-.3c1.6-1.6 3.2-3.1 4.7-4.7l.1-.1c3.3-3.3 6.5-6.7 9.6-10.1l.1-.1c1.5-1.7 3.1-3.3 4.6-5 0-.1.1-.1.1-.2 1.4-1.5 2.8-3.1 4.1-4.7.4-.5.8-.9 1.2-1.4a99 99 0 003.3-3.7zm4.1-142.6c-13.8 32.6-32 62.8-54.2 90.2a444.07 444.07 0 00-81.5-55.9c11.6-46.9 18.8-98.4 20.7-152.6H887c-3 40.9-12.6 80.6-28.5 118.3zM887 484H743.5c-1.9-54.2-9.1-105.7-20.7-152.6 29.3-15.6 56.6-34.4 81.5-55.9A373.86 373.86 0 01887 484zM658.3 165.5c39.7 16.8 75.8 40 107.6 69.2a394.72 394.72 0 01-59.4 41.8c-15.7-45-35.8-84.1-59.2-115.4 3.7 1.4 7.4 2.9 11 4.4zm-90.6 700.6c-9.2 7.2-18.4 12.7-27.7 16.4V697a389.1 389.1 0 01115.7 26.2c-8.3 24.6-17.9 47.3-29 67.8-17.4 32.4-37.8 58.3-59 75.1zm59-633.1c11 20.6 20.7 43.3 29 67.8A389.1 389.1 0 01540 327V141.6c9.2 3.7 18.5 9.1 27.7 16.4 21.2 16.7 41.6 42.6 59 75zM540 640.9V540h147.5c-1.6 44.2-7.1 87.1-16.3 127.8l-.3 1.2A445.02 445.02 0 00540 640.9zm0-156.9V383.1c45.8-2.8 89.8-12.5 130.9-28.1l.3 1.2c9.2 40.7 14.7 83.5 16.3 127.8H540zm-56 56v100.9c-45.8 2.8-89.8 12.5-130.9 28.1l-.3-1.2c-9.2-40.7-14.7-83.5-16.3-127.8H484zm-147.5-56c1.6-44.2 7.1-87.1 16.3-127.8l.3-1.2c41.1 15.6 85 25.3 130.9 28.1V484H336.5zM484 697v185.4c-9.2-3.7-18.5-9.1-27.7-16.4-21.2-16.7-41.7-42.7-59.1-75.1-11-20.6-20.7-43.3-29-67.8 37.2-14.6 75.9-23.3 115.8-26.1zm0-370a389.1 389.1 0 01-115.7-26.2c8.3-24.6 17.9-47.3 29-67.8 17.4-32.4 37.8-58.4 59.1-75.1 9.2-7.2 18.4-12.7 27.7-16.4V327zM365.7 165.5c3.7-1.5 7.3-3 11-4.4-23.4 31.3-43.5 70.4-59.2 115.4-21-12-40.9-26-59.4-41.8 31.8-29.2 67.9-52.4 107.6-69.2zM165.5 365.7c13.8-32.6 32-62.8 54.2-90.2 24.9 21.5 52.2 40.3 81.5 55.9-11.6 46.9-18.8 98.4-20.7 152.6H137c3-40.9 12.6-80.6 28.5-118.3zM137 540h143.5c1.9 54.2 9.1 105.7 20.7 152.6a444.07 444.07 0 00-81.5 55.9A373.86 373.86 0 01137 540zm228.7 318.5c-39.7-16.8-75.8-40-107.6-69.2 18.5-15.8 38.4-29.7 59.4-41.8 15.7 45 35.8 84.1 59.2 115.4-3.7-1.4-7.4-2.9-11-4.4zm292.6 0c-3.7 1.5-7.3 3-11 4.4 23.4-31.3 43.5-70.4 59.2-115.4 21 12 40.9 26 59.4 41.8a373.81 373.81 0 01-107.6 69.2z"}}]},name:"global",theme:"outlined"};function Wp(){return Wp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Wp.apply(this,arguments)}const d7=(e,t)=>u.createElement(Dt,Wp({},e,{ref:t,icon:f7})),m7=u.forwardRef(d7);var g7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M847.7 112H176.3c-35.5 0-64.3 28.8-64.3 64.3v671.4c0 35.5 28.8 64.3 64.3 64.3h671.4c35.5 0 64.3-28.8 64.3-64.3V176.3c0-35.5-28.8-64.3-64.3-64.3zm0 736c-447.8-.1-671.7-.2-671.7-.3.1-447.8.2-671.7.3-671.7 447.8.1 671.7.2 671.7.3-.1 447.8-.2 671.7-.3 671.7zM230.6 411.9h118.7v381.8H230.6zm59.4-52.2c37.9 0 68.8-30.8 68.8-68.8a68.8 68.8 0 10-137.6 0c-.1 38 30.7 68.8 68.8 68.8zm252.3 245.1c0-49.8 9.5-98 71.2-98 60.8 0 61.7 56.9 61.7 101.2v185.7h118.6V584.3c0-102.8-22.2-181.9-142.3-181.9-57.7 0-96.4 31.7-112.3 61.7h-1.6v-52.2H423.7v381.8h118.6V604.8z"}}]},name:"linkedin",theme:"outlined"};function Yp(){return Yp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Yp.apply(this,arguments)}const p7=(e,t)=>u.createElement(Dt,Yp({},e,{ref:t,icon:g7})),h7=u.forwardRef(p7);var y7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"}}]},name:"mail",theme:"outlined"};function Kp(){return Kp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Kp.apply(this,arguments)}const b7=(e,t)=>u.createElement(Dt,Kp({},e,{ref:t,icon:y7})),v7=u.forwardRef(b7);var S7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z"}}]},name:"menu",theme:"outlined"};function kp(){return kp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},kp.apply(this,arguments)}const C7=(e,t)=>u.createElement(Dt,kp({},e,{ref:t,icon:S7})),x7=u.forwardRef(C7);var E7={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M489.5 111.66c30.65-1.8 45.98 36.44 22.58 56.33A243.35 243.35 0 00426 354c0 134.76 109.24 244 244 244 72.58 0 139.9-31.83 186.01-86.08 19.87-23.38 58.07-8.1 56.34 22.53C900.4 745.82 725.15 912 512.5 912 291.31 912 112 732.69 112 511.5c0-211.39 164.29-386.02 374.2-399.65l.2-.01zm-81.15 79.75l-4.11 1.36C271.1 237.94 176 364.09 176 511.5 176 697.34 326.66 848 512.5 848c148.28 0 274.94-96.2 319.45-230.41l.63-1.93-.11.07a307.06 307.06 0 01-159.73 46.26L670 662c-170.1 0-308-137.9-308-308 0-58.6 16.48-114.54 46.27-162.47z"}}]},name:"moon",theme:"outlined"};function Qp(){return Qp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Qp.apply(this,arguments)}const $7=(e,t)=>u.createElement(Dt,Qp({},e,{ref:t,icon:E7})),w7=u.forwardRef($7);var T7={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 254.3c-30.6 13.2-63.9 22.7-98.2 26.4a170.1 170.1 0 0075-94 336.64 336.64 0 01-108.2 41.2A170.1 170.1 0 00672 174c-94.5 0-170.5 76.6-170.5 170.6 0 13.2 1.6 26.4 4.2 39.1-141.5-7.4-267.7-75-351.6-178.5a169.32 169.32 0 00-23.2 86.1c0 59.2 30.1 111.4 76 142.1a172 172 0 01-77.1-21.7v2.1c0 82.9 58.6 151.6 136.7 167.4a180.6 180.6 0 01-44.9 5.8c-11.1 0-21.6-1.1-32.2-2.6C211 652 273.9 701.1 348.8 702.7c-58.6 45.9-132 72.9-211.7 72.9-14.3 0-27.5-.5-41.2-2.1C171.5 822 261.2 850 357.8 850 671.4 850 843 590.2 843 364.7c0-7.4 0-14.8-.5-22.2 33.2-24.3 62.3-54.4 85.5-88.2z"}}]},name:"twitter",theme:"outlined"};function Zp(){return Zp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var o=arguments[t];for(var a in o)Object.prototype.hasOwnProperty.call(o,a)&&(e[a]=o[a])}return e},Zp.apply(this,arguments)}const M7=(e,t)=>u.createElement(Dt,Zp({},e,{ref:t,icon:T7})),gC=u.forwardRef(M7);async function Zh(e){const t=await fetch(e);if(!t.ok){let o=`Request failed with status ${t.status}`;try{const a=await t.json();typeof a.error=="string"&&a.error.length>0&&(o=a.error)}catch{}throw new Error(o)}return t.json()}function R7(){return Zh("/api/bootstrap")}function N7(){return Zh("/api/articles")}function z7(e){return Zh(`/api/articles/${encodeURIComponent(e)}`)}const pC=["article","blog-post","x-thread","x-post","linkedin-post","reddit-post","newsletter"],hC=["shared-plan","planning","sections","image-prompts","images","output","links"];function R$(e){return e.reduce((t,o)=>{const a=o.contentType||"article",l=t[a]??[];return l.push(o),l.sort((c,f)=>c.index-f.index),t[a]=l,t},{})}function N$(e){return[...e].sort((t,o)=>{const a=pC.indexOf(t),l=pC.indexOf(o),c=a===-1?Number.MAX_SAFE_INTEGER:a,f=l===-1?Number.MAX_SAFE_INTEGER:l;return c!==f?c-f:t.localeCompare(o)})}function z$(e){const t=Array.isArray(e?.llmCalls)?e.llmCalls:[],o=Array.isArray(e?.t2iCalls)?e.t2iCalls:[],a=t.map((c,f)=>({id:`llm-${f}`,source:"llm",stageId:String(c.stageId||"unknown"),operationId:String(c.operationId||""),status:String(c.status||""),requestType:String(c.requestType||""),provider:String(c.provider||""),modelId:String(c.modelId||""),durationMs:Number(c.durationMs||0),raw:c})),l=o.map((c,f)=>({id:`t2i-${f}`,source:"t2i",stageId:String(c.stageId||"images"),operationId:String(c.operationId||""),status:String(c.status||""),requestType:"t2i",provider:String(c.provider||""),modelId:String(c.modelId||""),durationMs:Number(c.durationMs||0),raw:c}));return a.concat(l).sort((c,f)=>{const m=new Date(yC(c.raw)).getTime(),h=new Date(yC(f.raw)).getTime();return m!==h?m-h:c.id.localeCompare(f.id)})}function O7(e){const t=e.reduce((o,a)=>{const l=o[a.stageId]??[];return l.push(a),o[a.stageId]=l,o},{});return Object.keys(t).sort((o,a)=>{const l=hC.indexOf(o),c=hC.indexOf(a),f=l===-1?Number.MAX_SAFE_INTEGER:l,m=c===-1?Number.MAX_SAFE_INTEGER:c;return f!==m?f-m:o.localeCompare(a)}).map(o=>({stageId:o,items:t[o]??[]}))}function A7(e){if(e.source==="t2i"){const f=e.raw;return{promptText:String(f.prompt||""),responseText:f.errorMessage?`Error: ${f.errorMessage}`:"Image request completed. Inspect Full JSON for the resolved input payload."}}const t=e.raw,o=bC(t.requestBody),a=bC(t.responseBody),l=Array.isArray(o?.messages)?o.messages.map(f=>`[${String(f.role||"unknown")}]
|
|
215
215
|
${String(f.content||"")}`).join(`
|
|
216
216
|
|
|
217
217
|
---
|
package/dist/preview/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="./app-assets/favicon-ZM13UXfJ.svg" />
|
|
7
7
|
<title>Ideon Preview</title>
|
|
8
|
-
<script type="module" crossorigin src="./app-assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./app-assets/index-C9aRaijU.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="./app-assets/index-IigmpN5C.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|