hubspaces 0.1.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 (35) hide show
  1. hubspaces-0.1.0/.gitignore +9 -0
  2. hubspaces-0.1.0/LICENSE +21 -0
  3. hubspaces-0.1.0/PKG-INFO +229 -0
  4. hubspaces-0.1.0/README.md +202 -0
  5. hubspaces-0.1.0/hubspace/__init__.py +0 -0
  6. hubspaces-0.1.0/hubspace/assets/favicon.svg +14 -0
  7. hubspaces-0.1.0/hubspace/assets/hub.css +299 -0
  8. hubspaces-0.1.0/hubspace/assets/hub.js +792 -0
  9. hubspaces-0.1.0/hubspace/config.py +138 -0
  10. hubspaces-0.1.0/hubspace/db.py +446 -0
  11. hubspaces-0.1.0/hubspace/example/acme-api/CLAUDE.md +3 -0
  12. hubspaces-0.1.0/hubspace/example/acme-api/README.md +3 -0
  13. hubspaces-0.1.0/hubspace/example/acme-api/app/skills/rate_limiting/SKILL.md +3 -0
  14. hubspaces-0.1.0/hubspace/example/acme-api/app/skills/rate_limiting/references/algorithms.md +6 -0
  15. hubspaces-0.1.0/hubspace/example/acme-api/app/skills/rate_limiting/references/redis-keys.md +4 -0
  16. hubspaces-0.1.0/hubspace/example/acme-api/tasks/add-oauth-login/data/latency-metrics.xlsx +0 -0
  17. hubspaces-0.1.0/hubspace/example/acme-api/tasks/add-oauth-login/data/users-sample.csv +5 -0
  18. hubspaces-0.1.0/hubspace/example/acme-api/tasks/add-oauth-login/manifest.md +36 -0
  19. hubspaces-0.1.0/hubspace/example/acme-api/tasks/migrate-to-postgres/manifest.md +15 -0
  20. hubspaces-0.1.0/hubspace/example/acme-api/tasks/rate-limiter/manifest.md +12 -0
  21. hubspaces-0.1.0/hubspace/example/web-dashboard/CLAUDE.md +3 -0
  22. hubspaces-0.1.0/hubspace/example/web-dashboard/app/skills/auth/SKILL.md +3 -0
  23. hubspaces-0.1.0/hubspace/example/web-dashboard/app/skills/auth/references/token-lifecycle.md +3 -0
  24. hubspaces-0.1.0/hubspace/example/web-dashboard/tasks/charts-revamp/data/sales.csv +5 -0
  25. hubspaces-0.1.0/hubspace/example/web-dashboard/tasks/charts-revamp/manifest.md +12 -0
  26. hubspaces-0.1.0/hubspace/example/web-dashboard/tasks/dark-mode/manifest.md +18 -0
  27. hubspaces-0.1.0/hubspace/example/web-dashboard/tasks/onboarding-flow/manifest.md +11 -0
  28. hubspaces-0.1.0/hubspace/hub.py +505 -0
  29. hubspaces-0.1.0/hubspace/metadata.py +158 -0
  30. hubspaces-0.1.0/hubspace/migrations/001_initial_schema.sql +63 -0
  31. hubspaces-0.1.0/hubspace/migrations/002_skill_columns.sql +2 -0
  32. hubspaces-0.1.0/hubspace/server.py +1101 -0
  33. hubspaces-0.1.0/hubspace/templates/template.html +150 -0
  34. hubspaces-0.1.0/plugin/hub-agent/README.md +20 -0
  35. hubspaces-0.1.0/pyproject.toml +54 -0
