nber-cli 0.3.0__tar.gz → 0.4.0__tar.gz

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 (86) hide show
  1. nber_cli-0.4.0/CHANGELOG.md +68 -0
  2. {nber_cli-0.3.0 → nber_cli-0.4.0}/PKG-INFO +1 -1
  3. nber_cli-0.4.0/docs/en/changelog.md +74 -0
  4. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/cli.md +115 -24
  5. nber_cli-0.4.0/docs/en/configuration.md +139 -0
  6. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/getting-started.md +2 -2
  7. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/python-api.md +112 -7
  8. nber_cli-0.4.0/docs/zh/changelog.md +74 -0
  9. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/cli.md +115 -24
  10. nber_cli-0.4.0/docs/zh/configuration.md +139 -0
  11. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/getting-started.md +2 -2
  12. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/python-api.md +112 -7
  13. {nber_cli-0.3.0 → nber_cli-0.4.0}/pyproject.toml +1 -1
  14. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/__init__.py +46 -2
  15. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/cli.py +243 -21
  16. nber_cli-0.4.0/src/nber_cli/config_store.py +154 -0
  17. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/core/models.py +12 -0
  18. nber_cli-0.4.0/src/nber_cli/db.py +649 -0
  19. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/feed.py +21 -141
  20. nber_cli-0.4.0/src/nber_cli/info_cache.py +51 -0
  21. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/mcp.py +5 -2
  22. nber_cli-0.4.0/tests/conftest.py +26 -0
  23. {nber_cli-0.3.0 → nber_cli-0.4.0}/tests/test_cli.py +291 -32
  24. nber_cli-0.4.0/tests/test_config_store.py +88 -0
  25. nber_cli-0.4.0/tests/test_db.py +205 -0
  26. {nber_cli-0.3.0 → nber_cli-0.4.0}/tests/test_feed.py +9 -9
  27. nber_cli-0.4.0/tests/test_info_cache.py +281 -0
  28. nber_cli-0.4.0/tests/test_info_cache_flow.py +99 -0
  29. nber_cli-0.4.0/tests/test_logs.py +121 -0
  30. {nber_cli-0.3.0 → nber_cli-0.4.0}/uv.lock +1 -1
  31. nber_cli-0.3.0/CHANGELOG.md +0 -39
  32. nber_cli-0.3.0/docs/en/changelog.md +0 -41
  33. nber_cli-0.3.0/docs/en/configuration.md +0 -120
  34. nber_cli-0.3.0/docs/zh/changelog.md +0 -41
  35. nber_cli-0.3.0/docs/zh/configuration.md +0 -120
  36. nber_cli-0.3.0/tests/conftest.py +0 -11
  37. {nber_cli-0.3.0 → nber_cli-0.4.0}/.claude/agents/code-to-docs.md +0 -0
  38. {nber_cli-0.3.0 → nber_cli-0.4.0}/.claude/agents/sync-docs-for-i18n.md +0 -0
  39. {nber_cli-0.3.0 → nber_cli-0.4.0}/.claude/settings.json +0 -0
  40. {nber_cli-0.3.0 → nber_cli-0.4.0}/.claude-plugin/marketplace.json +0 -0
  41. {nber_cli-0.3.0 → nber_cli-0.4.0}/.codex/config.toml +0 -0
  42. {nber_cli-0.3.0 → nber_cli-0.4.0}/.github/workflows/docs.yml +0 -0
  43. {nber_cli-0.3.0 → nber_cli-0.4.0}/.github/workflows/lint.yml +0 -0
  44. {nber_cli-0.3.0 → nber_cli-0.4.0}/.github/workflows/publish.yml +0 -0
  45. {nber_cli-0.3.0 → nber_cli-0.4.0}/.github/workflows/pytest.yml +0 -0
  46. {nber_cli-0.3.0 → nber_cli-0.4.0}/.gitignore +0 -0
  47. {nber_cli-0.3.0 → nber_cli-0.4.0}/.mcp.json +0 -0
  48. {nber_cli-0.3.0 → nber_cli-0.4.0}/.python-version +0 -0
  49. {nber_cli-0.3.0 → nber_cli-0.4.0}/LICENSE +0 -0
  50. {nber_cli-0.3.0 → nber_cli-0.4.0}/README.md +0 -0
  51. {nber_cli-0.3.0 → nber_cli-0.4.0}/README.zh-CN.md +0 -0
  52. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/agents/claude-code.md +0 -0
  53. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/agents/codex.md +0 -0
  54. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/agents/index.md +0 -0
  55. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/agents/openclaw.md +0 -0
  56. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/agents/others.md +0 -0
  57. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/contributing.md +0 -0
  58. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/development.md +0 -0
  59. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/index.md +0 -0
  60. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/mcp.md +0 -0
  61. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/en/policy.md +0 -0
  62. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/agents/claude-code.md +0 -0
  63. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/agents/codex.md +0 -0
  64. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/agents/index.md +0 -0
  65. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/agents/openclaw.md +0 -0
  66. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/agents/others.md +0 -0
  67. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/contributing.md +0 -0
  68. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/development.md +0 -0
  69. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/index.md +0 -0
  70. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/mcp.md +0 -0
  71. {nber_cli-0.3.0 → nber_cli-0.4.0}/docs/zh/policy.md +0 -0
  72. {nber_cli-0.3.0 → nber_cli-0.4.0}/mkdocs.yml +0 -0
  73. {nber_cli-0.3.0 → nber_cli-0.4.0}/plugins/nber-cli/.claude-plugin/plugin.json +0 -0
  74. {nber_cli-0.3.0 → nber_cli-0.4.0}/plugins/nber-cli/.codex-plugin/plugin.json +0 -0
  75. {nber_cli-0.3.0 → nber_cli-0.4.0}/plugins/nber-cli/.mcp.json +0 -0
  76. {nber_cli-0.3.0 → nber_cli-0.4.0}/plugins/nber-cli/skills/NBER-CLI/SKILL.md +0 -0
  77. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/__main__.py +0 -0
  78. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/config.py +0 -0
  79. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/core/__init__.py +0 -0
  80. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/download.py +0 -0
  81. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/fetcher.py +0 -0
  82. {nber_cli-0.3.0 → nber_cli-0.4.0}/src/nber_cli/formatters.py +0 -0
  83. {nber_cli-0.3.0 → nber_cli-0.4.0}/tests/__init__.py +0 -0
  84. {nber_cli-0.3.0 → nber_cli-0.4.0}/tests/test_downloader.py +0 -0
  85. {nber_cli-0.3.0 → nber_cli-0.4.0}/tests/test_fetcher.py +0 -0
  86. {nber_cli-0.3.0 → nber_cli-0.4.0}/tests/test_main.py +0 -0
