@telepat/ideon 0.1.27 → 0.1.28
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 +64 -86
- 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.28",
|
|
1428
1428
|
description: "CLI for generating rich articles and images from ideas.",
|
|
1429
1429
|
type: "module",
|
|
1430
1430
|
repository: {
|
|
@@ -6152,10 +6152,44 @@ 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 combined = [...customLinks, ...links];
|
|
6181
|
+
return combined.filter((entry) => {
|
|
6182
|
+
if (typeof entry !== "object" || entry === null) {
|
|
6183
|
+
return false;
|
|
6184
|
+
}
|
|
6185
|
+
const e = entry;
|
|
6186
|
+
return typeof e.expression === "string" && typeof e.url === "string" && (e.title === null || typeof e.title === "string");
|
|
6187
|
+
}).map((entry) => ({
|
|
6188
|
+
expression: entry.expression.trim(),
|
|
6189
|
+
url: entry.url.trim(),
|
|
6190
|
+
title: entry.title
|
|
6191
|
+
})).filter((entry) => entry.expression.length > 0 && entry.url.length > 0);
|
|
6192
|
+
}
|
|
6159
6193
|
function enrichMarkdownWithLinks(markdown, links) {
|
|
6160
6194
|
if (links.length === 0) {
|
|
6161
6195
|
return markdown;
|
|
@@ -6202,14 +6236,29 @@ function isInProtectedSpan(content, start, end) {
|
|
|
6202
6236
|
return true;
|
|
6203
6237
|
}
|
|
6204
6238
|
}
|
|
6239
|
+
if (/^#{1,6}\s/.test(line)) {
|
|
6240
|
+
return true;
|
|
6241
|
+
}
|
|
6205
6242
|
return false;
|
|
6206
6243
|
}
|
|
6207
6244
|
function escapeRegExp(value2) {
|
|
6208
|
-
return value2.replace(/[
|
|
6245
|
+
return value2.replace(/[.*+?^{}()|[\]\\]/g, "\\$&");
|
|
6246
|
+
}
|
|
6247
|
+
function enrichWithFrontmatterGuard(markdown, links) {
|
|
6248
|
+
if (links.length === 0) {
|
|
6249
|
+
return markdown;
|
|
6250
|
+
}
|
|
6251
|
+
const frontmatterMatch = markdown.match(/^---\s*\n[\s\S]*?\n---\s*\n?/);
|
|
6252
|
+
if (!frontmatterMatch) {
|
|
6253
|
+
return enrichMarkdownWithLinks(markdown, links);
|
|
6254
|
+
}
|
|
6255
|
+
const frontmatter = frontmatterMatch[0];
|
|
6256
|
+
const body = markdown.slice(frontmatter.length);
|
|
6257
|
+
return `${frontmatter}${enrichMarkdownWithLinks(body, links)}`;
|
|
6209
6258
|
}
|
|
6210
6259
|
|
|
6211
6260
|
// src/server/previewHelpers.ts
|
|
6212
|
-
import { readdir, stat as stat4, readFile as
|
|
6261
|
+
import { readdir, stat as stat4, readFile as readFile9 } from "fs/promises";
|
|
6213
6262
|
import path11 from "path";
|
|
6214
6263
|
var DEFAULT_PORT = 4173;
|
|
6215
6264
|
var CONTENT_TYPE_ORDER = ["article", "blog-post", "x-thread", "x-post", "linkedin-post", "reddit-post", "newsletter"];
|
|
@@ -6311,7 +6360,7 @@ function extractCoverImageUrl(markdown) {
|
|
|
6311
6360
|
return match?.[1] ?? null;
|
|
6312
6361
|
}
|
|
6313
6362
|
async function extractArticleMetadata(markdownPath) {
|
|
6314
|
-
const markdown = await
|
|
6363
|
+
const markdown = await readFile9(markdownPath, "utf8");
|
|
6315
6364
|
const fileStat = await stat4(markdownPath);
|
|
6316
6365
|
const slug = extractFrontmatterSlug(markdown) ?? path11.basename(markdownPath, ".md");
|
|
6317
6366
|
const title = extractHeadingTitle(stripFrontmatter2(markdown)) ?? slug;
|
|
@@ -6468,7 +6517,7 @@ async function resolvePrimaryContentType(outputs) {
|
|
|
6468
6517
|
}
|
|
6469
6518
|
const jobPath = path11.join(generationDir, "job.json");
|
|
6470
6519
|
try {
|
|
6471
|
-
const raw = await
|
|
6520
|
+
const raw = await readFile9(jobPath, "utf8");
|
|
6472
6521
|
const parsed = JSON.parse(raw);
|
|
6473
6522
|
const targets = Array.isArray(parsed.contentTargets) ? parsed.contentTargets : Array.isArray(parsed.settings?.contentTargets) ? parsed.settings.contentTargets : [];
|
|
6474
6523
|
const primary = targets.find((target) => target?.role === "primary" && typeof target.contentType === "string");
|
|
@@ -6509,7 +6558,7 @@ async function runOutputCommand(options, dependencies = {}) {
|
|
|
6509
6558
|
);
|
|
6510
6559
|
}
|
|
6511
6560
|
const sourceMarkdownPath = articleOutput.sourcePath;
|
|
6512
|
-
const sourceMarkdown = await
|
|
6561
|
+
const sourceMarkdown = await readFile10(sourceMarkdownPath, "utf8");
|
|
6513
6562
|
const slug = extractFrontmatterSlug2(sourceMarkdown) ?? path12.basename(sourceMarkdownPath, ".md");
|
|
6514
6563
|
const exportFilename = `${slug}.md`;
|
|
6515
6564
|
const destinationDir = await resolveDestinationDir(options.destinationPath, cwd2);
|
|
@@ -6520,7 +6569,7 @@ async function runOutputCommand(options, dependencies = {}) {
|
|
|
6520
6569
|
);
|
|
6521
6570
|
}
|
|
6522
6571
|
await mkdir7(destinationDir, { recursive: true });
|
|
6523
|
-
const links = await
|
|
6572
|
+
const links = await loadLinksFromSidecar(sourceMarkdownPath);
|
|
6524
6573
|
const enrichedMarkdown = enrichWithFrontmatterGuard(sourceMarkdown, links);
|
|
6525
6574
|
const sourceDir = path12.dirname(sourceMarkdownPath);
|
|
6526
6575
|
const allFiles = await listFilesRecursively(sourceDir, () => true);
|
|
@@ -6572,51 +6621,6 @@ async function fileExists2(filePath) {
|
|
|
6572
6621
|
return false;
|
|
6573
6622
|
}
|
|
6574
6623
|
}
|
|
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
6624
|
function extractFrontmatterSlug2(markdown) {
|
|
6621
6625
|
const frontmatterMatch = markdown.match(/^---\s*\n([\s\S]*?)\n---\s*\n?/);
|
|
6622
6626
|
const block = frontmatterMatch?.[1];
|
|
@@ -7498,7 +7502,7 @@ import { spawn } from "child_process";
|
|
|
7498
7502
|
// src/server/previewServer.ts
|
|
7499
7503
|
import { execFile } from "child_process";
|
|
7500
7504
|
import { promisify } from "util";
|
|
7501
|
-
import { readFile as
|
|
7505
|
+
import { readFile as readFile11, stat as stat6 } from "fs/promises";
|
|
7502
7506
|
import { watch as fsWatch } from "fs";
|
|
7503
7507
|
import path13 from "path";
|
|
7504
7508
|
import { fileURLToPath } from "url";
|
|
@@ -7598,7 +7602,7 @@ async function startPreviewServer(options) {
|
|
|
7598
7602
|
if (options.watch) {
|
|
7599
7603
|
let html2;
|
|
7600
7604
|
try {
|
|
7601
|
-
html2 = await
|
|
7605
|
+
html2 = await readFile11(path13.join(previewClientDir, "index.html"), "utf8");
|
|
7602
7606
|
} catch {
|
|
7603
7607
|
res.status(200).type("html").send(
|
|
7604
7608
|
`<!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 +7666,7 @@ async function getArticleContent(generationId, markdownOutputDir) {
|
|
|
7662
7666
|
generation.outputs.map(async (output) => {
|
|
7663
7667
|
let markdown = "";
|
|
7664
7668
|
try {
|
|
7665
|
-
markdown = await
|
|
7669
|
+
markdown = await readFile11(output.sourcePath, "utf8");
|
|
7666
7670
|
} catch (error) {
|
|
7667
7671
|
if (isMissingFileError(error)) {
|
|
7668
7672
|
throw new MissingArticleError(`Generation "${generationId}" no longer exists.`);
|
|
@@ -7718,41 +7722,15 @@ function isMissingFileError(error) {
|
|
|
7718
7722
|
}
|
|
7719
7723
|
async function renderArticleHtml(markdown, generationId, sourcePath) {
|
|
7720
7724
|
let content = stripFrontmatter2(markdown);
|
|
7721
|
-
const links = await
|
|
7725
|
+
const links = await loadLinksFromSidecar(sourcePath);
|
|
7722
7726
|
content = enrichMarkdownWithLinks(content, links);
|
|
7723
7727
|
const html = await marked.parse(content);
|
|
7724
7728
|
return rewriteRelativeAssetUrls(html, generationId);
|
|
7725
7729
|
}
|
|
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
7730
|
async function loadSavedInteractions(generationDir) {
|
|
7753
7731
|
const interactionsPath = path13.join(generationDir, "model.interactions.json");
|
|
7754
7732
|
try {
|
|
7755
|
-
const raw = await
|
|
7733
|
+
const raw = await readFile11(interactionsPath, "utf8");
|
|
7756
7734
|
const parsed = JSON.parse(raw);
|
|
7757
7735
|
const llmCalls = Array.isArray(parsed.llmCalls) ? parsed.llmCalls.filter(isPreviewLlmInteraction) : [];
|
|
7758
7736
|
const t2iCalls = Array.isArray(parsed.t2iCalls) ? parsed.t2iCalls.filter(isPreviewT2IInteraction) : [];
|
|
@@ -7770,7 +7748,7 @@ async function loadSavedInteractions(generationDir) {
|
|
|
7770
7748
|
async function loadSavedAnalyticsSummary(generationDir) {
|
|
7771
7749
|
const analyticsPath = path13.join(generationDir, "generation.analytics.json");
|
|
7772
7750
|
try {
|
|
7773
|
-
const raw = await
|
|
7751
|
+
const raw = await readFile11(analyticsPath, "utf8");
|
|
7774
7752
|
const parsed = JSON.parse(raw);
|
|
7775
7753
|
const summary = parsed.summary;
|
|
7776
7754
|
if (!summary || typeof summary !== "object") {
|
|
@@ -7794,7 +7772,7 @@ async function loadSavedAnalyticsSummary(generationDir) {
|
|
|
7794
7772
|
async function loadSavedMetaJson(generationDir) {
|
|
7795
7773
|
const metaJsonPath = path13.join(generationDir, "meta.json");
|
|
7796
7774
|
try {
|
|
7797
|
-
const raw = await
|
|
7775
|
+
const raw = await readFile11(metaJsonPath, "utf8");
|
|
7798
7776
|
return JSON.parse(raw);
|
|
7799
7777
|
} catch {
|
|
7800
7778
|
return null;
|