code-data-ark 2.0.4__tar.gz → 2.0.6__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 (36) hide show
  1. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/PKG-INFO +49 -21
  2. code_data_ark-2.0.6/cda/__main__.py +10 -0
  3. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/kernel/paths.py +36 -6
  4. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/ui/cli.py +250 -5
  5. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/changelog.md +26 -0
  6. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/pyproject.toml +1 -1
  7. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/readme.md +48 -20
  8. code_data_ark-2.0.6/version +1 -0
  9. code_data_ark-2.0.4/version +0 -1
  10. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/.flake8 +0 -0
  11. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/.github/workflows/ci.yml +0 -0
  12. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/.gitignore +0 -0
  13. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/bin/release.py +0 -0
  14. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/__init__.py +0 -0
  15. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/kernel/__init__.py +0 -0
  16. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/kernel/control_db.py +0 -0
  17. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/kernel/pmf_kernel.py +0 -0
  18. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/kernel/selfcheck.py +0 -0
  19. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/__init__.py +0 -0
  20. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/embed.py +0 -0
  21. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/extract.py +0 -0
  22. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/ingest.py +0 -0
  23. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/parse_edits.py +0 -0
  24. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/reconstruct.py +0 -0
  25. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/pipeline/watcher.py +0 -0
  26. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/ui/__init__.py +0 -0
  27. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/cda/ui/web.py +0 -0
  28. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/contributing.md +0 -0
  29. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/docs/architecture.md +0 -0
  30. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/docs/examples/usage.md +0 -0
  31. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/docs/pmf_kernel.md +0 -0
  32. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/docs/roadmap.md +0 -0
  33. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/license +0 -0
  34. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/makefile +0 -0
  35. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/tests/test_basic.py +0 -0
  36. {code_data_ark-2.0.4 → code_data_ark-2.0.6}/tests/test_selfcheck.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-data-ark
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: Code Data Ark — local observability and intelligence platform for VS Code + Copilot Chat sessions
5
5
  Project-URL: Homepage, https://github.com/goCosmix/cda
6
6
  Project-URL: Repository, https://github.com/goCosmix/cda.git
@@ -95,10 +95,17 @@ The runtime is managed by an embedded process kernel (PMF) that supervises the w
95
95
  pip install code-data-ark
96
96
  ```
97
97
 
98
+ > **macOS / system Python note**: pip installs the `cda` binary to `~/Library/Python/3.x/bin/` which is not on `PATH` by default. Use the fallback below — `cda setup` will fix PATH for you automatically:
99
+ >
100
+ > ```bash
101
+ > python3 -m cda setup
102
+ > ```
103
+
98
104
  ### Install with pipx
99
105
 
100
106
  ```bash
101
107
  pipx install code-data-ark
108
+ # pipx automatically manages PATH — `cda setup` works immediately
102
109
  ```
103
110
 
104
111
  ### Install from source
@@ -117,52 +124,73 @@ pip install -e ".[dev]"
117
124
  make install-dev
118
125
  ```
119
126
 
120
- > The `cda` console command is installed into your active Python environment's `bin` directory. Activate your virtual environment before running `cda`.
127
+ > The `cda` console command is installed into your Python environment's `bin` directory. If it isn't on PATH yet, use `python3 -m cda setup` — setup patches `~/.zprofile` automatically.
121
128
 
122
129
  ## ⚡ Quick Start
123
130
 
124
- 1. **Install**
125
-
126
131
  ```bash
127
132
  pip install code-data-ark
133
+ python3 -m cda setup # use this if `cda` isn't on PATH yet
128
134
  ```
129
135
 
130
- 2. **Initialize create `~/.cda/` and validate your VS Code data path**
136
+ After the first run, `cda setup` patches `~/.zprofile` so `cda` is on PATH in every new terminal.
131
137
 
132
- ```bash
133
- cda init
134
- ```
138
+ `cda setup` runs four steps in sequence:
139
+
140
+ | Step | What it does |
141
+ |------|-------------|
142
+ | **1. Init** | Creates `~/Library/goCosmix/apps/code-data-ark/` — all app data in one organized namespace. Also patches `~/.zprofile` if `cda` isn't on PATH yet. |
143
+ | **2. PMF install** | Registers a macOS LaunchAgent — CDA starts automatically on every login via `cda pmf up` |
144
+ | **3. Sync** | Ingests all VS Code + Copilot session data into `cda.db` |
145
+ | **4. Up** | Starts the watcher daemon and web UI via the PMF kernel, opens browser |
135
146
 