@@ -0,0 +1,68 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.4.0] - 2026-06-04
6
+
7
+ ### Added
8
+ - `nber-cli info --refresh` skips the local `info_cache` and re-fetches the paper from NBER. The new data is written back to the cache when the cache is enabled.
9
+ - `nber-cli info cache --turn-on` / `--turn-off` toggle the `info_cache` lookup globally and persist the state to `~/.nber-cli/config.json`.
10
+ - `nber-cli info cache --set-refresh <N>` sets the cache refresh interval in days. The value is persisted to `~/.nber-cli/config.json` and used as the TTL for every subsequent `info` call. Defaults to `30` days.
11
+ - `nber-cli info cache clear` with `--days`, `--all`, `--start-date`, or `--end-date` mirrors the `feed clean` parameter set, using `last_fetched_at` from the `info_cache` table. `nber-cli info cache clean` is a convenience alias for `clear --all`.
12
+ - `nber-cli info cache` (no sub-action) prints the current cache state, TTL, and cached row count.
13
+ - New `nber_cli.config_store` module: centralised read and write of `~/.nber-cli/config.json` plus the `InfoCacheSettings` dataclass and helpers (`get_info_cache_settings`, `set_info_cache_enabled`, `set_info_cache_ttl_days`).
14
+ - New `nber_cli.info_cache.get_paper_with_info_cache_result` async helper that returns an `InfoCacheLookupResult` carrying the `NBER` paper and a `from_cache` flag, so callers (CLI and MCP) can surface a "loaded from cache" hint.
15
+ - Public Python API exports: `InfoCacheSettings`, `InfoCacheLookupResult`, `clear_info_cache`, `count_info_cache`, `get_info_cache_settings`, `get_info_cache_ttl_days`, `is_info_cache_enabled`, `is_info_cache_expired`, `set_info_cache_enabled`, `set_info_cache_ttl_days`, `NBERInfoCacheClearResult`.
16
+
17
+ ### Changed
18
+ - `~/.nber-cli/config.json` now carries an `info` section: `info.cache_enabled` (default `true`) and `info.cache_ttl_days` (default `30`). Missing or malformed fields fall back to defaults.
19
+ - `info` now prints a one-line stderr hint when the paper was served from the local cache, pointing to `nber-cli info <id> --refresh` for a fresh fetch.
20
+
21
+ ## [0.3.1] - 2026-06-03
22
+
23
+ ### Added
24
+ - `db init` and `db migrate` top-level subcommands replace `feed init` and `feed migrate`. The database is now general-purpose and stores feed cache, behavior logs, and paper metadata cache.
25
+ - `info_cache` table caches paper metadata fetched via `info` and the MCP `get_paper_info` tool. Subsequent lookups return immediately from the cache.
26
+ - `query_log`, `download_log`, and `info_log` tables record search keywords, download outcomes, and paper info lookups for later auditing.
27
+ - `schema_version` field written to `~/.nber-cli/config.json` so future schema migrations can roll forward safely.
28
+
29
+ ### Changed
30
+ - Default database renamed from `feed.db` to `nber.db`. Existing `~/.nber-cli/feed.db` installations continue to work without manual steps.
31
+ - Database schema upgraded from `user_version = 1` to `user_version = 2`. Existing v1 databases are upgraded automatically on next CLI invocation; original `feed_items` rows are preserved.
32
+ - Database code consolidated into `nber_cli.db`. The original `init_feed_database`, `migrate_feed_database`, and `get_feed_database_path` helpers are kept as thin compatibility wrappers.
33
+
34
+ ## [0.3.0] - 2026-06-03
35
+
36
+ ### Added
37
+ - `feed init` subcommand: initialize a local SQLite feed cache and write its path to user config.
38
+ - `feed fetch` subcommand: fetch NBER's new working papers RSS feed, cache seen items, and show newly discovered papers by default.
39
+ - `feed fetch --max-items`: limit displayed feed output. When used without `--display-all`, display-all behavior is enabled automatically.
40
+ - `feed migrate` subcommand: move the feed cache database and SQLite sidecar files to a new path, then update user config.
41
+ - `feed clean` subcommand: clean cached feed database records by age, date range, or all records after interactive confirmation.
42
+ - Python API exports for feed cache helpers and feed result models.
43
+
44
+ ### Changed
45
+ - Added user config support at `~/.nber-cli/config.json` for the feed cache database path.
46
+ - Expanded English and Chinese documentation for feed commands, configuration, Python API, and release notes.
47
+
48
+ ## [0.2.0] - 2026-05-31
49
+
50
+ ### Added
51
+ - `download` subcommand: single paper ID or batch mode (`--batch`), explicit file path (`--file`), target directory (`--save-base`).
52
+ - `info` subcommand: paper metadata with `--all` flag for full details and `--format json` option.
53
+ - `search` subcommand: full-text search with date filters (`--start-date`, `--end-date`), pagination (`--page`, `--per-page`), `--format json` option.
54
+ - `mcp-server` subcommand: MCP server for AI agent integration with stdio and streamable_http transports.
55
+
56
+ ### Changed
57
+ - Reworked CLI into subcommand syntax (`nber-cli <subcommand>`).
58
+ - Simplified downloader to direct async HTTP PDF fetches (removed database-backed state tracking).
59
+ - Removed legacy web UI module and script entrypoint.
60
+
61
+ ## [0.1.4] - 2025-08-09
62
+
63
+ ### Added
64
+ - Added `--version` / `-v` flag to display current version.
65
+ - Added comprehensive help message with examples.
66
+ - Added `__main__.py` file to support `python -m nber_cli` usage.
67
+ - Added argument grouping for better CLI organization.
68
+ - Added automatic help display when no arguments are provided.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nber-cli
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: A command line interface for reaching the National Bureau of Economic Research (NBER) paper without brower.
5
5
  Project-URL: Homepage, https://github.com/sepinetam/nber-cli
