cortex-kg 0.2.1__tar.gz → 0.2.2__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.
- {cortex_kg-0.2.1/src/cortex_kg.egg-info → cortex_kg-0.2.2}/PKG-INFO +1 -1
- cortex_kg-0.2.2/docs/cortex-brain.md +186 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/pyproject.toml +1 -1
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/__init__.py +1 -1
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/api/rest.py +11 -3
- cortex_kg-0.2.2/src/cortex/api/workspace_viz.py +579 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/daemon.py +34 -1
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/models.py +14 -0
- cortex_kg-0.2.2/src/cortex/static/brain/assets/index-BUW5gdiE.js +486 -0
- cortex_kg-0.2.2/src/cortex/static/brain/assets/index-C5hkz5MJ.css +1 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/static/brain/index.html +2 -2
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/storage/graph_store.py +15 -1
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/workspace/registry.py +25 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2/src/cortex_kg.egg-info}/PKG-INFO +1 -1
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex_kg.egg-info/SOURCES.txt +3 -2
- cortex_kg-0.2.1/docs/cortex-brain.md +0 -90
- cortex_kg-0.2.1/src/cortex/static/brain/assets/index-B8habZrD.js +0 -486
- cortex_kg-0.2.1/src/cortex/static/brain/assets/index-Dvrg6tJc.css +0 -1
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/LICENSE +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/MANIFEST.in +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/README.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/README.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/automation.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/cursor.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/installation.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/other-platforms.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/project-workflow.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/publishing.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/templates/cortex-agent-rule.mdc +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/docs/templates/cortex-mcp.json +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/api/openapi.yaml +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/docs/adr-001-session-tokens.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/docs/architecture.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/notes/meeting-2026-07-10-billing-sync.md +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/schema/schema.sql +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/src/auth_service.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/examples/sample_repo/src/billing_service.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/scripts/build_brain_ui.sh +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/sdk/python/cortex_sdk/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/sdk/python/pyproject.toml +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/sdk/typescript/package.json +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/sdk/typescript/src/index.ts +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/sdk/typescript/tsconfig.json +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/setup.cfg +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/agents/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/agents/hooks.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/agents/writeback.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/api/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/api/graph_viz.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/cli.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/config.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/context/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/context/generator.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/api_spec_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/base.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/code_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/db_schema_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/git_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/image_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/llm_relation_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/markdown_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/notes_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/extractors/pdf_extractor.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/ingestion/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/ingestion/content_hash.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/ingestion/pipeline.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/ingestion/resolver.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/mcp_server/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/mcp_server/server.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/offline/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/offline/local_llm.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/ontology/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/ontology/registry.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/plugins/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/plugins/examples/jira_like_plugin/plugin.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/plugins/interface.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/plugins/loader.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/replication/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/replication/crdt.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/retrieval/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/retrieval/embeddings.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/retrieval/fusion.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/retrieval/planner.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/retrieval/query_engine.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/retrieval/traversal.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/security/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/security/acl.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/security/audit.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/security/encryption.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/security/secrets_scanner.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/server_profile/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/server_profile/neo4j_store.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/setup/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/setup/generators.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/storage/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/storage/keyword_store.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/storage/provenance.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/storage/vector_store.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/sync/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/sync/change_feed.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/sync/job_queue.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/sync/watcher.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/versioning/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/versioning/bitemporal.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/workspace/__init__.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex/workspace/federation.py +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex_kg.egg-info/dependency_links.txt +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex_kg.egg-info/entry_points.txt +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex_kg.egg-info/requires.txt +0 -0
- {cortex_kg-0.2.1 → cortex_kg-0.2.2}/src/cortex_kg.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Cortex Brain — interactive knowledge graph UI
|
|
2
|
+
|
|
3
|
+
Cortex Brain is the WebGL visualization of your Engineering Knowledge Graph.
|
|
4
|
+
After install, you open it in a browser — **no separate frontend server**.
|
|
5
|
+
|
|
6
|
+
## One-time setup (3 commands)
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# 1. Install
|
|
10
|
+
pipx install cortex-kg
|
|
11
|
+
# or: pip install cortex-kg
|
|
12
|
+
|
|
13
|
+
# 2. Index a project (creates knowledge in a workspace)
|
|
14
|
+
cortex --workspace default ingest /path/to/your/repo --project MyApp
|
|
15
|
+
|
|
16
|
+
# 3. Start the API + UI
|
|
17
|
+
cortex --workspace default serve-api
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Open **http://localhost:8420** in your browser.
|
|
21
|
+
|
|
22
|
+
In the top bar, set **Workspace** to the same name you used above
|
|
23
|
+
(`default`, `demo`, `work`, …). If it doesn’t match, the canvas looks empty.
|
|
24
|
+
|
|
25
|
+
That’s the whole setup.
|
|
26
|
+
|
|
27
|
+
## What you’ll see
|
|
28
|
+
|
|
29
|
+
| Area | What it does |
|
|
30
|
+
|---|---|
|
|
31
|
+
| **Graph canvas** | Zoom, pan, drag nodes; hover to highlight neighbors |
|
|
32
|
+
| **Search** | Find a node and center it (`/` focuses the box) |
|
|
33
|
+
| **Views** | Brain, Project, Architecture, Cluster, Timeline, AI Context, … |
|
|
34
|
+
| **Filters** | Node/edge types, project, technology, date range |
|
|
35
|
+
| **Node panel** | Metadata, connections, provenance, AI explanation |
|
|
36
|
+
| **Intelligence** | Paths, impact, orphans, duplicates, similar nodes |
|
|
37
|
+
| **AI Context** | Replay what retrieval would feed an LLM |
|
|
38
|
+
| **Workspaces** | The Engineering Brain across one, many, or every workspace |
|
|
39
|
+
|
|
40
|
+
Keyboard: `/` search · `f` fit view · `Esc` clear selection.
|
|
41
|
+
|
|
42
|
+
## Workspaces view — workspace-aware knowledge visualization
|
|
43
|
+
|
|
44
|
+
Every other view is scoped to the single **Workspace** field in the top bar.
|
|
45
|
+
The **Workspaces** view is different: it lets you explore *across*
|
|
46
|
+
workspaces, on the model that the Engineering Brain is conceptually one
|
|
47
|
+
knowledge graph and a workspace is a filtering/organizational lens over it,
|
|
48
|
+
not a separate graph. Pick it from the view switcher to swap the filter
|
|
49
|
+
rail for a workspace selector + mode switch, with five lenses over the
|
|
50
|
+
same data:
|
|
51
|
+
|
|
52
|
+
| Mode | Shows |
|
|
53
|
+
|---|---|
|
|
54
|
+
| **Single** | One workspace's own nodes/relationships |
|
|
55
|
+
| **Multi** | Selected workspaces merged, with shared knowledge cross-linked and highlighted |
|
|
56
|
+
| **Global Brain** | Every known workspace, clustered together (like neural clusters connected by cross-workspace edges) |
|
|
57
|
+
| **Cross-Workspace** | Only what crosses a workspace boundary — explicit links + shared knowledge |
|
|
58
|
+
| **Dependency** | A workspace-level graph: one node per workspace, edges aggregate how they relate |
|
|
59
|
+
|
|
60
|
+
**Shared knowledge:** a node ingested independently into two workspaces
|
|
61
|
+
(e.g. the same `AuthService`) is detected by matching type + name and
|
|
62
|
+
rendered as one *shared* node — larger, color-blended across its
|
|
63
|
+
workspaces, with a slow breathing pulse on the canvas, and a workspace
|
|
64
|
+
badge list in the node panel. This is a heuristic (exact name+type match),
|
|
65
|
+
distinct from **explicit cross-workspace links** (`POST /api/workspaces/link`)
|
|
66
|
+
which are authoritative, purpose-created relationships between two specific
|
|
67
|
+
nodes (e.g. "our AuthService" `inspired_by` "the reference pattern in
|
|
68
|
+
workspace `oss-reference`").
|
|
69
|
+
|
|
70
|
+
**Workspace analytics** (in the rail, or `GET /api/workspaces/analytics`):
|
|
71
|
+
most-connected workspace, most-reused knowledge, cross-workspace
|
|
72
|
+
dependencies, possible duplicate knowledge, orphan workspaces, a knowledge
|
|
73
|
+
reuse score, and a collaboration score — all computed from your real graph
|
|
74
|
+
data (bounded per-workspace sampling for responsiveness), never fabricated.
|
|
75
|
+
|
|
76
|
+
**AI Context, federated:** asking a question from the Workspaces view (with
|
|
77
|
+
2+ workspaces selected) replays retrieval in *every* selected workspace and
|
|
78
|
+
shows a per-workspace contribution bar — which workspace(s) were searched,
|
|
79
|
+
and what percentage of the answer came from each.
|
|
80
|
+
|
|
81
|
+
### How this actually works (and its honest limits)
|
|
82
|
+
|
|
83
|
+
Physically, each workspace still has its own isolated embedded store
|
|
84
|
+
(`~/.cortex/<workspace>/`) — Kuzu is single-writer, and workspaces have
|
|
85
|
+
always been Cortex's storage-level isolation boundary (see
|
|
86
|
+
`cortex.workspace.registry`). The Workspaces view delivers the "one graph"
|
|
87
|
+
experience by **federating across workspaces at read time**, not by
|
|
88
|
+
merging their storage:
|
|
89
|
+
|
|
90
|
+
- Nodes keep their own workspace's id; "shared" is a client-visible flag
|
|
91
|
+
(`workspaceIds`, `shared`), not a physical merge — the underlying
|
|
92
|
+
duplicate nodes still exist separately, each with its own provenance.
|
|
93
|
+
- A synthetic `Workspace` node is injected per workspace so it can be
|
|
94
|
+
clustered, colored, and linked like anything else in the graph.
|
|
95
|
+
- Multi/Global/Cross/Dependency modes open **every selected workspace's**
|
|
96
|
+
database in the same process. A workspace that's locked by another
|
|
97
|
+
process (e.g. Cursor's `serve-mcp` integration) is skipped and reported
|
|
98
|
+
in `lockedWorkspaces` rather than failing the whole call.
|
|
99
|
+
- Shared-knowledge detection and analytics sample up to a bounded number of
|
|
100
|
+
nodes per workspace (`limit`, default a few thousand) for responsiveness
|
|
101
|
+
— at true "hundreds of workspaces / millions of nodes" scale, treat these
|
|
102
|
+
as directional signals, not exhaustive ones.
|
|
103
|
+
- Kuzu's per-database virtual memory reservation is capped
|
|
104
|
+
(`CORTEX_KUZU_MAX_DB_SIZE`, default 8 GiB) specifically so many workspace
|
|
105
|
+
databases can be open in one process at once without exhausting the OS's
|
|
106
|
+
mmap budget — the failure mode looks like `Buffer manager exception: Mmap
|
|
107
|
+
... failed` if you ever raise this too high with many workspaces in play.
|
|
108
|
+
|
|
109
|
+
If you want a literal single merged graph (one physical store, no
|
|
110
|
+
per-workspace isolation) that's a separate, larger storage migration this
|
|
111
|
+
feature intentionally does not attempt — federation was chosen so nothing
|
|
112
|
+
about your existing per-workspace data or ingestion flow has to change.
|
|
113
|
+
|
|
114
|
+
## Sample data (optional)
|
|
115
|
+
|
|
116
|
+
From a clone of this repo:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install -e ".[dev]"
|
|
120
|
+
cortex --workspace demo ingest examples/sample_repo --project SampleApp
|
|
121
|
+
cortex --workspace demo serve-api
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Open http://localhost:8420 and set **Workspace** to `demo`.
|
|
125
|
+
|
|
126
|
+
## Tips
|
|
127
|
+
|
|
128
|
+
- **Re-ingest** after code/docs change: `cortex ingest . --project MyApp`
|
|
129
|
+
Unchanged files are skipped automatically.
|
|
130
|
+
- **API docs** (same process): http://localhost:8420/docs
|
|
131
|
+
- **Custom port:** `cortex serve-api --port 9000`
|
|
132
|
+
- **Custom UI folder** (advanced): `export CORTEX_WEB_DIST=/path/to/dist`
|
|
133
|
+
- Data lives in `~/.cortex/<workspace>/` (override with `CORTEX_HOME`)
|
|
134
|
+
- The **Workspace** field in the top bar commits on blur/Enter, not every
|
|
135
|
+
keystroke — typing a workspace id auto-creates it on first use, so
|
|
136
|
+
committing on every keystroke used to create (and lock-probe) a phantom
|
|
137
|
+
workspace per partial string typed.
|
|
138
|
+
|
|
139
|
+
## Troubleshooting: "Workspace 'X' is locked by another Cortex process"
|
|
140
|
+
|
|
141
|
+
The embedded graph DB (Kuzu) only allows **one read-write process per
|
|
142
|
+
workspace** at a time. If you see this error (a `503` in the graph
|
|
143
|
+
canvas, or in `serve-api`'s logs), something else already has that
|
|
144
|
+
workspace open — most commonly:
|
|
145
|
+
|
|
146
|
+
- **Cursor's Cortex MCP integration** (`cortex --workspace <ws> serve-mcp`),
|
|
147
|
+
started automatically whenever Cursor uses `search_knowledge`,
|
|
148
|
+
`get_context`, etc. against that workspace.
|
|
149
|
+
- **Another `serve-api` / CLI command** (`cortex ingest`, `cortex info`, …)
|
|
150
|
+
still running against the same workspace.
|
|
151
|
+
|
|
152
|
+
Fix: either stop the other process, or point Brain at a workspace that
|
|
153
|
+
isn't in use elsewhere (switch **Workspace** in the top bar). Ingesting
|
|
154
|
+
into a workspace that Cursor's MCP server is actively using will hit the
|
|
155
|
+
same conflict — pick a workspace Cursor doesn't reference, or briefly stop
|
|
156
|
+
the MCP server, ingest, then restart it.
|
|
157
|
+
|
|
158
|
+
## Developing the UI itself
|
|
159
|
+
|
|
160
|
+
Only needed if you change the React app under `web/`:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Terminal 1
|
|
164
|
+
cortex --workspace demo serve-api
|
|
165
|
+
|
|
166
|
+
# Terminal 2
|
|
167
|
+
cd web && npm install && npm run dev
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Then open the Vite URL (usually http://localhost:5173).
|
|
171
|
+
To refresh the packaged UI that `serve-api` serves:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
./scripts/build_brain_ui.sh
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Connect Cursor (optional)
|
|
178
|
+
|
|
179
|
+
The Brain UI explores knowledge in a browser. For AI tools inside Cursor:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
cortex ingest . --project MyApp
|
|
183
|
+
cortex setup project --write --project MyApp
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
See [cursor.md](cursor.md).
|
|
@@ -24,7 +24,7 @@ from pydantic import BaseModel
|
|
|
24
24
|
from sse_starlette.sse import EventSourceResponse
|
|
25
25
|
|
|
26
26
|
from cortex.config import DEFAULT_WORKSPACE
|
|
27
|
-
from cortex.daemon import CortexDaemon, get_daemon
|
|
27
|
+
from cortex.daemon import CortexDaemon, WorkspaceLockedError, get_daemon
|
|
28
28
|
from cortex.models import Edge, Node, Provenance
|
|
29
29
|
from cortex.sync.change_feed import ChangeFeed
|
|
30
30
|
|
|
@@ -71,7 +71,10 @@ app.add_middleware(_StripApiPrefixMiddleware)
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def daemon_dep(workspace: str = Query(default=DEFAULT_WORKSPACE)) -> CortexDaemon:
|
|
74
|
-
|
|
74
|
+
try:
|
|
75
|
+
return get_daemon(workspace)
|
|
76
|
+
except WorkspaceLockedError as exc:
|
|
77
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
75
78
|
|
|
76
79
|
|
|
77
80
|
class NodeIn(BaseModel):
|
|
@@ -267,7 +270,10 @@ async def change_feed_stream(workspace: str = Query(default=DEFAULT_WORKSPACE)):
|
|
|
267
270
|
"""Server-sent events: live subscription to graph changes (roadmap
|
|
268
271
|
section 10) -- any tool can react to new knowledge instead of polling.
|
|
269
272
|
"""
|
|
270
|
-
|
|
273
|
+
try:
|
|
274
|
+
daemon = get_daemon(workspace)
|
|
275
|
+
except WorkspaceLockedError as exc:
|
|
276
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
271
277
|
feed = ChangeFeed.instance(daemon)
|
|
272
278
|
q = feed.subscribe()
|
|
273
279
|
|
|
@@ -286,8 +292,10 @@ async def change_feed_stream(workspace: str = Query(default=DEFAULT_WORKSPACE)):
|
|
|
286
292
|
|
|
287
293
|
|
|
288
294
|
from cortex.api.graph_viz import router as graph_viz_router # noqa: E402
|
|
295
|
+
from cortex.api.workspace_viz import router as workspace_viz_router # noqa: E402
|
|
289
296
|
|
|
290
297
|
app.include_router(graph_viz_router)
|
|
298
|
+
app.include_router(workspace_viz_router)
|
|
291
299
|
|
|
292
300
|
|
|
293
301
|
def _resolve_brain_ui_dir() -> Optional[Path]:
|