136
- 3. **Ingest all VS Code session data**
147
+ All data lives in `~/Library/goCosmix/apps/code-data-ark/`. After setup, everything is managed by the **PMF kernel** no terminal interaction required.
148
+
149
+ ### Options
137
150
 
138
151
  ```bash
139
- cda sync
152
+ cda setup --skip-sync # Skip initial ingest (run `cda sync` manually later)
153
+ cda setup --no-browser # Don't open browser when the UI starts
140
154
  ```
141
155
 
142
- 4. **Start the live watcher daemon**
156
+ ### After setup
143
157
 
144
158
  ```bash
145
- cda watch start
159
+ cda check # Full system health diagnostic
160
+ cda sync # Re-ingest after significant new session activity
161
+ cda pmf services # View all running services and their status
162
+ cda pmf uninstall # Remove the auto-start LaunchAgent registration
146
163
  ```
147
164
 
148
- 5. **Open the web dashboard**
165
+ ## 🔧 Process Management (PMF)
149
166
 
150
- ```bash
151
- cda serve # → http://127.0.0.1:10001
167
+ All background processes run through the embedded PMF kernel. The LaunchAgent is the entry point — nothing starts directly on the host outside of PMF.
168
+
169
+ ```
170
+ launchd (login)
171
+ └─ cda pmf up
172
+ ├─ PMF kernel → watcher daemon (cda.pipeline.watcher)
173
+ └─ PMF kernel → web UI server (cda.ui.web)
152
174
  ```
153
175
 
154
- 6. **Build semantic intelligence** (optional, requires `sentence-transformers`)
176
+ ### PMF commands
155
177
 
156
178
  ```bash
157
- cda embed build
179
+ cda pmf services # List all services with status and PID
180
+ cda pmf start <service> # Start a service (watcher, ui, sync, reconstruct, embed-build)
181
+ cda pmf stop <service> # Stop a service
182
+ cda pmf restart <service> # Restart a service
183
+ cda pmf logs <service> # Tail the service log
184
+ cda pmf up # Start watcher + UI (opens browser) — same as launchd trigger
185
+ cda pmf install # Register LaunchAgent (done automatically by cda setup)
186
+ cda pmf uninstall # Remove LaunchAgent
158
187
  ```
159
188
 
160
189
  ## 🌐 Web UI
161
190
 
162
- - **Background service**: `cda ui start`
163
- - **Stop service**: `cda ui stop`
164
- - **Service status**: `cda ui status`
165
- - **Foreground mode**: `cda serve`
191
+ - **Background service** (default after setup): managed by PMF, starts on login
192
+ - **Foreground mode**: `cda serve` — runs in the terminal, opens browser, Ctrl+C to stop
193
+ - **Access**: `http://127.0.0.1:10001`
166
194
 
167
195
  The web UI includes:
168
196
 
@@ -0,0 +1,10 @@
1
+ """
2
+ Allows `python3 -m cda <command>` as a fallback when the `cda` binary
3
+ is not yet on PATH (e.g. immediately after `pip install code-data-ark`).
4
+
5
+ python3 -m cda setup
6
+ """
7
+ from cda.ui.cli import main
8
+
9
+ if __name__ == "__main__":
10
+ main()
@@ -5,10 +5,16 @@ CDA_HOME is the single root for all runtime state (DB, PID files, logs,
5
5
  queue, PMF runtime). It is resolved exactly once at import time via:
6
6
 
7
7
  1. CDA_HOME environment variable (absolute path)
8
- 2. ~/.cda/ (default — survives pip install, editable install, CI)
8
+ 2. ~/Library/goCosmix/apps/code-data-ark/ (macOS default)
9
+ 3. ~/.gocosmix/apps/code-data-ark/ (fallback on non-macOS)
9
10
 
10
- Pipeline stages and the CLI all import from here so every module agrees
11
- on the same paths regardless of where the package is installed.
11
+ All goCosmix apps share the ~/Library/goCosmix/ namespace:
12
+
13
+ ~/Library/goCosmix/
14
+ ├── apps/
15
+ │ ├── code-data-ark/ ← CDA_HOME
16
+ │ └── ... ← future goCosmix apps
17
+ └── system/ ← shared goCosmix infrastructure
12
18
  """
13
19
 
14
20
  import os
@@ -17,17 +23,40 @@ from pathlib import Path
17
23
  # ── home resolution ──────────────────────────────────────────────────────────
18
24
 
19
25
 
26
+ def _default_cda_home() -> Path:
27
+ """Platform-appropriate default for CDA_HOME."""
28
+ library = Path.home() / "Library"
29
+ if library.exists(): # macOS
30
+ return library / "goCosmix" / "apps" / "code-data-ark"
31
+ return Path.home() / ".gocosmix" / "apps" / "code-data-ark"
32
+
33
+
20
34
  def get_cda_home() -> Path:
21
35
  """Return the CDA home directory, creating it if it doesn't exist."""