6
6
  Project-URL: Repository, https://github.com/sepinetam/nber-cli
@@ -0,0 +1,74 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented here.
4
+
5
+ ## 0.4.0 - 2026-06-04
6
+
7
+ ### Added
8
+
9
+ - Added `nber-cli info --refresh` to bypass the local `info_cache` and re-fetch paper metadata from NBER. The fresh data is written back to the cache when the cache is enabled.
10
+ - Added `nber-cli info cache --turn-on` and `--turn-off` to toggle the `info_cache` lookup globally. The setting is persisted to `~/.nber-cli/config.json`.
11
+ - Added `nber-cli info cache --set-refresh <N>` to set the cache refresh interval in days. The value is persisted to `~/.nber-cli/config.json` and applied as the TTL for every subsequent `info` call. Defaults to `30` days.
12
+ - Added `nber-cli info cache clear` with the same parameter set as `feed clean`: `--days`, `--all`, `--start-date`, and `--end-date`. Filtering uses `last_fetched_at` from the `info_cache` table. `nber-cli info cache clean` is a convenience alias for `clear --all`.
13
+ - Added `nber-cli info cache` (no sub-action) to print the current cache state, TTL, and cached row count.
14
+ - Added `nber_cli.config_store` module with `InfoCacheSettings` and helpers (`get_info_cache_settings`, `set_info_cache_enabled`, `set_info_cache_ttl_days`) for reading and writing `~/.nber-cli/config.json`.
15
+ - Added `nber_cli.info_cache.get_paper_with_info_cache_result` async helper that returns an `InfoCacheLookupResult` carrying the `NBER` paper and a `from_cache` flag.
16
+ - Added public Python API exports for the new info cache helpers and `NBERInfoCacheClearResult` model.
17
+
18
+ ### Changed
19
+
20
+ - `~/.nber-cli/config.json` now stores an `info` section: `info.cache_enabled` (default `true`) and `info.cache_ttl_days` (default `30`). Missing or malformed fields fall back to defaults.
21
+ - `info` now prints a one-line stderr hint when the paper was served from the local cache, pointing to `nber-cli info <id> --refresh` for a fresh fetch.
22
+
23
+ ## 0.3.1 - 2026-06-03
24
+
25
+ ### Added
26
+
27
+ - Added `nber-cli db init` and `nber-cli db migrate` for initializing and relocating the local database. These replace `feed init` and `feed migrate`.
28
+ - Added `info_cache` table so repeated `nber-cli info` and MCP `get_paper_info` calls return immediately from cache.
29
+ - Added `query_log`, `download_log`, and `info_log` tables for recording search keywords, download outcomes, and info lookups.
30
+ - Added `schema_version` field in `~/.nber-cli/config.json` for forward-compatible schema upgrades.
31
+
32
+ ### Changed
33
+
34
+ - Renamed default database file from `feed.db` to `nber.db`. Existing `~/.nber-cli/feed.db` installations keep working without manual steps.
35
+ - Upgraded database schema from version 1 to version 2 with automatic upgrade on next invocation.
36
+ - Consolidated database code into `nber_cli.db`. Old `init_feed_database` and `migrate_feed_database` helpers remain as thin compatibility wrappers.
37
+
38
+ ## 0.3.0 - 2026-06-03
39
+
40
+ ### Added
41
+
42
+ - Added `nber-cli feed init` for creating a local SQLite feed cache.
43
+ - Added `nber-cli feed fetch` for fetching NBER's new working papers RSS feed and showing newly cached items.
44
+ - Added `nber-cli feed fetch --max-items` for limiting displayed feed output.
45
+ - Added `nber-cli feed migrate` for moving the feed cache database and updating user config.
46
+ - Added `nber-cli feed clean` for cleaning cached feed database records with confirmation.
47
+ - Added Python API documentation for feed cache helpers and feed data models.
48
+
49
+ ### Changed
50
+
51
+ - Added user config documentation for `~/.nber-cli/config.json` and `feed.db-path`.
52
+ - Expanded English and Chinese feed cache documentation across CLI, getting started, configuration, and Python API pages.
53
+
54
+ ## 0.2.0 - 2026-05-27
55
+
56
+ ### Changed
57
+
58
+ - Reworked the CLI into `nber-cli download ...` subcommand syntax.
59
+ - Added `--file/-f` and `--save-base/-s` path handling behavior.
60
+ - Added `--batch/-b` multi-ID download mode.
61
+ - Removed database-backed download state tracking.
62
+ - Simplified the downloader to direct async HTTP PDF fetches.
63
+ - Updated documentation for the v0.2 command model.
64
+ - Removed the legacy web UI module and script entrypoint.
65
+
66
+ ## 0.1.4 - 2025-08-09
67
+
68
+ ### Added
69
+
70
+ - Added `--version` / `-v` flag to display current version.
71
+ - Added comprehensive help message with examples.
72
+ - Added `__main__.py` support for `python -m nber_cli`.
73
+ - Added argument grouping for better CLI organization.
74
+ - Added automatic help display when no arguments are provided.
@@ -22,6 +22,7 @@ Running `nber-cli` without a subcommand prints the top-level help and exits succ
22
22
  | `download` | Download one or more paper PDFs. |
