@vncsleal/quillby 0.3.0
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/LICENSE +21 -0
- package/README.md +140 -0
- package/bin/quillby-mcp +12 -0
- package/config/context.json +1 -0
- package/config/memory.json +1 -0
- package/config/rss_sources.txt +2 -0
- package/dist/agent.d.ts +21 -0
- package/dist/agent.js +61 -0
- package/dist/agent.js.map +1 -0
- package/dist/agents/compose.d.ts +2 -0
- package/dist/agents/compose.js +40 -0
- package/dist/agents/compose.js.map +1 -0
- package/dist/agents/discover.d.ts +15 -0
- package/dist/agents/discover.js +39 -0
- package/dist/agents/discover.js.map +1 -0
- package/dist/agents/harvest.d.ts +31 -0
- package/dist/agents/harvest.js +100 -0
- package/dist/agents/harvest.js.map +1 -0
- package/dist/agents/onboard.d.ts +14 -0
- package/dist/agents/onboard.js +88 -0
- package/dist/agents/onboard.js.map +1 -0
- package/dist/agents/seeds.d.ts +34 -0
- package/dist/agents/seeds.js +64 -0
- package/dist/agents/seeds.js.map +1 -0
- package/dist/cli.d.ts +44 -0
- package/dist/cli.js +233 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/extractors/content.d.ts +13 -0
- package/dist/extractors/content.js +93 -0
- package/dist/extractors/content.js.map +1 -0
- package/dist/extractors/reddit.d.ts +7 -0
- package/dist/extractors/reddit.js +69 -0
- package/dist/extractors/reddit.js.map +1 -0
- package/dist/extractors/rss.d.ts +4 -0
- package/dist/extractors/rss.js +58 -0
- package/dist/extractors/rss.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +139 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +192 -0
- package/dist/init.js.map +1 -0
- package/dist/llm.d.ts +2 -0
- package/dist/llm.js +11 -0
- package/dist/llm.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +1278 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/output/feedback.d.ts +51 -0
- package/dist/output/feedback.js +78 -0
- package/dist/output/feedback.js.map +1 -0
- package/dist/output/structures.d.ts +5 -0
- package/dist/output/structures.js +121 -0
- package/dist/output/structures.js.map +1 -0
- package/dist/types.d.ts +305 -0
- package/dist/types.js +74 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic RSS feed discovery — no hardcoded lists.
|
|
3
|
+
*
|
|
4
|
+
* Sources:
|
|
5
|
+
* 1. Google News RSS — one query-based feed per topic, zero API keys, multilingual
|
|
6
|
+
* 2. Medium tag feeds — one feed per topic, covers any niche (healthcare, law, fashion, etc.)
|
|
7
|
+
* 3. Feedly Search — discovers curated publication feeds by topic (no key required)
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Build Google News RSS search URLs for each topic.
|
|
11
|
+
* Results are real-time news, multilingual, maintained by Google.
|
|
12
|
+
*
|
|
13
|
+
* @param topics User topic strings
|
|
14
|
+
* @param hl BCP-47 language tag: "en-US", "pt-BR", "fr-FR", etc.
|
|
15
|
+
* @param gl ISO 3166-1 country code: "US", "BR", "FR", etc.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getGoogleNewsFeeds(topics: string[], hl?: string, gl?: string): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Build Medium tag RSS feed URLs for each topic.
|
|
20
|
+
* Medium covers virtually every professional topic: healthcare, law, fashion,
|
|
21
|
+
* farming, construction, marketing, fitness, finance, etc.
|
|
22
|
+
* No API key required — these are standard RSS feeds.
|
|
23
|
+
*
|
|
24
|
+
* Topics are slugified (lowercase, spaces → dashes) to match Medium tag format.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getMediumTagFeeds(topics: string[]): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Query Feedly's free search endpoint to find curated publication RSS/Atom feeds
|
|
29
|
+
* for each topic. Returns raw feed URLs ("feed/" prefix stripped).
|
|
30
|
+
*
|
|
31
|
+
* No API key required. Each topic is fetched independently; network errors
|
|
32
|
+
* are swallowed per-topic so a single failure never aborts the whole run.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getFeedlyFeeds(topics: string[], perTopic?: number): Promise<string[]>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic RSS feed discovery — no hardcoded lists.
|
|
3
|
+
*
|
|
4
|
+
* Sources:
|
|
5
|
+
* 1. Google News RSS — one query-based feed per topic, zero API keys, multilingual
|
|
6
|
+
* 2. Medium tag feeds — one feed per topic, covers any niche (healthcare, law, fashion, etc.)
|
|
7
|
+
* 3. Feedly Search — discovers curated publication feeds by topic (no key required)
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Build Google News RSS search URLs for each topic.
|
|
11
|
+
* Results are real-time news, multilingual, maintained by Google.
|
|
12
|
+
*
|
|
13
|
+
* @param topics User topic strings
|
|
14
|
+
* @param hl BCP-47 language tag: "en-US", "pt-BR", "fr-FR", etc.
|
|
15
|
+
* @param gl ISO 3166-1 country code: "US", "BR", "FR", etc.
|
|
16
|
+
*/
|
|
17
|
+
export function getGoogleNewsFeeds(topics, hl = "en-US", gl = "US") {
|
|
18
|
+
const lang = hl.split("-")[0];
|
|
19
|
+
return topics.map((t) => `https://news.google.com/rss/search?q=${encodeURIComponent(t)}&hl=${hl}&gl=${gl}&ceid=${gl}:${lang}`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build Medium tag RSS feed URLs for each topic.
|
|
23
|
+
* Medium covers virtually every professional topic: healthcare, law, fashion,
|
|
24
|
+
* farming, construction, marketing, fitness, finance, etc.
|
|
25
|
+
* No API key required — these are standard RSS feeds.
|
|
26
|
+
*
|
|
27
|
+
* Topics are slugified (lowercase, spaces → dashes) to match Medium tag format.
|
|
28
|
+
*/
|
|
29
|
+
export function getMediumTagFeeds(topics) {
|
|
30
|
+
return topics.map((t) => {
|
|
31
|
+
const slug = t.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
|
32
|
+
return `https://medium.com/feed/tag/${slug}`;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Query Feedly's free search endpoint to find curated publication RSS/Atom feeds
|
|
37
|
+
* for each topic. Returns raw feed URLs ("feed/" prefix stripped).
|
|
38
|
+
*
|
|
39
|
+
* No API key required. Each topic is fetched independently; network errors
|
|
40
|
+
* are swallowed per-topic so a single failure never aborts the whole run.
|
|
41
|
+
*/
|
|
42
|
+
export async function getFeedlyFeeds(topics, perTopic = 3) {
|
|
43
|
+
const found = new Set();
|
|
44
|
+
for (const topic of topics) {
|
|
45
|
+
try {
|
|
46
|
+
const url = `https://cloud.feedly.com/v3/search/feeds?query=${encodeURIComponent(topic)}&count=${perTopic}`;
|
|
47
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(6000) });
|
|
48
|
+
if (!res.ok)
|
|
49
|
+
continue;
|
|
50
|
+
const data = (await res.json());
|
|
51
|
+
for (const r of data.results ?? []) {
|
|
52
|
+
// feedId format: "feed/https://example.com/rss" — strip the prefix
|
|
53
|
+
if (r.feedId?.startsWith("feed/http")) {
|
|
54
|
+
found.add(r.feedId.slice(5));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// network error or timeout — skip this topic
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...found];
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=seeds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeds.js","sourceRoot":"","sources":["../../src/agents/seeds.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAgB,EAChB,EAAE,GAAG,OAAO,EACZ,EAAE,GAAG,IAAI;IAET,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,GAAG,CACf,CAAC,CAAC,EAAE,EAAE,CACJ,wCAAwC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CACvG,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAgB;IAChD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACpF,OAAO,+BAA+B,IAAI,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAgB,EAChB,QAAQ,GAAG,CAAC;IAEZ,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,kDAAkD,kBAAkB,CAAC,KAAK,CAAC,UAAU,QAAQ,EAAE,CAAC;YAC5G,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,SAAS;YACtB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwC,CAAC;YACvE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;gBACnC,mEAAmE;gBACnE,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;oBACtC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,6CAA6C;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Start an animated spinner
|
|
3
|
+
*/
|
|
4
|
+
export declare function startSpinner(text: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* Stop the spinner and clear the line
|
|
7
|
+
*/
|
|
8
|
+
export declare function stopSpinner(): void;
|
|
9
|
+
export declare function printHeader(title: string, subtitle: string): void;
|
|
10
|
+
export declare function printStageStart(stageName: string): void;
|
|
11
|
+
export declare function printProgress(current: number, total: number, context?: string): void;
|
|
12
|
+
export declare function printProgressDone(): void;
|
|
13
|
+
export declare function printResult(label: string, count: number, total?: number, details?: string): void;
|
|
14
|
+
export declare function printSummaryLine(label: string, value: string | number): void;
|
|
15
|
+
export declare function printSelection(items: string[], limit?: number): void;
|
|
16
|
+
export declare function printError(message: string): void;
|
|
17
|
+
export declare function printCompletion(stats: {
|
|
18
|
+
feeds: number;
|
|
19
|
+
raw: number;
|
|
20
|
+
selected: number;
|
|
21
|
+
researched: number;
|
|
22
|
+
trends: number;
|
|
23
|
+
concepts: number;
|
|
24
|
+
drafts: number;
|
|
25
|
+
calls: number;
|
|
26
|
+
failed: number;
|
|
27
|
+
duration: string;
|
|
28
|
+
cost?: number;
|
|
29
|
+
billedCost?: number;
|
|
30
|
+
outputDir?: string;
|
|
31
|
+
}): void;
|
|
32
|
+
export declare function printSection(title: string): void;
|
|
33
|
+
export declare function printInitCompletion(stats: {
|
|
34
|
+
agentsPersonalized: number;
|
|
35
|
+
agentsTotal: number;
|
|
36
|
+
failed: number;
|
|
37
|
+
writingSamples: number;
|
|
38
|
+
rssSeed: boolean;
|
|
39
|
+
duration: string;
|
|
40
|
+
cost?: number;
|
|
41
|
+
billedCost?: number;
|
|
42
|
+
}): void;
|
|
43
|
+
export declare function printMessage(text: string, level?: "info" | "success" | "muted"): void;
|
|
44
|
+
export declare function clearLine(): void;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import * as readline from "readline";
|
|
3
|
+
/**
|
|
4
|
+
* Beautiful CLI utilities with detailed output
|
|
5
|
+
*/
|
|
6
|
+
const colors = {
|
|
7
|
+
heading: (text) => chalk.bold.cyan(text),
|
|
8
|
+
section: (text) => chalk.bold.white(text),
|
|
9
|
+
subsection: (text) => chalk.cyan(text),
|
|
10
|
+
success: (text) => chalk.green(text),
|
|
11
|
+
status: (text) => chalk.gray(text),
|
|
12
|
+
number: (text) => chalk.bold.yellow(text),
|
|
13
|
+
highlight: (text) => chalk.bold.white(text),
|
|
14
|
+
muted: (text) => chalk.dim.gray(text),
|
|
15
|
+
error: (text) => chalk.red(text),
|
|
16
|
+
secondary: (text) => chalk.gray(text),
|
|
17
|
+
};
|
|
18
|
+
// Spinner animation frames
|
|
19
|
+
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
20
|
+
let spinnerFrame = 0;
|
|
21
|
+
let spinnerInterval = null;
|
|
22
|
+
let spinnerText = "";
|
|
23
|
+
/**
|
|
24
|
+
* Start an animated spinner
|
|
25
|
+
*/
|
|
26
|
+
export function startSpinner(text) {
|
|
27
|
+
spinnerText = text;
|
|
28
|
+
spinnerFrame = 0;
|
|
29
|
+
spinnerInterval = setInterval(() => {
|
|
30
|
+
const frame = spinnerFrames[spinnerFrame % spinnerFrames.length];
|
|
31
|
+
const line = ` ${colors.subsection(frame)} ${text}`;
|
|
32
|
+
readline.cursorTo(process.stdout, 0);
|
|
33
|
+
process.stdout.write(line.padEnd(80));
|
|
34
|
+
readline.cursorTo(process.stdout, 0);
|
|
35
|
+
spinnerFrame++;
|
|
36
|
+
}, 80);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Stop the spinner and clear the line
|
|
40
|
+
*/
|
|
41
|
+
export function stopSpinner() {
|
|
42
|
+
if (spinnerInterval) {
|
|
43
|
+
clearInterval(spinnerInterval);
|
|
44
|
+
spinnerInterval = null;
|
|
45
|
+
}
|
|
46
|
+
readline.clearLine(process.stdout, 0);
|
|
47
|
+
readline.cursorTo(process.stdout, 0);
|
|
48
|
+
}
|
|
49
|
+
export function printHeader(title, subtitle) {
|
|
50
|
+
console.log("");
|
|
51
|
+
console.log(colors.heading(` ╭─ ${title}`));
|
|
52
|
+
console.log(colors.muted(` ╰─ ${subtitle}`));
|
|
53
|
+
console.log("");
|
|
54
|
+
}
|
|
55
|
+
export function printStageStart(stageName) {
|
|
56
|
+
console.log("");
|
|
57
|
+
console.log(colors.section(` ▸ ${stageName}`));
|
|
58
|
+
}
|
|
59
|
+
export function printProgress(current, total, context) {
|
|
60
|
+
const percent = Math.round((current / total) * 100);
|
|
61
|
+
const bar = createProgressBar(percent);
|
|
62
|
+
const status = `${colors.number(current.toString())}/${colors.muted(total.toString())}`;
|
|
63
|
+
const ctx = context ? ` ${colors.muted(context)}` : "";
|
|
64
|
+
const line = ` ${bar} ${status}${ctx}`;
|
|
65
|
+
process.stdout.write(`\r${line.padEnd(90)}`);
|
|
66
|
+
}
|
|
67
|
+
export function printProgressDone() {
|
|
68
|
+
process.stdout.write("\n");
|
|
69
|
+
}
|
|
70
|
+
function createProgressBar(percent, width = 20) {
|
|
71
|
+
const filled = Math.round((percent / 100) * width);
|
|
72
|
+
const empty = width - filled;
|
|
73
|
+
const filledPart = colors.success("█".repeat(filled));
|
|
74
|
+
const emptyPart = colors.muted("░".repeat(empty));
|
|
75
|
+
return `[${filledPart}${emptyPart}]`;
|
|
76
|
+
}
|
|
77
|
+
export function printResult(label, count, total, details) {
|
|
78
|
+
const countStr = total
|
|
79
|
+
? `${colors.number(count.toString())} ${colors.muted(`/ ${total}`)}`
|
|
80
|
+
: colors.number(count.toString());
|
|
81
|
+
const detail = details ? ` ${colors.muted(`(${details})`)}` : "";
|
|
82
|
+
console.log(` ${colors.success("✓")} ${label} ${countStr}${detail}`);
|
|
83
|
+
}
|
|
84
|
+
export function printSummaryLine(label, value) {
|
|
85
|
+
const formattedValue = typeof value === "number" ? colors.number(String(value)) : value;
|
|
86
|
+
const paddedLabel = label.padEnd(24);
|
|
87
|
+
console.log(` ${colors.secondary(paddedLabel)} ${formattedValue}`);
|
|
88
|
+
}
|
|
89
|
+
export function printSelection(items, limit = 5) {
|
|
90
|
+
items.slice(0, limit).forEach((item, i) => {
|
|
91
|
+
console.log(` ${colors.secondary(`${(i + 1).toString().padStart(2)}.`)} ${item}`);
|
|
92
|
+
});
|
|
93
|
+
if (items.length > limit) {
|
|
94
|
+
console.log(` ${colors.muted(`... and ${items.length - limit} more`)}`);
|
|
95
|
+
}
|
|
96
|
+
console.log("");
|
|
97
|
+
}
|
|
98
|
+
export function printError(message) {
|
|
99
|
+
console.error(`\n ${colors.error("✘ " + message)}\n`);
|
|
100
|
+
}
|
|
101
|
+
export function printCompletion(stats) {
|
|
102
|
+
const boxWidth = getCompletionBoxWidth();
|
|
103
|
+
const title = "─ PIPELINE COMPLETE ";
|
|
104
|
+
const topFill = Math.max(0, boxWidth - title.length);
|
|
105
|
+
console.log("");
|
|
106
|
+
console.log(colors.section(` ╭${title}${"─".repeat(topFill)}╮`));
|
|
107
|
+
printBoxEmpty(boxWidth);
|
|
108
|
+
printBoxHeader("Metrics", boxWidth);
|
|
109
|
+
printBoxDivider(boxWidth);
|
|
110
|
+
printBoxStat("Feeds scanned", stats.feeds, boxWidth);
|
|
111
|
+
printBoxStat("Raw items fetched", stats.raw, boxWidth);
|
|
112
|
+
printBoxStat("Items selected", stats.selected, boxWidth);
|
|
113
|
+
printBoxStat("Articles researched", stats.researched, boxWidth);
|
|
114
|
+
printBoxStat("Trends identified", stats.trends, boxWidth);
|
|
115
|
+
printBoxStat("Content concepts", stats.concepts, boxWidth);
|
|
116
|
+
printBoxStat("Drafts generated", stats.drafts, boxWidth);
|
|
117
|
+
printBoxDivider(boxWidth);
|
|
118
|
+
printBoxHeader("API Usage", boxWidth);
|
|
119
|
+
printBoxDivider(boxWidth);
|
|
120
|
+
printBoxStat("Total LLM calls", stats.calls, boxWidth);
|
|
121
|
+
if (stats.failed > 0) {
|
|
122
|
+
printBoxStat("Failed calls", stats.failed, boxWidth, true);
|
|
123
|
+
}
|
|
124
|
+
if (stats.cost !== undefined) {
|
|
125
|
+
const costStr = `$${stats.cost.toFixed(4)}`;
|
|
126
|
+
const label = stats.billedCost !== undefined ? "Estimated cost" : "Estimated cost";
|
|
127
|
+
printBoxStatStr(label, costStr, boxWidth);
|
|
128
|
+
}
|
|
129
|
+
if (stats.billedCost !== undefined) {
|
|
130
|
+
const billedStr = `$${stats.billedCost.toFixed(4)}`;
|
|
131
|
+
printBoxStatStr("Actual billed cost", billedStr, boxWidth);
|
|
132
|
+
}
|
|
133
|
+
printBoxDivider(boxWidth);
|
|
134
|
+
printBoxHeader("Duration", boxWidth);
|
|
135
|
+
printBoxDivider(boxWidth);
|
|
136
|
+
printBoxValue(stats.duration, boxWidth);
|
|
137
|
+
if (stats.outputDir) {
|
|
138
|
+
printBoxDivider(boxWidth);
|
|
139
|
+
printBoxHeader("Output", boxWidth);
|
|
140
|
+
printBoxDivider(boxWidth);
|
|
141
|
+
const outputPath = stats.outputDir.replace(process.cwd(), ".");
|
|
142
|
+
printBoxStatStr("Directory", outputPath, boxWidth);
|
|
143
|
+
}
|
|
144
|
+
printBoxEmpty(boxWidth);
|
|
145
|
+
console.log(colors.section(` ╰${"─".repeat(boxWidth)}╯`));
|
|
146
|
+
console.log("");
|
|
147
|
+
}
|
|
148
|
+
function printBoxEmpty(width) {
|
|
149
|
+
console.log(colors.section(" │") + " ".repeat(width) + colors.section("│"));
|
|
150
|
+
}
|
|
151
|
+
function printBoxDivider(width) {
|
|
152
|
+
console.log(colors.section(" │") + colors.muted(" " + "─".repeat(width - 2)) + colors.section("│"));
|
|
153
|
+
}
|
|
154
|
+
function printBoxHeader(title, width) {
|
|
155
|
+
const left = ` ${title}`;
|
|
156
|
+
const row = left.padEnd(width, " ");
|
|
157
|
+
console.log(colors.section(" │") + colors.subsection(row) + colors.section("│"));
|
|
158
|
+
}
|
|
159
|
+
function printBoxStat(label, value, width, isError = false) {
|
|
160
|
+
const icon = isError ? colors.error("✘") : colors.success("✓");
|
|
161
|
+
const leftPlain = ` ${isError ? "✘" : "✓"} ${label}`;
|
|
162
|
+
const rightPlain = String(value);
|
|
163
|
+
const gap = Math.max(1, width - leftPlain.length - rightPlain.length - 2);
|
|
164
|
+
const row = ` ${icon} ${isError ? colors.error(label) : label}${" ".repeat(gap)}${colors.number(rightPlain)}`;
|
|
165
|
+
console.log(colors.section(" │") + row + " " + colors.section("│"));
|
|
166
|
+
}
|
|
167
|
+
function printBoxStatStr(label, value, width) {
|
|
168
|
+
const leftPlain = ` ✓ ${label}`;
|
|
169
|
+
const rightPlain = value;
|
|
170
|
+
const gap = Math.max(1, width - leftPlain.length - rightPlain.length - 2);
|
|
171
|
+
const row = ` ${colors.success("✓")} ${label}${" ".repeat(gap)}${colors.number(rightPlain)}`;
|
|
172
|
+
console.log(colors.section(" │") + row + " " + colors.section("│"));
|
|
173
|
+
}
|
|
174
|
+
function printBoxValue(value, width) {
|
|
175
|
+
const text = colors.number(value);
|
|
176
|
+
const leftPad = Math.max(0, Math.floor((width - value.length) / 2));
|
|
177
|
+
const rightPad = Math.max(0, width - leftPad - value.length);
|
|
178
|
+
console.log(colors.section(" │") + " ".repeat(leftPad) + text + " ".repeat(rightPad) + colors.section("│"));
|
|
179
|
+
}
|
|
180
|
+
function getCompletionBoxWidth() {
|
|
181
|
+
const terminalCols = process.stdout.columns ?? 80;
|
|
182
|
+
const minWidth = 48;
|
|
183
|
+
const maxWidth = 68;
|
|
184
|
+
const horizontalPadding = 4;
|
|
185
|
+
const target = terminalCols - horizontalPadding;
|
|
186
|
+
return Math.max(minWidth, Math.min(maxWidth, target));
|
|
187
|
+
}
|
|
188
|
+
export function printSection(title) {
|
|
189
|
+
console.log("");
|
|
190
|
+
console.log(colors.subsection(` ◆ ${title}`));
|
|
191
|
+
}
|
|
192
|
+
export function printInitCompletion(stats) {
|
|
193
|
+
const boxWidth = getCompletionBoxWidth();
|
|
194
|
+
const title = "─ INIT COMPLETE ";
|
|
195
|
+
const topFill = Math.max(0, boxWidth - title.length);
|
|
196
|
+
console.log("");
|
|
197
|
+
console.log(colors.section(` ╭${title}${"─".repeat(topFill)}╮`));
|
|
198
|
+
printBoxEmpty(boxWidth);
|
|
199
|
+
printBoxHeader("Setup", boxWidth);
|
|
200
|
+
printBoxDivider(boxWidth);
|
|
201
|
+
printBoxStat("Agents personalized", stats.agentsPersonalized, boxWidth);
|
|
202
|
+
if (stats.failed > 0)
|
|
203
|
+
printBoxStat("Agents failed", stats.failed, boxWidth, true);
|
|
204
|
+
printBoxStat("Writing samples used", stats.writingSamples, boxWidth);
|
|
205
|
+
printBoxStat("RSS seed generated", stats.rssSeed ? 1 : 0, boxWidth);
|
|
206
|
+
if (stats.cost !== undefined) {
|
|
207
|
+
printBoxDivider(boxWidth);
|
|
208
|
+
printBoxHeader("API Usage", boxWidth);
|
|
209
|
+
printBoxDivider(boxWidth);
|
|
210
|
+
const costStr = `$${stats.cost.toFixed(4)}`;
|
|
211
|
+
const label = stats.billedCost !== undefined ? "Estimated cost" : "Estimated cost";
|
|
212
|
+
printBoxStatStr(label, costStr, boxWidth);
|
|
213
|
+
}
|
|
214
|
+
if (stats.billedCost !== undefined) {
|
|
215
|
+
const billedStr = `$${stats.billedCost.toFixed(4)}`;
|
|
216
|
+
printBoxStatStr("Actual billed cost", billedStr, boxWidth);
|
|
217
|
+
}
|
|
218
|
+
printBoxDivider(boxWidth);
|
|
219
|
+
printBoxHeader("Duration", boxWidth);
|
|
220
|
+
printBoxDivider(boxWidth);
|
|
221
|
+
printBoxValue(stats.duration, boxWidth);
|
|
222
|
+
printBoxEmpty(boxWidth);
|
|
223
|
+
console.log(colors.section(` ╰${"─".repeat(boxWidth)}╯`));
|
|
224
|
+
console.log("");
|
|
225
|
+
}
|
|
226
|
+
export function printMessage(text, level = "info") {
|
|
227
|
+
const styled = level === "success" ? colors.success(text) : level === "muted" ? colors.muted(text) : text;
|
|
228
|
+
console.log(` ${styled}`);
|
|
229
|
+
}
|
|
230
|
+
export function clearLine() {
|
|
231
|
+
process.stdout.write("\r" + " ".repeat(100) + "\r");
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const CONFIG: {
|
|
2
|
+
FILES: {
|
|
3
|
+
CONTEXT: string;
|
|
4
|
+
MEMORY: string;
|
|
5
|
+
SOURCES: string;
|
|
6
|
+
OUTPUT_DIR: string;
|
|
7
|
+
CACHE: string;
|
|
8
|
+
};
|
|
9
|
+
RSS: {
|
|
10
|
+
ITEMS_PER_FEED: number;
|
|
11
|
+
TIMEOUT: number;
|
|
12
|
+
CONCURRENCY: number;
|
|
13
|
+
};
|
|
14
|
+
ENRICHMENT: {
|
|
15
|
+
ENABLED: boolean;
|
|
16
|
+
MAX_CONTENT_LENGTH: number;
|
|
17
|
+
TIMEOUT: number;
|
|
18
|
+
RETRIES: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function ensureDir(dir: string): void;
|
|
22
|
+
export declare function readTextFile(filePath: string): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
export const CONFIG = {
|
|
4
|
+
FILES: {
|
|
5
|
+
CONTEXT: path.join(process.cwd(), "config/context.json"),
|
|
6
|
+
MEMORY: path.join(process.cwd(), "config/memory.json"),
|
|
7
|
+
SOURCES: path.join(process.cwd(), "config/rss_sources.txt"),
|
|
8
|
+
OUTPUT_DIR: path.join(process.cwd(), "output"),
|
|
9
|
+
CACHE: path.join(process.cwd(), ".cache/seen_urls.json"),
|
|
10
|
+
},
|
|
11
|
+
RSS: {
|
|
12
|
+
ITEMS_PER_FEED: parseInt(process.env.RSS_ITEMS_PER_FEED || "5", 10),
|
|
13
|
+
TIMEOUT: 12000,
|
|
14
|
+
CONCURRENCY: 8,
|
|
15
|
+
},
|
|
16
|
+
ENRICHMENT: {
|
|
17
|
+
ENABLED: true,
|
|
18
|
+
MAX_CONTENT_LENGTH: 6000,
|
|
19
|
+
TIMEOUT: 10000,
|
|
20
|
+
RETRIES: 2,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export function ensureDir(dir) {
|
|
24
|
+
if (!fs.existsSync(dir))
|
|
25
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
export function readTextFile(filePath) {
|
|
28
|
+
const ext = path.extname(filePath);
|
|
29
|
+
const localVariant = ext
|
|
30
|
+
? `${filePath.slice(0, -ext.length)}.local${ext}`
|
|
31
|
+
: `${filePath}.local`;
|
|
32
|
+
for (const candidate of [localVariant, filePath]) {
|
|
33
|
+
const resolved = path.isAbsolute(candidate)
|
|
34
|
+
? candidate
|
|
35
|
+
: path.join(process.cwd(), candidate);
|
|
36
|
+
if (fs.existsSync(resolved))
|
|
37
|
+
return fs.readFileSync(resolved, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`Cannot read config file: ${filePath}`);
|
|
40
|
+
}
|
|
41
|
+
// Initialize required directories on import
|
|
42
|
+
ensureDir(path.dirname(CONFIG.FILES.CACHE));
|
|
43
|
+
ensureDir(CONFIG.FILES.OUTPUT_DIR);
|
|
44
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,EAAE;QACL,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAqB,CAAC;QACxD,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC;QACtD,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,wBAAwB,CAAC;QAC3D,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC;QAC9C,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uBAAuB,CAAC;KACzD;IACD,GAAG,EAAE;QACH,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,GAAG,EAAE,EAAE,CAAC;QACnE,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;KACf;IACD,UAAU,EAAE;QACV,OAAO,EAAE,IAAI;QACb,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,CAAC;KACX;CACF,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,GAAG;QACtB,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE;QACjD,CAAC,CAAC,GAAG,QAAQ,QAAQ,CAAC;IAExB,KAAK,MAAM,SAAS,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YACzC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;QACxC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,4CAA4C;AAC5C,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch HTML from a URL with redirect handling
|
|
3
|
+
*/
|
|
4
|
+
export declare function fetchURL(url: string, redirects?: number): Promise<string>;
|
|
5
|
+
/**
|
|
6
|
+
* Extract readable text from HTML using Mozilla Readability.
|
|
7
|
+
* Falls back to basic tag stripping if Readability cannot parse the page.
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractTextFromHTML(html: string, url: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Fetch and extract key content from a URL
|
|
12
|
+
*/
|
|
13
|
+
export declare function enrichArticle(url: string, title: string): Promise<string>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as https from "https";
|
|
2
|
+
import * as http from "http";
|
|
3
|
+
import { Readability } from "@mozilla/readability";
|
|
4
|
+
import { JSDOM } from "jsdom";
|
|
5
|
+
import { CONFIG } from "../config.js";
|
|
6
|
+
/**
|
|
7
|
+
* Fetch HTML from a URL with redirect handling
|
|
8
|
+
*/
|
|
9
|
+
export function fetchURL(url, redirects = 0) {
|
|
10
|
+
if (redirects > 5)
|
|
11
|
+
return Promise.resolve("");
|
|
12
|
+
// Validate URL
|
|
13
|
+
try {
|
|
14
|
+
new URL(url);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return Promise.resolve("");
|
|
18
|
+
}
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const protocol = url.startsWith("https") ? https : http;
|
|
21
|
+
const req = protocol.get(url, {
|
|
22
|
+
headers: {
|
|
23
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
|
|
24
|
+
Accept: "text/html,application/xhtml+xml",
|
|
25
|
+
},
|
|
26
|
+
timeout: CONFIG.ENRICHMENT.TIMEOUT,
|
|
27
|
+
}, (res) => {
|
|
28
|
+
// Handle redirects
|
|
29
|
+
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
30
|
+
const redirectUrl = new URL(res.headers.location, url).href;
|
|
31
|
+
fetchURL(redirectUrl, redirects + 1).then(resolve);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let data = "";
|
|
35
|
+
res.on("data", (chunk) => {
|
|
36
|
+
data += chunk;
|
|
37
|
+
});
|
|
38
|
+
res.on("end", () => resolve(data));
|
|
39
|
+
res.on("error", () => resolve(""));
|
|
40
|
+
});
|
|
41
|
+
req.on("error", () => resolve(""));
|
|
42
|
+
req.on("timeout", () => {
|
|
43
|
+
req.destroy();
|
|
44
|
+
resolve("");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extract readable text from HTML using Mozilla Readability.
|
|
50
|
+
* Falls back to basic tag stripping if Readability cannot parse the page.
|
|
51
|
+
*/
|
|
52
|
+
export function extractTextFromHTML(html, url) {
|
|
53
|
+
try {
|
|
54
|
+
const dom = new JSDOM(html, { url });
|
|
55
|
+
const article = new Readability(dom.window.document).parse();
|
|
56
|
+
if (article?.textContent) {
|
|
57
|
+
return article.textContent.replace(/\s+/g, " ").trim().slice(0, CONFIG.ENRICHMENT.MAX_CONTENT_LENGTH);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// fall through to basic extraction
|
|
62
|
+
}
|
|
63
|
+
// Fallback: strip all tags
|
|
64
|
+
return html
|
|
65
|
+
.replace(/<[^>]+>/g, " ")
|
|
66
|
+
.replace(/ /g, " ")
|
|
67
|
+
.replace(/&/g, "&")
|
|
68
|
+
.replace(/\s+/g, " ")
|
|
69
|
+
.trim()
|
|
70
|
+
.slice(0, CONFIG.ENRICHMENT.MAX_CONTENT_LENGTH);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Fetch and extract key content from a URL
|
|
74
|
+
*/
|
|
75
|
+
export async function enrichArticle(url, title) {
|
|
76
|
+
if (!CONFIG.ENRICHMENT.ENABLED)
|
|
77
|
+
return "";
|
|
78
|
+
for (let attempt = 0; attempt < CONFIG.ENRICHMENT.RETRIES; attempt++) {
|
|
79
|
+
try {
|
|
80
|
+
const html = await fetchURL(url);
|
|
81
|
+
if (!html)
|
|
82
|
+
continue;
|
|
83
|
+
const text = extractTextFromHTML(html, url);
|
|
84
|
+
if (text.length > 200)
|
|
85
|
+
return text;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// continue to next attempt
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/extractors/content.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RssItem } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fetch hot posts from a subreddit.
|
|
4
|
+
* @param subreddit subreddit name without r/ prefix (e.g. "marketing")
|
|
5
|
+
* @param sort "hot" | "new" | "top" | "rising"
|
|
6
|
+
*/
|
|
7
|
+
export declare function fetchReddit(subreddit: string, sort?: string, log?: (msg: string) => void): Promise<RssItem[]>;
|