mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-23 12:06:42 +02:00
M4 — Tags + Filter: - queries.ts: useArticleTagIds(id) + batched useArticleTagMap(ids) live queries against articleTagOps (the junction into globalTags). - DetailView: TagField from @mana/shared-ui with the global tag pool + this article's selected ids; onChange fans out through articleTagOps.setTags, which diffs add/remove internally. - ListView: 6 filter chips (Alle | Ungelesen | In Arbeit | Gelesen | Favoriten | Archiv) with live counts. Archived articles are hidden from the "Alle" view and only surface under the Archiv filter. Tag chips render inline on each card using the batched tag map + the global tag pool for colour lookup. M5 — Migration + news deprecation: - modules/articles/migrations/from-news.ts: boot-gated migration (per- device localStorage sentinel). Reads newsArticles with type='saved', decrypts under the newsArticles allowlist, re-encrypts under the articles allowlist, and copies into the articles table. Status maps isArchived→archived, isRead→finished, else unread. Source rows get soft-deleted so the sync engine removes them from other devices. Ran after crypto init (from (app)/+layout.svelte boot block), not in the Dexie .upgrade() hook, because the decrypt→re-encrypt round- trip needs Web Crypto + the master key. - news/stores/articles.svelte.ts: removed saveFromUrl — ad-hoc URL saves now live in the articles module. - news/api.ts: removed extractFromUrl helper + ExtractedArticleDto. The /api/v1/news/extract/* routes stay in apps/api for now because news-research still hits them for RSS discovery. - news/index.ts: dropped the extractFromUrl re-export. - news/tools.ts: the save_news_article AI tool keeps its name (so historic Mission iterations in the DB still resolve) but its execute body now routes through the articles module's saveFromUrl. - routes/(app)/news/add + /news/saved: replaced with single-shot redirects to /articles/add and /articles respectively. - news-research ListView + page: "Speichern" buttons now route to the articles module and navigate to /articles/[id] on success. Plan: docs/plans/articles-module.md. M6 (AI tools + proposal inbox), M7 (share target + bookmarklet), M8 (highlights view + stats) open. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
/**
|
|
* News Tools — LLM-accessible operations for the news module.
|
|
*
|
|
* `save_news_article` is the agent's path into the user's reading list.
|
|
* M5 moved the saved-article storage to the `articles` module; this
|
|
* tool now routes through `articlesStore.saveFromUrl(url)` there. The
|
|
* tool name stays `save_news_article` because historic AI mission
|
|
* iterations in the DB reference it — renaming would break the audit
|
|
* trail. A future `save_article` can be added as an alias in M6.
|
|
*
|
|
* `title` and `summary` are display hints for the approval dialog —
|
|
* the canonical title/excerpt come from the extractor so the AI can't
|
|
* lie about content.
|
|
*/
|
|
|
|
import type { ModuleTool } from '$lib/data/tools/types';
|
|
import { articlesStore } from '$lib/modules/articles/stores/articles.svelte';
|
|
|
|
export const newsTools: ModuleTool[] = [
|
|
{
|
|
name: 'save_news_article',
|
|
module: 'news',
|
|
description:
|
|
'Speichert einen Artikel von einer URL in die Leseliste. URL wird serverseitig per Readability extrahiert.',
|
|
parameters: [
|
|
{ name: 'url', type: 'string', description: 'Die Artikel-URL', required: true },
|
|
{
|
|
name: 'title',
|
|
type: 'string',
|
|
description: 'Anzeigetitel für den Approval-Dialog (informativ)',
|
|
required: false,
|
|
},
|
|
{
|
|
name: 'summary',
|
|
type: 'string',
|
|
description: 'Kurze Begründung warum dieser Artikel relevant ist',
|
|
required: false,
|
|
},
|
|
],
|
|
async execute(params) {
|
|
const url = params.url as string;
|
|
const { article, duplicate } = await articlesStore.saveFromUrl(url);
|
|
return {
|
|
success: true,
|
|
message: duplicate
|
|
? `Artikel bereits gespeichert: ${article.title}`
|
|
: `Artikel gespeichert: ${article.title}`,
|
|
data: { articleId: article.id, title: article.title, duplicate },
|
|
};
|
|
},
|
|
},
|
|
];
|