@telepat/ideon 0.1.27 → 0.1.29
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 +72 -88
- package/package.json +1 -1
package/dist/ideon.js
CHANGED
|
@@ -1424,7 +1424,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
1424
1424
|
// package.json
|
|
1425
1425
|
var package_default = {
|
|
1426
1426
|
name: "@telepat/ideon",
|
|
1427
|
-
version: "0.1.
|
|
1427
|
+
version: "0.1.29",
|
|
1428
1428
|
description: "CLI for generating rich articles and images from ideas.",
|
|
1429
1429
|
type: "module",
|
|
1430
1430
|
repository: {
|
|
@@ -6152,10 +6152,45 @@ function resolveCustomLinks(existing, addRaw, removeExpressions) {
|
|
|
6152
6152
|
}
|
|
6153
6153
|
|
|
6154
6154
|
// src/cli/commands/export.ts
|
|
6155
|
-
import { copyFile as copyFile2, mkdir as mkdir7, readFile as
|
|
6155
|
+
import { copyFile as copyFile2, mkdir as mkdir7, readFile as readFile10, stat as stat5, writeFile as writeFile6 } from "fs/promises";
|
|
6156
6156
|
import path12 from "path";
|
|
6157
6157
|
|
|
6158
6158
|
// src/output/enrichMarkdownWithLinks.ts
|
|
6159
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
6160
|
+
async function loadLinksFromSidecar(markdownPath) {
|
|
6161
|
+
const linksPath = resolveLinksPath(markdownPath);
|
|
6162
|
+
let raw;
|
|
6163
|
+
try {
|
|
6164
|
+
raw = await readFile8(linksPath, "utf8");
|
|
6165
|
+
} catch {
|
|
6166
|
+
return [];
|
|
6167
|
+
}
|
|
6168
|
+
let parsed;
|
|
6169
|
+
try {
|
|
6170
|
+
parsed = JSON.parse(raw);
|
|
6171
|
+
} catch {
|
|
6172
|
+
return [];
|
|
6173
|
+
}
|
|
6174
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
6175
|
+
return [];
|
|
6176
|
+
}
|
|
6177
|
+
const record = parsed;
|
|
6178
|
+
const links = Array.isArray(record.links) ? record.links : [];
|
|
6179
|
+
const customLinks = Array.isArray(record.customLinks) ? record.customLinks : [];
|
|
6180
|
+
const filterAndMap = (entries, isCustom) => entries.filter((entry) => {
|
|
6181
|
+
if (typeof entry !== "object" || entry === null) {
|
|
6182
|
+
return false;
|
|
6183
|
+
}
|
|
6184
|
+
const e = entry;
|
|
6185
|
+
return typeof e.expression === "string" && typeof e.url === "string" && (e.title === null || typeof e.title === "string");
|
|
6186
|
+
}).map((entry) => ({
|
|
6187
|
+
expression: entry.expression.trim(),
|
|
6188
|
+
url: entry.url.trim(),
|
|
6189
|
+
title: entry.title,
|
|
6190
|
+
isCustom
|
|
6191
|
+
})).filter((entry) => entry.expression.length > 0 && entry.url.length > 0);
|
|
6192
|
+
return [...filterAndMap(customLinks, true), ...filterAndMap(links, false)];
|
|
6193
|
+
}
|
|
6159
6194
|
function enrichMarkdownWithLinks(markdown, links) {
|
|
6160
6195
|
if (links.length === 0) {
|
|
6161
6196
|
return markdown;
|
|
@@ -6174,8 +6209,13 @@ function enrichMarkdownWithLinks(markdown, links) {
|
|
|
6174
6209
|
if (isInProtectedSpan(updated, start, end)) {
|
|
6175
6210
|
continue;
|
|
6176
6211
|
}
|
|
6177
|
-
|
|
6178
|
-
|
|
6212
|
+
const replacement = `[${match[0]}](${link.url})`;
|
|
6213
|
+
updated = `${updated.slice(0, start)}${replacement}${updated.slice(end)}`;
|
|
6214
|
+
if (link.isCustom) {
|
|
6215
|
+
expressionRegex.lastIndex = start + replacement.length;
|
|
6216
|
+
} else {
|
|
6217
|
+
break;
|
|
6218
|
+
}
|
|
6179
6219
|
}
|
|
6180
6220
|
}
|
|
6181
6221
|
return updated;
|
|
@@ -6202,14 +6242,29 @@ function isInProtectedSpan(content, start, end) {
|
|
|
6202
6242
|
return true;
|
|
6203
6243
|
}
|
|
6204
6244
|
}
|
|
6245
|
+
if (/^#{1,6}\s/.test(line)) {
|
|
6246
|
+
return true;
|
|
6247
|
+
}
|
|
6205
6248
|
return false;
|
|
6206
6249
|
}
|
|
6207
6250
|
function escapeRegExp(value2) {
|
|
6208
|
-
return value2.replace(/[
|
|
6251
|
+
return value2.replace(/[.*+?^{}()|[\]\\]/g, "\\$&");
|
|
6252
|
+
}
|
|
6253
|
+
function enrichWithFrontmatterGuard(markdown, links) {
|
|
6254
|
+
if (links.length === 0) {
|
|
6255
|
+
return markdown;
|
|
6256
|
+
}
|
|
6257
|
+
const frontmatterMatch = markdown.match(/^---\s*\n[\s\S]*?\n---\s*\n?/);
|
|
6258
|
+
if (!frontmatterMatch) {
|
|
6259
|
+
return enrichMarkdownWithLinks(markdown, links);
|
|
6260
|
+
}
|
|
6261
|
+
const frontmatter = frontmatterMatch[0];
|
|
6262
|
+
const body = markdown.slice(frontmatter.length);
|
|
6263
|
+
return `${frontmatter}${enrichMarkdownWithLinks(body, links)}`;
|
|
6209
6264
|
}
|
|
6210
6265
|
|
|
6211
6266
|
// src/server/previewHelpers.ts
|
|
6212
|
-
import { readdir, stat as stat4, readFile as
|
|
6267
|
+
import { readdir, stat as stat4, readFile as readFile9 } from "fs/promises";
|
|
6213
6268
|
import path11 from "path";
|
|
6214
6269
|
var DEFAULT_PORT = 4173;
|
|
6215
6270
|
var CONTENT_TYPE_ORDER = ["article", "blog-post", "x-thread", "x-post", "linkedin-post", "reddit-post", "newsletter"];
|
|
@@ -6311,7 +6366,7 @@ function extractCoverImageUrl(markdown) {
|
|
|
6311
6366
|
return match?.[1] ?? null;
|
|
6312
6367
|
}
|
|
6313
6368
|
async function extractArticleMetadata(markdownPath) {
|
|
6314
|
-
const markdown = await
|
|
6369
|
+
const markdown = await readFile9(markdownPath, "utf8");
|
|
6315
6370
|
const fileStat = await stat4(markdownPath);
|
|
6316
6371
|
const slug = extractFrontmatterSlug(markdown) ?? path11.basename(markdownPath, ".md");
|
|
6317
6372
|
const title = extractHeadingTitle(stripFrontmatter2(markdown)) ?? slug;
|
|
@@ -6468,7 +6523,7 @@ async function resolvePrimaryContentType(outputs) {
|
|
|
6468
6523
|
}
|
|
6469
6524
|
const jobPath = path11.join(generationDir, "job.json");
|
|
6470
6525
|
try {
|
|
6471
|
-
const raw = await
|
|
6526
|
+
const raw = await readFile9(jobPath, "utf8");
|
|
6472
6527
|
const parsed = JSON.parse(raw);
|
|
6473
6528
|
const targets = Array.isArray(parsed.contentTargets) ? parsed.contentTargets : Array.isArray(parsed.settings?.contentTargets) ? parsed.settings.contentTargets : [];
|
|
6474
6529
|
const primary = targets.find((target) => target?.role === "primary" && typeof target.contentType === "string");
|
|
@@ -6509,7 +6564,7 @@ async function runOutputCommand(options, dependencies = {}) {
|
|
|
6509
6564
|
);
|
|
6510
6565
|
}
|
|
6511
6566
|
const sourceMarkdownPath = articleOutput.sourcePath;
|
|
6512
|
-
const sourceMarkdown = await
|
|
6567
|
+
const sourceMarkdown = await readFile10(sourceMarkdownPath, "utf8");
|
|
6513
6568
|
const slug = extractFrontmatterSlug2(sourceMarkdown) ?? path12.basename(sourceMarkdownPath, ".md");
|
|
6514
6569
|
const exportFilename = `${slug}.md`;
|
|
6515
6570
|
const destinationDir = await resolveDestinationDir(options.destinationPath, cwd2);
|
|
@@ -6520,7 +6575,7 @@ async function runOutputCommand(options, dependencies = {}) {
|
|
|
6520
6575
|
);
|
|
6521
6576
|
}
|
|
6522
6577
|
await mkdir7(destinationDir, { recursive: true });
|
|
6523
|
-
const links = await
|
|
6578
|
+
const links = await loadLinksFromSidecar(sourceMarkdownPath);
|
|
6524
6579
|
const enrichedMarkdown = enrichWithFrontmatterGuard(sourceMarkdown, links);
|
|
6525
6580
|
const sourceDir = path12.dirname(sourceMarkdownPath);
|
|
6526
6581
|
const allFiles = await listFilesRecursively(sourceDir, () => true);
|
|
@@ -6572,51 +6627,6 @@ async function fileExists2(filePath) {
|
|
|
6572
6627
|
return false;
|
|
6573
6628
|
}
|
|
6574
6629
|
}
|
|
6575
|
-
async function loadLinks(markdownPath) {
|
|
6576
|
-
const linksPath = resolveLinksPath(markdownPath);
|
|
6577
|
-
let raw;
|
|
6578
|
-
try {
|
|
6579
|
-
raw = await readFile9(linksPath, "utf8");
|
|
6580
|
-
} catch {
|
|
6581
|
-
return [];
|
|
6582
|
-
}
|
|
6583
|
-
let parsed;
|
|
6584
|
-
try {
|
|
6585
|
-
parsed = JSON.parse(raw);
|
|
6586
|
-
} catch {
|
|
6587
|
-
return [];
|
|
6588
|
-
}
|
|
6589
|
-
if (typeof parsed !== "object" || parsed === null) {
|
|
6590
|
-
return [];
|
|
6591
|
-
}
|
|
6592
|
-
const record = parsed;
|
|
6593
|
-
const links = Array.isArray(record.links) ? record.links : [];
|
|
6594
|
-
const customLinks = Array.isArray(record.customLinks) ? record.customLinks : [];
|
|
6595
|
-
const combined = [...customLinks, ...links];
|
|
6596
|
-
return combined.filter((entry) => {
|
|
6597
|
-
if (typeof entry !== "object" || entry === null) {
|
|
6598
|
-
return false;
|
|
6599
|
-
}
|
|
6600
|
-
const e = entry;
|
|
6601
|
-
return typeof e.expression === "string" && typeof e.url === "string" && (e.title === null || typeof e.title === "string");
|
|
6602
|
-
}).map((entry) => ({
|
|
6603
|
-
expression: entry.expression.trim(),
|
|
6604
|
-
url: entry.url.trim(),
|
|
6605
|
-
title: entry.title
|
|
6606
|
-
})).filter((entry) => entry.expression.length > 0 && entry.url.length > 0);
|
|
6607
|
-
}
|
|
6608
|
-
function enrichWithFrontmatterGuard(markdown, links) {
|
|
6609
|
-
if (links.length === 0) {
|
|
6610
|
-
return markdown;
|
|
6611
|
-
}
|
|
6612
|
-
const frontmatterMatch = markdown.match(/^---\s*\n[\s\S]*?\n---\s*\n?/);
|
|
6613
|
-
if (!frontmatterMatch) {
|
|
6614
|
-
return enrichMarkdownWithLinks(markdown, links);
|
|
6615
|
-
}
|
|
6616
|
-
const frontmatter = frontmatterMatch[0];
|
|
6617
|
-
const body = markdown.slice(frontmatter.length);
|
|
6618
|
-
return `${frontmatter}${enrichMarkdownWithLinks(body, links)}`;
|
|
6619
|
-
}
|
|
6620
6630
|
function extractFrontmatterSlug2(markdown) {
|
|
6621
6631
|
const frontmatterMatch = markdown.match(/^---\s*\n([\s\S]*?)\n---\s*\n?/);
|
|
6622
6632
|
const block = frontmatterMatch?.[1];
|
|
@@ -7498,7 +7508,7 @@ import { spawn } from "child_process";
|
|
|
7498
7508
|
// src/server/previewServer.ts
|
|
7499
7509
|
import { execFile } from "child_process";
|
|
7500
7510
|
import { promisify } from "util";
|
|
7501
|
-
import { readFile as
|
|
7511
|
+
import { readFile as readFile11, stat as stat6 } from "fs/promises";
|
|
7502
7512
|
import { watch as fsWatch } from "fs";
|
|
7503
7513
|
import path13 from "path";
|
|
7504
7514
|
import { fileURLToPath } from "url";
|
|
@@ -7598,7 +7608,7 @@ async function startPreviewServer(options) {
|
|
|
7598
7608
|
if (options.watch) {
|
|
7599
7609
|
let html2;
|
|
7600
7610
|
try {
|
|
7601
|
-
html2 = await
|
|
7611
|
+
html2 = await readFile11(path13.join(previewClientDir, "index.html"), "utf8");
|
|
7602
7612
|
} catch {
|
|
7603
7613
|
res.status(200).type("html").send(
|
|
7604
7614
|
`<!doctype html><html><head><meta charset="utf-8"><title>Rebuilding\u2026</title><style>body{margin:0;display:flex;align-items:center;justify-content:center;height:100vh;font-family:sans-serif;background:#101820;color:#e0eaf0}p{font-size:15px;opacity:.7}</style></head><body><p>Rebuilding\u2026</p><script>const s=new EventSource('/api/__reload');s.onmessage=function(){location.reload()};</script></body></html>`
|
|
@@ -7662,7 +7672,7 @@ async function getArticleContent(generationId, markdownOutputDir) {
|
|
|
7662
7672
|
generation.outputs.map(async (output) => {
|
|
7663
7673
|
let markdown = "";
|
|
7664
7674
|
try {
|
|
7665
|
-
markdown = await
|
|
7675
|
+
markdown = await readFile11(output.sourcePath, "utf8");
|
|
7666
7676
|
} catch (error) {
|
|
7667
7677
|
if (isMissingFileError(error)) {
|
|
7668
7678
|
throw new MissingArticleError(`Generation "${generationId}" no longer exists.`);
|
|
@@ -7718,41 +7728,15 @@ function isMissingFileError(error) {
|
|
|
7718
7728
|
}
|
|
7719
7729
|
async function renderArticleHtml(markdown, generationId, sourcePath) {
|
|
7720
7730
|
let content = stripFrontmatter2(markdown);
|
|
7721
|
-
const links = await
|
|
7731
|
+
const links = await loadLinksFromSidecar(sourcePath);
|
|
7722
7732
|
content = enrichMarkdownWithLinks(content, links);
|
|
7723
7733
|
const html = await marked.parse(content);
|
|
7724
7734
|
return rewriteRelativeAssetUrls(html, generationId);
|
|
7725
7735
|
}
|
|
7726
|
-
async function loadSavedLinks(markdownPath) {
|
|
7727
|
-
const linksPath = resolveLinksPath(markdownPath);
|
|
7728
|
-
try {
|
|
7729
|
-
const raw = await readFile10(linksPath, "utf8");
|
|
7730
|
-
const parsed = JSON.parse(raw);
|
|
7731
|
-
if (!Array.isArray(parsed.links)) {
|
|
7732
|
-
return [];
|
|
7733
|
-
}
|
|
7734
|
-
return parsed.links.filter((entry) => {
|
|
7735
|
-
if (typeof entry !== "object" || entry === null) {
|
|
7736
|
-
return false;
|
|
7737
|
-
}
|
|
7738
|
-
const record = entry;
|
|
7739
|
-
return typeof record.expression === "string" && typeof record.url === "string" && (record.title === null || typeof record.title === "string");
|
|
7740
|
-
}).map((entry) => ({
|
|
7741
|
-
expression: entry.expression.trim(),
|
|
7742
|
-
url: entry.url.trim(),
|
|
7743
|
-
title: entry.title
|
|
7744
|
-
})).filter((entry) => entry.expression.length > 0 && entry.url.length > 0);
|
|
7745
|
-
} catch (error) {
|
|
7746
|
-
if (isMissingFileError(error)) {
|
|
7747
|
-
return [];
|
|
7748
|
-
}
|
|
7749
|
-
return [];
|
|
7750
|
-
}
|
|
7751
|
-
}
|
|
7752
7736
|
async function loadSavedInteractions(generationDir) {
|
|
7753
7737
|
const interactionsPath = path13.join(generationDir, "model.interactions.json");
|
|
7754
7738
|
try {
|
|
7755
|
-
const raw = await
|
|
7739
|
+
const raw = await readFile11(interactionsPath, "utf8");
|
|
7756
7740
|
const parsed = JSON.parse(raw);
|
|
7757
7741
|
const llmCalls = Array.isArray(parsed.llmCalls) ? parsed.llmCalls.filter(isPreviewLlmInteraction) : [];
|
|
7758
7742
|
const t2iCalls = Array.isArray(parsed.t2iCalls) ? parsed.t2iCalls.filter(isPreviewT2IInteraction) : [];
|
|
@@ -7770,7 +7754,7 @@ async function loadSavedInteractions(generationDir) {
|
|
|
7770
7754
|
async function loadSavedAnalyticsSummary(generationDir) {
|
|
7771
7755
|
const analyticsPath = path13.join(generationDir, "generation.analytics.json");
|
|
7772
7756
|
try {
|
|
7773
|
-
const raw = await
|
|
7757
|
+
const raw = await readFile11(analyticsPath, "utf8");
|
|
7774
7758
|
const parsed = JSON.parse(raw);
|
|
7775
7759
|
const summary = parsed.summary;
|
|
7776
7760
|
if (!summary || typeof summary !== "object") {
|
|
@@ -7794,7 +7778,7 @@ async function loadSavedAnalyticsSummary(generationDir) {
|
|
|
7794
7778
|
async function loadSavedMetaJson(generationDir) {
|
|
7795
7779
|
const metaJsonPath = path13.join(generationDir, "meta.json");
|
|
7796
7780
|
try {
|
|
7797
|
-
const raw = await
|
|
7781
|
+
const raw = await readFile11(metaJsonPath, "utf8");
|
|
7798
7782
|
return JSON.parse(raw);
|
|
7799
7783
|
} catch {
|
|
7800
7784
|
return null;
|