@1a35e1/sonar-cli 0.2.0 → 0.3.4

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.
Files changed (42) hide show
  1. package/README.md +151 -166
  2. package/dist/commands/{inbox/archive.js → archive.js} +2 -2
  3. package/dist/commands/config/data/download.js +2 -2
  4. package/dist/commands/config/data/sync.js +2 -2
  5. package/dist/commands/config/nuke.js +20 -2
  6. package/dist/commands/feed.js +105 -155
  7. package/dist/commands/index.js +172 -4
  8. package/dist/commands/{inbox/later.js → later.js} +2 -2
  9. package/dist/commands/refresh.js +41 -0
  10. package/dist/commands/{inbox/skip.js → skip.js} +2 -2
  11. package/dist/commands/status.js +128 -0
  12. package/dist/commands/sync/bookmarks.js +35 -0
  13. package/dist/commands/topics/add.js +71 -0
  14. package/dist/commands/topics/delete.js +42 -0
  15. package/dist/commands/topics/edit.js +97 -0
  16. package/dist/commands/topics/index.js +54 -0
  17. package/dist/commands/topics/suggest.js +125 -0
  18. package/dist/commands/topics/view.js +48 -0
  19. package/dist/components/AccountCard.js +1 -1
  20. package/dist/components/Banner.js +11 -0
  21. package/dist/components/InteractiveSession.js +95 -210
  22. package/dist/components/Spinner.js +5 -4
  23. package/dist/components/TopicCard.js +15 -0
  24. package/dist/components/TweetCard.js +76 -0
  25. package/dist/lib/ai.js +85 -0
  26. package/dist/lib/client.js +66 -39
  27. package/dist/lib/config.js +3 -2
  28. package/dist/lib/data-queries.js +1 -3
  29. package/dist/lib/skill.js +66 -226
  30. package/package.json +13 -3
  31. package/dist/commands/account.js +0 -75
  32. package/dist/commands/inbox/index.js +0 -103
  33. package/dist/commands/inbox/read.js +0 -41
  34. package/dist/commands/ingest/bookmarks.js +0 -55
  35. package/dist/commands/ingest/index.js +0 -5
  36. package/dist/commands/ingest/tweets.js +0 -55
  37. package/dist/commands/interests/create.js +0 -107
  38. package/dist/commands/interests/index.js +0 -56
  39. package/dist/commands/interests/match.js +0 -33
  40. package/dist/commands/interests/update.js +0 -153
  41. package/dist/commands/monitor.js +0 -93
  42. package/dist/components/InterestCard.js +0 -10