22
36
  env = os.environ.get("CDA_HOME")
23
37
  if env:
24
38
  home = Path(env).expanduser().resolve()
25
39
  else:
26
- home = Path.home() / ".cda"
40
+ home = _default_cda_home()
27
41
  home.mkdir(parents=True, exist_ok=True)
28
42
  return home
29
43
 
30
44
 
45
+ # ── goCosmix namespace (shared across all goCosmix apps) ────────────────────
46
+
47
+ def get_gocosmix_home() -> Path:
48
+ """Return ~/Library/goCosmix (macOS) or ~/.gocosmix (other)."""
49
+ library = Path.home() / "Library"
50
+ if library.exists():
51
+ return library / "goCosmix"
52
+ return Path.home() / ".gocosmix"
53
+
54
+
55
+ GOCOSMIX_HOME = get_gocosmix_home()
56
+ GOCOSMIX_APPS = GOCOSMIX_HOME / "apps"
57
+ GOCOSMIX_SYSTEM = GOCOSMIX_HOME / "system"
58
+
59
+
31
60
  # ── canonical paths (module-level constants, computed once) ─────────────────
32
61
 
33
62
  CDA_HOME = get_cda_home()
@@ -49,6 +78,7 @@ RUNTIME_FILE = PMF_DIR / "runtime.json"
49
78
 
50
79
 
51
80
  def ensure_dirs() -> None:
52
- """Create all runtime directories. Safe to call multiple times."""
53
- for d in (DATA_DIR, RUN_DIR, LOG_DIR, QUEUE_DIR, PMF_DIR, PMF_LOG_DIR, CONFIG_DIR):
81
+ """Create all runtime directories (including goCosmix namespace). Safe to call multiple times."""
82
+ for d in (GOCOSMIX_HOME, GOCOSMIX_APPS, GOCOSMIX_SYSTEM,
83
+ DATA_DIR, RUN_DIR, LOG_DIR, QUEUE_DIR, PMF_DIR, PMF_LOG_DIR, CONFIG_DIR):
54
84
  d.mkdir(parents=True, exist_ok=True)
@@ -28,7 +28,8 @@ Commands:
28
28
  cda pmf install Register as macOS LaunchAgent (auto-start on login)
29
29
  cda pmf uninstall Remove the LaunchAgent registration
30
30
  cda check Run a full self-diagnostic. The system checks itself.
31
- cda init First-run setup — create ~/.cda/ and validate environment
31
+ cda init First-run setup — create ~/Library/goCosmix/ and validate environment
32
+ cda setup Full onboarding: init → pmf install → sync → up (browser opens)
32
33
  cda serve Start the local web UI on port 10001
33
34
  cda sync Full re-ingest from disk (rebuilds entire DB)
34
35
  cda reconstruct Re-run reconstruction and FTS rebuild only
@@ -80,6 +81,14 @@ import click
80
81
  # Ensure runtime dirs exist on every CLI invocation
81
82
  ensure_dirs()
82
83
 
84
+
85
+ def _pmf_warn_if_not_installed():
86
+ """Emit a one-time advisory if the LaunchAgent is not registered."""
87
+ if not plist_path().exists():
88
+ click.echo(yellow(" Note: LaunchAgent not installed — services won't auto-start on login."))
89
+ click.echo(yellow(" Run `cda setup` to register, or `cda pmf install` to add just the plist."))
90
+
91
+
83
92
  kernel = PMFKernel()
84
93
 
85
94
 
@@ -408,7 +417,8 @@ def _ui_is_running():
408
417
  @click.option("--port", default=10001, show_default=True, help="Local port for the web UI")
409
418
  @click.option("--no-browser", "no_browser", is_flag=True, default=False, help="Don't open browser automatically")
410
419
  def ui_start(host, port, no_browser):
411
- """Start the web UI as a background service."""
420
+ """Start the web UI as a background service (via PMF kernel)."""
421
+ _pmf_warn_if_not_installed()
412
422
  try:
413
423
  result = kernel.start_service("ui", options={"host": host, "port": port})
414
424
  url = f"http://{host}:{port}"
@@ -788,10 +798,11 @@ def watch():
788
798
 
789
799
  @watch.command("start")
790
800
  def watch_start():
791
- """Start the live sync watcher daemon."""
801
+ """Start the live sync watcher daemon (via PMF kernel)."""
802
+ _pmf_warn_if_not_installed()
792
803
  try:
793
804
  result = kernel.start_service("watcher")
794
- click.echo(green(f" Watcher started pid={result['pid']}"))
805
+ click.echo(green(f" Watcher started pid={result['pid']} (via PMF)"))
795
806
  except PMFKernelError as exc:
796
807
  click.echo(red(f" {exc}"))
797
808
 
@@ -2646,13 +2657,247 @@ def check(as_json, fail_fast):
2646
2657
  sys.exit(0 if passed_all else 1)
2647
2658
 
2648
2659
 
2660
+ # ─────────────────────────────────────────────
2661
+ # SETUP
2662
+ # ─────────────────────────────────────────────
2663
+
2664
+ @cli.command("setup")
2665
+ @click.option("--skip-sync", "skip_sync", is_flag=True, default=False,
2666
+ help="Skip initial data ingest (run `cda sync` manually later)")
2667
+ @click.option("--no-browser", "no_browser", is_flag=True, default=False,
2668
+ help="Don't open browser when the web UI starts")
2669
+ def setup(skip_sync, no_browser):
2670
+ """
2671
+ Full onboarding in four steps: init → pmf install → sync → up.
2672
+
2673
+ \b
2674
+ Run this once after `pip install code-data-ark`.
2675
+ If `cda` isn't on PATH yet, use the fallback:
2676
+
2677
+ python3 -m cda setup
2678
+
2679
+ \b
2680
+ What each step does:
2681
+ 1. Init — create ~/Library/goCosmix/apps/code-data-ark/, patch PATH
2682
+ 2. Install — register a macOS LaunchAgent so CDA starts on every login
2683
+ 3. Sync — ingest all VS Code + Copilot session data into cda.db
2684
+ 4. Up — start the watcher daemon and web UI via PMF, open browser
2685
+
2686
+ All processes are managed by the PMF kernel. The LaunchAgent calls
2687
+ `cda pmf up` on every login — no manual interaction needed after setup.
2688
+ """
2689
+ import shutil as _shutil
2690
+ import os as _os
2691
+ from cda.kernel.paths import (
2692
+ CDA_HOME, DATA_DIR, RUN_DIR, LOG_DIR, QUEUE_DIR,
2693
+ PMF_DIR, PMF_LOG_DIR, CONFIG_DIR, POLICY_FILE,
2694
+ GOCOSMIX_HOME, GOCOSMIX_APPS, GOCOSMIX_SYSTEM,
2695
+ )
2696
+
2697
+ W = 52
2698
+ BAR = "═" * W
2699
+ bar = "─" * W
2700
+ host, port = "127.0.0.1", 10001
2701
+ url = f"http://{host}:{port}"
2702
+
2703
+ click.echo()
2704
+ click.echo(bold(BAR))
2705
+ click.echo(bold(" Code Data Ark — setup"))
2706
+ click.echo(bold(BAR))
2707
+ click.echo()
2708
+ click.echo(dim(" Four steps to a fully operational CDA installation:"))
2709
+ click.echo(dim(f" 1. Init — create {CDA_HOME}"))
2710
+ click.echo(dim(" 2. Install — register macOS LaunchAgent (auto-start on login)"))
2711
+ click.echo(dim(" 3. Sync — first-run data ingest") + (dim(" [skipped]") if skip_sync else ""))
2712
+ click.echo(dim(" 4. Up — start watcher + web UI via PMF, open browser"))
2713
+ click.echo()
2714
+
2715
+ # ── Step 1: Init ─────────────────────────────────────────────
2716
+ click.echo(bold(bar))
2717
+ click.echo(bold(" Step 1/4 — Init"))
2718
+ click.echo(bold(bar))
2719
+ click.echo()
2720
+
2721
+ # Create full goCosmix namespace + app dirs
2722
+ dirs = [GOCOSMIX_HOME, GOCOSMIX_APPS, GOCOSMIX_SYSTEM,
2723
+ DATA_DIR, RUN_DIR, LOG_DIR, QUEUE_DIR, PMF_DIR, PMF_LOG_DIR, CONFIG_DIR]
2724
+ for d in dirs:
2725
+ existed = d.exists()
2726
+ d.mkdir(parents=True, exist_ok=True)
2727
+ if not existed:
2728
+ click.echo(f" {green('+')} {d}")
2729
+ else:
2730
+ click.echo(f" {green('✓')} {d}")
2731
+
2732
+ if not POLICY_FILE.exists():
2733
+ POLICY_FILE.write_text("# CDA access policy\n# ALLOW <pattern>\n# DENY <pattern>\n")
2734
+
2735
+ # Offer migration from legacy ~/.cda/
2736
+ legacy = Path.home() / ".cda"
2737
+ if legacy.exists() and legacy != CDA_HOME:
2738
+ click.echo()
2739
+ click.echo(yellow(f" ⚠ Legacy data found at {legacy}"))
2740
+ click.echo(yellow(" Run `cda migrate-home` after setup to move it to the new location."))
2741
+
2742
+ # VS Code data dir check
2743
+ vscode_data = Path(_os.environ.get(
2744
+ "VSCODE_DATA_DIR",
2745
+ Path.home() / "Library/Application Support/Code/User",
2746
+ ))
2747
+ if vscode_data.exists():
2748
+ click.echo(f" {green('✓')} VS Code data dir found")
2749
+ else:
2750
+ click.echo(f" {yellow('⚠')} VS Code data dir not found: {vscode_data}")
2751
+ click.echo(yellow(" Set VSCODE_DATA_DIR if your data is elsewhere."))
2752
+
2753
+ click.echo()
2754
+ click.echo(f" {green('✓')} CDA_HOME: {CDA_HOME}")
2755
+ click.echo()
2756
+
2757
+ # ── PATH patch ───────────────────────────────────────────────
2758
+ # Detect where pip placed the `cda` binary and ensure it's on PATH.
2759
+ # Works whether invoked as `cda setup` or `python3 -m cda setup`.
2760
+ cda_bin_dir = None
2761
+ cda_bin = _shutil.which("cda")
2762
+ if cda_bin:
2763
+ cda_bin_dir = str(Path(cda_bin).parent)
2764
+ else:
2765
+ # pip install --user puts scripts next to python executable
2766
+ py_bin_dir = Path(sys.executable).parent
2767
+ candidate = py_bin_dir / "cda"
2768
+ if candidate.exists():
2769
+ cda_bin_dir = str(py_bin_dir)
2770
+
2771
+ if cda_bin_dir and cda_bin_dir not in _os.environ.get("PATH", "").split(":"):
2772
+ export_line = f'export PATH="{cda_bin_dir}:$PATH"'
2773
+ zprofile = Path.home() / ".zprofile"
2774
+ existing = zprofile.read_text() if zprofile.exists() else ""
2775
+ if export_line not in existing:
2776
+ with open(zprofile, "a") as f:
2777
+ f.write(f"\n# goCosmix — added by cda setup\n{export_line}\n")
2778
+ click.echo(f" {green('+')} PATH updated in ~/.zprofile")
2779
+ click.echo(yellow(" Run `source ~/.zprofile` or open a new terminal to activate."))
2780
+ click.echo(f" {green('✓')} cda binary: {cda_bin_dir}/cda")
2781
+ elif cda_bin:
2782
+ click.echo(f" {green('✓')} cda binary on PATH: {cda_bin}")
2783
+
2784
+ click.echo()
2785
+
2786
+ # ── Step 2: PMF install ──────────────────────────────────────
2787
+ click.echo(bold(bar))
2788
+ click.echo(bold(" Step 2/4 — PMF install"))
2789
+ click.echo(bold(bar))
2790
+ click.echo()
2791
+ click.echo(dim(" The LaunchAgent registers CDA with macOS launchd. On every login,"))
2792
+ click.echo(dim(" launchd calls `cda pmf up` — starts watcher + web UI via PMF kernel."))
2793
+ click.echo(dim(" No terminal required after this."))
2794
+ click.echo()
2795
+
2796
+ pmf_ok = False
2797
+ try:
2798
+ target = install_launchd(CDA_HOME)
2799
+ click.echo(f" {green('✓')} LaunchAgent: {target}")
2800
+ click.echo(f" {green('✓')} Loaded — CDA starts automatically on every login")
2801
+ pmf_ok = True
2802
+ except PMFKernelError as exc:
2803
+ click.echo(f" {yellow('⚠')} LaunchAgent registration failed: {exc}")
2804
+ click.echo(yellow(" Fix PATH then run `cda pmf install` to retry."))
2805
+ click.echo()
2806
+
2807
+ # ── Step 3: Sync ─────────────────────────────────────────────
2808
+ click.echo(bold(bar))
2809
+ click.echo(bold(" Step 3/4 — Sync"))
2810
+ click.echo(bold(bar))
2811
+ click.echo()
2812
+
2813
+ if skip_sync:
2814
+ click.echo(f" {yellow('↳')} Skipped (--skip-sync). Run `cda sync` when ready.")
2815
+ click.echo()
2816
+ else:
2817
+ click.echo(dim(" Scanning VS Code workspaceStorage and building cda.db."))
2818
+ click.echo(dim(" First run may take a few minutes depending on session history."))
2819
+ click.echo()
2820
+
2821
+ sync_failed = False
2822
+ stages = [
2823
+ ("cda.pipeline.ingest", "Ingest — reading VS Code storage"),
2824
+ ("cda.pipeline.reconstruct", "Reconstruct — building exchanges + FTS"),
2825
+ ("cda.pipeline.extract", "Extract — behavioral signals + tokens"),
2826
+ ("cda.pipeline.embed", "Embed — semantic intelligence layer"),
2827
+ ]
2828
+ for module, label in stages:
2829
+ click.echo(yellow(f" → {label}"))
2830
+ result = subprocess.run([sys.executable, "-m", module], capture_output=False)
2831
+ if result.returncode != 0:
2832
+ click.echo(red(" ✗ Failed — sync incomplete"))
2833
+ sync_failed = True
2834
+ break
2835
+ click.echo(green(" ✓ Done"))
2836
+ click.echo()
2837
+
2838
+ if not sync_failed:
2839
+ click.echo(green(" ✓ Sync complete"))
2840
+ click.echo()
2841
+
2842
+ # ── Step 4: Up ───────────────────────────────────────────────
2843
+ click.echo(bold(bar))
2844
+ click.echo(bold(" Step 4/4 — Up"))
2845
+ click.echo(bold(bar))
2846
+ click.echo()
2847
+ click.echo(dim(" Starting all services through the PMF kernel."))
2848
+ click.echo(dim(" Each process is tracked, logged, and restartable via `cda pmf`."))
2849
+ click.echo()
2850
+
2851
+ for svc_id, opts, label in [
2852
+ ("watcher", None, "Watcher daemon"),
2853
+ ("ui", {"host": host, "port": port}, f"Web UI → {url}"),
2854
+ ]:
2855
+ try:
2856
+ result = kernel.start_service(svc_id, options=opts)
2857
+ click.echo(f" {green('✓')} {label} pid={result['pid']}")
2858
+ except PMFKernelError as exc:
2859
+ msg = str(exc)
2860
+ if "already running" in msg.lower():
2861
+ click.echo(f" {green('✓')} {label} (already running)")
2862
+ else:
2863
+ click.echo(f" {yellow('⚠')} {label} {msg}")
2864
+
2865
+ click.echo()
2866
+
2867
+ if not no_browser:
2868
+ click.echo(dim(" Waiting for web UI..."))
2869
+ opened = wait_for_port_and_open_browser(url, host, port)
2870
+ if opened:
2871
+ click.echo(f" {green('✓')} Browser opened: {url}")
2872
+ else:
2873
+ click.echo(f" {yellow('⚠')} Server not responding yet — visit {url} manually")
2874
+ click.echo()
2875
+
2876
+ # ── Done ─────────────────────────────────────────────────────
2877
+ click.echo(bold(BAR))
2878
+ click.echo(bold(" Setup complete."))
2879
+ click.echo(bold(BAR))
2880
+ click.echo()
2881
+ if pmf_ok:
2882
+ click.echo(dim(" CDA starts automatically on every login via launchd."))
2883
+ click.echo(dim(" The watcher daemon keeps your session data in sync automatically."))
2884
+ click.echo(dim(f" Visit {url} any time to explore your data."))
2885
+ click.echo()
2886
+ click.echo(dim(" Useful commands:"))
2887
+ click.echo(dim(" cda check — full system health diagnostic"))
2888
+ click.echo(dim(" cda sync — re-ingest after significant new session activity"))
2889
+ click.echo(dim(" cda pmf services — view running services and their status"))
2890
+ click.echo(dim(" cda pmf uninstall — remove the auto-start LaunchAgent"))
2891
+ click.echo()
2892
+
2893
+
2649
2894
  # ─────────────────────────────────────────────