@@ -0,0 +1,9 @@
1
+ build/
2
+ __pycache__/
3
+ *.pyc
4
+ .scan_root
5
+ .hub.log
6
+ .venv/
7
+ *.DS_Store
8
+
9
+ /tasks/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Atharva
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: hubspaces
3
+ Version: 0.1.0
4
+ Summary: Local markdown/HTML browser with split-pane preview, full-text search, and a task board — stdlib-only.
5
+ Project-URL: Homepage, https://github.com/auth-02/hub
6
+ Project-URL: Repository, https://github.com/auth-02/hub
7
+ Author: Atharva
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: browser,documentation,full-text-search,markdown,notes,static-site
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Documentation
23
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
24
+ Classifier: Topic :: Utilities
25
+ Requires-Python: >=3.11
26
+ Description-Content-Type: text/markdown
27
+
28
+ ![Hub — Every .md & .html, one page](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/banner.png)
29
+
30
+ <div align="center">
31
+
32
+ # Hub
33
+
34
+ **Point it at a folder. Get every `.md` and `.html` inside as one searchable, previewable page.**
35
+
36
+ [![PyPI](https://img.shields.io/pypi/v/hubspaces)](https://pypi.org/project/hubspaces/)
37
+ [![Python](https://img.shields.io/pypi/pyversions/hubspaces)](https://pypi.org/project/hubspaces/)
38
+ [![tests](https://github.com/auth-02/hub/actions/workflows/tests.yml/badge.svg)](https://github.com/auth-02/hub/actions/workflows/tests.yml)
39
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
40
+
41
+ **[📖 Docs & live demo →](https://auth-02.github.io/hub/)**
42
+
43
+ </div>
44
+
45
+ Hub scans a directory tree, indexes every document into SQLite with full-text search and task lineage, and serves a fast local browser at `http://localhost:8787`. No npm. No framework. No runtime dependencies — pure stdlib Python (3.11+).
46
+
47
+ ---
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ pipx install hubspaces # isolated, recommended
53
+ # or
54
+ pip install hubspaces
55
+ ```
56
+
57
+ From a clone (no publish needed):
58
+
59
+ ```bash
60
+ git clone https://github.com/auth-02/hub && cd hub
61
+ pipx install .
62
+ ```
63
+
64
+ This puts two commands on your `PATH`: **`hub`** (build the index) and **`hub-server`** (serve it + watch for changes).
65
+
66
+ ## Run
67
+
68
+ ```bash
69
+ cd ~/my-project # any folder you want to browse
70
+ hub-server # serves http://localhost:8787 and rebuilds on change
71
+ ```
72
+
73
+ Then open <http://localhost:8787>. That's it — Hub indexes the current directory by default.
74
+
75
+ Want to see it before pointing it at your own files? `hub --demo` builds the index from a bundled example repo, then `hub-server --demo` serves it.
76
+
77
+ ```bash
78
+ hub-server --demo
79
+ ```
80
+
81
+ ---
82
+
83
+ ### Index — grouped by repo, filtered by kind, sorted by recency
84
+ Status badges on every task manifest. Click to cycle `ongoing → completed → paused`, saved instantly.
85
+
86
+ ![Hub index](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/index.png)
87
+
88
+ ### Split-pane preview with task trace
89
+ Click any row to open a live preview. The `// trace` panel links to related runs, artifacts, and the parent task.
90
+
91
+ ![Split-pane preview](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/preview.png)
92
+
93
+ ### Hub Feed — floating activity drawer
94
+ Press `Ctrl+F` or click the `// feed` tab on the right edge. Shows the last 50 file events across the scan root — what changed, which task, when.
95
+
96
+ ![Hub feed drawer](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/feed-drawer.png)
97
+
98
+ ### Hub Timeline — daily work summary
99
+ Press `Ctrl+T` or click the `// timeline` tab. Answers *What have I been working on? / yesterday? / this week?* — grouped by task, with git commits, runs logged, artifacts generated, and task status inline.
100
+
101
+ ![Hub timeline drawer](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/timeline.png)
102
+
103
+ ### Markdown & HTML document pages
104
+ Every file opened in its own tab gets a clean reading view with a `// trace` bar below the heading. HTML artifacts are served with the hub's own CSS injected.
105
+
106
+ ![Markdown document page](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/doc.png)
107
+
108
+ ---
109
+
110
+ ## Features
111
+
112
+ - **Full-text search** — filter by repo, path, title, and body simultaneously. Implicit AND, `repo:name` prefix supported.
113
+ - **Kind chips** — one-click filters for TASK, RUN, ARTIFACT, CLAUDE, README, DOC, PROMPT. Stack with repo chips and search.
114
+ - **Task status badges** — every task manifest shows a clickable status pill. Cycles `ongoing → completed → paused`. Persisted — survives DB resets, scan-root changes, and git branch switches.
115
+ - **Split-pane preview** — click any row for a live rendered preview with lineage trace. No page navigation needed.
116
+ - **Hub Feed** — floating drawer (`Ctrl+F`) showing recent file activity: what changed, which task, how long ago.
117
+ - **Hub Timeline** — drawer (`Ctrl+T`) with a synthesised daily summary grouped by *today / yesterday / this week*, pulling from the activity log + `git log` across all repos.
118
+ - **Auto-rebuild** — file watcher triggers a rebuild within ~3 s of any change in the scan root.
119
+ - **Keyboard-first** — navigate the full list without a mouse.
120
+
121
+ ---
122
+
123
+ ## Configuration
124
+
125
+ Everything is optional. Drop a `hub.toml` in the folder you run Hub from (or run `hub init` to scaffold one):
126
+
127
+ ```toml
128
+ [hub]
129
+ scan_root = "." # directory to index (default: CWD)
130
+ port = 8787 # local server port
131
+ exclude_dirs = ["vendor", "fixtures"] # extra dirs to skip (added to built-ins)
132
+ default_view = "board" # work | list | board | calendar | activity
133
+ ```
134
+
135
+ Environment variables override the file:
136
+
137
+ | Var | Default | Purpose |
138
+ |-----|---------|---------|
139
+ | `HUB_SCAN_ROOT` | *(current directory)* | Directory to scan |
140
+ | `HUB_SERVER_PORT` | `8787` | Server port |
141
+ | `HUB_OUTPUT` | `~/.local/state/hub/build/docs-index.html` | Generated HTML path |
142
+ | `HUB_DB` | `~/.local/state/hub/hub.db` | SQLite database |
143
+ | `HUB_DEBUG` | off | `1` enables logging to `~/.local/state/hub/hub.log` |
144
+
145
+ Scan-root priority: `--root` flag → `HUB_SCAN_ROOT` → `hub.toml` → `.scan_root` sidecar → current directory.
146
+ You can also change it live: click the scan-root path in the header → edit → **Save & Rebuild**.
147
+
148
+ ---
149
+
150
+ ## Task structure
151
+
152
+ Hub understands this layout and builds a lineage graph automatically:
153
+
154
+ ```
155
+ {repo}/tasks/{slug}/
156
+ ├── manifest.md ← TASK (links to all below)
157
+ ├── runs/YYYY-MM-DD/ ← RUN (↑ back-link to manifest)
158
+ ├── artifacts/ ← ARTIFACT
159
+ └── prompts/ ← PROMPT
160
+ ```
161
+
162
+ `hub new task <slug>` scaffolds a valid task for you.
163
+
164
+ ---
165
+
166
+ ## Agent plugin (optional)
167
+
168
+ Hub is the **viewer**. If you drive work with Claude Code, the companion
169
+ `hub-agent` plugin is the **producer** — it bundles the `manifest` skill, which
170
+ creates and maintains the `tasks/<slug>/manifest.md` structure above as you
171
+ work, so the board, trace, and timeline fill themselves in.
172
+
173
+ ```
174
+ /plugin marketplace add auth-02/hub
175
+ /plugin install hub-agent@hub
176
+ ```
177
+
178
+ Fully opt-in — Hub needs no plugin and no agent to deliver the full
179
+ index/search/preview/trace experience.
180
+
181
+ ---
182
+
183
+ ## Search
184
+
185
+ | Query | Finds |
186
+ |-------|-------|
187
+ | `session tokens` | files whose title or body contains both words |
188
+ | `repo:tasks manifest` | manifests in the tasks repo |
189
+ | `repo:docs architecture` | docs matching "architecture" |
190
+
191
+ ## Keyboard shortcuts
192
+
193
+ | Key | Action | | Key | Action |
194
+ |-----|--------|-|-----|--------|
195
+ | `/` | Focus search | | `Enter` | Open in new tab |
196
+ | `Ctrl+F` | Toggle feed drawer | | `j` / `↓` | Next file |
197
+ | `Ctrl+T` | Toggle timeline drawer | | `k` / `↑` | Previous file |
198
+ | `Esc` | Close preview / drawer | | | |
199
+
200
+ ---
201
+
202
+ ## Keep it running (macOS)
203
+
204
+ Two launchd agents start Hub at login — the server (+ watcher) and a periodic rebuild:
205
+
206
+ ```bash
207
+ bash scripts/setup-launchd.sh
208
+ # custom scan root:
209
+ HUB_SCAN_ROOT=~/work bash scripts/setup-launchd.sh
210
+ ```
211
+
212
+ Reload after upgrading:
213
+ ```bash
214
+ launchctl kickstart -k gui/$(id -u)/com.user.hub-server
215
+ launchctl kickstart -k gui/$(id -u)/com.user.hub
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Development
221
+
222
+ ```bash
223
+ git clone https://github.com/auth-02/hub && cd hub
224
+ python3 -m hubspace.server # run from source, no install
225
+ python3 tests/run_tests.py # 246 tests, stdlib unittest
226
+ ```
227
+
228
+ Layout: code is the `hubspace/` package; all generated/writable state (index, DB, log)
229
+ lives under `~/.local/state/hub/`, never the package directory.
@@ -0,0 +1,202 @@
1
+ ![Hub — Every .md & .html, one page](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/banner.png)
2
+
3
+ <div align="center">
4
+
5
+ # Hub
6
+
7
+ **Point it at a folder. Get every `.md` and `.html` inside as one searchable, previewable page.**
8
+
9
+ [![PyPI](https://img.shields.io/pypi/v/hubspaces)](https://pypi.org/project/hubspaces/)
10
+ [![Python](https://img.shields.io/pypi/pyversions/hubspaces)](https://pypi.org/project/hubspaces/)
11
+ [![tests](https://github.com/auth-02/hub/actions/workflows/tests.yml/badge.svg)](https://github.com/auth-02/hub/actions/workflows/tests.yml)
12
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
13
+
14
+ **[📖 Docs & live demo →](https://auth-02.github.io/hub/)**
15
+
16
+ </div>
17
+
18
+ Hub scans a directory tree, indexes every document into SQLite with full-text search and task lineage, and serves a fast local browser at `http://localhost:8787`. No npm. No framework. No runtime dependencies — pure stdlib Python (3.11+).
19
+
20
+ ---
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pipx install hubspaces # isolated, recommended
26
+ # or
27
+ pip install hubspaces
28
+ ```
29
+
30
+ From a clone (no publish needed):
31
+
32
+ ```bash
33
+ git clone https://github.com/auth-02/hub && cd hub
34
+ pipx install .
35
+ ```
36
+
37
+ This puts two commands on your `PATH`: **`hub`** (build the index) and **`hub-server`** (serve it + watch for changes).
38
+
39
+ ## Run
40
+
41
+ ```bash
42
+ cd ~/my-project # any folder you want to browse
43
+ hub-server # serves http://localhost:8787 and rebuilds on change
44
+ ```
45
+
46
+ Then open <http://localhost:8787>. That's it — Hub indexes the current directory by default.
47
+
48
+ Want to see it before pointing it at your own files? `hub --demo` builds the index from a bundled example repo, then `hub-server --demo` serves it.
49
+
50
+ ```bash
51
+ hub-server --demo
52
+ ```
53
+
54
+ ---
55
+
56
+ ### Index — grouped by repo, filtered by kind, sorted by recency
57
+ Status badges on every task manifest. Click to cycle `ongoing → completed → paused`, saved instantly.
58
+
59
+ ![Hub index](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/index.png)
60
+
61
+ ### Split-pane preview with task trace
62
+ Click any row to open a live preview. The `// trace` panel links to related runs, artifacts, and the parent task.
63
+
64
+ ![Split-pane preview](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/preview.png)
65
+
66
+ ### Hub Feed — floating activity drawer
67
+ Press `Ctrl+F` or click the `// feed` tab on the right edge. Shows the last 50 file events across the scan root — what changed, which task, when.
68
+
69
+ ![Hub feed drawer](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/feed-drawer.png)
70
+
71
+ ### Hub Timeline — daily work summary
72
+ Press `Ctrl+T` or click the `// timeline` tab. Answers *What have I been working on? / yesterday? / this week?* — grouped by task, with git commits, runs logged, artifacts generated, and task status inline.
73
+
74
+ ![Hub timeline drawer](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/timeline.png)
75
+
76
+ ### Markdown & HTML document pages
77
+ Every file opened in its own tab gets a clean reading view with a `// trace` bar below the heading. HTML artifacts are served with the hub's own CSS injected.
78
+
79
+ ![Markdown document page](https://raw.githubusercontent.com/auth-02/hub/main/hubspace/assets/screenshots/doc.png)
80
+
81
+ ---
82
+
83
+ ## Features
84
+
85
+ - **Full-text search** — filter by repo, path, title, and body simultaneously. Implicit AND, `repo:name` prefix supported.
86
+ - **Kind chips** — one-click filters for TASK, RUN, ARTIFACT, CLAUDE, README, DOC, PROMPT. Stack with repo chips and search.
87
+ - **Task status badges** — every task manifest shows a clickable status pill. Cycles `ongoing → completed → paused`. Persisted — survives DB resets, scan-root changes, and git branch switches.
88
+ - **Split-pane preview** — click any row for a live rendered preview with lineage trace. No page navigation needed.
89
+ - **Hub Feed** — floating drawer (`Ctrl+F`) showing recent file activity: what changed, which task, how long ago.
90
+ - **Hub Timeline** — drawer (`Ctrl+T`) with a synthesised daily summary grouped by *today / yesterday / this week*, pulling from the activity log + `git log` across all repos.
91
+ - **Auto-rebuild** — file watcher triggers a rebuild within ~3 s of any change in the scan root.
92
+ - **Keyboard-first** — navigate the full list without a mouse.
93
+
94
+ ---
95
+
96
+ ## Configuration
97
+
98
+ Everything is optional. Drop a `hub.toml` in the folder you run Hub from (or run `hub init` to scaffold one):
99
+
100
+ ```toml
101
+ [hub]
102
+ scan_root = "." # directory to index (default: CWD)
103
+ port = 8787 # local server port
104
+ exclude_dirs = ["vendor", "fixtures"] # extra dirs to skip (added to built-ins)
105
+ default_view = "board" # work | list | board | calendar | activity
106
+ ```
107
+
108
+ Environment variables override the file:
109
+
110
+ | Var | Default | Purpose |
111
+ |-----|---------|---------|
112
+ | `HUB_SCAN_ROOT` | *(current directory)* | Directory to scan |
113
+ | `HUB_SERVER_PORT` | `8787` | Server port |
114
+ | `HUB_OUTPUT` | `~/.local/state/hub/build/docs-index.html` | Generated HTML path |
115
+ | `HUB_DB` | `~/.local/state/hub/hub.db` | SQLite database |
116
+ | `HUB_DEBUG` | off | `1` enables logging to `~/.local/state/hub/hub.log` |
117
+
118
+ Scan-root priority: `--root` flag → `HUB_SCAN_ROOT` → `hub.toml` → `.scan_root` sidecar → current directory.
119
+ You can also change it live: click the scan-root path in the header → edit → **Save & Rebuild**.
120
+
121
+ ---
122
+
123
+ ## Task structure
124
+
125
+ Hub understands this layout and builds a lineage graph automatically:
126
+
127
+ ```
128
+ {repo}/tasks/{slug}/
129
+ ├── manifest.md ← TASK (links to all below)
130
+ ├── runs/YYYY-MM-DD/ ← RUN (↑ back-link to manifest)
131
+ ├── artifacts/ ← ARTIFACT
132
+ └── prompts/ ← PROMPT
133
+ ```
134
+
135
+ `hub new task <slug>` scaffolds a valid task for you.
136
+
137
+ ---
138
+
139
+ ## Agent plugin (optional)
140
+
141
+ Hub is the **viewer**. If you drive work with Claude Code, the companion
142
+ `hub-agent` plugin is the **producer** — it bundles the `manifest` skill, which
143
+ creates and maintains the `tasks/<slug>/manifest.md` structure above as you
144
+ work, so the board, trace, and timeline fill themselves in.
145
+
146
+ ```
147
+ /plugin marketplace add auth-02/hub
148
+ /plugin install hub-agent@hub
149
+ ```
150
+
151
+ Fully opt-in — Hub needs no plugin and no agent to deliver the full
152
+ index/search/preview/trace experience.
153
+
154
+ ---
155
+
156
+ ## Search
157
+
158
+ | Query | Finds |
159
+ |-------|-------|
160
+ | `session tokens` | files whose title or body contains both words |
161
+ | `repo:tasks manifest` | manifests in the tasks repo |
162
+ | `repo:docs architecture` | docs matching "architecture" |
163
+
164
+ ## Keyboard shortcuts
165
+
166
+ | Key | Action | | Key | Action |
167
+ |-----|--------|-|-----|--------|
168
+ | `/` | Focus search | | `Enter` | Open in new tab |
169
+ | `Ctrl+F` | Toggle feed drawer | | `j` / `↓` | Next file |
170
+ | `Ctrl+T` | Toggle timeline drawer | | `k` / `↑` | Previous file |
171
+ | `Esc` | Close preview / drawer | | | |
172
+
173
+ ---
174
+
175
+ ## Keep it running (macOS)
176
+
177
+ Two launchd agents start Hub at login — the server (+ watcher) and a periodic rebuild:
178
+
179
+ ```bash
180
+ bash scripts/setup-launchd.sh
181
+ # custom scan root:
182
+ HUB_SCAN_ROOT=~/work bash scripts/setup-launchd.sh
183
+ ```
184
+
185
+ Reload after upgrading:
186
+ ```bash
187
+ launchctl kickstart -k gui/$(id -u)/com.user.hub-server
188
+ launchctl kickstart -k gui/$(id -u)/com.user.hub
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Development
194
+
195
+ ```bash
196
+ git clone https://github.com/auth-02/hub && cd hub
197
+ python3 -m hubspace.server # run from source, no install
198
+ python3 tests/run_tests.py # 246 tests, stdlib unittest
199
+ ```
200
+
201
+ Layout: code is the `hubspace/` package; all generated/writable state (index, DB, log)
202
+ lives under `~/.local/state/hub/`, never the package directory.
File without changes
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
+ <rect width="32" height="32" fill="#F4EFE4"/>
3
+ <g stroke="#7A2828" stroke-width="1.5">
4
+ <line x1="16" y1="16" x2="16" y2="6"/>
5
+ <line x1="16" y1="16" x2="25" y2="22"/>
6
+ <line x1="16" y1="16" x2="7" y2="22"/>
7
+ </g>
8
+ <g fill="#7A2828">
9
+ <circle cx="16" cy="6" r="2.6"/>
10
+ <circle cx="25" cy="22" r="2.6"/>
11
+ <circle cx="7" cy="22" r="2.6"/>
12
+ <circle cx="16" cy="16" r="4.2"/>
13
+ </g>
14
+ </svg>