@@ -1,93 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
3
- import zod from 'zod';
4
- import { Box, Text, useApp } from 'ink';
5
- import { getToken, getApiUrl } from '../lib/config.js';
6
- import { gql } from '../lib/client.js';
7
- import { Spinner } from '../components/Spinner.js';
8
- import { AccountCard } from '../components/AccountCard.js';
9
- export const options = zod.object({
10
- watch: zod.boolean().default(false).describe('Poll and refresh every 2 seconds'),
11
- });
12
- const POLL_INTERVAL = 2000;
13
- const QUEUE_LABELS = {
14
- tweets: 'Tweets',
15
- bookmarks: 'Bookmarks',
16
- social_graph: 'Social graph',
17
- suggestions: 'Suggestions',
18
- };
19
- export default function Monitor({ options: flags }) {
20
- const { exit } = useApp();
21
- const [data, setData] = useState(null);
22
- const [error, setError] = useState(null);
23
- useEffect(() => {
24
- const token = getToken();
25
- const baseUrl = getApiUrl().replace(/\/graphql$/, '');
26
- async function fetchStatus() {
27
- const controller = new AbortController();
28
- const timer = setTimeout(() => controller.abort(), 10_000);
29
- try {
30
- const [statusRes, meRes] = await Promise.all([
31
- fetch(`${baseUrl}/indexing/status`, {
32
- signal: controller.signal,
33
- headers: { Authorization: `Bearer ${token}` },
34
- }),
35
- gql(`
36
- query MonitorStatus {
37
- me {
38
- accountId
39
- email
40
- xHandle
41
- xid
42
- isPayingCustomer
43
- indexingAccounts
44
- indexedTweets
45
- pendingEmbeddings
46
- twitterIndexedAt
47
- refreshedSuggestionsAt
48
- }
49
- }
50
- `),
51
- ]);
52
- clearTimeout(timer);
53
- if (!statusRes.ok)
54
- throw new Error(`HTTP ${statusRes.status} from ${baseUrl}`);
55
- const status = await statusRes.json();
56
- setData({ me: meRes.me, queues: status.queues });
57
- setError(null);
58
- }
59
- catch (err) {
60
- clearTimeout(timer);
61
- if (err instanceof DOMException && err.name === 'AbortError') {
62
- setError('Monitor request timed out (10s). ' +
63
- 'The server may be overloaded. ' +
64
- 'Check SONAR_API_URL or retry without --watch.');
65
- }
66
- else {
67
- setError(err instanceof Error ? err.message : String(err));
68
- }
69
- }
70
- }
71
- fetchStatus();
72
- if (!flags.watch)
73
- return;
74
- const timer = setInterval(fetchStatus, POLL_INTERVAL);
75
- return () => clearInterval(timer);
76
- }, []);
77
- useEffect(() => {
78
- if (!flags.watch && data !== null)
79
- exit();
80
- }, [data]);
81
- useEffect(() => {
82
- if (!flags.watch && error !== null)
83
- exit(new Error(error));
84
- }, [error]);
85
- if (error)
86
- return _jsxs(Text, { color: "red", children: ["Error: ", error] });
87
- if (!data)
88
- return _jsx(Spinner, { label: "Loading ingest status..." });
89
- const { me, queues } = data;
90
- const entries = Object.entries(queues);
91
- const hasActivity = entries.length > 0 || me.pendingEmbeddings > 0;
92
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(AccountCard, { me: me }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: "cyan", children: "Job Queues" }), !hasActivity ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: "green", children: "No active ingest jobs." }), _jsxs(Text, { color: "green", children: ["Run ", _jsx(Text, { color: "cyan", children: "sonar interests match" }), " to start surface relevant tweets."] })] })) : (_jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsxs(Box, { gap: 2, marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: ('Queue').padEnd(16) }), _jsx(Text, { bold: true, color: "cyan", children: 'Running'.padEnd(10) }), _jsx(Text, { bold: true, color: "cyan", children: "Queued" })] }), entries.map(([name, counts]) => (_jsxs(Box, { gap: 2, children: [_jsx(Text, { children: (QUEUE_LABELS[name] ?? name).padEnd(16) }), _jsx(Text, { color: counts.running > 0 ? 'green' : 'white', children: String(counts.running).padEnd(10) }), _jsx(Text, { color: counts.queued > 0 ? 'yellow' : 'white', children: counts.queued })] }, name)))] }))] })] }));
93
- }
@@ -1,10 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- export function InterestCard({ interest, termWidth, isLast }) {
4
- const updatedAt = new Date(interest.updatedAt).toLocaleDateString('en-US', {
5
- month: 'short',
6
- day: 'numeric',
7
- year: 'numeric',
8
- });
9
- return (_jsxs(Box, { flexDirection: "column", marginBottom: isLast ? 0 : 1, width: termWidth, children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: interest.name }), _jsxs(Text, { dimColor: true, children: [" v", interest.version, " \u00B7 ", interest.id, " \u00B7 ", updatedAt] })] }), interest.description && (_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ['└', " "] }), _jsx(Text, { wrap: "wrap", children: interest.description })] })), interest.keywords && interest.keywords.length > 0 && (_jsxs(Box, { marginLeft: 2, children: [_jsx(Text, { dimColor: true, children: "keywords " }), _jsx(Text, { color: "yellow", children: interest.keywords.join(' ') })] })), interest.relatedTopics && interest.relatedTopics.length > 0 && (_jsxs(Box, { marginLeft: 2, children: [_jsx(Text, { dimColor: true, children: "topics " }), _jsx(Text, { children: interest.relatedTopics.join(' ') })] })), !isLast && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: '─'.repeat(Math.min(termWidth - 2, 72)) }) }))] }));
10
- }