2650
2895
  # INIT
2651
2896
  # ─────────────────────────────────────────────
2652
2897
 
2653
2898
  @cli.command("init")
2654
2899
  def init():
2655
- """First-run setup — create ~/.cda/ directory structure and validate environment."""
2900
+ """First-run setup — create ~/Library/goCosmix/apps/code-data-ark/ directory structure and validate environment."""
2656
2901
  from cda.kernel.paths import (
2657
2902
  CDA_HOME, DATA_DIR, RUN_DIR, LOG_DIR, QUEUE_DIR,
2658
2903
  PMF_DIR, PMF_LOG_DIR, CONFIG_DIR, POLICY_FILE,
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.6] - 2026-05-11
9
+
10
+ ### Added
11
+ - **`~/Library/goCosmix/` home namespace** — all goCosmix apps share a unified `~/Library/goCosmix/` directory (macOS) or `~/.gocosmix/` (other). CDA now installs to `~/Library/goCosmix/apps/code-data-ark/` instead of `~/.cda/`. Provides a clean, organized home for all future goCosmix systems.
12
+ - **`GOCOSMIX_HOME`, `GOCOSMIX_APPS`, `GOCOSMIX_SYSTEM`** constants in `cda.kernel.paths` — shared namespace anchors for future goCosmix apps.
13
+ - **Auto PATH patching in `cda setup`** — detects where pip placed the `cda` binary and patches `~/.zprofile` if the bin dir is missing from PATH. Solves the macOS system Python `command not found` blocker.
14
+ - **`python3 -m cda` entry point** (`cda/__main__.py`) — bootstrapping fallback so users can run `python3 -m cda setup` before PATH is configured.
15
+ - **Legacy migration notice** — `cda setup` detects an existing `~/.cda/` and advises running `cda migrate-home`.
16
+
17
+ ### Changed
18
+ - `cda.kernel.paths.get_cda_home()` default changed from `~/.cda` to `~/Library/goCosmix/apps/code-data-ark` (macOS) / `~/.gocosmix/apps/code-data-ark` (other). `CDA_HOME` env var still overrides.
19
+ - `ensure_dirs()` now creates the full goCosmix namespace tree in addition to app-level dirs.
20
+ - README quickstart updated: install command is `python3 -m cda setup` as the safe default.
21
+ - `cda setup` Step 1 shows `+` for new dirs and `✓` for existing ones.
22
+
23
+ ## [2.0.5] - 2026-05-11
24
+
25
+ ### Added
26
+ - **`cda setup`** — master onboarding command: init → pmf install → sync → up. Replaces the four-step manual process with a single command. Idempotent, safe to re-run. Accepts `--skip-sync` and `--no-browser`.
27
+ - **PMF-first architecture**: all background processes (watcher, web UI) start exclusively through the PMF kernel. `cda watch start` and `cda ui start` now display an advisory if the LaunchAgent is not installed.
28
+ - `_pmf_warn_if_not_installed()` helper — emitted before any background service start when the LaunchAgent plist is absent.
29
+
30
+ ### Changed
31
+ - README quickstart simplified to two commands: `pip install code-data-ark` + `cda setup`
32
+ - Added PMF architecture diagram and process management reference to README
33
+
8
34
  ## [2.0.4] - 2026-05-11
