thinking-phrases 1.0.1 → 2.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.
Files changed (41) hide show
  1. package/README.md +230 -142
  2. package/configs/hn-top.config.json +60 -27
  3. package/launchd/rss-update.error.log +3 -27
  4. package/launchd/rss-update.log +308 -0
  5. package/launchd/task-health.json +54 -0
  6. package/out/dwyl-quotes.json +1621 -0
  7. package/out/javascript-tips.json +107 -0
  8. package/out/league-loading-screen-tips.json +107 -0
  9. package/out/ruby-tips.json +115 -0
  10. package/out/settings-linux.json +87 -0
  11. package/out/settings-mac.json +87 -0
  12. package/out/settings-windows.json +87 -0
  13. package/out/typescript-tips.json +131 -0
  14. package/out/vscode-tips.json +87 -0
  15. package/out/wow-loading-screen-tips.json +116 -0
  16. package/package.json +19 -12
  17. package/scripts/build.ts +3 -3
  18. package/scripts/debug-hn-hydration.ts +33 -0
  19. package/scripts/run-rss-update.zsh +25 -3
  20. package/scripts/show-thinking-phrases-health.ts +74 -0
  21. package/scripts/trigger-thinking-phrases-scheduler.zsh +50 -0
  22. package/src/core/config.ts +65 -3
  23. package/src/core/githubModels.ts +200 -112
  24. package/src/core/interactive.ts +49 -67
  25. package/src/core/phraseCache.ts +242 -0
  26. package/src/core/phraseFormats.ts +243 -0
  27. package/src/core/presets.ts +1 -1
  28. package/src/core/runner.ts +246 -113
  29. package/src/core/scheduler.ts +1 -1
  30. package/src/core/taskHealth.ts +213 -0
  31. package/src/core/types.ts +32 -8
  32. package/src/core/utils.ts +27 -2
  33. package/src/sources/customJson.ts +28 -18
  34. package/src/sources/earthquakes.ts +4 -4
  35. package/src/sources/githubActivity.ts +120 -48
  36. package/src/sources/hackerNews.ts +19 -7
  37. package/src/sources/rss.ts +25 -11
  38. package/src/sources/stocks.ts +31 -10
  39. package/src/sources/weatherAlerts.ts +173 -7
  40. package/tsconfig.json +1 -1
  41. package/scripts/update-rss-settings.ts +0 -7
package/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Thinking Phrases
2
2
 