23
23
  | `info` | Show metadata and abstract for one paper. |
24
24
  | `search` | Search NBER working papers. |
25
+ | `db` | Manage the local SQLite database. |
25
26
  | `feed` | Manage the NBER new working papers RSS feed cache. |
26
27
  | `mcp-server` | Start the MCP server for agents. |
27
28
 
@@ -99,6 +100,85 @@ nber-cli info w25000 -f json
99
100
  | `paper_id` | Required paper ID, with or without the `w` prefix. |
100
101
  | `--all`, `-a` | Include related fields and published-version information when available. |
101
102
  | `--format`, `-f` | Output format: `list` or `json`. Defaults to `list`. |
103
+ | `--refresh` | Bypass the local `info_cache` and re-fetch from NBER. The new data is written back to the cache when the cache is enabled. |
104
+
105
+ When the cache is enabled and the cached entry has not yet passed the configured TTL, repeated `info` calls are served from the local database. The first `info` call after a TTL expiry, or any call with `--refresh`, performs a live fetch.
106
+
107
+ The MCP `get_paper_info` tool follows the same cache behavior, including the `--refresh` flag.
108
+
109
+ ## info cache
110
+
111
+ Manage the `info_cache` lookup behavior and clear cached records.
112
+
113
+ Show the current cache state, TTL, and row count:
114
+
115
+ ```bash
116
+ nber-cli info cache
117
+ ```
118
+
119
+ Toggle the cache globally:
120
+
121
+ ```bash
122
+ nber-cli info cache --turn-on
123
+ nber-cli info cache --turn-off
124
+ ```
125
+
126
+ Set the cache refresh interval in days:
127
+
128
+ ```bash
129
+ nber-cli info cache --set-refresh 7
130
+ nber-cli info cache --set-refresh 30
131
+ ```
132
+
133
+ `--set-refresh` requires a positive integer. The new value is written to `~/.nber-cli/config.json` and used as the TTL for every subsequent `info` call.
134
+
135
+ Clean cached records not refreshed in the last 30 days:
136
+
137
+ ```bash
138
+ nber-cli info cache clear
139
+ nber-cli info cache clear --days 30
140
+ ```
141
+
142
+ Clean all cached records:
143
+
144
+ ```bash
145
+ nber-cli info cache clear --all
146
+ nber-cli info cache clean
147
+ ```
148
+
149
+ `info cache clean` is a convenience alias for `info cache clear --all`.
150
+
151
+ Clean cached records by `last_fetched_at` date:
152
+
153
+ ```bash
154
+ nber-cli info cache clear --end-date 2026-06-01
155
+ nber-cli info cache clear --start-date 2026-05-01 --end-date 2026-06-01
156
+ ```
157
+
158
+ `--end-date` without `--start-date` cleans from the earliest cached record through the end date. `--start-date` and `--end-date` are inclusive. Passing only `--start-date` is invalid.
159
+
160
+ Before deleting anything, `info cache clear` prints how many cached records match and asks for confirmation:
161
+
162
+ ```text
163
+ This operation is irreversible.
164
+ Deleted info cache records may be fetched again from NBER.
165
+ Continue? [y/N]:
166
+ ```
167
+
168
+ Only `y` or `Y` continues. Any other response aborts without deleting records.
169
+
170
+ ### info cache Options
171
+
172
+ | Subcommand | Option | Description |
173
+ | --- | --- | --- |
174
+ | (none) | `--turn-on` | Enable the info cache globally. |
175
+ | (none) | `--turn-off` | Disable the info cache globally. |
176
+ | (none) | `--set-refresh` | Set the info cache refresh interval in days. Must be a positive integer. |
177
+ | `clear` | `--days` | Clean cached records not refreshed for this many days. Defaults to `30`. |
178
+ | `clear` | `--all` | Clean all cached records. |
179
+ | `clear` | `--start-date` | Clean cached records refreshed on or after this date, formatted `YYYY-MM-DD`. |
180
+ | `clear` | `--end-date` | Clean cached records refreshed on or before this date, formatted `YYYY-MM-DD`. |
181
+ | `clean` | — | Alias for `clear --all`. |
102
182
 
