sondakika 1.0.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/AGENTS.md +158 -0
- package/index.js +97 -0
- package/package.json +23 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# AGENTS.md - News CLI Project
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
This is a simple Node.js CLI application that fetches and displays news from RSS feeds. It uses `rss-parser` to parse RSS feeds and displays news in a styled terminal output.
|
|
6
|
+
|
|
7
|
+
## Project Structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
haberler/
|
|
11
|
+
├── index.js # Main CLI entry point
|
|
12
|
+
├── package.json # Project dependencies and scripts
|
|
13
|
+
└── AGENTS.md # This file - guidelines for AI agents
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Build & Run Commands
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Run the CLI
|
|
20
|
+
npm start # Runs: node index.js
|
|
21
|
+
node index.js # Direct execution
|
|
22
|
+
|
|
23
|
+
# With arguments
|
|
24
|
+
node index.js ntv # Show NTV news (default 10 items)
|
|
25
|
+
node index.js ntv 15 # Show 15 NTV news items
|
|
26
|
+
|
|
27
|
+
# Global installation (for 'news' command)
|
|
28
|
+
npm link
|
|
29
|
+
news ntv 15 # Run as global command
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Adding New RSS Sources
|
|
33
|
+
|
|
34
|
+
To add a new news source, edit `index.js` and add to the `sources` object:
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
const sources = {
|
|
38
|
+
ntv: 'https://www.ntv.com.tr/son-dakika.rss',
|
|
39
|
+
bbc: 'https://feeds.bbci.co.uk/news/rss.xml',
|
|
40
|
+
cnn: 'http://rss.cnn.com/rss/edition.rss'
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then run with:
|
|
45
|
+
```bash
|
|
46
|
+
node index.js bbc
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## No Test/Lint Commands
|
|
50
|
+
|
|
51
|
+
This project does not currently have:
|
|
52
|
+
- Unit tests
|
|
53
|
+
- Linting configuration
|
|
54
|
+
- TypeScript
|
|
55
|
+
- CI/CD pipelines
|
|
56
|
+
|
|
57
|
+
If you add tests, use:
|
|
58
|
+
```bash
|
|
59
|
+
npm test # Run tests
|
|
60
|
+
npm run lint # Run ESLint (if configured)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Code Style Guidelines
|
|
64
|
+
|
|
65
|
+
### General Principles
|
|
66
|
+
- Keep the codebase simple and minimal
|
|
67
|
+
- Use vanilla JavaScript (no TypeScript for this project)
|
|
68
|
+
- Avoid unnecessary dependencies
|
|
69
|
+
- Focus on readability and maintainability
|
|
70
|
+
|
|
71
|
+
### File Structure
|
|
72
|
+
- `index.js` - Main entry point (single file application)
|
|
73
|
+
- `package.json` - Project configuration
|
|
74
|
+
|
|
75
|
+
### Naming Conventions
|
|
76
|
+
- **Variables/Functions**: camelCase (e.g., `fetchNews`, `wrapText`)
|
|
77
|
+
- **Constants**: UPPER_SNAKE_CASE if truly constant (e.g., `MAX_WIDTH`)
|
|
78
|
+
- **Files**: lowercase with hyphens (kebab-case)
|
|
79
|
+
|
|
80
|
+
### Code Style
|
|
81
|
+
- Use **2 spaces** for indentation
|
|
82
|
+
- **No semicolons** at end of statements (optional, but consistent with project)
|
|
83
|
+
- Use template literals (backticks) for string interpolation
|
|
84
|
+
- Use arrow functions for callbacks
|
|
85
|
+
- Prefer `const` over `let`, avoid `var`
|
|
86
|
+
|
|
87
|
+
### Imports
|
|
88
|
+
```javascript
|
|
89
|
+
// Direct require for Node built-ins
|
|
90
|
+
const path = require('path');
|
|
91
|
+
|
|
92
|
+
// Third-party packages
|
|
93
|
+
const Parser = require('rss-parser');
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Functions
|
|
97
|
+
- Keep functions small and focused
|
|
98
|
+
- Use descriptive names
|
|
99
|
+
- Add JSDoc comments for exported functions
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
/**
|
|
103
|
+
* Wraps text to specified width for terminal display
|
|
104
|
+
* @param {string} text - Text to wrap
|
|
105
|
+
* @param {number} width - Maximum line width
|
|
106
|
+
* @returns {string[]} Array of wrapped lines
|
|
107
|
+
*/
|
|
108
|
+
function wrapText(text, width = 68) { ... }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Error Handling
|
|
112
|
+
- Use try-catch for async operations
|
|
113
|
+
- Display user-friendly error messages
|
|
114
|
+
- Exit with non-zero code on errors: `process.exit(1)`
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
try {
|
|
118
|
+
const feed = await parser.parseURL(url);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
console.error('Error fetching news:', err.message);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### CLI Output
|
|
126
|
+
- Use Unicode characters for borders (┌─┐│└┘)
|
|
127
|
+
- Support clickable URLs via ANSI escape codes (iTerm2/Windows Terminal)
|
|
128
|
+
- Wrap long text to fit terminal width (default: 68 chars)
|
|
129
|
+
- Add emoji for visual appeal (📰, 🔗)
|
|
130
|
+
- Add separator lines between news items for clarity
|
|
131
|
+
|
|
132
|
+
### Dependencies
|
|
133
|
+
- Keep dependencies minimal
|
|
134
|
+
- Use well-maintained packages:
|
|
135
|
+
- `rss-parser` - RSS feed parsing
|
|
136
|
+
- `cli-table3` - Table formatting (if needed)
|
|
137
|
+
|
|
138
|
+
## Dependencies
|
|
139
|
+
|
|
140
|
+
Current dependencies (from package.json):
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"rss-parser": "^3.13.0",
|
|
144
|
+
"cli-table3": "^0.6.5"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Future Improvements (for agents)
|
|
149
|
+
|
|
150
|
+
If adding features, consider:
|
|
151
|
+
1. Adding unit tests with Jest or Mocha
|
|
152
|
+
2. Adding ESLint for code quality
|
|
153
|
+
3. Supporting multiple RSS sources beyond NTV
|
|
154
|
+
4. Adding configuration file for sources
|
|
155
|
+
5. Adding caching to reduce network calls
|
|
156
|
+
6. Adding date/time formatting for news items
|
|
157
|
+
7. Adding color output for different news categories
|
|
158
|
+
8. Adding pagination for large result sets
|
package/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const Parser = require('rss-parser');
|
|
4
|
+
|
|
5
|
+
const sources = {
|
|
6
|
+
ntv: 'https://www.ntv.com.tr/son-dakika.rss'
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const parser = new Parser();
|
|
10
|
+
|
|
11
|
+
function wrapText(text, width = 68) {
|
|
12
|
+
const lines = [];
|
|
13
|
+
let start = 0;
|
|
14
|
+
while (start < text.length) {
|
|
15
|
+
let end = Math.min(start + width, text.length);
|
|
16
|
+
if (end < text.length) {
|
|
17
|
+
lines.push(text.substring(start, end));
|
|
18
|
+
} else {
|
|
19
|
+
lines.push(text.substring(start));
|
|
20
|
+
}
|
|
21
|
+
start = end;
|
|
22
|
+
}
|
|
23
|
+
return lines;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function separator() {
|
|
27
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function fetchNews(source, count) {
|
|
31
|
+
const url = sources[source.toLowerCase()];
|
|
32
|
+
if (!url) {
|
|
33
|
+
console.error(`Unknown source: ${source}`);
|
|
34
|
+
console.log(`Available sources: ${Object.keys(sources).join(', ')}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const feed = await parser.parseURL(url);
|
|
40
|
+
const items = feed.items.slice(0, count);
|
|
41
|
+
|
|
42
|
+
console.log('\n📰 ' + '═'.repeat(50));
|
|
43
|
+
console.log(` Latest ${items.length} News from ${source.toUpperCase()}`);
|
|
44
|
+
console.log(' ' + '═'.repeat(50) + '\n');
|
|
45
|
+
|
|
46
|
+
items.forEach((item, index) => {
|
|
47
|
+
const title = item.title;
|
|
48
|
+
const summary = item.summary || item.contentSnippet || '';
|
|
49
|
+
const link = item.link;
|
|
50
|
+
|
|
51
|
+
const titleLines = wrapText(title, 68);
|
|
52
|
+
const summaryLines = wrapText(summary, 68);
|
|
53
|
+
|
|
54
|
+
const maxWidth = Math.max(
|
|
55
|
+
...titleLines.map(l => l.length),
|
|
56
|
+
...summaryLines.map(l => l.length),
|
|
57
|
+
3
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const borderWidth = Math.min(maxWidth + 1, 70);
|
|
61
|
+
const clickableUrl = `\u001b]8;;${link}\u0007${link}\u001b]8;;\u0007`;
|
|
62
|
+
|
|
63
|
+
console.log(` ┌─ ${index + 1}. ${titleLines[0]}`);
|
|
64
|
+
titleLines.slice(1).forEach(line => {
|
|
65
|
+
console.log(` │ ${line}`);
|
|
66
|
+
});
|
|
67
|
+
console.log(` │`);
|
|
68
|
+
|
|
69
|
+
summaryLines.forEach(line => {
|
|
70
|
+
console.log(` │ ${line}`);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
console.log(` └${'─'.repeat(borderWidth)}`);
|
|
74
|
+
console.log(` 🔗 ${clickableUrl}`);
|
|
75
|
+
console.log();
|
|
76
|
+
separator();
|
|
77
|
+
console.log();
|
|
78
|
+
});
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error('Error fetching news:', err.message);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const args = process.argv.slice(2);
|
|
86
|
+
|
|
87
|
+
if (args.length === 0) {
|
|
88
|
+
console.log('Usage: news <source> [count]');
|
|
89
|
+
console.log(`Available sources: ${Object.keys(sources).join(', ')}`);
|
|
90
|
+
console.log('Example: news ntv 15');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const source = args[0];
|
|
95
|
+
const count = args[1] ? parseInt(args[1]) : 10;
|
|
96
|
+
|
|
97
|
+
fetchNews(source, count);
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sondakika",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI to display breaking news from RSS feeds",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"news": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node index.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"news",
|
|
14
|
+
"rss",
|
|
15
|
+
"cli"
|
|
16
|
+
],
|
|
17
|
+
"author": "Sedat ERGOZ",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"cli-table3": "^0.6.5",
|
|
21
|
+
"rss-parser": "^3.13.0"
|
|
22
|
+
}
|
|
23
|
+
}
|