9
35
 
10
36
  ### Added
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-data-ark"
7
- version = "2.0.4"
7
+ version = "2.0.6"
8
8
  description = "Code Data Ark — local observability and intelligence platform for VS Code + Copilot Chat sessions"
9
9
  readme = "readme.md"
10
10
  license = "MIT"
@@ -52,10 +52,17 @@ The runtime is managed by an embedded process kernel (PMF) that supervises the w
52
52
  pip install code-data-ark
53
53
  ```
54
54
 
55
+ > **macOS / system Python note**: pip installs the `cda` binary to `~/Library/Python/3.x/bin/` which is not on `PATH` by default. Use the fallback below — `cda setup` will fix PATH for you automatically:
56
+ >
57
+ > ```bash
58
+ > python3 -m cda setup
59
+ > ```
60
+
55
61
  ### Install with pipx
56
62
 
57
63
  ```bash
58
64
  pipx install code-data-ark
65
+ # pipx automatically manages PATH — `cda setup` works immediately
59
66
  ```
60
67
 
61
68
  ### Install from source
@@ -74,52 +81,73 @@ pip install -e ".[dev]"
74
81
  make install-dev
75
82
  ```
76
83
 
77
- > The `cda` console command is installed into your active Python environment's `bin` directory. Activate your virtual environment before running `cda`.
84
+ > The `cda` console command is installed into your Python environment's `bin` directory. If it isn't on PATH yet, use `python3 -m cda setup` — setup patches `~/.zprofile` automatically.
78
85
 