103
183
  ## search
104
184
 
@@ -142,18 +222,7 @@ When only `--start-date` is provided, NBER-CLI automatically uses the current da
142
222
 
143
223
  ## feed
144
224
 
145
- `feed` works with NBER's new working papers RSS feed and a local SQLite cache. The cache tracks which RSS items have already been seen, so `feed fetch` can show only newly discovered papers by default.
146
-
147
- ### feed init
148
-
149
- Initialize the feed cache database and write the database path to the user config:
150
-
151
- ```bash
152
- nber-cli feed init
153
- nber-cli feed init --db-path ~/.nber-cli/feed.db
154
- ```
155
-
156
- If `--db-path` is omitted, the default database path is `~/.nber-cli/feed.db`.
225
+ `feed` works with NBER's new working papers RSS feed and the local SQLite database. The database tracks which RSS items have already been seen, so `feed fetch` can show only newly discovered papers by default.
157
226
 
158
227
  ### feed fetch
159
228
 
@@ -185,16 +254,6 @@ nber-cli feed fetch --format json
185
254
  nber-cli feed fetch -f json
186
255
  ```
187
256
 
188
- ### feed migrate
189
-
190
- Move the feed cache database to a new path and update the user config:
191
-
192
- ```bash
193
- nber-cli feed migrate ~/data/nber-feed.db
194
- ```
195
-
196
- Migration moves the SQLite database file and any SQLite sidecar files such as `-wal`, `-shm`, and `-journal`. The target path must not already exist.
197
-
198
257
  ### feed clean
199
258
 
200
259
  Clean cached feed database records. This deletes records from the local cache, not from NBER. Deleted cache records may be fetched again as new items if they still appear in the RSS feed.
@@ -235,16 +294,48 @@ Only `y` or `Y` continues. Any other response aborts without deleting records.
235
294
 
236
295
  | Subcommand | Option | Description |
237
296
  | --- | --- | --- |
238
- | `init` | `--db-path` | SQLite cache database path. Defaults to `~/.nber-cli/feed.db`. |
239
297
  | `fetch` | `--display-all [true|false]` | Display all fetched RSS items instead of only new items. |
240
298
  | `fetch` | `--format`, `-f` | Output format: `list` or `json`. Defaults to `list`. |
241
299
  | `fetch` | `--max-items` | Maximum number of feed items to display. |
242
- | `migrate` | `new_db_path` | New SQLite cache database path. |
243
300
  | `clean` | `--days` | Clean cached records not seen for this many days. Defaults to `30`. |
244
301
  | `clean` | `--all` | Clean all cached feed records. |
245
302
  | `clean` | `--start-date` | Clean cached records last seen on or after this date, formatted `YYYY-MM-DD`. |
246
303
  | `clean` | `--end-date` | Clean cached records last seen on or before this date, formatted `YYYY-MM-DD`. |
247
304
 
305
+ ## db
306
+
307
+ `db` manages the local SQLite database used by `info`, `search`, `download`, and `feed` for cache and behavior logs.
308
+
309
+ ### db init
310
+
311
+ Initialize the database and write its path to the user config:
312
+
313
+ ```bash
314
+ nber-cli db init
315
+ nber-cli db init --db-path ~/.nber-cli/nber.db
316
+ ```
317
+
318
+ If `--db-path` is omitted, the default database path is `~/.nber-cli/nber.db`.
319
+
320
+ If an existing `~/.nber-cli/feed.db` from 0.3.0 is present and no `nber.db` exists yet, NBER-CLI uses that legacy file in place. Schema is automatically upgraded from version 1 to version 2 on first use.
321
+
322
+ ### db migrate
323
+
324
+ Move the database to a new path and update the user config:
325
+
326
+ ```bash
327
+ nber-cli db migrate ~/data/nber.db
328
+ ```
329
+
330
+ Migration moves the SQLite database file and any SQLite sidecar files such as `-wal`, `-shm`, and `-journal`. The target path must not already exist.
331
+
332
+ ### db Options
333
+
334
+ | Subcommand | Option | Description |
335
+ | --- | --- | --- |
336
+ | `init` | `--db-path` | SQLite database path. Defaults to `~/.nber-cli/nber.db`. |
337
+ | `migrate` | `new_db_path` | New SQLite database path. |
338
+
248
339
  ## mcp-server
249
340
 
250
341
  Start the default stdio MCP server:
@@ -0,0 +1,139 @@
1
+ # Configuration
2
+
3
+ Most NBER-CLI runtime behavior uses built-in defaults. The local database also uses a small user config file to remember the SQLite database path selected by `nber-cli db init` or `nber-cli db migrate`.
4
+
5
+ ## Runtime Defaults
6
+
7
+ | Setting | Default | Description |
8
+ | --- | --- | --- |
9
+ | Request timeout | `60` seconds | Total timeout for network requests. |
10
+ | Retry count | `3` | Failed eligible requests are retried before surfacing the error. |
11
+ | Request attempts | `4` | Derived from retry count plus the first attempt. |
12
+ | Download connection limit | `100` | Maximum concurrent download connections. |
13
+ | Per-host connection limit | `10` | Maximum concurrent connections to one host. |
14
+ | Search page sizes | `20`, `50`, `100` | Accepted values for `--per-page`. |
15
+
16
+ These values live in `NBERCLIConfig` and `NBER_CLI_CONFIG`.
17
+
18
+ ## User Config File
19
+
20
+ The user config file is:
21
+
22
+ ```text
23
+ ~/.nber-cli/config.json
24
+ ```
25
+
26
+ Current schema:
27
+
28
+ ```json
29
+ {
30
+ "schema_version": 2,
31
+ "feed": {
32
+ "db-path": "/Users/name/.nber-cli/nber.db"
33
+ },
34
+ "info": {
35
+ "cache_enabled": true,
36
+ "cache_ttl_days": 30
37
+ }
38
+ }
39
+ ```
40
+
41
+ `feed.db-path` points to the SQLite database used by `info`, `search`, `download`, and `feed`. The historical `feed` key name is preserved for backward compatibility; the database itself is general-purpose.
42
+
43
+ `schema_version` records the current database schema version. NBER-CLI updates it after `db init` or schema upgrades.
44
+
45
+ `info.cache_enabled` controls the `info_cache` lookup globally. Set to `false` to force every `info` call (and the MCP `get_paper_info` tool) to go straight to NBER. Defaults to `true`.
46
+
47
+ `info.cache_ttl_days` sets the refresh interval in days. Cached entries older than this threshold are treated as cache misses and re-fetched on the next `info` call. Must be a positive integer. Defaults to `30`.
48
+
49
+ Both `info` keys are managed by `nber-cli info cache --turn-on/--off/--set-refresh <N>`. Missing or malformed fields fall back to defaults and never cause NBER-CLI to fail.
50
+
51
+ ## Local Database
52
+
53
+ Default database path:
54
+
55
+ ```text
56
+ ~/.nber-cli/nber.db
57
+ ```
58
+
59
+ Initialize the default database:
60
+
61
+ ```bash
62
+ nber-cli db init
63
+ ```
64
+
65
+ Initialize at a custom path:
66
+
67
+ ```bash
68
+ nber-cli db init --db-path ~/data/nber.db
69
+ ```
70
+
71
+ Move an existing database and update the config:
72
+
73
+ ```bash
74
+ nber-cli db migrate ~/data/nber.db
75
+ ```
76
+
77
+ If you upgraded from 0.3.0 and still have `~/.nber-cli/feed.db`, NBER-CLI will keep using that legacy file when no `nber.db` is present. The schema is upgraded automatically on first invocation.
78
+
79
+ The database holds:
80
+
81
+ - `feed_items` and `feed_fetches`: RSS cache used by `feed fetch` and `feed clean`.
82
+ - `info_cache`: paper metadata cache used by `info` and the MCP `get_paper_info` tool. Cache reads are gated by `info.cache_enabled` and respect the `info.cache_ttl_days` TTL.
83
+ - `query_log`, `download_log`, `info_log`: behavior logs for search keywords, download outcomes, and info lookups.
84
+
85
+ ## Output Paths
86
+
87
+ Single download default:
88
+
89
+ ```bash
90
+ nber-cli download w34567
91
+ ```
92
+
93
+ Creates:
94
+
95
+ ```text
96
+ ./w34567.pdf
97
+ ```
98
+
99
+ Directory-based download:
100
+
101
+ ```bash
102
+ nber-cli download w34567 --save-base ~/papers/nber
103
+ ```
104
+
105
+ Creates:
106
+
107
+ ```text
108
+ ~/papers/nber/w34567.pdf
109
+ ```
110
+
111
+ Explicit file download:
112
+
113
+ ```bash
114
+ nber-cli download w34567 --file ~/papers/custom-name.pdf
115
+ ```
116
+
117
+ Creates exactly the requested path, including parent directories when possible.
118
+
119
+ ## Date Filtering
120
+
121
+ Search dates use `YYYY-MM-DD`.
122
+
123
+ ```bash
124
+ nber-cli search "trade" --start-date 2024-01-01 --end-date 2024-12-31
125
+ ```
126
+
127
+ If `--start-date` is provided without `--end-date`, NBER-CLI uses the current date as the end date.
128
+
129
+ ## Network Behavior
130
+
131
+ NBER-CLI sends a browser-like user agent, uses retries for transient failures, and raises readable errors for common download failures:
132
+
133
+ - HTTP 403 can mean a newly released paper is still under NBER's first-week access restriction.
134
+ - HTTP 404 means the paper PDF was not found.
135
+ - Timeout and connection failures are reported as network errors.
136
+
137
+ ## No Credentials Required
138
+
139
+ NBER-CLI does not require an API key. It works against public NBER web pages and NBER's public working paper search endpoint.
@@ -75,10 +75,10 @@ nber-cli info w25000 --all
75
75
 
76
76
  ## Follow New Papers with the Feed Cache
77
77
 
78
- Initialize the local RSS feed cache:
78
+ Initialize the local database:
79
79
 
80
80
  ```bash