3
- Turn your VS Code thinking indicator into a live dashboard. Static tip packs, real-time data sources, AI-powered summariesall piped into [`chat.agent.thinking.phrases`](https://code.visualstudio.com/updates/v1_110#_custom-thinking-phrases).
3
+ Instead of staring into the abyss while Copilot thinks contemplating how agents are going to take your job you could be doing something useful with that dead time.
4
+
5
+ This hooks into VS Code's [`chat.agent.thinking.phrases`](https://code.visualstudio.com/updates/v1_110#_custom-thinking-phrases) and turns it into a live dashboard. A `launchd` cron job fetches real-time data and swaps your phrases in the background. Interactive CLI to set it up. That's it.
6
+
7
+ - 📰 **Catch up on the news** — Google News, Hacker News, RSS/Atom, any feed
8
+ - 🐙 **GitHub activity** — commits, org feeds, security advisories, your timeline
9
+ - 🌦️ **Get the weather** — current conditions + severe alerts (lol like I go outside)
10
+ - 📈 **Watch the stock market go brrr** while your agents go brrr
11
+ - 🧠 **Learn something new** — VS Code tips, TypeScript snippets, programming languages
12
+ - 🎮 **Loading screen tips** — WoW, League of Legends... because why not
13
+ - 🤖 **AI-powered summaries** — GitHub Models rewrites articles into concise phrases
4
14
 
5
15
  ## Quick start
6
16
 
@@ -8,30 +18,26 @@ Turn your VS Code thinking indicator into a live dashboard. Static tip packs, re
8
18
  npx thinking-phrases --interactive
9
19
  ```
10
20
 
11
- That's it. No install, no clone, no config files. The interactive CLI walks you through picking sources, previewing phrases, writing to VS Code settings, and optionally installing a macOS scheduler.
21
+ No install, no clone, no config files. The interactive CLI walks you through picking sources, previewing phrases, writing to VS Code settings, and optionally installing a macOS scheduler.
12
22
 
13
- ## Features
23
+ Or just grab the [static thinking phrases](https://github.com/austenstone/thinking-phrases/tree/main/out) directly.
14
24
 
15
- ### 8 live data sources
25
+ ## Live data sources
16
26
 
17
27
  | Source | What it shows | Example phrase |
18
28
  |--------|--------------|----------------|
19
- | **RSS / Atom** | Any feed URL | `Ars Technica Linux 6.14 lands with…2h ago` |
20
- | **Stocks** | Live ticker quotes via Yahoo Finance | `NVDA $128.44 0.84%` |
21
- | **Hacker News** | Top/new/best/ask/show/jobs | `Show HN: I built a database in a spreadsheet45m ago` |
22
- | **Earthquakes** | USGS earthquake catalog near a ZIP | `M4.2 — 12 km NE of Ridgecrest, CA — 38m ago` |
23
- | **Weather Alerts** | NOAA/NWS severe weather by ZIP | `Severe Thunderstorm WarningBroward, FL — 12m ago` |
24
- | **Custom JSON** | Any JSON API with configurable field mapping | `My APIArticle title 1h ago` |
25
- | **GitHub Commits** | Recent repo or org commits with diffs | `vscode@c0ebf3e fix devtools entrypoint (+1 -1) 4h ago - @deepak1556` |
26
- | **GitHub Feeds** | Org activity, timeline, security advisories | `@dependabot opened a pull request in copilot-sdk — 3m ago` |
27
-
28
- ### AI-powered formatting
29
-
30
- Enable [GitHub Models](https://docs.github.com/en/github-models) and the engine rewrites raw headlines into concise, factual phrases. For GitHub commits, it can digest the **full commit diff** so the summary reflects what actually changed.
29
+ | **RSS / Atom** | Any feed URL | `Copilot code review now accounts for over 20% of all code reviews on GitHub, reflecting a tenfold increase in usage since its launch. The GitHub Blog (2d ago)` |
30
+ | **Stocks** | Live ticker quotes via Yahoo Finance | `BTC - USD $66,978.232.02% 🟢` |
31
+ | **Hacker News** | Top/new/best/ask/show/jobs | `Multiple cursors enable simultaneous operations on syntax nodes, significantly enhancing bulk editing and refactoring capabilities. Hacker News @ravenical 378 pts (17h ago)` |
32
+ | **Earthquakes** | USGS earthquake catalog near a ZIP | `M4.2 — 12 km NE of Ridgecrest, CA — USGS (38m ago)` |
33
+ | **Weather** | Temp, humidity, wind + NWS alerts | `77°F, Mostly Cloudy, Wind E 50 mph Fort Lauderdale, FL — Weather.gov` |
34
+ | **Custom JSON** | Any JSON API with field mapping | `Article titleMy API (1h ago)` |
35
+ | **GitHub Commits** | Repo or org commits with diffs | `fix devtools entrypoint — vscode +1/-1 @deepak1556 (4h ago)` |
36
+ | **GitHub Feeds** | Org activity, timeline, advisories | `opened a pull request in copilot-sdk — @dependabot (3m ago)` |
31
37
 
32
- ### Static phrase packs
38
+ ## Static phrase packs
33
39
 
34
- Pre-built JSON packs for when you want something stable:
40
+ Pre-built packs for when you just want vibes:
35
41
 
36
42
  | Pack | Phrases |
37
43
  |------|---------|
@@ -43,19 +49,7 @@ Pre-built JSON packs for when you want something stable:
43
49
  | WoW loading screen tips | 109 |
44
50
  | Inspirational quotes | 1,614 |
45
51
 
46
- ### Interactive CLI
47
-
48
- A guided terminal UI that walks you through source selection, config, preview, and installation — no flag memorization required.
49
-
50
- ### macOS scheduler
51
-
52
- A `launchd` job that refreshes your phrases on a cron-like interval. Set it to 5 minutes for stocks, an hour for news, whatever you want.
53
-
54
- ### Multiple config profiles
55
-
56
- Keep separate configs for different moods. `configs/github-timeline.config.json` for work, `configs/stocks-only.config.json` for market hours, swap between them.
57
-
58
- ### One-liner examples
52
+ ## Examples
59
53
 
60
54
  ```bash
61
55
  # GitHub org activity feed
@@ -70,37 +64,44 @@ npx thinking-phrases --stocks MSFT,NVDA,TSLA --feed https://github.blog/feed/
70
64
  # Earthquakes near a ZIP
71
65
  npx thinking-phrases --use-earthquakes --quake-zip 94103 --quake-min-magnitude 2
72
66
 
73
- # Weather alerts near a ZIP
67
+ # Weather conditions + alerts
74
68
  npx thinking-phrases --use-weather-alerts --weather-zip 33312
75
69
 
76
- # Dry run (preview only, don't write)
77
- npx thinking-phrases --dry-run --use-github --github-mode feed --github-feed-kind organization --github-org github
70
+ # Hacker News top stories
71
+ npx thinking-phrases --use-hacker-news --hn-feed top --hn-max-items 15 --hn-min-score 100
78
72
 
79
- # Write to settings
80
- npx thinking-phrases --use-github --github-mode feed --github-feed-kind organization --github-org github
73
+ # Custom JSON API
74
+ npx thinking-phrases --use-custom-json --json-url "https://hn.algolia.com/api/v1/search?tags=front_page" --json-items-path hits --json-title-field title
75
+
76
+ # Dry run (preview only, don't write)
77
+ npx thinking-phrases --dry-run --stocks MSFT,NVDA --use-hacker-news
81
78
  ```
82
79
 
83
- ### Install globally (optional)
80
+ ## Install
84
81
 
85
82
  ```bash
83
+ # Just run it (no install needed)
84
+ npx thinking-phrases --interactive
85
+
86
+ # Or install globally
86
87
  npm install -g thinking-phrases
87
88
  thinking-phrases --interactive
88
- ```
89
89
 
90
- ### Clone for development
91
-
92
- ```bash
90
+ # Or clone for development
93
91
  git clone https://github.com/austenstone/thinking-phrases.git
94
92
  cd thinking-phrases
95
93
  npm install
96
94
  npm run start:interactive
97
95
  ```
98
96
 
99
- ## Data sources
97
+ ## Data source config
100
98
 
101
- ### RSS / Atom feeds
99
+ Each source can be configured via CLI flags, config files, or the interactive CLI. Here's what each one looks like in a config file:
102
100
 
103
- Any RSS or Atom feed URL. Google News, GitHub Blog, Ars Technica, your company blog — whatever you want.
101
+ <details>
102
+ <summary><b>RSS / Atom feeds</b></summary>
103
+
104
+ Any feed URL. Google News, GitHub Blog, Ars Technica, your company blog — whatever. When AI is enabled, full article HTML is fetched for richer summaries.
104
105
 
105
106
  ```json
106
107
  "feeds": [
@@ -109,34 +110,45 @@ Any RSS or Atom feed URL. Google News, GitHub Blog, Ars Technica, your company b
109
110
  ]
110
111
  ```
111
112
 
112
- ### Stock quotes
113
+ Default refresh: every 6 hours.
114
+ </details>
115
+
116
+ <details>
117
+ <summary><b>Stock quotes</b></summary>
113
118
 
114
- Live prices via Yahoo Finance. Supports market state labels (pre-market, after-hours).
119
+ Live prices via Yahoo Finance. Pre-market, after-hours, closed labels.
115
120
 
116
121
  ```json
117
122
  "stockQuotes": {
118
123
  "enabled": true,
119
124
  "symbols": ["MSFT", "NVDA", "TSLA", "AMZN", "GOOGL", "AMD"],
120
- "includeMarketState": true
125
+ "includeMarketState": true,
126
+ "showClosed": false,
127
+ "fetchIntervalSeconds": 60
121
128
  }
122
129
  ```
130
+ </details>
123
131
 
124
- ### Hacker News
132
+ <details>
133
+ <summary><b>Hacker News</b></summary>
125
134
 
126
- Top, new, best, ask, show, or jobs feed. Configurable minimum score and item count.
135
+ Top, new, best, ask, show, or jobs feed. Configurable minimum score.
127
136
 
128
137
  ```json
129
138
  "hackerNews": {
130
139
  "enabled": true,
131
140
  "feed": "top",
132
141
  "maxItems": 10,
133
- "minScore": 50
142
+ "minScore": 50,
143
+ "fetchIntervalSeconds": 300
134
144
  }
135
145
  ```
146
+ </details>
136
147
 
137
- ### Earthquakes (USGS)
148
+ <details>
149
+ <summary><b>Earthquakes (USGS)</b></summary>
138
150
 
139
- Enter a ZIP code and the engine resolves it to lat/lon, then queries the USGS earthquake catalog within a configurable radius.
151
+ Enter a ZIP code or place name resolves to lat/lon queries USGS within a radius.
140
152
 
141
153
  ```json
142
154
  "earthquakes": {
@@ -144,26 +156,37 @@ Enter a ZIP code and the engine resolves it to lat/lon, then queries the USGS ea
144
156
  "zipCode": "94103",
145
157
  "minMagnitude": 2,
146
158
  "radiusKm": 500,
147
- "limit": 10
159
+ "windowHours": 24,
160
+ "limit": 10,
161
+ "orderBy": "time",
162
+ "fetchIntervalSeconds": 1800
148
163
  }
149
164
  ```
165
+ </details>
150
166
 
151
- ### Weather alerts (NOAA/NWS)
167
+ <details>
168
+ <summary><b>Weather (NOAA/NWS)</b></summary>
152
169
 
153
- Enter a ZIP code and the engine resolves it to a state, then queries NOAA for active severe weather alerts.
170
+ Current conditions (temp, humidity, wind, description) + active severe weather alerts. Auto-detects location in interactive mode.
154
171
 
155
172
  ```json
156
173
  "weatherAlerts": {
157
174
  "enabled": true,
158
175
  "zipCode": "33312",
176
+ "area": "FL",
159
177
  "minimumSeverity": "moderate",
160
- "limit": 10
178
+ "limit": 10,
179
+ "fetchIntervalSeconds": 1800
161
180
  }
162
181
  ```
163
182
 
164
- ### Custom JSON API
183
+ Severity levels: `minor`, `moderate`, `severe`, `extreme`.
184
+ </details>
185
+
186
+ <details>
187
+ <summary><b>Custom JSON API</b></summary>
165
188
 
166
- Point it at any JSON endpoint. Map title, content, link, source, date, and ID fields. Works with anything that returns an array of objects.
189
+ Point at any JSON endpoint and map the fields. Multiple sources supported via `customJsonSources[]`.
167
190
 
168
191
  ```json
169
192
  "customJson": {
@@ -171,19 +194,21 @@ Point it at any JSON endpoint. Map title, content, link, source, date, and ID fi
171
194
  "url": "https://hn.algolia.com/api/v1/search?tags=front_page",
172
195
  "itemsPath": "hits",
173
196
  "titleField": "title",
197
+ "contentField": "summary",
174
198
  "linkField": "url",
175
199
  "sourceLabel": "HN API",
176
200
  "dateField": "created_at",
177
201
  "idField": "objectID",
178
- "maxItems": 10
202
+ "maxItems": 10,
203
+ "fetchIntervalSeconds": 3600
179
204
  }
180
205
  ```
206
+ </details>
181
207
 
182
- ### GitHub activity
183
-
184
- Three modes for GitHub data:
208
+ <details>
209
+ <summary><b>GitHub activity</b></summary>
185
210
 
186
- **Repo commits** recent commits from a specific repository. Includes short SHA, line deltas, and author handle in the phrase. When AI is enabled with extra context, the model gets the **full commit diff**.
211
+ Three modes: **repo-commits** (recent commits with diffs), **org-commits** (push events across an org), and **feed** (Atom feeds org activity, timeline, security advisories, etc.).
187
212
 
188
213
  ```json
189
214
  "githubActivity": {
@@ -192,105 +217,72 @@ Three modes for GitHub data:
192
217
  "repo": "microsoft/vscode",
193
218
  "branch": "main",
194
219
  "maxItems": 10,
195
- "tokenEnvVar": "GITHUB_TOKEN"
196
- }
197
- ```
198
-
199
- **Org commits** — recent push events across an entire GitHub organization. Fetches commit details for each push.
200
-
201
- ```json
202
- "githubActivity": {
203
- "enabled": true,
204
- "mode": "org-commits",
205
- "org": "github",
206
- "maxItems": 10
207
- }
208
- ```
209
-
210
- **Feeds** — GitHub Atom feeds including organization activity, your personal timeline, security advisories, or any custom feed URL. Supports authenticated private feed discovery via `/feeds` with fallback to public org events.
211
-
212
- ```json
213
- "githubActivity": {
214
- "enabled": true,
215
- "mode": "feed",
216
- "feedKind": "organization",
217
- "org": "github",
218
- "maxItems": 20
220
+ "sinceHours": 24,
221
+ "tokenEnvVar": "GITHUB_TOKEN",
222
+ "fetchIntervalSeconds": 300
219
223
  }
220
224
  ```
221
225
 
222
- Available feed kinds: `timeline`, `current-user-public`, `current-user`, `current-user-actor`, `security-advisories`, `organization`, `custom-url`.
226
+ Feed kinds: `timeline`, `current-user-public`, `current-user`, `current-user-actor`, `security-advisories`, `organization`, `custom-url`.
227
+ </details>
223
228
 
224
- ## GitHub Models (AI)
229
+ ## AI-powered formatting
225
230
 
226
- When enabled, the engine sends fetched items to GitHub Models for rewriting into concise, factual phrases. Falls back to the normal formatter if auth or inference fails.
231
+ Enable [GitHub Models](https://docs.github.com/en/github-models) and each article gets individually rewritten by AI into a concise phrase. Works with `gpt-4o-mini`, `gpt-5`, `o3`, or any OpenAI-compatible model. Source attribution (`— Source (time)`) is appended automatically the model just focuses on content.
227
232
 
228
- For GitHub commits specifically, the model receives the full commit diff as additional context when extra content fetching is enabled — so it can summarize what actually changed, not just echo the commit message.
233
+ Results are cached per-article (7-day TTL) so re-runs don't burn tokens. Falls back to template formatting if auth or inference fails.
229
234
 
230
235
  ```json
231
236
  "githubModels": {
232
237
  "enabled": true,
233
- "model": "openai/gpt-4.1",
238
+ "model": "openai/gpt-4o-mini",
234
239
  "fetchArticleContent": true
235
240
  }
236
241
  ```
237
242
 
238
- ### Auth
243
+ Auth resolves in order: `GITHUB_MODELS_TOKEN` → `GITHUB_TOKEN` → `gh auth token`.
239
244
 
240
- Tokens are resolved in this order for both GitHub API and GitHub Models:
245
+ ## Phrase format
241
246
 
242
- 1. Configured env var (`GITHUB_MODELS_TOKEN` / `GITHUB_TOKEN`)
243
- 2. `GITHUB_TOKEN` env var
244
- 3. `gh auth token` (GitHub CLI)
247
+ Customizable templates with `%variable%` substitution. The engine auto-strips empty brackets and collapses whitespace.
245
248
 
246
- For GitHub activity, if a token causes 401/403 on public endpoints, it silently retries without auth.
249
+ ```json
250
+ "phraseFormatting": {
251
+ "includeSource": true,
252
+ "includeTime": true,
253
+ "maxLength": 140,
254
+ "templates": {
255
+ "article": "%title% — %source% (%time%)",
256
+ "hackerNews": "%title% — HN %score% (%time%)",
257
+ "stock": "%symbol% %price% %change% %market%",
258
+ "githubCommit": "%headline% — %repo% %delta% @%author% (%time%)",
259
+ "githubFeed": "%action% — @%handle% (%time%)"
260
+ }
261
+ }
262
+ ```
247
263
 
248
264
  ## Presets
249
265
 
250
- The interactive installer includes built-in presets to get started fast:
266
+ The interactive CLI includes presets to get started fast:
251
267
 
252
- | Preset | Sources |
253
- |--------|---------|
268
+ | Preset | What you get |
269
+ |--------|-------------|
254
270
  | **Dev Pulse** | Google Tech news + Hacker News top stories |
255
- | **Market Watch** | Big-tech stock quotes with fast-refresh defaults |
256
- | **World Signals** | Earthquakes + severe weather + Hacker News best |
271
+ | **Market Watch** | MSFT, NVDA, AMZN, GOOGL, AMD, TSLA stock quotes |
272
+ | **World Signals** | Earthquakes (M4.5+) + severe weather + Hacker News best |
257
273
 
258
274
  ## Scheduler (macOS)
259
275
 
260
- The interactive installer can set up a `launchd` scheduler that refreshes your phrases on a timer. If you cloned the repo, you can also install it manually:
261
-
262
- ```bash
263
- npm run rss:install # default: every 3600s (1 hour)
264
- npm run rss:install -- 300 # every 5 minutes
265
- npm run rss:install -- 900 ./configs/stocks-only.config.json
266
- ```
267
-
268
- The scheduler runs at the OS level. Your VS Code settings update silently in the background.
276
+ A `launchd` job that refreshes phrases in the background. The interactive CLI can set this up, or do it manually:
269
277
 
270
278
  ```bash
271
- npm run rss:uninstall # remove the scheduler
272
- npx thinking-phrases --uninstall # remove thinking phrases from settings
279
+ npm run schedule # every 1 hour (default)
280
+ npm run schedule -- 300 # every 5 minutes
281
+ npm run schedule:trigger # run now
282
+ npm run schedule:remove # remove it
273
283
  ```
274
284
 
275
- ## Config profiles
276
-
277
- Keep multiple configs in `configs/` and switch between them:
278
-
279
- ```text
280
- configs/
281
- rss-settings.config.json
282
- github-timeline.config.json
283
- github-commits.config.json
284
- google-news.config.json
285
- google-technology-stocks.config.json
286
- hn-best-earthquakes-weather-alerts.config.json
287
- stocks-only.config.json
288
- ```
289
-
290
- ```bash
291
- npm run rss:run -- --config configs/stocks-only.config.json
292
- npm run rss:install -- 300 configs/stocks-only.config.json
293
- ```
285
+ Also available via CLI flags: `--install-scheduler`, `--trigger-scheduler-now`, `--uninstall-scheduler`.
294
286
 
295
287
  ## Static packs
296
288
 
@@ -327,33 +319,129 @@ Standalone string arrays — just drop them in:
327
319
  - WoW loading screen tips (109)
328
320
  - Inspirational quotes (1,614 — from `dwyl/quotes`, GPL-2.0)
329
321
 
322
+ Install a static pack directly:
323
+
324
+ ```bash
325
+ npx thinking-phrases --static-pack out/typescript-tips.json
326
+ ```
327
+
330
328
  ## CLI reference
331
329
 
330
+ ### Commands
331
+
332
332
  | Command | Description |
333
333
  |---------|-------------|
334
334
  | `npx thinking-phrases --interactive` | Guided interactive setup |
335
335
  | `npx thinking-phrases --dry-run` | Preview phrases without writing |
336
336
  | `npx thinking-phrases` | Write phrases to VS Code settings |
337
337
  | `npx thinking-phrases --uninstall` | Remove thinking phrases from settings |
338
-
339
- All `--flags` from the data source sections above work with any of these commands.
338
+ | `npx thinking-phrases --static-pack <path>` | Install a static phrase pack |
339
+
340
+ ### Global flags
341
+
342
+ | Flag | Description |
343
+ |------|-------------|
344
+ | `--config <path>` | Load a saved config file |
345
+ | `--settings <path>` | Custom VS Code settings.json path |
346
+ | `--dry-run` | Preview phrases without writing to settings |
347
+ | `--verbose` | Verbose output |
348
+ | `--debug` | Debug output (includes verbose) |
349
+ | `--limit <num>` | Max total phrases (default: 100) |
350
+ | `--mode append\|replace` | Append to or replace existing phrases |
351
+ | `--target auto\|insiders\|stable` | Which VS Code edition to target |
352
+ | `--max-length <num>` | Max phrase length in characters (default: 140) |
353
+ | `--no-source` | Omit source attribution from phrases |
354
+ | `--no-time` | Omit relative time from phrases |
355
+
356
+ ### Source flags
357
+
358
+ | Flag | Description |
359
+ |------|-------------|
360
+ | `--feed <url>` | Add an RSS/Atom feed URL (repeatable) |
361
+ | `--use-stocks` / `--no-stocks` | Enable/disable stock quotes |
362
+ | `--stocks <SYMBOLS>` | Comma-separated stock tickers |
363
+ | `--use-hacker-news` | Enable Hacker News |
364
+ | `--hn-feed <type>` | top, new, best, ask, show, or jobs |
365
+ | `--hn-max-items <num>` | Max HN items |
366
+ | `--hn-min-score <num>` | Minimum HN score filter |
367
+ | `--use-earthquakes` | Enable earthquake source |
368
+ | `--quake-zip <zip>` | ZIP code for earthquake search center |
369
+ | `--quake-place <name>` | Place name for earthquake search |
370
+ | `--quake-min-magnitude <num>` | Minimum magnitude filter |
371
+ | `--quake-radius-km <num>` | Search radius in km |
372
+ | `--quake-hours <num>` | Time window in hours |
373
+ | `--quake-order time\|magnitude` | Sort order |
374
+ | `--quake-limit <num>` | Max earthquake results |
375
+ | `--use-weather-alerts` | Enable weather source |
376
+ | `--weather-zip <zip>` | ZIP code for weather |
377
+ | `--weather-area <area>` | US state code (e.g. FL) |
378
+ | `--weather-severity <level>` | Minimum severity (minor/moderate/severe/extreme) |
379
+ | `--weather-limit <num>` | Max weather alert results |
380
+ | `--use-custom-json` | Enable custom JSON source |
381
+ | `--json-url <url>` | JSON endpoint URL |
382
+ | `--json-items-path <path>` | JSONPath to items array |
383
+ | `--json-title-field <field>` | Field name for title |
384
+ | `--json-content-field <field>` | Field name for content |
385
+ | `--json-link-field <field>` | Field name for link |
386
+ | `--json-source-field <field>` | Field name for source |
387
+ | `--json-source-label <label>` | Fallback source label |
388
+ | `--json-date-field <field>` | Field name for date |
389
+ | `--json-id-field <field>` | Field name for ID |
390
+ | `--json-max-items <num>` | Max JSON items |
391
+ | `--use-github` | Enable GitHub activity |
392
+ | `--github-mode <mode>` | repo-commits, org-commits, or feed |
393
+ | `--github-repo <owner/repo>` | Target repository |
394
+ | `--github-org <org>` | Target organization |
395
+ | `--github-branch <branch>` | Branch filter |
396
+ | `--github-feed-kind <kind>` | Feed type (see GitHub activity section) |
397
+ | `--github-feed-url <url>` | Custom feed URL |
398
+ | `--github-max-items <num>` | Max GitHub items |
399
+ | `--github-since-hours <num>` | Lookback window in hours |
400
+ | `--github-token-env <var>` | Env var name for GitHub token |
401
+
402
+ ### AI model flags
403
+
404
+ | Flag | Description |
405
+ |------|-------------|
406
+ | `--use-models` / `--no-models` | Enable/disable AI rewriting |
407
+ | `--model <name>` | Model ID (default: `openai/gpt-4o-mini`) |
408
+ | `--models-endpoint <url>` | Inference endpoint |
409
+ | `--models-token-env <var>` | Env var for model auth token |
410
+ | `--models-max-concurrency <num>` | Parallel inference requests |
411
+ | `--models-max-input-items <num>` | Max articles sent to model |
412
+ | `--models-max-input-tokens <num>` | Max input token budget |
413
+ | `--models-max-tokens <num>` | Max output tokens per request |
414
+ | `--models-max-phrases-per-article <num>` | Phrases generated per article |
415
+ | `--models-temperature <0-1>` | Sampling temperature |
416
+ | `--fetch-article-content` / `--no-fetch-article-content` | Fetch full article HTML for AI |
417
+ | `--max-article-content-length <num>` | Max chars of article body sent to model |
418
+
419
+ ### Scheduler flags
420
+
421
+ | Flag | Description |
422
+ |------|-------------|
423
+ | `--install-scheduler` | Install/update macOS launchd job |
424
+ | `--trigger-scheduler-now` | Trigger the scheduler immediately |
425
+ | `--uninstall-scheduler` | Remove the launchd job |
340
426
 
341
427
  ## How it works
342
428
 
343
429
  ```
344
- Sources → Normalize → Format → Write
430
+ Sources → Normalize → Format → Cache → Write
345
431
  ```
346
432
 
347
- 1. **Sources** fetch live data (RSS, stocks, GitHub, USGS, NOAA, JSON APIs)
348
- 2. **Core** normalizes everything into article or stock items
349
- 3. **Formatter** builds phrases either basic `source title time` or AI-rewritten via GitHub Models
350
- 4. **Sink** writes the final phrases into VS Code `settings.json`
433
+ 1. **Sources** fetch live data (RSS, stocks, GitHub, USGS, NOAA, JSON APIs) — each respects its own refresh interval
434
+ 2. **Core** normalizes everything into `ArticleItem` or `StockItem` objects
435
+ 3. **Formatter** builds display phrases from customizable templatescontent first, source/metadata suffix appended
436
+ 4. **AI** (optional) rewrites phrases via GitHub Models, with per-article caching to avoid redundant inference
437
+ 5. **Phrase store** persists phrases per-source in `~/.cache/thinking-phrases/` so different refresh intervals don't clobber each other
438
+ 6. **Sink** writes the merged phrases into VS Code `settings.json` using `jsonc-parser` (preserves comments and formatting)
351
439
 
352
- The source catalog is modular. Each source is a simple `{ isEnabled, fetch }` object registered in the catalog. Adding a new source means writing one file and registering it.
440
+ The source catalog is modular. Each source is a `{ type, isEnabled, fetch }` object registered in the catalog. Adding a new source means writing one file and registering it.
353
441
 
354
442
  ## Portability
355
443
 
356
- Settings path auto-detection works on macOS, Linux, and Windows. Supports both VS Code Stable and Insiders. You can also pass `--settings` to point at any path.
444
+ Settings path auto-detection works on macOS, Linux, and Windows. Supports both VS Code Stable and Insiders. You can also pass `--settings` to point at any path or `--target` to force a specific edition.
357
445
 
358
446
  ## References
359
447