secondbrain-py 0.2.1__py3-none-any.whl
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.
- brain/__init__.py +0 -0
- brain/__main__.py +18 -0
- brain/_capture_command.py +445 -0
- brain/_compose.py +52 -0
- brain/activity.py +206 -0
- brain/ask.py +631 -0
- brain/audio.py +591 -0
- brain/backfill/__init__.py +12 -0
- brain/backfill/search_extras.py +141 -0
- brain/backfill/source_rows.py +101 -0
- brain/bin/__init__.py +1 -0
- brain/bin/_launcher.py +107 -0
- brain/bin/down.py +8 -0
- brain/bin/launchd.py +268 -0
- brain/bin/monitor.py +570 -0
- brain/bin/rebuild.py +8 -0
- brain/bin/status.py +8 -0
- brain/bin/up.py +8 -0
- brain/brief.py +272 -0
- brain/capture.py +49 -0
- brain/chat.py +293 -0
- brain/cli.py +9760 -0
- brain/cli_claude.py +81 -0
- brain/cli_connect.py +285 -0
- brain/cli_demo.py +266 -0
- brain/config.py +1949 -0
- brain/connect.py +925 -0
- brain/db.py +540 -0
- brain/demo/__init__.py +452 -0
- brain/demo/corpus/manifest.json +403 -0
- brain/demo/embedder.py +74 -0
- brain/durations.py +84 -0
- brain/edit_session.py +156 -0
- brain/editor.py +67 -0
- brain/elicit/__init__.py +16 -0
- brain/elicit/detectors.py +250 -0
- brain/elicit/drafter.py +70 -0
- brain/elicit/queue.py +220 -0
- brain/elicit/schema.py +48 -0
- brain/elicit/session.py +445 -0
- brain/embedding_targets.py +54 -0
- brain/embeddings.py +424 -0
- brain/enrichment.py +808 -0
- brain/errors.py +357 -0
- brain/eval/__init__.py +129 -0
- brain/eval/answer_eval.py +281 -0
- brain/eval/baseline.py +265 -0
- brain/eval/concept_extraction.py +378 -0
- brain/eval/corpus.py +152 -0
- brain/eval/errors.py +19 -0
- brain/eval/graph_baseline.py +226 -0
- brain/eval/graph_retrieval.py +202 -0
- brain/eval/graph_runner.py +319 -0
- brain/eval/metrics.py +101 -0
- brain/eval/runner.py +223 -0
- brain/format.py +783 -0
- brain/gaps.py +390 -0
- brain/graph_rag/__init__.py +94 -0
- brain/graph_rag/_retrieval_common.py +113 -0
- brain/graph_rag/aggregates.py +303 -0
- brain/graph_rag/aliases/__init__.py +583 -0
- brain/graph_rag/backends/__init__.py +10 -0
- brain/graph_rag/backends/_age_helpers.py +473 -0
- brain/graph_rag/backends/age.py +782 -0
- brain/graph_rag/backends/base.py +272 -0
- brain/graph_rag/build.py +344 -0
- brain/graph_rag/communities.py +644 -0
- brain/graph_rag/communities_summary.py +437 -0
- brain/graph_rag/concepts.py +202 -0
- brain/graph_rag/cooccur.py +193 -0
- brain/graph_rag/cross_type.py +312 -0
- brain/graph_rag/extract.py +885 -0
- brain/graph_rag/fuse.py +371 -0
- brain/graph_rag/global_.py +412 -0
- brain/graph_rag/grouping.py +372 -0
- brain/graph_rag/person_resolver.py +167 -0
- brain/graph_rag/reconcile.py +792 -0
- brain/graph_rag/relational.py +353 -0
- brain/graph_rag/retrieve.py +526 -0
- brain/graph_rag/router.py +288 -0
- brain/graph_rag/schema.py +320 -0
- brain/graph_rag/sync.py +237 -0
- brain/graph_rag/tenancy.py +43 -0
- brain/graph_rag/themes.py +501 -0
- brain/graph_rag/weighting.py +202 -0
- brain/ingest/__init__.py +1926 -0
- brain/ingest/chunker.py +249 -0
- brain/ingest/docx.py +40 -0
- brain/ingest/gmail.py +621 -0
- brain/ingest/markdown.py +37 -0
- brain/ingest/pdf.py +61 -0
- brain/ingest/stdin.py +22 -0
- brain/ingest/sub_tokens.py +91 -0
- brain/ingest/text.py +16 -0
- brain/interactions.py +205 -0
- brain/maintenance.py +355 -0
- brain/mcp_server.py +3405 -0
- brain/migrations/001_init.sql +43 -0
- brain/migrations/002_qwen3_embedding.sql +17 -0
- brain/migrations/003_vault_model.sql +41 -0
- brain/migrations/004_relax_content_hash_uniqueness.sql +18 -0
- brain/migrations/005_derived_links.sql +67 -0
- brain/migrations/006_dedup_file_by_source_path.sql +25 -0
- brain/migrations/007_email_thread_and_draft.sql +15 -0
- brain/migrations/008_gmail_thread_unique.sql +11 -0
- brain/migrations/009_chunks_weighted_tsv.sql +28 -0
- brain/migrations/010_interactions.sql +30 -0
- brain/migrations/011_documents_summary.sql +23 -0
- brain/migrations/012_graphrag.sql +171 -0
- brain/migrations/013_graphrag_communities.sql +125 -0
- brain/migrations/014_graphrag_community_summary_hash.sql +33 -0
- brain/migrations/015_interactions_graph_targets.sql +89 -0
- brain/migrations/016_index_hygiene.sql +61 -0
- brain/migrations/017_elicit.sql +30 -0
- brain/migrations/018_review_gap_signal_kinds.sql +40 -0
- brain/migrations/019_search_queries.sql +35 -0
- brain/migrations/020_link_suggestions.sql +40 -0
- brain/migrations/021_timeline_doc_date.sql +34 -0
- brain/migrations/022_link_suggestions_undirected.sql +84 -0
- brain/migrations/023_search_queries_fts_count.sql +28 -0
- brain/quartz_overrides/__init__.py +8 -0
- brain/quartz_overrides/quartz/bootstrap-cli.mjs +65 -0
- brain/quartz_overrides/quartz/build.ts +568 -0
- brain/quartz_overrides/quartz/cli/args.js +152 -0
- brain/quartz_overrides/quartz/cli/build_partial_handler.js +544 -0
- brain/quartz_overrides/quartz/cli/handlers.js +636 -0
- brain/quartz_overrides/quartz/components/CommandPalette.tsx +172 -0
- brain/quartz_overrides/quartz/components/Explorer.tsx +198 -0
- brain/quartz_overrides/quartz/components/Footer.tsx +27 -0
- brain/quartz_overrides/quartz/components/Graph.tsx +468 -0
- brain/quartz_overrides/quartz/components/PageTitle.tsx +72 -0
- brain/quartz_overrides/quartz/components/RelatedDocs.tsx +38 -0
- brain/quartz_overrides/quartz/components/Search.tsx +161 -0
- brain/quartz_overrides/quartz/components/SummaryLede.tsx +72 -0
- brain/quartz_overrides/quartz/components/index.ts +92 -0
- brain/quartz_overrides/quartz/components/pages/TagContent.tsx +272 -0
- brain/quartz_overrides/quartz/components/scripts/commandPalette.inline.ts +665 -0
- brain/quartz_overrides/quartz/components/scripts/explorer.inline.ts +768 -0
- brain/quartz_overrides/quartz/components/scripts/graph.inline.ts +2302 -0
- brain/quartz_overrides/quartz/components/scripts/relatedDocs.inline.ts +163 -0
- brain/quartz_overrides/quartz/components/scripts/search.inline.ts +1011 -0
- brain/quartz_overrides/quartz/plugins/emitters/contentIndex.ts +546 -0
- brain/quartz_overrides/quartz/plugins/transformers/codeCopy.ts +94 -0
- brain/quartz_overrides/quartz/plugins/transformers/derivedFenceMark.ts +302 -0
- brain/quartz_overrides/quartz/plugins/transformers/emailThread.ts +148 -0
- brain/quartz_overrides/quartz/plugins/transformers/emptyDoorFilter.ts +213 -0
- brain/quartz_overrides/quartz/plugins/transformers/index.ts +114 -0
- brain/quartz_overrides/quartz/plugins/transformers/linkKindMark.ts +205 -0
- brain/quartz_overrides/quartz/plugins/transformers/linkSourceTag.ts +104 -0
- brain/quartz_overrides/quartz/plugins/transformers/relativeDate.ts +100 -0
- brain/quartz_overrides/quartz/plugins/transformers/reloadSignal.ts +131 -0
- brain/quartz_overrides/quartz/processors/parse.ts +371 -0
- brain/quartz_overrides/quartz/processors/parser_cache.ts +78 -0
- brain/quartz_overrides/quartz/static/brain-logo-dark.png +0 -0
- brain/quartz_overrides/quartz/static/brain-logo-light.png +0 -0
- brain/quartz_overrides/quartz/static/codeCopy.js +196 -0
- brain/quartz_overrides/quartz/static/emailThread.js +334 -0
- brain/quartz_overrides/quartz/static/favicon.ico +0 -0
- brain/quartz_overrides/quartz/static/icon.png +0 -0
- brain/quartz_overrides/quartz/static/linkSourceTag.js +104 -0
- brain/quartz_overrides/quartz/static/relativeDate.js +142 -0
- brain/quartz_overrides/quartz/static/reload.js +168 -0
- brain/quartz_overrides/quartz/styles/brain/_article.scss +252 -0
- brain/quartz_overrides/quartz/styles/brain/_atmosphere.scss +113 -0
- brain/quartz_overrides/quartz/styles/brain/_callouts.scss +180 -0
- brain/quartz_overrides/quartz/styles/brain/_cmdk.scss +7 -0
- brain/quartz_overrides/quartz/styles/brain/_code.scss +208 -0
- brain/quartz_overrides/quartz/styles/brain/_command_palette.scss +369 -0
- brain/quartz_overrides/quartz/styles/brain/_email_thread.scss +228 -0
- brain/quartz_overrides/quartz/styles/brain/_explorer.scss +142 -0
- brain/quartz_overrides/quartz/styles/brain/_home.scss +182 -0
- brain/quartz_overrides/quartz/styles/brain/_links.scss +322 -0
- brain/quartz_overrides/quartz/styles/brain/_marginalia.scss +117 -0
- brain/quartz_overrides/quartz/styles/brain/_motion.scss +175 -0
- brain/quartz_overrides/quartz/styles/brain/_people_hub.scss +100 -0
- brain/quartz_overrides/quartz/styles/brain/_related_docs.scss +137 -0
- brain/quartz_overrides/quartz/styles/brain/_search.scss +252 -0
- brain/quartz_overrides/quartz/styles/brain/_sidebar.scss +468 -0
- brain/quartz_overrides/quartz/styles/brain/_summary_lede.scss +56 -0
- brain/quartz_overrides/quartz/styles/brain/_surface.scss +43 -0
- brain/quartz_overrides/quartz/styles/brain/_tag_content.scss +118 -0
- brain/quartz_overrides/quartz/styles/brain/_tokens.scss +197 -0
- brain/quartz_overrides/quartz/styles/brain/_typography.scss +92 -0
- brain/quartz_overrides/quartz/styles/custom.scss +89 -0
- brain/quartz_overrides/quartz/styles/graph.scss +505 -0
- brain/quartz_overrides/quartz/util/ctx.ts +92 -0
- brain/quartz_overrides/quartz/util/fastpath_manifest.ts +608 -0
- brain/quartz_overrides/quartz/util/path.ts +358 -0
- brain/quartz_overrides/quartz/util/sourceIcons.ts +55 -0
- brain/quartz_overrides/quartz.config.ts +270 -0
- brain/quartz_overrides/quartz.layout.ts +314 -0
- brain/queries.py +1188 -0
- brain/rank_fusion.py +8 -0
- brain/resurface.py +210 -0
- brain/review/__init__.py +26 -0
- brain/review/emit.py +27 -0
- brain/review/queries.py +436 -0
- brain/review/render.py +196 -0
- brain/review/scans.py +355 -0
- brain/review/weekly.py +413 -0
- brain/search.py +704 -0
- brain/set_similarity.py +15 -0
- brain/setup.py +1205 -0
- brain/tags.py +56 -0
- brain/templates/Caddyfile.j2 +9 -0
- brain/templates/__init__.py +1 -0
- brain/templates/bin/__init__.py +1 -0
- brain/templates/bin/_brain-brief-fg.sh +25 -0
- brain/templates/bin/_brain-build-fg.sh +53 -0
- brain/templates/bin/_brain-watcher-fg.sh +65 -0
- brain/templates/bin/brain-down.sh +89 -0
- brain/templates/bin/brain-status.sh +83 -0
- brain/templates/bin/brain-up.sh +221 -0
- brain/templates/docker/age/Dockerfile +79 -0
- brain/templates/docker-compose.stock.yml.j2 +26 -0
- brain/templates/docker-compose.yml.j2 +34 -0
- brain/templates/env.example +190 -0
- brain/templates/launchd/__init__.py +1 -0
- brain/templates/launchd/com.brain.brief.plist.j2 +45 -0
- brain/templates/launchd/com.brain.build.plist.j2 +46 -0
- brain/templates/launchd/com.brain.watcher.plist.j2 +46 -0
- brain/templates/skill/SKILL.md +63 -0
- brain/templates/skill/__init__.py +1 -0
- brain/timeline.py +834 -0
- brain/todo.py +124 -0
- brain/uninstall.py +185 -0
- brain/vault/__init__.py +115 -0
- brain/vault/_atomic.py +25 -0
- brain/vault/daily_index.py +228 -0
- brain/vault/derived_links/__init__.py +50 -0
- brain/vault/derived_links/directory.py +683 -0
- brain/vault/derived_links/fence.py +408 -0
- brain/vault/derived_links/gws.py +64 -0
- brain/vault/derived_links/participants.py +143 -0
- brain/vault/derived_links/pass_runner.py +362 -0
- brain/vault/derived_links/rules.py +137 -0
- brain/vault/export.py +683 -0
- brain/vault/frontmatter.py +165 -0
- brain/vault/graph.py +620 -0
- brain/vault/graph_format.py +388 -0
- brain/vault/link_rewrite.py +235 -0
- brain/vault/links.py +260 -0
- brain/vault/note_builder.py +211 -0
- brain/vault/paths.py +55 -0
- brain/vault/quartz_overlay.py +236 -0
- brain/vault/rename.py +591 -0
- brain/vault/resolver.py +304 -0
- brain/vault/slug.py +127 -0
- brain/vault/sync.py +1513 -0
- brain/vault/sync_summaries.py +264 -0
- brain/vault/templates.py +145 -0
- brain/vault/watch.py +1052 -0
- brain/wiki/__init__.py +6 -0
- brain/wiki/_github_slugger.py +76 -0
- brain/wiki/_person_name.py +314 -0
- brain/wiki/build_homepage.py +541 -0
- brain/wiki/build_partial.py +273 -0
- brain/wiki/build_people.py +934 -0
- brain/wiki/build_related.py +758 -0
- brain/wiki/build_swap.py +585 -0
- brain/wiki/build_watcher.py +975 -0
- brain/wiki/edit_classifier.py +215 -0
- brain/wiki/errors.py +10 -0
- brain/wiki/fastpath_manifest.py +475 -0
- brain/wiki/fastpath_state.py +174 -0
- brain/wiki/install.py +296 -0
- brain/wiki/slug.py +111 -0
- secondbrain_py-0.2.1.dist-info/METADATA +195 -0
- secondbrain_py-0.2.1.dist-info/RECORD +273 -0
- secondbrain_py-0.2.1.dist-info/WHEEL +5 -0
- secondbrain_py-0.2.1.dist-info/entry_points.txt +11 -0
- secondbrain_py-0.2.1.dist-info/licenses/LICENSE +21 -0
- secondbrain_py-0.2.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
// Brain palette for the custom Quartz Graph component.
|
|
2
|
+
//
|
|
3
|
+
// This file is a TEMPLATE. It is installed at
|
|
4
|
+
// `<vault>/.quartz/quartz/styles/graph.scss` by `brain vault render
|
|
5
|
+
// --overlay`. It is brand-new — not a replacement for upstream's
|
|
6
|
+
// `quartz/components/styles/graph.scss`, which carries the
|
|
7
|
+
// component's box layout (sidebar sizing, modal positioning) and
|
|
8
|
+
// is untouched by this overlay. The brain palette below loads
|
|
9
|
+
// alongside it, imported as a sibling stylesheet by the custom
|
|
10
|
+
// `Graph.tsx` and concatenated onto the component's `css` property.
|
|
11
|
+
//
|
|
12
|
+
// Tested against Quartz v4.5.x (April 2026). The CSS variables
|
|
13
|
+
// defined here are referenced by name from
|
|
14
|
+
// `components/scripts/graph.inline.ts` (via the `cssVars`
|
|
15
|
+
// precompute list and the `cssVar()` helper) and by the
|
|
16
|
+
// `D3Config.tierColors` / `sourceColors` defaults in
|
|
17
|
+
// `components/Graph.tsx`. Renaming or removing a variable here
|
|
18
|
+
// requires the matching update in those two files; the renderer
|
|
19
|
+
// would otherwise resolve to an empty string and silently fall
|
|
20
|
+
// through to `--gray`.
|
|
21
|
+
|
|
22
|
+
// brain-extension: the `--brain-tier-*` and `--brain-source-*` tokens
|
|
23
|
+
// formerly declared here moved to
|
|
24
|
+
// `quartz/styles/brain/_tokens.scss` as part of the 2026-05-02
|
|
25
|
+
// redesign (Lane A) so the graph palette and the ingested-link
|
|
26
|
+
// styling (Lane B) share one source of truth.
|
|
27
|
+
//
|
|
28
|
+
// Note: the previous dark-mode block selected on `[data-theme="dark"]`,
|
|
29
|
+
// which Quartz never sets (the dark-mode toggle writes
|
|
30
|
+
// `<html saved-theme="dark">` — see `darkmode.inline.ts`). The new
|
|
31
|
+
// tokens file uses the correct selector so dark-mode source colors
|
|
32
|
+
// actually fire.
|
|
33
|
+
//
|
|
34
|
+
// Future graph-only tokens live alongside the palette in `_tokens.scss`.
|
|
35
|
+
|
|
36
|
+
// brain-extension: in-graph controls (search input + filter chip rows).
|
|
37
|
+
// Rendered as the first child of `.graph-container` / `.global-graph-container`
|
|
38
|
+
// so they sit above the PixiJS canvas. Sized to take minimal vertical space
|
|
39
|
+
// and to wrap if the sidebar is narrow.
|
|
40
|
+
.brain-graph-controls {
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
gap: 0.25rem;
|
|
44
|
+
margin-bottom: 0.4rem;
|
|
45
|
+
font-size: 0.75rem;
|
|
46
|
+
line-height: 1.2;
|
|
47
|
+
min-width: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.brain-graph-toolbar {
|
|
51
|
+
flex-direction: row;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: 0.45rem;
|
|
54
|
+
padding: 0.55rem 0.65rem;
|
|
55
|
+
margin-bottom: 0;
|
|
56
|
+
border-bottom: 1px solid var(--rule);
|
|
57
|
+
background: color-mix(in srgb, var(--surface-1) 94%, var(--dark) 6%);
|
|
58
|
+
position: relative;
|
|
59
|
+
z-index: 2;
|
|
60
|
+
|
|
61
|
+
.brain-graph-search {
|
|
62
|
+
max-width: 24rem;
|
|
63
|
+
min-width: 12rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.brain-graph-chip-row {
|
|
67
|
+
flex-wrap: nowrap;
|
|
68
|
+
overflow-x: auto;
|
|
69
|
+
scrollbar-width: thin;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.brain-graph-search {
|
|
74
|
+
width: 100%;
|
|
75
|
+
min-width: 0;
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
// brain (Linear-variant feedback): bumped padding so the input
|
|
78
|
+
// stands ~28px tall, visually balancing the 24×24 graph icon
|
|
79
|
+
// buttons absolutely-positioned to its right. Was 0.25rem 0.5rem
|
|
80
|
+
// — too short, read as a stubby strip next to the buttons.
|
|
81
|
+
padding: 0.45rem 0.7rem;
|
|
82
|
+
border: 1px solid var(--lightgray);
|
|
83
|
+
border-radius: 4px;
|
|
84
|
+
background: var(--light);
|
|
85
|
+
color: var(--dark);
|
|
86
|
+
font: inherit;
|
|
87
|
+
|
|
88
|
+
// brain: explicit focus indicator for keyboard users — a border-color
|
|
89
|
+
// change alone wasn't enough at high-contrast settings. Outline-offset
|
|
90
|
+
// keeps the ring outside the rounded border so the visual cue is
|
|
91
|
+
// unambiguous.
|
|
92
|
+
&:focus {
|
|
93
|
+
outline: 2px solid var(--secondary);
|
|
94
|
+
outline-offset: 1px;
|
|
95
|
+
border-color: var(--secondary);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.brain-graph-chip-row {
|
|
100
|
+
display: flex;
|
|
101
|
+
flex-wrap: wrap;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: 0.2rem;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.brain-graph-chip-label {
|
|
107
|
+
color: var(--darkgray);
|
|
108
|
+
margin-right: 0.15rem;
|
|
109
|
+
text-transform: capitalize;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Each chip is a button by element so it remains keyboard-focusable. The
|
|
113
|
+
// "active" class flips it to a filled state so the user reads which values
|
|
114
|
+
// are currently included in the filter at a glance.
|
|
115
|
+
.brain-graph-chip {
|
|
116
|
+
appearance: none;
|
|
117
|
+
border: 1px solid var(--lightgray);
|
|
118
|
+
background: transparent;
|
|
119
|
+
color: var(--darkgray);
|
|
120
|
+
border-radius: 999px;
|
|
121
|
+
padding: 0.1rem 0.55rem;
|
|
122
|
+
font: inherit;
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
transition:
|
|
125
|
+
background-color 0.12s ease,
|
|
126
|
+
color 0.12s ease,
|
|
127
|
+
border-color 0.12s ease;
|
|
128
|
+
|
|
129
|
+
&:hover {
|
|
130
|
+
border-color: var(--gray);
|
|
131
|
+
color: var(--dark);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// brain: explicit focus ring for keyboard navigation. `:focus-visible`
|
|
135
|
+
// (vs plain `:focus`) keeps the indicator from showing on mouse-click,
|
|
136
|
+
// which feels noisy on a chip group, while still surfacing it for
|
|
137
|
+
// tab-traversed users.
|
|
138
|
+
&:focus-visible {
|
|
139
|
+
outline: 2px solid var(--secondary);
|
|
140
|
+
outline-offset: 1px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&.active {
|
|
144
|
+
background: var(--secondary);
|
|
145
|
+
border-color: var(--secondary);
|
|
146
|
+
color: var(--light);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// The "all" chip gets a subtler accent so it doesn't compete with the
|
|
150
|
+
// value chips for attention — it's a reset affordance, not a filter
|
|
151
|
+
// value in its own right.
|
|
152
|
+
&.brain-graph-chip-all {
|
|
153
|
+
font-weight: 600;
|
|
154
|
+
text-transform: uppercase;
|
|
155
|
+
font-size: 0.65rem;
|
|
156
|
+
letter-spacing: 0.04em;
|
|
157
|
+
|
|
158
|
+
&.active {
|
|
159
|
+
background: var(--tertiary);
|
|
160
|
+
border-color: var(--tertiary);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// brain: stock Quartz renders the global-graph button as
|
|
166
|
+
// `<button class="global-graph-icon">` directly inside `.graph-outer`,
|
|
167
|
+
// but its own graph.scss only styles `.graph-icon` (no `global-` prefix
|
|
168
|
+
// and inside a `.graph-icons` wrapper that doesn't exist in the markup).
|
|
169
|
+
// Result on stock Quartz: the button sits unstyled in the top-left,
|
|
170
|
+
// hard to see and easy to miss. We position + size it explicitly so
|
|
171
|
+
// readers can actually find the "open global graph" affordance.
|
|
172
|
+
//
|
|
173
|
+
// brain-extension: `.brain-stock-graph-icon` is a sibling affordance that
|
|
174
|
+
// opens the SAME global-graph modal but with the renderer's brain extensions
|
|
175
|
+
// disabled (stock Quartz visuals). Same visual rules — only the absolute-
|
|
176
|
+
// position offset differs.
|
|
177
|
+
//
|
|
178
|
+
// Layout note (Linear-variant feedback): the buttons are absolutely
|
|
179
|
+
// positioned at the top-right corner. The `.brain-graph-controls`
|
|
180
|
+
// below reserves a `padding-right` equal to both buttons' combined
|
|
181
|
+
// horizontal footprint, so the search input shrinks to leave room
|
|
182
|
+
// rather than slipping under the buttons.
|
|
183
|
+
.graph > .graph-outer > .global-graph-icon,
|
|
184
|
+
.graph > .graph-outer > .brain-stock-graph-icon,
|
|
185
|
+
.graph > .graph-outer > .local-graph-fullscreen-icon,
|
|
186
|
+
.graph > .graph-outer > .brain-graph-workbench-icon {
|
|
187
|
+
position: absolute;
|
|
188
|
+
top: 0;
|
|
189
|
+
margin: 0.3rem;
|
|
190
|
+
cursor: pointer;
|
|
191
|
+
background: none;
|
|
192
|
+
border: none;
|
|
193
|
+
color: var(--dark);
|
|
194
|
+
opacity: 0.5;
|
|
195
|
+
width: 24px;
|
|
196
|
+
height: 24px;
|
|
197
|
+
padding: 0.2rem;
|
|
198
|
+
border-radius: 4px;
|
|
199
|
+
background-color: transparent;
|
|
200
|
+
transition: background-color 0.2s ease, opacity 0.2s ease;
|
|
201
|
+
display: inline-flex;
|
|
202
|
+
align-items: center;
|
|
203
|
+
justify-content: center;
|
|
204
|
+
z-index: 1;
|
|
205
|
+
|
|
206
|
+
svg {
|
|
207
|
+
width: 100%;
|
|
208
|
+
height: 100%;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
&:hover {
|
|
212
|
+
background-color: var(--lightgray);
|
|
213
|
+
opacity: 1;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
&:focus-visible {
|
|
217
|
+
outline: 2px solid var(--secondary);
|
|
218
|
+
outline-offset: 1px;
|
|
219
|
+
opacity: 1;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.graph > .graph-outer > .global-graph-icon {
|
|
224
|
+
right: 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// brain-extension: dot-grid affordance sits 28px to the left of the globe so
|
|
228
|
+
// the two icons read as a pair without visually colliding. Width-based offset
|
|
229
|
+
// (`right: 28px`) keeps them aligned to the same right edge regardless of the
|
|
230
|
+
// surrounding sidebar width.
|
|
231
|
+
.graph > .graph-outer > .brain-stock-graph-icon {
|
|
232
|
+
right: 28px;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.graph > .graph-outer > .brain-graph-workbench-icon {
|
|
236
|
+
right: 56px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// brain-extension: maximize affordance sits left of the diagnostic,
|
|
240
|
+
// dot-grid, and global buttons. Order reads left-to-right as: local
|
|
241
|
+
// fullscreen / diagnostic workbench / stock / global.
|
|
242
|
+
.graph > .graph-outer > .local-graph-fullscreen-icon {
|
|
243
|
+
right: 84px;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// brain: keep upstream's `.graph-outer { height: 250px; overflow: hidden; }`
|
|
247
|
+
// untouched. The compact `.brain-graph-controls` redesign above takes
|
|
248
|
+
// only ~30px of vertical space (vs the previous ~94px), so a 250px
|
|
249
|
+
// container leaves ~220px for the canvas — plenty of room for the
|
|
250
|
+
// cluster — without growing the panel and pushing Table of Contents +
|
|
251
|
+
// Backlinks past the viewport. The d3-zoom fit-to-bounds pass in
|
|
252
|
+
// graph.inline.ts auto-scales the cluster to whatever canvas height
|
|
253
|
+
// we end up with.
|
|
254
|
+
//
|
|
255
|
+
// Defense-in-depth: also let the right sidebar scroll internally if a
|
|
256
|
+
// future content addition (e.g. a long ToC on a deeply-headed page)
|
|
257
|
+
// pushes total content past the viewport. No-op when content fits;
|
|
258
|
+
// gracefully scrolls when it doesn't.
|
|
259
|
+
// brain (Linear variant): global/local graph modal — contrast +
|
|
260
|
+
// positioning override.
|
|
261
|
+
//
|
|
262
|
+
// Stock paints `.global-graph-container` with `var(--light)` +
|
|
263
|
+
// `var(--lightgray)` border, which makes the modal invisible in our
|
|
264
|
+
// charcoal dark mode (page bg = `#0a0a0a` = same as `--light`). We
|
|
265
|
+
// override to `--surface-1` so the panel has elevation, then layer in
|
|
266
|
+
// `--scrim` for the backdrop.
|
|
267
|
+
//
|
|
268
|
+
// brain (Linear-variant feedback round 3): stock's modal centering
|
|
269
|
+
// relies on `display: inline-block` on the outer wrapper plus
|
|
270
|
+
// `transform: translate(-50%, -50%)` on the container, which together
|
|
271
|
+
// have been rendering the modal as a narrow vertical strip on the
|
|
272
|
+
// right edge of the viewport instead of a centered 80vw × 80vh panel.
|
|
273
|
+
// Bypass the recipe entirely:
|
|
274
|
+
// 1. `display: block` on `.global-graph-outer.active` kills the
|
|
275
|
+
// `inline-block` (stock's `width: 100vw` declaration only takes
|
|
276
|
+
// effect reliably on a block-level element).
|
|
277
|
+
// 2. Replace the `transform: translate(-50%, -50%)` centering trick
|
|
278
|
+
// with explicit `left: 10vw; top: 10vh` offsets. No transforms
|
|
279
|
+
// means no chance of an accidental containing-block creation
|
|
280
|
+
// for the fixed-position container.
|
|
281
|
+
.graph > .global-graph-outer,
|
|
282
|
+
.graph > .local-graph-outer,
|
|
283
|
+
.graph > .brain-graph-workbench-outer {
|
|
284
|
+
background: var(--scrim);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.graph > .brain-graph-workbench-outer {
|
|
288
|
+
backdrop-filter: blur(4px);
|
|
289
|
+
display: none;
|
|
290
|
+
height: 100%;
|
|
291
|
+
left: 0;
|
|
292
|
+
overflow: hidden;
|
|
293
|
+
position: fixed;
|
|
294
|
+
top: 0;
|
|
295
|
+
width: 100vw;
|
|
296
|
+
z-index: 9999;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.graph > .global-graph-outer.active,
|
|
300
|
+
.graph > .local-graph-outer.active,
|
|
301
|
+
.graph > .brain-graph-workbench-outer.active {
|
|
302
|
+
display: block;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.graph > .global-graph-outer > .global-graph-container,
|
|
306
|
+
.graph > .local-graph-outer > .local-graph-container {
|
|
307
|
+
background-color: var(--surface-1);
|
|
308
|
+
border-color: var(--rule);
|
|
309
|
+
box-shadow: var(--shadow-md);
|
|
310
|
+
// Explicit positioning replaces stock's `top: 50%; left: 50%;
|
|
311
|
+
// transform: translate(-50%, -50%)` recipe.
|
|
312
|
+
left: 10vw;
|
|
313
|
+
top: 10vh;
|
|
314
|
+
transform: none;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.graph > .brain-graph-workbench-outer > .brain-graph-workbench-container {
|
|
318
|
+
background-color: var(--surface-1);
|
|
319
|
+
border: 1px solid var(--rule);
|
|
320
|
+
border-radius: 5px;
|
|
321
|
+
border-color: var(--rule);
|
|
322
|
+
box-sizing: border-box;
|
|
323
|
+
box-shadow: var(--shadow-md);
|
|
324
|
+
position: fixed;
|
|
325
|
+
left: 4vw;
|
|
326
|
+
top: 6vh;
|
|
327
|
+
width: 92vw;
|
|
328
|
+
height: 88vh;
|
|
329
|
+
transform: none;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.brain-graph-workbench-shell {
|
|
333
|
+
display: grid;
|
|
334
|
+
grid-template-areas:
|
|
335
|
+
"toolbar toolbar toolbar"
|
|
336
|
+
"rail graph inspector";
|
|
337
|
+
grid-template-columns: 9.5rem minmax(0, 1fr) 18rem;
|
|
338
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
339
|
+
height: 100%;
|
|
340
|
+
min-height: 0;
|
|
341
|
+
isolation: isolate;
|
|
342
|
+
overflow: hidden;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.brain-graph-workbench-shell > .brain-graph-toolbar {
|
|
346
|
+
grid-area: toolbar;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.brain-graph-mode-rail {
|
|
350
|
+
grid-area: rail;
|
|
351
|
+
border-right: 1px solid var(--rule);
|
|
352
|
+
background: var(--surface-1);
|
|
353
|
+
padding: 0.75rem;
|
|
354
|
+
display: flex;
|
|
355
|
+
flex-direction: column;
|
|
356
|
+
gap: 0.45rem;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.brain-graph-mode {
|
|
360
|
+
appearance: none;
|
|
361
|
+
border: 1px solid var(--lightgray);
|
|
362
|
+
background: transparent;
|
|
363
|
+
color: var(--dark);
|
|
364
|
+
border-radius: 6px;
|
|
365
|
+
padding: 0.55rem 0.6rem;
|
|
366
|
+
text-align: left;
|
|
367
|
+
cursor: pointer;
|
|
368
|
+
font: inherit;
|
|
369
|
+
|
|
370
|
+
small {
|
|
371
|
+
display: block;
|
|
372
|
+
color: var(--darkgray);
|
|
373
|
+
font-size: 0.68rem;
|
|
374
|
+
margin-top: 0.12rem;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
&.active {
|
|
378
|
+
border-color: var(--secondary);
|
|
379
|
+
background: color-mix(in srgb, var(--secondary) 14%, transparent);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.brain-graph-inspector {
|
|
384
|
+
grid-area: inspector;
|
|
385
|
+
align-self: stretch;
|
|
386
|
+
box-sizing: border-box;
|
|
387
|
+
border-left: 1px solid var(--rule);
|
|
388
|
+
background: #202124;
|
|
389
|
+
background-color: #202124;
|
|
390
|
+
color: var(--dark);
|
|
391
|
+
height: 100%;
|
|
392
|
+
justify-self: stretch;
|
|
393
|
+
min-height: 0;
|
|
394
|
+
min-width: 18rem;
|
|
395
|
+
padding: 0.9rem;
|
|
396
|
+
overflow: auto;
|
|
397
|
+
position: relative;
|
|
398
|
+
z-index: 3;
|
|
399
|
+
|
|
400
|
+
h3 {
|
|
401
|
+
margin: 0 0 0.25rem;
|
|
402
|
+
font-size: 1rem;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
h4 {
|
|
406
|
+
margin: 1rem 0 0.35rem;
|
|
407
|
+
color: var(--darkgray);
|
|
408
|
+
font-size: 0.72rem;
|
|
409
|
+
text-transform: uppercase;
|
|
410
|
+
letter-spacing: 0.04em;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
ul {
|
|
414
|
+
margin: 0;
|
|
415
|
+
padding-left: 1rem;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.brain-graph-inspector-meta {
|
|
420
|
+
color: var(--darkgray);
|
|
421
|
+
margin: 0 0 0.75rem;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.brain-graph-metrics {
|
|
425
|
+
display: grid;
|
|
426
|
+
grid-template-columns: 1fr 1fr;
|
|
427
|
+
gap: 0.45rem;
|
|
428
|
+
|
|
429
|
+
> div {
|
|
430
|
+
border: 1px solid var(--lightgray);
|
|
431
|
+
border-radius: 6px;
|
|
432
|
+
padding: 0.45rem;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
strong,
|
|
436
|
+
span {
|
|
437
|
+
display: block;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.brain-graph-canvas-pane {
|
|
442
|
+
grid-area: graph;
|
|
443
|
+
align-self: stretch;
|
|
444
|
+
contain: paint;
|
|
445
|
+
justify-self: stretch;
|
|
446
|
+
min-height: 0;
|
|
447
|
+
min-width: 0;
|
|
448
|
+
overflow: hidden;
|
|
449
|
+
position: relative;
|
|
450
|
+
z-index: 1;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.brain-graph-canvas-pane > canvas {
|
|
454
|
+
display: block;
|
|
455
|
+
max-height: 100%;
|
|
456
|
+
max-width: 100%;
|
|
457
|
+
min-width: 0;
|
|
458
|
+
overflow: hidden;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.brain-graph-workbench-shell > .brain-graph-tooltip {
|
|
462
|
+
grid-column: 2;
|
|
463
|
+
grid-row: 2;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
@media (max-width: 900px) {
|
|
467
|
+
.brain-graph-workbench-shell {
|
|
468
|
+
grid-template-areas:
|
|
469
|
+
"toolbar"
|
|
470
|
+
"rail"
|
|
471
|
+
"graph"
|
|
472
|
+
"inspector";
|
|
473
|
+
grid-template-columns: 1fr;
|
|
474
|
+
grid-template-rows: auto auto minmax(22rem, 1fr) auto;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.brain-graph-mode-rail {
|
|
478
|
+
flex-direction: row;
|
|
479
|
+
overflow-x: auto;
|
|
480
|
+
border-right: 0;
|
|
481
|
+
border-bottom: 1px solid var(--rule);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.brain-graph-inspector {
|
|
485
|
+
border-left: 0;
|
|
486
|
+
border-top: 1px solid var(--rule);
|
|
487
|
+
max-height: 14rem;
|
|
488
|
+
min-width: 0;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.sidebar.right {
|
|
493
|
+
overflow-y: auto;
|
|
494
|
+
// Hide the scrollbar gutter so the sidebar reads as a clean column
|
|
495
|
+
// when content fits. Still scrollable via wheel / touchpad gestures.
|
|
496
|
+
scrollbar-width: thin;
|
|
497
|
+
scrollbar-color: var(--lightgray) transparent;
|
|
498
|
+
&::-webkit-scrollbar {
|
|
499
|
+
width: 4px;
|
|
500
|
+
}
|
|
501
|
+
&::-webkit-scrollbar-thumb {
|
|
502
|
+
background: var(--lightgray);
|
|
503
|
+
border-radius: 2px;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Brain wiki — BuildCtx with parser-cache plumbing.
|
|
2
|
+
//
|
|
3
|
+
// This file is a TEMPLATE. It is installed at
|
|
4
|
+
// `<vault>/.quartz/quartz/util/ctx.ts` by `brain vault render --overlay`,
|
|
5
|
+
// overwriting the stock upstream module.
|
|
6
|
+
//
|
|
7
|
+
// Changes from upstream:
|
|
8
|
+
// * `Argv.noCache?: boolean` — opt-out flag. When true, parseMarkdown
|
|
9
|
+
// sets cacheDir to null and the parser cache is disabled for the run.
|
|
10
|
+
// The upstream Quartz CLI handler does not set this flag (it lives in
|
|
11
|
+
// upstream-only handlers.ts which we do not override), so in practice
|
|
12
|
+
// it is always undefined (falsy) and the cache is always active unless
|
|
13
|
+
// a future override of the CLI handler flips it. Wired in as
|
|
14
|
+
// `argv.noCache` so the flag propagates to workers via
|
|
15
|
+
// WorkerSerializableBuildCtx.argv without any additional plumbing.
|
|
16
|
+
// * `BuildCtx.cacheDir?: string | null` — on-disk path for the parser
|
|
17
|
+
// result cache. `null` disables the cache for the run.
|
|
18
|
+
// `undefined` means "not yet set by the caller"; parseMarkdown in
|
|
19
|
+
// parse.ts defaults it to `<argv.directory>/.quartz/.cache/parser`
|
|
20
|
+
// so it matches `bin/brain-rebuild --clean-cache`'s rm target.
|
|
21
|
+
// Optional so existing BuildCtx constructors (upstream handlers.ts
|
|
22
|
+
// and test fixtures) compile without modification.
|
|
23
|
+
// `WorkerSerializableBuildCtx = Omit<BuildCtx, "cfg" | "trie">` so
|
|
24
|
+
// cacheDir auto-propagates to workers via the type — no worker.ts
|
|
25
|
+
// edit needed. The serializableCtx literal in parse.ts does list
|
|
26
|
+
// fields by hand and explicitly includes `cacheDir`.
|
|
27
|
+
|
|
28
|
+
import { QuartzConfig } from "../cfg"
|
|
29
|
+
import { QuartzPluginData } from "../plugins/vfile"
|
|
30
|
+
import { FileTrieNode } from "./fileTrie"
|
|
31
|
+
import { FilePath, FullSlug } from "./path"
|
|
32
|
+
|
|
33
|
+
export interface Argv {
|
|
34
|
+
directory: string
|
|
35
|
+
verbose: boolean
|
|
36
|
+
output: string
|
|
37
|
+
serve: boolean
|
|
38
|
+
watch: boolean
|
|
39
|
+
port: number
|
|
40
|
+
wsPort: number
|
|
41
|
+
remoteDevHost?: string
|
|
42
|
+
concurrency?: number
|
|
43
|
+
// brain: opt-out flag for the parser cache. When true, parseMarkdown
|
|
44
|
+
// sets cacheDir = null so no cache reads or writes occur for this run.
|
|
45
|
+
// Not currently wired from the upstream CLI handler (handlers.ts is not
|
|
46
|
+
// overridden); a future override can expose `--no-cache` via yargs and
|
|
47
|
+
// set this field. Until then it is always undefined = cache active.
|
|
48
|
+
noCache?: boolean
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type BuildTimeTrieData = QuartzPluginData & {
|
|
52
|
+
slug: string
|
|
53
|
+
title: string
|
|
54
|
+
filePath: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface BuildCtx {
|
|
58
|
+
buildId: string
|
|
59
|
+
argv: Argv
|
|
60
|
+
cfg: QuartzConfig
|
|
61
|
+
allSlugs: FullSlug[]
|
|
62
|
+
allFiles: FilePath[]
|
|
63
|
+
trie?: FileTrieNode<BuildTimeTrieData>
|
|
64
|
+
incremental: boolean
|
|
65
|
+
// brain: on-disk directory for the parser result cache.
|
|
66
|
+
// string — active cache at this path
|
|
67
|
+
// null — cache explicitly disabled for this run (e.g. --no-cache)
|
|
68
|
+
// undefined — not yet set; parseMarkdown.ts defaults to
|
|
69
|
+
// <argv.directory>/.quartz/.cache/parser (matches
|
|
70
|
+
// brain.maintenance._PARSER_CACHE_RELPATH; wiped by
|
|
71
|
+
// `brain-rebuild --clean-cache`).
|
|
72
|
+
// Optional so existing BuildCtx constructors compile without change.
|
|
73
|
+
cacheDir?: string | null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function trieFromAllFiles(allFiles: QuartzPluginData[]): FileTrieNode<BuildTimeTrieData> {
|
|
77
|
+
const trie = new FileTrieNode<BuildTimeTrieData>([])
|
|
78
|
+
allFiles.forEach((file) => {
|
|
79
|
+
if (file.frontmatter) {
|
|
80
|
+
trie.add({
|
|
81
|
+
...file,
|
|
82
|
+
slug: file.slug!,
|
|
83
|
+
title: file.frontmatter.title,
|
|
84
|
+
filePath: file.filePath!,
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
return trie
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export type WorkerSerializableBuildCtx = Omit<BuildCtx, "cfg" | "trie">
|