gloomberb 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/README.md +153 -0
- package/install.mjs +69 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Gloomberb Terminal
|
|
2
|
+
|
|
3
|
+
A Bloomberg-inspired stock portfolio tracker for your terminal. Built with [OpenTUI](https://github.com/msmps/opentui) + React + Bun.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
+--[ GLOOMBERB TERMINAL ]----------[ 15:42:03 ]--[ USD ]--+
|
|
7
|
+
| | |
|
|
8
|
+
| [Main Portfolio|Tech WL] | [Overview|Financials|Chart] |
|
|
9
|
+
| -------------------------| |
|
|
10
|
+
| TICKER PRICE CHG% PE | AAPL - Apple Inc. |
|
|
11
|
+
| AAPL $189.50 +1.2% 29 | Price: $189.50 (+$2.24) |
|
|
12
|
+
|>MSFT $420.10 -0.3% 35 | ▁▂▃▄▅▆▅▄▅▆▇▆▅▆▇▆▅▆▇█▇▆▇ |
|
|
13
|
+
| GOOGL $175.80 +0.8% 25 | MCap: $2.91T P/E: 29.1 |
|
|
14
|
+
| NVDA $875.30 +2.1% 62 | Revenue: $391B FCF: $112B |
|
|
15
|
+
+---[ Ctrl+P search | Tab switch | q quit ]---------------+
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **Two-panel Bloomberg layout** with amber-on-black theme
|
|
21
|
+
- **Yahoo Finance integration** for real-time quotes, fundamentals, and 5-year price history
|
|
22
|
+
- **Markdown-based storage** - one `.md` file per ticker with YAML frontmatter, perfect for LLM agents
|
|
23
|
+
- **Multiple portfolios & watchlists** with configurable columns
|
|
24
|
+
- **Plugin architecture** - everything is a plugin, including core panes and broker integrations
|
|
25
|
+
- **Prefix command bar** (`Ctrl+P`) for fast keyboard-driven workflow
|
|
26
|
+
- **Multi-currency** support with cached exchange rates
|
|
27
|
+
- **ASCII stock charts** using braille characters with price/time axes
|
|
28
|
+
- **Editable notes** per ticker, saved to markdown
|
|
29
|
+
- **Interactive Brokers** integration via Flex Queries
|
|
30
|
+
- **Local-first** - all data stays on your machine (SQLite cache + markdown files)
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Install dependencies
|
|
36
|
+
bun install
|
|
37
|
+
|
|
38
|
+
# Run
|
|
39
|
+
bun dev
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
On first launch, data is stored in `~/gloomberb-data/`. Each ticker gets its own markdown file:
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
---
|
|
46
|
+
ticker: AAPL
|
|
47
|
+
exchange: NASDAQ
|
|
48
|
+
currency: USD
|
|
49
|
+
name: Apple Inc.
|
|
50
|
+
sector: Technology
|
|
51
|
+
portfolios:
|
|
52
|
+
- main
|
|
53
|
+
watchlists:
|
|
54
|
+
- tech
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Notes
|
|
58
|
+
|
|
59
|
+
Strong services growth. Watch for Vision Pro adoption.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Keyboard Shortcuts
|
|
63
|
+
|
|
64
|
+
| Key | Action |
|
|
65
|
+
|-----|--------|
|
|
66
|
+
| `Ctrl+P` or `` ` `` | Open command bar |
|
|
67
|
+
| `Tab` | Switch between left/right panels |
|
|
68
|
+
| `j` / `k` | Navigate ticker list |
|
|
69
|
+
| `h` / `l` | Switch tabs |
|
|
70
|
+
| `r` | Refresh selected ticker |
|
|
71
|
+
| `Shift+R` | Refresh all tickers |
|
|
72
|
+
| `Ctrl+,` | Open settings |
|
|
73
|
+
| `q` | Quit |
|
|
74
|
+
|
|
75
|
+
## Command Bar Prefixes
|
|
76
|
+
|
|
77
|
+
The command bar uses a prefix system for fast actions:
|
|
78
|
+
|
|
79
|
+
| Prefix | Action |
|
|
80
|
+
|--------|--------|
|
|
81
|
+
| `T <query>` | Search Yahoo Finance for a ticker |
|
|
82
|
+
| `AW` | Add current ticker to watchlist |
|
|
83
|
+
| `AP` | Add current ticker to portfolio |
|
|
84
|
+
| `RW` | Remove from watchlist |
|
|
85
|
+
| `RP` | Remove from portfolio |
|
|
86
|
+
| `NP` | New portfolio |
|
|
87
|
+
| `NW` | New watchlist |
|
|
88
|
+
| `R` | Refresh current ticker |
|
|
89
|
+
| `RA` | Refresh all |
|
|
90
|
+
| `IB` | Import from Interactive Brokers |
|
|
91
|
+
| `S` | Open settings |
|
|
92
|
+
|
|
93
|
+
## Architecture
|
|
94
|
+
|
|
95
|
+
Everything is a plugin. Core features use the same `GloomPlugin` interface as external extensions.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
src/
|
|
99
|
+
plugins/
|
|
100
|
+
registry.ts # OpenTUI slot-based plugin system
|
|
101
|
+
pane-manager.ts # Customizable pane layout
|
|
102
|
+
builtin/
|
|
103
|
+
portfolio-list.tsx # Left pane (portfolios + watchlists)
|
|
104
|
+
ticker-detail.tsx # Right pane (overview, financials, chart, notes)
|
|
105
|
+
ibkr-flex.tsx # IBKR Flex Query broker plugin
|
|
106
|
+
manual-entry.tsx # Manual position entry
|
|
107
|
+
sources/
|
|
108
|
+
yahoo-finance.ts # Yahoo Finance client with retry + caching
|
|
109
|
+
data/
|
|
110
|
+
markdown-store.ts # Ticker markdown file read/write
|
|
111
|
+
sqlite-cache.ts # Bun SQLite cache for Yahoo data
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Plugin Slots
|
|
115
|
+
|
|
116
|
+
Plugins can extend the UI through defined slots:
|
|
117
|
+
|
|
118
|
+
- `detail:tab` / `detail:section` - Add tabs or sections to the detail pane
|
|
119
|
+
- `list:column` - Custom columns in the ticker list
|
|
120
|
+
- `command:extra` / `command:preset` - Extend the command bar
|
|
121
|
+
- `status:widget` - Status bar widgets
|
|
122
|
+
- `config:section` - Settings page sections
|
|
123
|
+
- `data:post-refresh` / `data:enricher` - Hook into data lifecycle
|
|
124
|
+
|
|
125
|
+
### Planned Plugins
|
|
126
|
+
|
|
127
|
+
- News feed pane
|
|
128
|
+
- Chat component
|
|
129
|
+
- Option chain viewer
|
|
130
|
+
- Analyst ratings
|
|
131
|
+
- Tweet/social scanner
|
|
132
|
+
- Crypto feeds
|
|
133
|
+
- Custom columns (conviction score, etc.)
|
|
134
|
+
- Live stock feeds
|
|
135
|
+
|
|
136
|
+
## Data Storage
|
|
137
|
+
|
|
138
|
+
| Data | Storage | Why |
|
|
139
|
+
|------|---------|-----|
|
|
140
|
+
| Ticker metadata, positions, notes | Markdown files | Agent-readable, version-controllable |
|
|
141
|
+
| Yahoo Finance cache | SQLite (`bun:sqlite`) | Fast TTL-based lookup |
|
|
142
|
+
| Exchange rates | SQLite | Cached with 1hr TTL |
|
|
143
|
+
| Price history | SQLite | Large dataset, bad fit for markdown |
|
|
144
|
+
| App config | `config.json` | User settings |
|
|
145
|
+
|
|
146
|
+
## Requirements
|
|
147
|
+
|
|
148
|
+
- [Bun](https://bun.sh) runtime
|
|
149
|
+
- A terminal with true color support
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT
|
package/install.mjs
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createWriteStream, chmodSync, mkdirSync, existsSync, readFileSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import https from "https";
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
// Skip when running in the source repo (dev install)
|
|
9
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "package.json"), "utf-8"));
|
|
10
|
+
if (pkg.dependencies) process.exit(0);
|
|
11
|
+
const REPO = "vincelwt/gloomberb";
|
|
12
|
+
|
|
13
|
+
const platform = process.platform;
|
|
14
|
+
const arch = process.arch;
|
|
15
|
+
|
|
16
|
+
const osMap = { darwin: "darwin", linux: "linux" };
|
|
17
|
+
const archMap = { arm64: "arm64", x64: "x64" };
|
|
18
|
+
|
|
19
|
+
const os = osMap[platform];
|
|
20
|
+
let cpu = archMap[arch];
|
|
21
|
+
|
|
22
|
+
if (!os || !cpu) {
|
|
23
|
+
console.error(`Unsupported platform: ${platform}-${arch}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// macOS x64 uses arm64 binary (runs via Rosetta 2)
|
|
28
|
+
if (os === "darwin" && cpu === "x64") {
|
|
29
|
+
cpu = "arm64";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const asset = `gloomberb-${os}-${cpu}`;
|
|
33
|
+
const binDir = join(__dirname, "bin");
|
|
34
|
+
const binPath = join(binDir, "gloomberb");
|
|
35
|
+
|
|
36
|
+
if (!existsSync(binDir)) {
|
|
37
|
+
mkdirSync(binDir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const url = `https://github.com/${REPO}/releases/latest/download/${asset}`;
|
|
41
|
+
|
|
42
|
+
function download(url) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
https.get(url, (res) => {
|
|
45
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
46
|
+
return download(res.headers.location).then(resolve, reject);
|
|
47
|
+
}
|
|
48
|
+
if (res.statusCode !== 200) {
|
|
49
|
+
return reject(new Error(`Download failed: HTTP ${res.statusCode}`));
|
|
50
|
+
}
|
|
51
|
+
const file = createWriteStream(binPath);
|
|
52
|
+
res.pipe(file);
|
|
53
|
+
file.on("finish", () => {
|
|
54
|
+
file.close();
|
|
55
|
+
chmodSync(binPath, 0o755);
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
file.on("error", reject);
|
|
59
|
+
}).on("error", reject);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(`Downloading ${asset}...`);
|
|
64
|
+
download(url)
|
|
65
|
+
.then(() => console.log("gloomberb installed successfully."))
|
|
66
|
+
.catch((err) => {
|
|
67
|
+
console.error("Failed to download gloomberb binary:", err.message);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gloomberb",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Bloomberg-style stock portfolio tracker for the terminal",
|
|
5
|
+
"module": "src/index.tsx",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"gloomberb": "bin/gloomberb"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"install.mjs"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"dev": "bun run --watch src/index.tsx",
|
|
16
|
+
"build": "bun run scripts/build.ts",
|
|
17
|
+
"build:all": "bun run scripts/build.ts --all",
|
|
18
|
+
"postinstall": "node install.mjs"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/vincelwt/gloomberb"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"terminal",
|
|
27
|
+
"tui",
|
|
28
|
+
"stocks",
|
|
29
|
+
"portfolio",
|
|
30
|
+
"bloomberg",
|
|
31
|
+
"finance"
|
|
32
|
+
],
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/bun": "latest"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"typescript": "^5"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@opentui-ui/dialog": "^0.1.2",
|
|
41
|
+
"@opentui/core": "^0.1.90",
|
|
42
|
+
"@opentui/react": "^0.1.90",
|
|
43
|
+
"gray-matter": "^4.0.3",
|
|
44
|
+
"react": "^19.2.4",
|
|
45
|
+
"yahoo-finance2": "^3.13.2"
|
|
46
|
+
}
|
|
47
|
+
}
|