79
86
  ## ⚡ Quick Start
80
87
 
81
- 1. **Install**
82
-
83
88
  ```bash
84
89
  pip install code-data-ark
90
+ python3 -m cda setup # use this if `cda` isn't on PATH yet
85
91
  ```
86
92
 
87
- 2. **Initialize create `~/.cda/` and validate your VS Code data path**
93
+ After the first run, `cda setup` patches `~/.zprofile` so `cda` is on PATH in every new terminal.
88
94
 
89
- ```bash
90
- cda init
91
- ```
95
+ `cda setup` runs four steps in sequence:
96
+
97
+ | Step | What it does |
98
+ |------|-------------|
99
+ | **1. Init** | Creates `~/Library/goCosmix/apps/code-data-ark/` — all app data in one organized namespace. Also patches `~/.zprofile` if `cda` isn't on PATH yet. |
100
+ | **2. PMF install** | Registers a macOS LaunchAgent — CDA starts automatically on every login via `cda pmf up` |
101
+ | **3. Sync** | Ingests all VS Code + Copilot session data into `cda.db` |
102
+ | **4. Up** | Starts the watcher daemon and web UI via the PMF kernel, opens browser |
92
103
 
93
- 3. **Ingest all VS Code session data**
104
+ All data lives in `~/Library/goCosmix/apps/code-data-ark/`. After setup, everything is managed by the **PMF kernel** no terminal interaction required.
105
+
106
+ ### Options
94
107
 