81
- nber-cli feed init
81
+ nber-cli db init
82
82
  ```
83
83
 
84
84
  Fetch the NBER new working papers RSS feed:
@@ -92,14 +92,14 @@ async def main() -> None:
92
92
  asyncio.run(main())
93
93
  ```
94
94
 
95
- ## Work with the Feed Cache
95
+ ## Work with the Local Database
96
96
 
97
- Initialize the default feed cache:
97
+ Initialize the default database:
98
98
 
99
99
  ```python
100
- from nber_cli import init_feed_database
100
+ from nber_cli import init_database
101
101
 
102
- db_path = init_feed_database()
102
+ db_path = init_database()
103
103
  print(db_path)
104
104
  ```
105
105
 
@@ -123,14 +123,14 @@ from nber_cli import fetch_feed
123
123
  result = fetch_feed(display_all=True, max_items=5)
124
124
  ```
125
125
 
126
- Move the feed cache database:
126
+ Move the database:
127
127
 
128
128
  ```python
129
129
  from pathlib import Path
130
130
 
131
- from nber_cli import migrate_feed_database
131
+ from nber_cli import migrate_database
132
132
 
133
- old_path, new_path = migrate_feed_database(Path("~/data/nber-feed.db"))
133
+ old_path, new_path = migrate_database(Path("~/data/nber.db"))
134
134
  ```
135
135
 
136
136
  Clean cached feed database records:
@@ -147,6 +147,84 @@ print(result.deleted_count)
147
147
 
148
148
  `clean_feed_cache` deletes local cache records only. If deleted records still appear in the RSS feed, a later `fetch_feed` call may return them as new items again.
149
149
 
150
+ Read or write the paper metadata cache directly:
151
+
152
+ ```python
153
+ from nber_cli import read_info_cache, write_info_cache
154
+ from nber_cli import get_nber
155
+ import asyncio
156
+
157
+ paper = read_info_cache(None, "w25000")
158
+ if paper is None:
159
+ paper = asyncio.run(get_nber(25000))
160
+ write_info_cache(None, paper)
161
+ print(paper.title)
162
+ ```
163
+
164
+ Read the paper metadata cache through the high-level helper, which respects the user-config TTL and the global cache toggle:
165
+
166
+ ```python
167
+ import asyncio
168
+
169
+ from nber_cli import get_paper_with_info_cache_result
170
+
171
+
172
+ async def main() -> None:
173
+ result = await get_paper_with_info_cache_result(25000)
174
+ if result.from_cache:
175
+ print("Served from local info cache")
176
+ print(result.paper.title)
177
+
178
+
179
+ asyncio.run(main())
180
+ ```
181
+
182
+ `refresh=True` skips the cache lookup and re-fetches from NBER before optionally writing back:
183
+
184
+ ```python
185
+ import asyncio
186
+
187
+ from nber_cli import get_paper_with_info_cache_result
188
+
189
+
190
+ async def main() -> None:
191
+ result = await get_paper_with_info_cache_result(25000, refresh=True)
192
+ print(result.paper.title)
193
+
194
+
195
+ asyncio.run(main())
196
+ ```
197
+
198
+ Manage the user config (`~/.nber-cli/config.json`):
199
+
200
+ ```python
201
+ from nber_cli import (
202
+ get_info_cache_settings,
203
+ set_info_cache_enabled,
204
+ set_info_cache_ttl_days,
205
+ )
206
+
207
+ print(get_info_cache_settings())
208
+ set_info_cache_enabled(False)
209
+ set_info_cache_ttl_days(7)
210
+ ```
211
+
212
+ Clean cached paper metadata:
213
+
214
+ ```python
215
+ from nber_cli import clear_info_cache, count_info_cache
216
+
217
+ print(f"Cached rows: {count_info_cache()}")
218
+
219
+ preview = clear_info_cache(days=30, dry_run=True)
220
+ print(f"Matched: {preview.matched_count}")
221
+
222
+ result = clear_info_cache(days=30)
223
+ print(f"Deleted: {result.deleted_count}")
224
+ ```
225
+
226
+ The same `clear_info_cache` function also supports `delete_all=True` and `start_date` / `end_date` filters that mirror `clean_feed_cache`.
227
+
150
228
  ## Data Models
151
229
 
152
230
  ### NBER
@@ -212,6 +290,33 @@ print(result.deleted_count)
212
290
  | `end_date` | `str` or `None` | Inclusive end date for `date-range` mode. |
213
291
  | `dry_run` | `bool` | Whether the operation only counted matching records. |
214
292
 
293
+ ### NBERInfoCacheClearResult
294
+
295
+ | Field | Type | Description |
296
+ | --- | --- | --- |
297
+ | `database_path` | `Path` | SQLite cache database path. |
298
+ | `matched_count` | `int` | Number of cache records matching the clean criteria. |
299
+ | `deleted_count` | `int` | Number of cache records deleted. |
300
+ | `mode` | `str` | Clean mode: `days`, `all`, or `date-range`. |
301
+ | `days` | `int` or `None` | Day threshold for `days` mode. |
302
+ | `start_date` | `str` or `None` | Inclusive start date for `date-range` mode. |
303
+ | `end_date` | `str` or `None` | Inclusive end date for `date-range` mode. |
304
+ | `dry_run` | `bool` | Whether the operation only counted matching records. |
305
+
306
+ ### InfoCacheSettings
307
+
308
+ | Field | Type | Description |
309
+ | --- | --- | --- |
310
+ | `cache_enabled` | `bool` | Global toggle for the `info_cache` lookup. |
311
+ | `cache_ttl_days` | `int` | Cache refresh interval in days. |
312
+
313
+ ### InfoCacheLookupResult
314
+
315
+ | Field | Type | Description |
316
+ | --- | --- | --- |
317
+ | `paper` | `NBER` | The paper returned by the lookup. |
318
+ | `from_cache` | `bool` | `True` when the paper was served from the local `info_cache`. |
319
+
215
320
  ### DownloadFailure
216
321
 
217
322
  | Field | Type | Description |