@telepat/ideon 0.1.20 → 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.20",
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 brief, and adapt structure per channel without duplicating article-only scaffolding.`;
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 buildContentBriefGuideInstruction(intent, primaryContentType, secondaryContentTypes) {
2015
+ function buildContentPlanGuideInstruction(intent, primaryContentType, secondaryContentTypes) {
2016
2016
  return buildGuideBundle([
2017
- "writing-guide/references/multi-channel-brief-strategy.md",
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/contentBrief.ts
2038
- var contentBriefSchema = {
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 buildContentBriefMessages(idea, options) {
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 brief that can guide all requested content types in this run.",
2078
- buildContentBriefGuideInstruction(options.intent, options.primaryContentType, options.secondaryContentTypes),
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 brief must be specific, concrete, and directly usable by writers without extra clarification.",
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 brief from this idea:",
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/contentBriefSchema.ts
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 contentBriefSchema2 = z4.object({
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((brief, ctx) => {
2137
- const hasSecondaryTargets = brief.secondaryContentTypes.length > 0;
2136
+ }).superRefine((plan, ctx) => {
2137
+ const hasSecondaryTargets = plan.secondaryContentTypes.length > 0;
2138
2138
  if (!hasSecondaryTargets) {
2139
2139
  return;
2140
2140
  }
2141
- if (brief.secondaryContentStrategy.trim().length < 20) {
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/planContentBrief.ts
2155
- var SHARED_BRIEF_MAX_TOKENS = 8e3;
2156
- async function planContentBrief({
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 buildDryRunContentBrief(idea, targetAudienceHint);
2166
+ return buildDryRunContentPlan(idea, targetAudienceHint);
2167
2167
  }
2168
- const sharedBriefSettings = {
2168
+ const sharedPlanSettings = {
2169
2169
  ...settings,
2170
2170
  modelSettings: {
2171
2171
  ...settings.modelSettings,
2172
- maxTokens: Math.max(settings.modelSettings.maxTokens, SHARED_BRIEF_MAX_TOKENS)
2172
+ maxTokens: Math.max(settings.modelSettings.maxTokens, SHARED_PLAN_MAX_TOKENS)
2173
2173
  }
2174
2174
  };
2175
2175
  return await openRouter.requestStructured({
2176
- schemaName: "content_brief",
2177
- schema: contentBriefSchema,
2178
- messages: buildContentBriefMessages(idea, {
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: sharedBriefSettings,
2184
+ settings: sharedPlanSettings,
2185
2185
  interactionContext: {
2186
- stageId: "shared-brief",
2187
- operationId: "shared-brief:content-brief"
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 contentBriefSchema2.parse(data);
2192
+ return contentPlanSchema2.parse(data);
2193
2193
  }
2194
2194
  });
2195
2195
  }
2196
- function buildDryRunContentBrief(idea, targetAudienceHint) {
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 Brief";
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
  }
@@ -2318,7 +2318,7 @@ function buildArticlePlanMessages(idea, options) {
2318
2318
  "- The article should feel authoritative, practical, and clearly structured for scanning and deep reading.",
2319
2319
  "- Generate a memorable title and a sharp subtitle that promise a concrete benefit, mechanism, or outcome.",
2320
2320
  "- The slug must be lowercase kebab-case and publication-ready.",
2321
- "- The description should work as a concise meta description and align with the shared content brief.",
2321
+ "- The description should work as a concise meta description and align with the shared content plan.",
2322
2322
  `- Plan ${sectionCounts.label} strong sections with distinct focus areas and logical progression (no repetitive section intent).`,
2323
2323
  "- Frame section titles to reflect likely search intent or practical reader questions when appropriate.",
2324
2324
  "- Each section description should name the mechanism, evidence type, or practical action that makes the section useful.",
@@ -2328,12 +2328,12 @@ function buildArticlePlanMessages(idea, options) {
2328
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.",
2329
2329
  "- Image descriptions must be concrete and contextual, not generic stock-photo phrasing.",
2330
2330
  "",
2331
- "Shared content brief context:",
2332
- `- description: ${options.contentBrief.description}`,
2333
- `- targetAudience: ${options.contentBrief.targetAudience}`,
2334
- `- corePromise: ${options.contentBrief.corePromise}`,
2335
- `- keyPoints: ${options.contentBrief.keyPoints.join(" | ")}`,
2336
- `- voiceNotes: ${options.contentBrief.voiceNotes}`,
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}`,
2337
2337
  "",
2338
2338
  "Return JSON with all required fields:",