95
108
  ```bash
96
- cda sync
109
+ cda setup --skip-sync # Skip initial ingest (run `cda sync` manually later)
110
+ cda setup --no-browser # Don't open browser when the UI starts
97
111
  ```
98
112
 
99
- 4. **Start the live watcher daemon**
113
+ ### After setup
100
114
 
101
115
  ```bash
102
- cda watch start
116
+ cda check # Full system health diagnostic
117
+ cda sync # Re-ingest after significant new session activity
118
+ cda pmf services # View all running services and their status
119
+ cda pmf uninstall # Remove the auto-start LaunchAgent registration
103
120
  ```
104
121
 
105
- 5. **Open the web dashboard**
122
+ ## 🔧 Process Management (PMF)
106
123
 
107
- ```bash
108
- cda serve # → http://127.0.0.1:10001
124
+ All background processes run through the embedded PMF kernel. The LaunchAgent is the entry point — nothing starts directly on the host outside of PMF.
125
+
126
+ ```
127
+ launchd (login)
128
+ └─ cda pmf up
129
+ ├─ PMF kernel → watcher daemon (cda.pipeline.watcher)
130
+ └─ PMF kernel → web UI server (cda.ui.web)
109
131
  ```
110
132
 
111
- 6. **Build semantic intelligence** (optional, requires `sentence-transformers`)
133
+ ### PMF commands
112
134
 
113
135
  ```bash
114
- cda embed build
136
+ cda pmf services # List all services with status and PID
137
+ cda pmf start <service> # Start a service (watcher, ui, sync, reconstruct, embed-build)
138
+ cda pmf stop <service> # Stop a service
139
+ cda pmf restart <service> # Restart a service
140
+ cda pmf logs <service> # Tail the service log
141
+ cda pmf up # Start watcher + UI (opens browser) — same as launchd trigger
142
+ cda pmf install # Register LaunchAgent (done automatically by cda setup)
143
+ cda pmf uninstall # Remove LaunchAgent
115
144
  ```
116
145
 
117
146
  ## 🌐 Web UI
118
147
 
119
- - **Background service**: `cda ui start`
120
- - **Stop service**: `cda ui stop`
121
- - **Service status**: `cda ui status`
122
- - **Foreground mode**: `cda serve`
148
+ - **Background service** (default after setup): managed by PMF, starts on login
149
+ - **Foreground mode**: `cda serve` — runs in the terminal, opens browser, Ctrl+C to stop
150
+ - **Access**: `http://127.0.0.1:10001`
123
151
 
124
152
  The web UI includes:
125
153
 
@@ -0,0 +1 @@
1
+ 2.0.6
@@ -1 +0,0 @@
1
- 2.0.4
File without changes
File without changes
File without changes
File without changes