linkpress 0.1.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 +184 -0
- package/dist/ai.d.ts +31 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +428 -0
- package/dist/ai.js.map +1 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +38 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/clear.d.ts +3 -0
- package/dist/commands/clear.d.ts.map +1 -0
- package/dist/commands/clear.js +25 -0
- package/dist/commands/clear.js.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +38 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/index.d.ts +9 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +9 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +129 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +33 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/serve.d.ts +3 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +122 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/source.d.ts +3 -0
- package/dist/commands/source.d.ts.map +1 -0
- package/dist/commands/source.js +48 -0
- package/dist/commands/source.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +24 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +47 -0
- package/dist/config.js.map +1 -0
- package/dist/db.d.ts +14 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +140 -0
- package/dist/db.js.map +1 -0
- package/dist/i18n.d.ts +4 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +139 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/magazine.d.ts +6 -0
- package/dist/magazine.d.ts.map +1 -0
- package/dist/magazine.js +1751 -0
- package/dist/magazine.js.map +1 -0
- package/dist/process.d.ts +16 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +77 -0
- package/dist/process.js.map +1 -0
- package/dist/scraper.d.ts +11 -0
- package/dist/scraper.d.ts.map +1 -0
- package/dist/scraper.js +159 -0
- package/dist/scraper.js.map +1 -0
- package/dist/slack/auth.d.ts +6 -0
- package/dist/slack/auth.d.ts.map +1 -0
- package/dist/slack/auth.js +373 -0
- package/dist/slack/auth.js.map +1 -0
- package/dist/slack/browser-auth.d.ts +6 -0
- package/dist/slack/browser-auth.d.ts.map +1 -0
- package/dist/slack/browser-auth.js +236 -0
- package/dist/slack/browser-auth.js.map +1 -0
- package/dist/slack/client.d.ts +45 -0
- package/dist/slack/client.d.ts.map +1 -0
- package/dist/slack/client.js +98 -0
- package/dist/slack/client.js.map +1 -0
- package/dist/slack/index.d.ts +6 -0
- package/dist/slack/index.d.ts.map +1 -0
- package/dist/slack/index.js +4 -0
- package/dist/slack/index.js.map +1 -0
- package/dist/slack/sync.d.ts +12 -0
- package/dist/slack/sync.d.ts.map +1 -0
- package/dist/slack/sync.js +182 -0
- package/dist/slack/sync.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +15 -0
- package/dist/utils.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { syncSlackSources } from '../slack/index.js';
|
|
4
|
+
import { t } from '../i18n.js';
|
|
5
|
+
export const syncCommand = new Command('sync')
|
|
6
|
+
.description('Sync articles from configured sources')
|
|
7
|
+
.action(async () => {
|
|
8
|
+
console.log(chalk.bold(`\n🔄 ${t('sync.start')}\n`));
|
|
9
|
+
const result = await syncSlackSources();
|
|
10
|
+
console.log(chalk.bold('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
11
|
+
console.log(chalk.bold(`📊 ${t('sync.summary')}`));
|
|
12
|
+
console.log(chalk.dim(` ${t('sync.totalLinks', { count: result.total })}`));
|
|
13
|
+
console.log(chalk.green(` ${t('sync.newArticles', { count: result.newArticles })}`));
|
|
14
|
+
console.log(chalk.dim(` ${t('sync.alreadySaved', { count: result.skipped })}`));
|
|
15
|
+
console.log(chalk.yellow(` ${t('sync.filteredOut', { count: result.filtered })}`));
|
|
16
|
+
console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
17
|
+
if (result.newArticles > 0) {
|
|
18
|
+
console.log(chalk.dim(t('sync.generateHint')));
|
|
19
|
+
}
|
|
20
|
+
else if (result.total === 0) {
|
|
21
|
+
console.log(chalk.dim(t('sync.noLinksHint')));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAE/B,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAEjE,IAAI,MAAM,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config } from './types.js';
|
|
2
|
+
export declare function getConfigDir(): string;
|
|
3
|
+
export declare function getDbPath(): string;
|
|
4
|
+
export declare function ensureConfigDir(): void;
|
|
5
|
+
export declare function getDefaultConfig(): Config;
|
|
6
|
+
export declare function loadConfig(): Config;
|
|
7
|
+
export declare function saveConfig(config: Config): void;
|
|
8
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAMzC,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAazC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAWnC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAG/C"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import YAML from 'yaml';
|
|
5
|
+
const CONFIG_DIR = path.join(os.homedir(), '.linkpress');
|
|
6
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.yaml');
|
|
7
|
+
const DB_FILE = path.join(CONFIG_DIR, 'linkpress.db');
|
|
8
|
+
export function getConfigDir() {
|
|
9
|
+
return CONFIG_DIR;
|
|
10
|
+
}
|
|
11
|
+
export function getDbPath() {
|
|
12
|
+
return DB_FILE;
|
|
13
|
+
}
|
|
14
|
+
export function ensureConfigDir() {
|
|
15
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
16
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function getDefaultConfig() {
|
|
20
|
+
return {
|
|
21
|
+
sources: {},
|
|
22
|
+
ai: {
|
|
23
|
+
provider: 'anthropic',
|
|
24
|
+
model: '',
|
|
25
|
+
language: 'English',
|
|
26
|
+
},
|
|
27
|
+
output: {
|
|
28
|
+
directory: path.join(CONFIG_DIR, 'output'),
|
|
29
|
+
format: 'html',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function loadConfig() {
|
|
34
|
+
ensureConfigDir();
|
|
35
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
36
|
+
const defaultConfig = getDefaultConfig();
|
|
37
|
+
saveConfig(defaultConfig);
|
|
38
|
+
return defaultConfig;
|
|
39
|
+
}
|
|
40
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
41
|
+
return YAML.parse(content);
|
|
42
|
+
}
|
|
43
|
+
export function saveConfig(config) {
|
|
44
|
+
ensureConfigDir();
|
|
45
|
+
fs.writeFileSync(CONFIG_FILE, YAML.stringify(config), 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AACzD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;AAEtD,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,OAAO,EAAE,EAAE;QACX,EAAE,EAAE;YACF,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,SAAS;SACpB;QACD,MAAM,EAAE;YACN,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;YAC1C,MAAM,EAAE,MAAM;SACf;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,eAAe,EAAE,CAAC;IAElB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACzC,UAAU,CAAC,aAAa,CAAC,CAAC;QAC1B,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,eAAe,EAAE,CAAC;IAClB,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC"}
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import type { Article } from './types.js';
|
|
3
|
+
export declare function getDb(): Database.Database;
|
|
4
|
+
export declare function insertArticle(article: Article): void;
|
|
5
|
+
export declare function getUnprocessedArticles(): Article[];
|
|
6
|
+
export declare function getArticlesForReprocess(limit?: number): Article[];
|
|
7
|
+
export declare function getAllArticles(limit?: number): Article[];
|
|
8
|
+
export declare function updateArticle(article: Article): void;
|
|
9
|
+
export declare function articleExists(url: string): boolean;
|
|
10
|
+
export declare function clearAllArticles(): number;
|
|
11
|
+
export declare function markAsRead(articleId: string): void;
|
|
12
|
+
export declare function markAsUnread(articleId: string): void;
|
|
13
|
+
export declare function getArticleById(articleId: string): Article | undefined;
|
|
14
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAOzC;AA+CD,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyBpD;AAED,wBAAgB,sBAAsB,IAAI,OAAO,EAAE,CAOlD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAM,GAAG,OAAO,EAAE,CAO9D;AAED,wBAAgB,cAAc,CAAC,KAAK,SAAM,GAAG,OAAO,EAAE,CAOrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBpD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIlD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAMlD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGpD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAIrE"}
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { getDbPath, ensureConfigDir } from './config.js';
|
|
3
|
+
let db = null;
|
|
4
|
+
export function getDb() {
|
|
5
|
+
if (!db) {
|
|
6
|
+
ensureConfigDir();
|
|
7
|
+
db = new Database(getDbPath());
|
|
8
|
+
initSchema();
|
|
9
|
+
}
|
|
10
|
+
return db;
|
|
11
|
+
}
|
|
12
|
+
function initSchema() {
|
|
13
|
+
const database = db;
|
|
14
|
+
database.exec(`
|
|
15
|
+
CREATE TABLE IF NOT EXISTS articles (
|
|
16
|
+
id TEXT PRIMARY KEY,
|
|
17
|
+
url TEXT UNIQUE NOT NULL,
|
|
18
|
+
title TEXT,
|
|
19
|
+
description TEXT,
|
|
20
|
+
content TEXT,
|
|
21
|
+
summary TEXT,
|
|
22
|
+
tags TEXT,
|
|
23
|
+
difficulty TEXT,
|
|
24
|
+
reading_time_minutes INTEGER,
|
|
25
|
+
image TEXT,
|
|
26
|
+
source_label TEXT,
|
|
27
|
+
source_type TEXT NOT NULL,
|
|
28
|
+
source_id TEXT,
|
|
29
|
+
created_at TEXT NOT NULL,
|
|
30
|
+
processed_at TEXT
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_articles_url ON articles(url);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_articles_source ON articles(source_type, source_id);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_articles_created ON articles(created_at);
|
|
36
|
+
`);
|
|
37
|
+
migrateSchema(database);
|
|
38
|
+
}
|
|
39
|
+
function migrateSchema(database) {
|
|
40
|
+
const columns = database.prepare("PRAGMA table_info(articles)").all();
|
|
41
|
+
const columnNames = columns.map(c => c.name);
|
|
42
|
+
if (!columnNames.includes('image')) {
|
|
43
|
+
database.exec('ALTER TABLE articles ADD COLUMN image TEXT');
|
|
44
|
+
}
|
|
45
|
+
if (!columnNames.includes('source_label')) {
|
|
46
|
+
database.exec('ALTER TABLE articles ADD COLUMN source_label TEXT');
|
|
47
|
+
}
|
|
48
|
+
if (!columnNames.includes('read_at')) {
|
|
49
|
+
database.exec('ALTER TABLE articles ADD COLUMN read_at TEXT');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function insertArticle(article) {
|
|
53
|
+
const database = getDb();
|
|
54
|
+
const stmt = database.prepare(`
|
|
55
|
+
INSERT OR IGNORE INTO articles (
|
|
56
|
+
id, url, title, description, content, summary, tags,
|
|
57
|
+
difficulty, reading_time_minutes, source_type, source_id,
|
|
58
|
+
created_at, processed_at
|
|
59
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
60
|
+
`);
|
|
61
|
+
stmt.run(article.id, article.url, article.title, article.description ?? null, article.content ?? null, article.summary ?? null, JSON.stringify(article.tags), article.difficulty ?? null, article.readingTimeMinutes ?? null, article.sourceType, article.sourceId ?? null, article.createdAt.toISOString(), article.processedAt?.toISOString() ?? null);
|
|
62
|
+
}
|
|
63
|
+
export function getUnprocessedArticles() {
|
|
64
|
+
const database = getDb();
|
|
65
|
+
const rows = database.prepare(`
|
|
66
|
+
SELECT * FROM articles WHERE processed_at IS NULL ORDER BY created_at DESC
|
|
67
|
+
`).all();
|
|
68
|
+
return rows.map(rowToArticle);
|
|
69
|
+
}
|
|
70
|
+
export function getArticlesForReprocess(limit = 100) {
|
|
71
|
+
const database = getDb();
|
|
72
|
+
const rows = database.prepare(`
|
|
73
|
+
SELECT * FROM articles ORDER BY created_at DESC LIMIT ?
|
|
74
|
+
`).all(limit);
|
|
75
|
+
return rows.map(rowToArticle);
|
|
76
|
+
}
|
|
77
|
+
export function getAllArticles(limit = 100) {
|
|
78
|
+
const database = getDb();
|
|
79
|
+
const rows = database.prepare(`
|
|
80
|
+
SELECT * FROM articles ORDER BY created_at DESC LIMIT ?
|
|
81
|
+
`).all(limit);
|
|
82
|
+
return rows.map(rowToArticle);
|
|
83
|
+
}
|
|
84
|
+
export function updateArticle(article) {
|
|
85
|
+
const database = getDb();
|
|
86
|
+
const stmt = database.prepare(`
|
|
87
|
+
UPDATE articles SET
|
|
88
|
+
title = ?, description = ?, content = ?, summary = ?,
|
|
89
|
+
tags = ?, difficulty = ?, reading_time_minutes = ?,
|
|
90
|
+
image = ?, source_label = ?, processed_at = ?
|
|
91
|
+
WHERE id = ?
|
|
92
|
+
`);
|
|
93
|
+
stmt.run(article.title, article.description ?? null, article.content ?? null, article.summary ?? null, JSON.stringify(article.tags), article.difficulty ?? null, article.readingTimeMinutes ?? null, article.image ?? null, article.sourceLabel ?? null, article.processedAt?.toISOString() ?? null, article.id);
|
|
94
|
+
}
|
|
95
|
+
export function articleExists(url) {
|
|
96
|
+
const database = getDb();
|
|
97
|
+
const row = database.prepare('SELECT 1 FROM articles WHERE url = ?').get(url);
|
|
98
|
+
return !!row;
|
|
99
|
+
}
|
|
100
|
+
export function clearAllArticles() {
|
|
101
|
+
const database = getDb();
|
|
102
|
+
const countResult = database.prepare('SELECT COUNT(*) as count FROM articles').get();
|
|
103
|
+
const count = countResult.count;
|
|
104
|
+
database.prepare('DELETE FROM articles').run();
|
|
105
|
+
return count;
|
|
106
|
+
}
|
|
107
|
+
export function markAsRead(articleId) {
|
|
108
|
+
const database = getDb();
|
|
109
|
+
database.prepare('UPDATE articles SET read_at = ? WHERE id = ?').run(new Date().toISOString(), articleId);
|
|
110
|
+
}
|
|
111
|
+
export function markAsUnread(articleId) {
|
|
112
|
+
const database = getDb();
|
|
113
|
+
database.prepare('UPDATE articles SET read_at = NULL WHERE id = ?').run(articleId);
|
|
114
|
+
}
|
|
115
|
+
export function getArticleById(articleId) {
|
|
116
|
+
const database = getDb();
|
|
117
|
+
const row = database.prepare('SELECT * FROM articles WHERE id = ?').get(articleId);
|
|
118
|
+
return row ? rowToArticle(row) : undefined;
|
|
119
|
+
}
|
|
120
|
+
function rowToArticle(row) {
|
|
121
|
+
return {
|
|
122
|
+
id: row.id,
|
|
123
|
+
url: row.url,
|
|
124
|
+
title: row.title,
|
|
125
|
+
description: row.description,
|
|
126
|
+
content: row.content,
|
|
127
|
+
summary: row.summary,
|
|
128
|
+
tags: JSON.parse(row.tags || '[]'),
|
|
129
|
+
difficulty: row.difficulty,
|
|
130
|
+
readingTimeMinutes: row.reading_time_minutes,
|
|
131
|
+
image: row.image,
|
|
132
|
+
sourceLabel: row.source_label,
|
|
133
|
+
sourceType: row.source_type,
|
|
134
|
+
sourceId: row.source_id,
|
|
135
|
+
createdAt: new Date(row.created_at),
|
|
136
|
+
processedAt: row.processed_at ? new Date(row.processed_at) : undefined,
|
|
137
|
+
readAt: row.read_at ? new Date(row.read_at) : undefined,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
type MessageKey = 'sync.start' | 'sync.noSources' | 'sync.noSourcesHint' | 'sync.syncing' | 'sync.fetching' | 'sync.classifying' | 'sync.channelResult' | 'sync.channelFailed' | 'sync.summary' | 'sync.totalLinks' | 'sync.newArticles' | 'sync.alreadySaved' | 'sync.filteredOut' | 'sync.generateHint' | 'sync.noLinksHint' | 'clear.confirm' | 'clear.cancelled' | 'clear.success' | 'init.welcome' | 'init.selectProvider' | 'init.enterApiKey' | 'init.fetchingModels' | 'init.foundModels' | 'init.selectModel' | 'init.enterModelId' | 'init.selectLanguage' | 'init.enterLanguage' | 'init.selectOutputFormat' | 'init.configSaved' | 'init.nextSteps' | 'generate.processingSummary' | 'generate.processed' | 'generate.articleStats' | 'generate.total' | 'generate.ready' | 'generate.pending' | 'generate.magazineGenerated' | 'generate.serveHint' | 'generate.noArticles';
|
|
2
|
+
export declare function t(key: MessageKey, params?: Record<string, string | number>): string;
|
|
3
|
+
export {};
|
|
4
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GACX,YAAY,GACZ,gBAAgB,GAChB,oBAAoB,GACpB,cAAc,GACd,eAAe,GACf,kBAAkB,GAClB,oBAAoB,GACpB,oBAAoB,GACpB,cAAc,GACd,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,GAClB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,cAAc,GACd,qBAAqB,GACrB,kBAAkB,GAClB,qBAAqB,GACrB,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,GACnB,qBAAqB,GACrB,oBAAoB,GACpB,yBAAyB,GACzB,kBAAkB,GAClB,gBAAgB,GAChB,4BAA4B,GAC5B,oBAAoB,GACpB,uBAAuB,GACvB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,4BAA4B,GAC5B,oBAAoB,GACpB,qBAAqB,CAAC;AAgI1B,wBAAgB,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAcnF"}
|
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { loadConfig } from './config.js';
|
|
2
|
+
const messages = {
|
|
3
|
+
English: {
|
|
4
|
+
'sync.start': 'Syncing articles...',
|
|
5
|
+
'sync.noSources': 'No Slack sources configured.',
|
|
6
|
+
'sync.noSourcesHint': 'Add one with: linkpress source add slack',
|
|
7
|
+
'sync.syncing': 'Syncing: {workspace}',
|
|
8
|
+
'sync.fetching': 'Fetching from {channel}...',
|
|
9
|
+
'sync.classifying': '{channel}: Classifying links ({current}/{total})...',
|
|
10
|
+
'sync.channelResult': '{channel}: {total} links, {new} new, {existing} existing, {filtered} filtered',
|
|
11
|
+
'sync.channelFailed': '{channel}: Failed to fetch',
|
|
12
|
+
'sync.summary': 'Sync Summary',
|
|
13
|
+
'sync.totalLinks': 'Total links found: {count}',
|
|
14
|
+
'sync.newArticles': 'New articles: {count}',
|
|
15
|
+
'sync.alreadySaved': 'Already saved: {count}',
|
|
16
|
+
'sync.filteredOut': 'Filtered out: {count}',
|
|
17
|
+
'sync.generateHint': 'Run "linkpress generate" to create your magazine.',
|
|
18
|
+
'sync.noLinksHint': 'No links found. Try adding more channels or URLs manually.',
|
|
19
|
+
'clear.confirm': 'Are you sure you want to delete all articles?',
|
|
20
|
+
'clear.cancelled': 'Cancelled.',
|
|
21
|
+
'clear.success': 'Cleared {count} articles.',
|
|
22
|
+
'init.welcome': 'Welcome to LinkPress!',
|
|
23
|
+
'init.selectProvider': 'Select your AI provider:',
|
|
24
|
+
'init.enterApiKey': 'Enter your {provider} API key:',
|
|
25
|
+
'init.fetchingModels': 'Fetching available models...',
|
|
26
|
+
'init.foundModels': 'Found {count} models',
|
|
27
|
+
'init.selectModel': 'Select model:',
|
|
28
|
+
'init.enterModelId': 'Enter model ID:',
|
|
29
|
+
'init.selectLanguage': 'Select your preferred language for summaries:',
|
|
30
|
+
'init.enterLanguage': 'Enter language name:',
|
|
31
|
+
'init.selectOutputFormat': 'Select output format:',
|
|
32
|
+
'init.configSaved': 'Configuration saved to',
|
|
33
|
+
'init.nextSteps': 'Next steps:',
|
|
34
|
+
'generate.processingSummary': 'Processing Summary',
|
|
35
|
+
'generate.processed': 'Processed: {count}',
|
|
36
|
+
'generate.articleStats': 'Article Stats',
|
|
37
|
+
'generate.total': 'Total: {count}',
|
|
38
|
+
'generate.ready': 'Ready: {count}',
|
|
39
|
+
'generate.pending': 'Pending: {count}',
|
|
40
|
+
'generate.magazineGenerated': 'Magazine Generated!',
|
|
41
|
+
'generate.serveHint': 'Run "linkpress serve" to view your magazine.',
|
|
42
|
+
'generate.noArticles': 'No processed articles yet. Run without --skip-process first.',
|
|
43
|
+
},
|
|
44
|
+
'한국어': {
|
|
45
|
+
'sync.start': '아티클 동기화 중...',
|
|
46
|
+
'sync.noSources': 'Slack 소스가 설정되지 않았습니다.',
|
|
47
|
+
'sync.noSourcesHint': '다음 명령어로 추가하세요: linkpress source add slack',
|
|
48
|
+
'sync.syncing': '동기화 중: {workspace}',
|
|
49
|
+
'sync.fetching': '{channel}에서 가져오는 중...',
|
|
50
|
+
'sync.classifying': '{channel}: 링크 분류 중 ({current}/{total})...',
|
|
51
|
+
'sync.channelResult': '{channel}: {total}개 링크, {new}개 신규, {existing}개 기존, {filtered}개 필터링',
|
|
52
|
+
'sync.channelFailed': '{channel}: 가져오기 실패',
|
|
53
|
+
'sync.summary': '동기화 요약',
|
|
54
|
+
'sync.totalLinks': '총 링크 수: {count}',
|
|
55
|
+
'sync.newArticles': '신규 아티클: {count}',
|
|
56
|
+
'sync.alreadySaved': '이미 저장됨: {count}',
|
|
57
|
+
'sync.filteredOut': '필터링됨: {count}',
|
|
58
|
+
'sync.generateHint': '"linkpress generate" 명령어로 매거진을 생성하세요.',
|
|
59
|
+
'sync.noLinksHint': '링크가 없습니다. 채널을 추가하거나 URL을 직접 추가해보세요.',
|
|
60
|
+
'clear.confirm': '모든 아티클을 삭제하시겠습니까?',
|
|
61
|
+
'clear.cancelled': '취소되었습니다.',
|
|
62
|
+
'clear.success': '{count}개의 아티클이 삭제되었습니다.',
|
|
63
|
+
'init.welcome': 'LinkPress에 오신 것을 환영합니다!',
|
|
64
|
+
'init.selectProvider': 'AI 프로바이더를 선택하세요:',
|
|
65
|
+
'init.enterApiKey': '{provider} API 키를 입력하세요:',
|
|
66
|
+
'init.fetchingModels': '사용 가능한 모델 조회 중...',
|
|
67
|
+
'init.foundModels': '{count}개의 모델을 찾았습니다',
|
|
68
|
+
'init.selectModel': '모델을 선택하세요:',
|
|
69
|
+
'init.enterModelId': '모델 ID를 입력하세요:',
|
|
70
|
+
'init.selectLanguage': '요약에 사용할 언어를 선택하세요:',
|
|
71
|
+
'init.enterLanguage': '언어 이름을 입력하세요:',
|
|
72
|
+
'init.selectOutputFormat': '출력 형식을 선택하세요:',
|
|
73
|
+
'init.configSaved': '설정이 저장되었습니다:',
|
|
74
|
+
'init.nextSteps': '다음 단계:',
|
|
75
|
+
'generate.processingSummary': '처리 요약',
|
|
76
|
+
'generate.processed': '처리됨: {count}',
|
|
77
|
+
'generate.articleStats': '아티클 현황',
|
|
78
|
+
'generate.total': '전체: {count}',
|
|
79
|
+
'generate.ready': '준비됨: {count}',
|
|
80
|
+
'generate.pending': '대기중: {count}',
|
|
81
|
+
'generate.magazineGenerated': '매거진 생성 완료!',
|
|
82
|
+
'generate.serveHint': '"linkpress serve" 명령어로 매거진을 확인하세요.',
|
|
83
|
+
'generate.noArticles': '처리된 아티클이 없습니다. --skip-process 옵션 없이 실행하세요.',
|
|
84
|
+
},
|
|
85
|
+
'日本語': {
|
|
86
|
+
'sync.start': '記事を同期中...',
|
|
87
|
+
'sync.noSources': 'Slackソースが設定されていません。',
|
|
88
|
+
'sync.noSourcesHint': '次のコマンドで追加してください: linkpress source add slack',
|
|
89
|
+
'sync.syncing': '同期中: {workspace}',
|
|
90
|
+
'sync.fetching': '{channel}から取得中...',
|
|
91
|
+
'sync.classifying': '{channel}: リンクを分類中 ({current}/{total})...',
|
|
92
|
+
'sync.channelResult': '{channel}: {total}件のリンク, {new}件の新規, {existing}件の既存, {filtered}件のフィルタ',
|
|
93
|
+
'sync.channelFailed': '{channel}: 取得に失敗しました',
|
|
94
|
+
'sync.summary': '同期サマリー',
|
|
95
|
+
'sync.totalLinks': '合計リンク数: {count}',
|
|
96
|
+
'sync.newArticles': '新規記事: {count}',
|
|
97
|
+
'sync.alreadySaved': '保存済み: {count}',
|
|
98
|
+
'sync.filteredOut': 'フィルタ済み: {count}',
|
|
99
|
+
'sync.generateHint': '"linkpress generate"でマガジンを作成してください。',
|
|
100
|
+
'sync.noLinksHint': 'リンクが見つかりません。チャンネルを追加するか、URLを手動で追加してください。',
|
|
101
|
+
'clear.confirm': 'すべての記事を削除しますか?',
|
|
102
|
+
'clear.cancelled': 'キャンセルしました。',
|
|
103
|
+
'clear.success': '{count}件の記事を削除しました。',
|
|
104
|
+
'init.welcome': 'LinkPressへようこそ!',
|
|
105
|
+
'init.selectProvider': 'AIプロバイダーを選択:',
|
|
106
|
+
'init.enterApiKey': '{provider} APIキーを入力:',
|
|
107
|
+
'init.fetchingModels': '利用可能なモデルを取得中...',
|
|
108
|
+
'init.foundModels': '{count}個のモデルが見つかりました',
|
|
109
|
+
'init.selectModel': 'モデルを選択:',
|
|
110
|
+
'init.enterModelId': 'モデルIDを入力:',
|
|
111
|
+
'init.selectLanguage': '要約に使用する言語を選択:',
|
|
112
|
+
'init.enterLanguage': '言語名を入力:',
|
|
113
|
+
'init.selectOutputFormat': '出力形式を選択:',
|
|
114
|
+
'init.configSaved': '設定が保存されました:',
|
|
115
|
+
'init.nextSteps': '次のステップ:',
|
|
116
|
+
'generate.processingSummary': '処理サマリー',
|
|
117
|
+
'generate.processed': '処理済み: {count}',
|
|
118
|
+
'generate.articleStats': '記事ステータス',
|
|
119
|
+
'generate.total': '合計: {count}',
|
|
120
|
+
'generate.ready': '準備完了: {count}',
|
|
121
|
+
'generate.pending': '保留中: {count}',
|
|
122
|
+
'generate.magazineGenerated': 'マガジンが生成されました!',
|
|
123
|
+
'generate.serveHint': '"linkpress serve"でマガジンを確認してください。',
|
|
124
|
+
'generate.noArticles': '処理済みの記事がありません。--skip-processなしで実行してください。',
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
export function t(key, params) {
|
|
128
|
+
const config = loadConfig();
|
|
129
|
+
const lang = config.ai.language || 'English';
|
|
130
|
+
const langMessages = messages[lang] || messages['English'];
|
|
131
|
+
let message = langMessages[key] || messages['English'][key] || key;
|
|
132
|
+
if (params) {
|
|
133
|
+
for (const [k, v] of Object.entries(params)) {
|
|
134
|
+
message = message.replace(`{${k}}`, String(v));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return message;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=i18n.js.map
|
package/dist/i18n.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import { initCommand, addCommand, listCommand, sourceCommand, syncCommand, generateCommand, serveCommand, clearCommand, } from './commands/index.js';
|
|
4
|
+
program
|
|
5
|
+
.name('linkpress')
|
|
6
|
+
.description('Turn your Slack links into a personal tech magazine')
|
|
7
|
+
.version('0.1.0');
|
|
8
|
+
program.addCommand(initCommand);
|
|
9
|
+
program.addCommand(addCommand);
|
|
10
|
+
program.addCommand(listCommand);
|
|
11
|
+
program.addCommand(sourceCommand);
|
|
12
|
+
program.addCommand(syncCommand);
|
|
13
|
+
program.addCommand(generateCommand);
|
|
14
|
+
program.addCommand(serveCommand);
|
|
15
|
+
program.addCommand(clearCommand);
|
|
16
|
+
program.parse();
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,eAAe,EACf,YAAY,EACZ,YAAY,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,qDAAqD,CAAC;KAClE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"magazine.d.ts","sourceRoot":"","sources":["../src/magazine.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,eAAoB,GAAG,MAAM,CAkBtE"}
|