2339
2339
  "- title: string",
@@ -2382,7 +2382,7 @@ var imagePromptResultSchema = z5.object({
2382
2382
  // src/generation/planArticle.ts
2383
2383
  async function planArticle({
2384
2384
  idea,
2385
- contentBrief,
2385
+ contentPlan,
2386
2386
  settings,
2387
2387
  markdownOutputDir,
2388
2388
  openRouter,
@@ -2390,13 +2390,13 @@ async function planArticle({
2390
2390
  onLlmMetrics,
2391
2391
  onInteraction
2392
2392
  }) {
2393
- const basePlan = dryRun || !openRouter ? buildDryRunPlan(idea, contentBrief) : await openRouter.requestStructured({
2393
+ const basePlan = dryRun || !openRouter ? buildDryRunPlan(idea, contentPlan) : await openRouter.requestStructured({
2394
2394
  schemaName: "article_plan",
2395
2395
  schema: buildArticlePlanJsonSchema(settings.targetLength),
2396
2396
  messages: buildArticlePlanMessages(idea, {
2397
2397
  intent: settings.intent,
2398
2398
  contentTypes: settings.contentTargets.map((target) => target.contentType),
2399
- contentBrief,
2399
+ contentPlan,
2400
2400
  targetLength: settings.targetLength
2401
2401
  }),
2402
2402
  settings,
@@ -2423,14 +2423,14 @@ async function planArticle({
2423
2423
  }))
2424
2424
  };
2425
2425
  }
2426
- function buildDryRunPlan(idea, contentBrief) {
2426
+ function buildDryRunPlan(idea, contentPlan) {
2427
2427
  const title = idea.trim().split(/\s+/).slice(0, 7).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
2428
2428
  return {
2429
2429
  title,
2430
2430
  subtitle: "A practical editorial blueprint for turning a good idea into a strong article",
2431
2431
  keywords: ["writing", "editorial workflow", "ai tools", "content strategy"],
2432
2432
  slug: slugify(title),
2433
- description: contentBrief.description,
2433
+ description: contentPlan.description,
2434
2434
  introBrief: "Frame the tension between having ideas and actually shaping them into useful published work.",
2435
2435
  outroBrief: "End by emphasizing disciplined workflows, taste, and iteration.",
2436
2436
  sections: [
@@ -2515,16 +2515,16 @@ function buildSingleShotContentMessages(options) {
2515
2515
  `Primary content type: ${options.primaryContentType}`,
2516
2516
  `Output index: ${options.outputIndex} of ${options.outputCountForType}`,
2517
2517
  "",
2518
- "Shared content brief (must guide this output):",
2519
- `- title: ${options.contentBrief.title}`,
2520
- `- description: ${options.contentBrief.description}`,
2521
- `- targetAudience: ${options.contentBrief.targetAudience}`,
2522
- `- corePromise: ${options.contentBrief.corePromise}`,
2523
- `- keyPoints: ${options.contentBrief.keyPoints.join(" | ")}`,
2524
- `- voiceNotes: ${options.contentBrief.voiceNotes}`,
2525
- `- primaryContentType: ${options.contentBrief.primaryContentType}`,
2526
- `- secondaryContentTypes: ${options.contentBrief.secondaryContentTypes.join(" | ") || "none"}`,
2527
- `- secondaryContentStrategy: ${options.contentBrief.secondaryContentStrategy}`,
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}`,
2528
2528
  "",
2529
2529
  articleContext,
2530
2530
  "",
@@ -2548,7 +2548,7 @@ async function writeSingleShotContent({
2548
2548
  outputIndex,
2549
2549
  outputCountForType,
2550
2550
  articleReferenceMarkdown,
2551
- contentBrief,
2551
+ contentPlan,
2552
2552
  settings,
2553
2553
  openRouter,
2554
2554
  dryRun,
@@ -2563,7 +2563,7 @@ async function writeSingleShotContent({
2563
2563
  primaryContentType,
2564
2564
  outputIndex,
2565
2565
  outputCountForType,
2566
- contentBrief,
2566
+ contentPlan,
2567
2567
  articleReferenceMarkdown
2568
2568
  });
2569
2569
  }
@@ -2577,7 +2577,7 @@ async function writeSingleShotContent({
2577
2577
  intent,
2578
2578
  outputIndex,
2579
2579
  outputCountForType,
2580
- contentBrief,
2580
+ contentPlan,
2581
2581
  articleReferenceMarkdown,
2582
2582
  targetLength: settings.targetLength
2583
2583
  }),
@@ -2599,7 +2599,7 @@ function buildDryRunContent(options) {
2599
2599
  `Variant: ${options.outputIndex}/${options.outputCountForType}`,
2600
2600
  `Role: ${options.role}`,
2601
2601
  `Primary content type: ${options.primaryContentType}`,
2602
- `Shared brief: ${options.contentBrief.description}`,
2602
+ `Shared plan: ${options.contentPlan.description}`,
2603
2603
  anchorNote,
2604
2604
  "",
2605
2605
  "This is a dry-run placeholder for single-prompt channel generation."
@@ -3716,10 +3716,12 @@ ${body.join("\n").trim()}
3716
3716
  }
3717
3717
 
3718
3718
  // src/pipeline/sessionStore.ts
3719
+ import { createHash } from "crypto";
3719
3720
  import { mkdir as mkdir4, readFile as readFile5, rm as rm2, writeFile as writeFile5 } from "fs/promises";
3720
3721
  import path7 from "path";
3722
+ import envPaths3 from "env-paths";
3721
3723
  import { z as z6 } from "zod";
3722
- var STAGE_IDS = ["shared-brief", "planning", "sections", "image-prompts", "images", "output", "links"];
3724
+ var STAGE_IDS = ["shared-plan", "planning", "sections", "image-prompts", "images", "output", "links"];
3723
3725
  var generatedArticleSectionSchema = z6.object({
3724
3726
  title: z6.string().min(1),
3725
3727
  body: z6.string().min(1)
@@ -3779,7 +3781,7 @@ var writeSessionStateSchema = z6.object({
3779
3781
  lastCompletedStage: z6.enum(STAGE_IDS).nullable(),
3780
3782
  failedStage: z6.enum(STAGE_IDS).nullable(),
3781
3783
  errorMessage: z6.string().nullable(),
3782
- contentBrief: contentBriefSchema2.nullable().default(null),
3784
+ contentPlan: contentPlanSchema2.nullable().default(null),
3783
3785
  plan: articlePlanSchema.nullable(),
3784
3786
  text: z6.object({
3785
3787
  intro: z6.string().min(1),
@@ -3794,12 +3796,20 @@ var writeSessionStateSchema = z6.object({
3794
3796
  links: z6.array(linksResultSchema).nullable().default(null),
3795
3797
  artifact: pipelineArtifactSummarySchema.nullable()
3796
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
+ }
3797
3804
  function resolveWriteRoot(workingDir) {
3798
- return path7.join(workingDir, ".ideon", "write");
3805
+ return path7.join(sessionsDir, hashProjectPath(workingDir));
3799
3806
  }
3800
3807
  function resolveStateFilePath(workingDir) {
3801
3808
  return path7.join(resolveWriteRoot(workingDir), "state.json");
3802
3809
  }
3810
+ function resolveLegacyStatePath(workingDir) {
3811
+ return path7.join(workingDir, ".ideon", "write", "state.json");
3812
+ }
3803
3813
  async function startFreshWriteSession(seed, workingDir = process.cwd()) {
3804
3814
  const writeRoot = resolveWriteRoot(workingDir);
3805
3815
  await rm2(writeRoot, { recursive: true, force: true });
@@ -3819,7 +3829,7 @@ async function startFreshWriteSession(seed, workingDir = process.cwd()) {
3819
3829
  lastCompletedStage: null,
3820
3830
  failedStage: null,
3821
3831
  errorMessage: null,
3822
- contentBrief: null,
3832
+ contentPlan: null,
3823
3833
  plan: null,
3824
3834
  text: null,
3825
3835
  imagePrompts: null,
@@ -3835,6 +3845,17 @@ async function loadWriteSession(workingDir = process.cwd()) {
3835
3845
  try {
3836
3846
  const raw = await readFile5(statePath, "utf8");
3837
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;
3838
3859
  } catch (error) {
3839
3860
  if (isNotFoundError(error)) {
3840
3861
  return null;
@@ -3856,7 +3877,7 @@ async function saveWriteSession(state, workingDir = process.cwd()) {
3856
3877
  async function patchWriteSession(patch, workingDir = process.cwd()) {
3857
3878
  const existing = await loadWriteSession(workingDir);
3858
3879
  if (!existing) {
3859
- throw new Error("No active write session found in .ideon/write/state.json. Start a fresh write first.");
3880
+ throw new Error("No active write session found. Start a fresh write first.");
3860
3881
  }
3861
3882
  const has = (key) => Object.hasOwn(patch, key);
3862
3883
  const merged = {
@@ -3866,7 +3887,7 @@ async function patchWriteSession(patch, workingDir = process.cwd()) {
3866
3887
  lastCompletedStage: has("lastCompletedStage") ? patch.lastCompletedStage ?? null : existing.lastCompletedStage,
3867
3888
  failedStage: has("failedStage") ? patch.failedStage ?? null : existing.failedStage,
3868
3889
  errorMessage: has("errorMessage") ? patch.errorMessage ?? null : existing.errorMessage,
3869
- contentBrief: has("contentBrief") ? patch.contentBrief ?? null : existing.contentBrief,
3890
+ contentPlan: has("contentPlan") ? patch.contentPlan ?? null : existing.contentPlan,
3870
3891
  plan: has("plan") ? patch.plan ?? null : existing.plan,
3871
3892
  text: has("text") ? patch.text ?? null : existing.text,
3872
3893
  imagePrompts: has("imagePrompts") ? patch.imagePrompts ?? null : existing.imagePrompts,
@@ -3888,8 +3909,8 @@ function createInitialStages(options = { isArticlePrimary: true }) {
3888
3909
  const sectionsDetail = options.isArticlePrimary ? "Waiting for the approved article plan." : "Waiting for primary content generation to begin.";
3889
3910
  return [
3890
3911
  {
3891
- id: "shared-brief",
3892
- title: "Planning Shared Brief",
3912
+ id: "shared-plan",
3913
+ title: "Planning Shared Plan",
3893
3914
  status: "running",
3894
3915
  detail: "Generating explicit cross-channel content guidance."
3895
3916
  },
@@ -3952,7 +3973,7 @@ async function runPipelineShell(input, options = {}) {
3952
3973
  const stageTracking = /* @__PURE__ */ new Map();
3953
3974
  const stageRetryState = /* @__PURE__ */ new Map();
3954
3975
  const llmOperationRetryState = /* @__PURE__ */ new Map();
3955
- stageTracking.set("shared-brief", {
3976
+ stageTracking.set("shared-plan", {
3956
3977
  startedAtMs: runStartedAtMs,
3957
3978
  endedAtMs: null,
3958
3979
  retries: 0,
@@ -4016,7 +4037,7 @@ async function runPipelineShell(input, options = {}) {
4016
4037
  } else {
4017
4038
  const existing = await loadWriteSession(workingDir);
4018
4039
  if (!existing) {
4019
- throw new Error("No resumable write session found in .ideon/write/state.json. Start a fresh write first.");
4040
+ throw new Error("No resumable write session found. Start a fresh write first.");
4020
4041
  }
4021
4042
  if (existing.status === "completed") {
4022
4043
  }
@@ -4032,24 +4053,24 @@ async function runPipelineShell(input, options = {}) {
4032
4053
  replicateApiKey: requireSecret(input.config.secrets.replicateApiToken, "Replicate API token"),
4033
4054
  openrouterModel: input.config.settings.model
4034
4055
  });
4035
- let contentBrief = writeSession.contentBrief;
4056
+ let contentPlan = writeSession.contentPlan;
4036
4057
  let plan = writeSession.plan;
4037
4058
  let text = writeSession.text;
4038
4059
  let imagePrompts = writeSession.imagePrompts ?? writeSession.imageArtifacts?.imagePrompts ?? null;
4039
4060
  let imageArtifacts = writeSession.imageArtifacts;
4040
4061
  let linksResult = writeSession.links;
4041
4062
  let primaryMarkdownTemplate = null;
4042
- if (contentBrief) {
4043
- markStageCompleted(stageTracking, "shared-brief");
4063
+ if (contentPlan) {
4064
+ markStageCompleted(stageTracking, "shared-plan");
4044
4065
  stages[0] = {
4045
4066
  ...stages[0],
4046
4067
  status: "succeeded",
4047
- detail: "Reused saved shared brief from .ideon/write.",
4048
- summary: contentBrief.title,
4049
- stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-brief")
4068
+ detail: "Reused saved shared plan from cached session.",
4069
+ summary: contentPlan.title,
4070
+ stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-plan")
4050
4071
  };
4051
4072
  } else {
4052
- contentBrief = await planContentBrief({
4073
+ contentPlan = await planContentPlan({
4053
4074
  idea: input.idea,
4054
4075
  targetAudienceHint: input.targetAudienceHint,
4055
4076
  settings: input.config.settings,
@@ -4059,24 +4080,24 @@ async function runPipelineShell(input, options = {}) {
4059
4080
  onLlmInteraction(interaction);
4060
4081
  },
4061
4082
  onLlmMetrics(metrics) {
4062
- recordLlmMetrics(stageTracking, "shared-brief", metrics);
4083
+ recordLlmMetrics(stageTracking, "shared-plan", metrics);
4063
4084
  }
4064
4085
  });
4065
- markStageCompleted(stageTracking, "shared-brief");
4086
+ markStageCompleted(stageTracking, "shared-plan");
4066
4087
  stages[0] = {
4067
4088
  ...stages[0],
4068
4089
  status: "succeeded",
4069
- detail: "Shared brief generated successfully.",
4070
- summary: contentBrief.title,
4071
- stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-brief")
4090
+ detail: "Shared plan generated successfully.",
4091
+ summary: contentPlan.title,
4092
+ stageAnalytics: snapshotStageAnalytics(stageTracking, "shared-plan")
4072
4093
  };
4073
4094
  writeSession = await patchWriteSession(
4074
4095
  {
4075
4096
  status: "running",
4076
- lastCompletedStage: "shared-brief",
4097
+ lastCompletedStage: "shared-plan",
4077
4098
  failedStage: null,
4078
4099
  errorMessage: null,
4079
- contentBrief
4100
+ contentPlan
4080
4101
  },
4081
4102
  workingDir
4082
4103
  );
@@ -4094,17 +4115,17 @@ async function runPipelineShell(input, options = {}) {
4094
4115
  stages[1] = {
4095
4116
  ...stages[1],
4096
4117
  status: "succeeded",
4097
- detail: "Reused saved plan from .ideon/write.",
4118
+ detail: "Reused saved plan from cached session.",
4098
4119
  summary: `${plan.title} \u2022 ${plan.slug} \u2022 ${plan.sections.length} sections \u2022 ${plan.inlineImages.length + 1} images`,
4099
4120
  stageAnalytics: snapshotStageAnalytics(stageTracking, "planning")
4100
4121
  };
4101
4122
  } else {
4102
- if (!contentBrief) {
4103
- throw new Error("Shared content brief is missing for article planning stage.");
4123
+ if (!contentPlan) {
4124
+ throw new Error("Shared content plan is missing for article planning stage.");
4104
4125
  }
4105
4126
  plan = await planArticle({
4106
4127
  idea: input.idea,
4107
- contentBrief,
4128
+ contentPlan,
4108
4129
  settings: input.config.settings,
4109
4130
  markdownOutputDir: writeSession.outputPaths.markdownOutputDir,
4110
4131
  openRouter,
@@ -4130,7 +4151,7 @@ async function runPipelineShell(input, options = {}) {
4130
4151
  lastCompletedStage: "planning",
4131
4152
  failedStage: null,
4132
4153
  errorMessage: null,
4133
- contentBrief,
4154
+ contentPlan,
4134
4155
  plan
4135
4156
  },
4136
4157
  workingDir
@@ -4149,12 +4170,12 @@ async function runPipelineShell(input, options = {}) {
4149
4170
  stages[2] = {
4150
4171
  ...stages[2],
4151
4172
  status: "succeeded",
4152
- detail: "Reused saved section drafts from .ideon/write.",
4173
+ detail: "Reused saved section drafts from cached session.",
4153
4174
  summary: `Intro + ${text.sections.length} sections + conclusion`,
4154
4175
  items: (stages[2].items ?? []).map((item) => ({
4155
4176
  ...item,
4156
4177
  status: "succeeded",
4157
- detail: "Reused saved section draft from .ideon/write."
4178
+ detail: "Reused saved section draft from cached session."
4158
4179
  })),
4159
4180
  stageAnalytics: snapshotStageAnalytics(stageTracking, "sections")
4160
4181
  };
@@ -4268,7 +4289,7 @@ async function runPipelineShell(input, options = {}) {
4268
4289
  stages[3] = {
4269
4290
  ...stages[3],
4270
4291
  status: "succeeded",
4271
- detail: "Reused saved image prompts from .ideon/write.",
4292
+ detail: "Reused saved image prompts from cached session.",
4272
4293
  summary: `${imagePrompts.length} prompts ready`,
4273
4294
  stageAnalytics: snapshotStageAnalytics(stageTracking, "image-prompts")
4274
4295
  };
@@ -4343,8 +4364,8 @@ async function runPipelineShell(input, options = {}) {
4343
4364
  );
4344
4365
  }
4345
4366
  } else {
4346
- if (!contentBrief) {
4347
- throw new Error("Shared content brief is missing for primary content planning stage.");
4367
+ if (!contentPlan) {
4368
+ throw new Error("Shared content plan is missing for primary content planning stage.");
4348
4369
  }
4349
4370
  stages[1] = {
4350
4371
  ...stages[1],
@@ -4378,7 +4399,7 @@ async function runPipelineShell(input, options = {}) {
4378
4399
  outputIndex: 1,
4379
4400
  outputCountForType: 1,
4380
4401
  articleReferenceMarkdown: void 0,
4381
- contentBrief,
4402
+ contentPlan,
4382
4403
  settings: input.config.settings,
4383
4404
  openRouter,
4384
4405
  dryRun,
@@ -4404,7 +4425,7 @@ async function runPipelineShell(input, options = {}) {
4404
4425
  };
4405
4426
  markStageStarted(stageTracking, "image-prompts");
4406
4427
  options.onUpdate?.(cloneStages(stages));
4407
- imagePrompts = [buildPrimaryCoverPrompt(contentBrief, primaryTarget.contentType, primaryMarkdownTemplate)];
4428
+ imagePrompts = [buildPrimaryCoverPrompt(contentPlan, primaryTarget.contentType, primaryMarkdownTemplate)];
4408
4429
  markStageCompleted(stageTracking, "image-prompts");
4409
4430
  stages[3] = {
4410
4431
  ...stages[3],
@@ -4426,7 +4447,7 @@ async function runPipelineShell(input, options = {}) {
4426
4447
  };
4427
4448
  options.onUpdate?.(cloneStages(stages));
4428
4449
  }
4429
- const baseSlug = plan?.slug ?? slugifyIdea(input.idea);
4450
+ const baseSlug = plan?.slug ?? resolveGenerationSlug(input.idea, contentPlan?.title);
4430
4451
  const generationDir = path8.join(
4431
4452
  writeSession.outputPaths.markdownOutputDir,
4432
4453
  buildGenerationDirectoryName(baseSlug)
@@ -4457,7 +4478,7 @@ async function runPipelineShell(input, options = {}) {
4457
4478
  stages[4] = {
4458
4479
  ...stages[4],
4459
4480
  status: "succeeded",
4460
- detail: "Reused previously rendered images from .ideon/write.",
4481
+ detail: "Reused previously rendered images from cached session.",
4461
4482
  summary: sharedAssetDir,
4462
4483
  stageAnalytics: snapshotStageAnalytics(stageTracking, "images")
4463
4484
  };
@@ -4544,7 +4565,7 @@ async function runPipelineShell(input, options = {}) {
4544
4565
  stages[4] = {
4545
4566
  ...stages[4],
4546
4567
  status: "succeeded",
4547
- detail: "Reused previously rendered primary cover image from .ideon/write.",
4568
+ detail: "Reused previously rendered primary cover image from cached session.",
4548
4569
  summary: sharedAssetDir,
4549
4570
  stageAnalytics: snapshotStageAnalytics(stageTracking, "images")
4550
4571
  };
@@ -4616,7 +4637,7 @@ async function runPipelineShell(input, options = {}) {
4616
4637
  }
4617
4638
  primaryMarkdownTemplate = applyPrimaryTitleHeading(
4618
4639
  primaryMarkdownTemplate,
4619
- contentBrief.title || deriveTitleFromIdea2(input.idea)
4640
+ contentPlan.title || deriveTitleFromIdea2(input.idea)
4620
4641
  );
4621
4642
  }
4622
4643
  const markdownPaths = [];
@@ -4646,8 +4667,8 @@ async function runPipelineShell(input, options = {}) {
4646
4667
  };
4647
4668
  markStageStarted(stageTracking, "output");
4648
4669
  options.onUpdate?.(cloneStages(stages));
4649
- if (!contentBrief) {
4650
- throw new Error("Shared content brief is missing for output generation stage.");
4670
+ if (!contentPlan) {
4671
+ throw new Error("Shared content plan is missing for output generation stage.");
4651
4672
  }
4652
4673
  for (const output of requestedOutputs) {
4653
4674
  const itemId = toOutputItemId(output.filePrefix, output.index);
@@ -4682,7 +4703,7 @@ async function runPipelineShell(input, options = {}) {
4682
4703
  outputIndex: output.index,
4683
4704
  outputCountForType: output.outputCountForType,
4684
4705
  articleReferenceMarkdown: primaryMarkdownTemplate ?? void 0,
4685
- contentBrief,
4706
+ contentPlan,
4686
4707
  settings: input.config.settings,
4687
4708
  openRouter,
4688
4709
  dryRun,
@@ -4827,7 +4848,7 @@ async function runPipelineShell(input, options = {}) {
4827
4848
  stages[6] = {
4828
4849
  ...stages[6],
4829
4850
  status: "succeeded",
4830
- detail: "Reused saved link metadata from .ideon/write.",
4851
+ detail: "Reused saved link metadata from cached session.",
4831
4852
  summary: `${resumedLinks.reduce((sum, item) => sum + item.links.length, 0)} links`,
4832
4853
  items: (stages[6].items ?? []).map((item) => ({
4833
4854
  ...item,
@@ -4841,8 +4862,8 @@ async function runPipelineShell(input, options = {}) {
4841
4862
  const itemTracking = /* @__PURE__ */ new Map();
4842
4863
  linksResult = await enrichLinks({
4843
4864
  markdownFiles: eligibleOutputsForLinks,
4844
- articleTitle: plan?.title ?? contentBrief.title ?? deriveTitleFromIdea2(input.idea),
4845
- articleDescription: plan?.description ?? contentBrief.description,
4865
+ articleTitle: plan?.title ?? contentPlan.title ?? deriveTitleFromIdea2(input.idea),
4866
+ articleDescription: plan?.description ?? contentPlan.description,
4846
4867
  openRouter,
4847
4868
  settings: input.config.settings,
4848
4869
  dryRun,
@@ -4955,8 +4976,8 @@ async function runPipelineShell(input, options = {}) {
4955
4976
  await writeJsonFile(interactionsPath, interactions);
4956
4977
  const primaryMarkdownPathForArtifact = markdownPaths[0] ?? primaryMarkdownPath;
4957
4978
  const artifact = {
4958
- title: plan?.title ?? contentBrief.title ?? deriveTitleFromIdea2(input.idea),
4959
- slug: plan?.slug ?? slugifyIdea(input.idea),
4979
+ title: plan?.title ?? contentPlan.title ?? deriveTitleFromIdea2(input.idea),
4980
+ slug: plan?.slug ?? resolveGenerationSlug(input.idea, contentPlan?.title),
4960
4981
  sectionCount: text?.sections.length ?? 0,
4961
4982
  imageCount: imageArtifacts?.renderedImages.length ?? 0,
4962
4983
  outputCount: markdownPaths.length,
@@ -5065,7 +5086,7 @@ function buildRunAnalytics({
5065
5086
  linkEnrichmentCalls
5066
5087
  }) {
5067
5088
  const runEndedAtMs = Date.now();
5068
- const orderedStageIds = ["shared-brief", "planning", "sections", "image-prompts", "images", "output", "links"];
5089
+ const orderedStageIds = ["shared-plan", "planning", "sections", "image-prompts", "images", "output", "links"];
5069
5090
  const stages = orderedStageIds.map((stageId) => {
5070
5091
  const tracked = stageTracking.get(stageId);
5071
5092
  const startedAtMs = tracked?.startedAtMs ?? runEndedAtMs;
@@ -5282,7 +5303,7 @@ function getSecondaryTargets(contentTargets) {
5282
5303
  count: target.count
5283
5304
  }));
5284
5305
  }
5285
- function buildPrimaryCoverPrompt(contentBrief, primaryContentType, primaryMarkdown) {
5306
+ function buildPrimaryCoverPrompt(contentPlan, primaryContentType, primaryMarkdown) {
5286
5307
  const markdownExcerpt = primaryMarkdown.replace(/\s+/g, " ").trim().slice(0, 240);
5287
5308
  return {
5288
5309
  id: "cover",
@@ -5291,10 +5312,10 @@ function buildPrimaryCoverPrompt(contentBrief, primaryContentType, primaryMarkdo
5291
5312
  anchorAfterSection: null,
5292
5313
  prompt: [
5293
5314
  `Cover image for ${primaryContentType}.`,
5294
- `Core angle: ${contentBrief.description}`,
5295
- `Audience: ${contentBrief.targetAudience}`,
5296
- `Promise: ${contentBrief.corePromise}`,
5297
- `Voice: ${contentBrief.voiceNotes}`,
5315
+ `Core angle: ${contentPlan.description}`,
5316
+ `Audience: ${contentPlan.targetAudience}`,
5317
+ `Promise: ${contentPlan.corePromise}`,
5318
+ `Voice: ${contentPlan.voiceNotes}`,
5298
5319
  `Primary excerpt: ${markdownExcerpt}`,
5299
5320
  "Do not include any words, letters, numbers, logos, watermarks, or signage in the image."
5300
5321
  ].join(" ")
@@ -5329,8 +5350,18 @@ function deriveTitleFromIdea2(idea) {
5329
5350
  }
5330
5351
  return normalized.split(/\s+/).slice(0, 8).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
5331
5352
  }
5332
- function slugifyIdea(idea) {
5333
- return idea.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "generated-content";
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);
5334
5365
  }
5335
5366
  function buildRunJobDefinition(input) {
5336
5367
  return {
@@ -5388,7 +5419,7 @@ ${imageRows}
5388
5419
  `;
5389
5420
  }
5390
5421
  function asWriteStageId(stageId) {
5391
- if (stageId === "shared-brief" || stageId === "planning" || stageId === "sections" || stageId === "image-prompts" || stageId === "images" || stageId === "output" || stageId === "links") {
5422
+ if (stageId === "shared-plan" || stageId === "planning" || stageId === "sections" || stageId === "image-prompts" || stageId === "images" || stageId === "output" || stageId === "links") {
5392
5423
  return stageId;
5393
5424
  }
5394
5425
  return null;
@@ -6301,7 +6332,7 @@ async function startIdeonMcpServer() {
6301
6332
  try {
6302
6333
  const session = await loadWriteSession(cwd());
6303
6334
  if (!session) {
6304
- throw new ReportedError("No resumable write session found in .ideon/write/state.json.");
6335
+ throw new ReportedError("No resumable write session found.");
6305
6336
  }
6306
6337
  if (session.status === "completed") {
6307
6338
  throw new ReportedError("The last write session already completed.");
@@ -8312,7 +8343,7 @@ function renderShell({
8312
8343
  const articleListElement = document.getElementById('articleList');
8313
8344
  const themeToggleButton = document.getElementById('themeToggle');
8314
8345
  const typeOrder = ['article', 'blog-post', 'x-thread', 'x-post', 'linkedin-post', 'reddit-post', 'newsletter'];
8315
- const stageOrder = ['shared-brief', 'planning', 'sections', 'image-prompts', 'images', 'output', 'links'];
8346
+ const stageOrder = ['shared-plan', 'planning', 'sections', 'image-prompts', 'images', 'output', 'links'];
8316
8347
 
8317
8348
  let currentGeneration = null;
8318
8349
  let activeType = '';
@@ -8974,7 +9005,7 @@ function formatStageCost(costUsd, costSource) {
8974
9005
  return costSource === "estimated" ? `~${formatted}` : formatted;
8975
9006
  }
8976
9007
  function formatStageId(stageId) {
8977
- if (stageId === "shared-brief") return "shared-brief";
9008
+ if (stageId === "shared-plan") return "shared-plan";
8978
9009
  if (stageId === "planning") return "planning";
8979
9010
  if (stageId === "sections") return "sections";
8980
9011
  if (stageId === "image-prompts") return "image-prompts";
@@ -9872,7 +9903,7 @@ async function runWriteCommand(options) {
9872
9903
  async function runWriteResumeCommand(options = {}) {
9873
9904
  const session = await loadWriteSession();
9874
9905
  if (!session) {
9875
- throw new ReportedError("No resumable write session found in .ideon/write/state.json. Run ideon write <idea> first.");
9906
+ throw new ReportedError("No resumable write session found. Run ideon write <idea> first.");
9876
9907
  }
9877
9908
  if (session.status === "completed") {
9878
9909
  throw new ReportedError("The last write session already completed. Run ideon write <idea> to start fresh.");
@@ -10169,7 +10200,7 @@ async function runCli(argv) {
10169
10200
  watch: options.watch
10170
10201
  });
10171
10202
  });
10172
- 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-brief 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) => {
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) => {
10173
10204
  await runWriteCommand({
10174
10205
  idea: options.idea ?? ideaArg,
10175
10206
  audience: options.audience,
@@ -10188,7 +10219,7 @@ async function runCli(argv) {
10188
10219
  maxImages: options.maxImages
10189
10220
  });
10190
10221
  });
10191
- writeCommand.command("resume").description("Resume the last failed or interrupted write session from .ideon/write.").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) => {
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) => {
10192
10223
  await runWriteResumeCommand({
10193
10224
  noInteractive: options.noInteractive,
10194
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
  ---
@@ -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-D3k0cA_1.js"></script>
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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telepat/ideon",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "CLI for generating rich articles and images from ideas.",
5
5
  "type": "module",
6
6
  "repository": {