code-context-control 2.46.0__py3-none-any.whl → 2.46.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.
cli/c3.py CHANGED
@@ -85,7 +85,7 @@ console = Console() if HAS_RICH else None
85
85
  # Config
86
86
  CONFIG_DIR = ".c3"
87
87
  CONFIG_FILE = ".c3/config.json"
88
- __version__ = "2.46.0"
88
+ __version__ = "2.46.1"
89
89
 
90
90
 
91
91
  def _command_deps() -> CommandDeps:
cli/tools/compress.py CHANGED
@@ -8,9 +8,8 @@ import sys
8
8
  from concurrent.futures import ThreadPoolExecutor, as_completed
9
9
  from pathlib import Path
10
10
 
11
- from core import count_tokens
12
-
13
11
  from cli.tools._helpers import finalize_with_tokens, show_token_ratios
12
+ from core import count_tokens
14
13
 
15
14
 
16
15
  def _run_memory_mcp_cli(args: list, cwd: str, timeout: int = 30) -> tuple:
cli/tools/federate.py CHANGED
@@ -7,7 +7,6 @@ unions child facts. Results stay in per-scope sections — TF-IDF scores are
7
7
  not comparable across corpora, so no interleaved ranking.
8
8
  """
9
9
 
10
- from pathlib import Path
11
10
 
12
11
  # Budget split for scope='all': the parent keeps the lion's share.
13
12
  _PARENT_BUDGET_SHARE = 0.6
cli/tools/filter.py CHANGED
@@ -10,9 +10,8 @@ import json
10
10
  import re
11
11
  from pathlib import Path
12
12
 
13
- from core import count_tokens
14
-
15
13
  from cli.tools._helpers import finalize_with_tokens, show_token_ratios
14
+ from core import count_tokens
16
15
 
17
16
 
18
17
  def handle_filter(file_path: str, text: str, pattern: str, max_lines: int,
cli/tools/read.py CHANGED
@@ -6,9 +6,8 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
6
6
  from pathlib import Path
7
7
  from typing import Any
8
8
 
9
- from core import count_tokens
10
-
11
9
  from cli.tools._helpers import finalize_with_tokens
10
+ from core import count_tokens
12
11
 
13
12
 
14
13
  def _coerce_list(val: Any) -> list[str] | None:
cli/tools/search.py CHANGED
@@ -5,9 +5,8 @@ import time
5
5
  from concurrent.futures import ThreadPoolExecutor, as_completed
6
6
  from pathlib import Path
7
7
 
8
- from core import count_tokens
9
-
10
8
  from cli.tools._helpers import finalize_with_tokens, show_token_ratios
9
+ from core import count_tokens
11
10
 
12
11
  # Hard cap: responses above this are truncated to avoid filling context.
13
12
  _RESPONSE_TOKEN_CAP = 2400
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.46.0
3
+ Version: 2.46.1
4
4
  Summary: Local code-intelligence layer for AI coding tools (Claude Code, Codex, Gemini, Copilot). Retrieve less, read less, edit safer — and version the configs that shape your agent (CLAUDE.md, skills, hooks, MCP).
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  cli/__init__.py,sha256=ec66drCZGNMRU4V6ov0zVhYZph1us12Vn8OvG_LJyRY,22
2
2
  cli/_hook_utils.py,sha256=zlquaQm0dvwdaZewD6YnFyF_LBzhmfFUUhL_8UbBKGA,11749
3
- cli/c3.py,sha256=DvhSlvy2rI6L11_vEoL5J0tinVXjxmbOV7sSU_TdrVs,304129
3
+ cli/c3.py,sha256=Sx8ySlKiRJsdWwmBjhzaca8gEOWE4CLHangvpeRiGek,304129
4
4
  cli/docs.html,sha256=CC_-4PaQxfjNXbcqcVuU5rzdbP1NosYJxFRiXZV4joI,143645
5
5
  cli/edits.html,sha256=UjAhoCmBmQ89cklGvJqzC6eyNP2tc8H6T-e01DVkLvE,43418
6
6
  cli/hook_artifact.py,sha256=Se1CNBfoBFyvJQlRmYdNtdRXIkQp9zaF0O6ndRMo7ts,2198
@@ -61,17 +61,17 @@ cli/tools/_helpers.py,sha256=lv6Bxeh_pseDXCJ4trKn0cpzPSxdb7AYjMmtSrjqkbQ,5858
61
61
  cli/tools/agent.py,sha256=fdt5kmw9O-AEKlYaij-PPmCJ4sI7bmdej56V4NGWaqI,48145
62
62
  cli/tools/artifacts.py,sha256=98shRIs3cdC8r0E1gfsEOIDUopqSP1WpYwzFiWfdtg0,7491
63
63
  cli/tools/bitbucket.py,sha256=_hgORCW9-IF5xZJaznoONVfaTGKaX8VcU7ALrBeLhWo,27518
64
- cli/tools/compress.py,sha256=XuhxebMGyWNqysZs4V17F8IN6b4tkmq52aUXXkMOADM,10061
64
+ cli/tools/compress.py,sha256=aZ4owwqaQLtkszDr_g7yv5KkvtQPuqaSyMk-aM_hsCY,10060
65
65
  cli/tools/delegate.py,sha256=mwsEUsPXlC1ldkhhSk-i4_JUMsXy9ptIwlYV2_-kOoI,53812
66
66
  cli/tools/edit.py,sha256=GB3qdMhWEly4TYyU-P66Uqe87Nw6ZBzH-9ZO6_Q64t4,16604
67
67
  cli/tools/edits.py,sha256=8zM01TzLmjm7ULQlCmXOmitlJd84zQHVzE0z7UHJUdA,5520
68
- cli/tools/federate.py,sha256=PTjYVTHHZfKfWiW9t9bi4IiKFISkPocgj1bSCy_JSXQ,4675
69
- cli/tools/filter.py,sha256=KzBMbKLlWpFt3wIgD9BuFctoP28ztyxCQFa8nGcR1Aw,12084
68
+ cli/tools/federate.py,sha256=wmC2QN7A6aay3cT7U9LDPYRCZKL1m_T6qFdZzpZmPx4,4650
69
+ cli/tools/filter.py,sha256=_yhjOncC1kb-aRxjT7pkSILcMC-yXarBMh7oNS057rQ,12083
70
70
  cli/tools/impact.py,sha256=jjWkFTxHu-gBpZZNd2HTdBl22itA6-wwwOZXxk_qBl8,6257
71
71
  cli/tools/memory.py,sha256=yDDRsEngeFcjb6nXUrhRZXuboasXfixJeyltKhDbZD4,24935
72
72
  cli/tools/project.py,sha256=_2a2Rjw2xwbE-muJtH28uT7vjnPGQLGDDXbhmDO6Gh0,16407
73
- cli/tools/read.py,sha256=o-3BzUPHpR35sk34FF0YEYw8-fFp6_u9hMgya5cWLXg,12351
74
- cli/tools/search.py,sha256=CahWN9NbsD2A7z7okYnUlZlncteujLDXENFq3_3pL1U,14681
73
+ cli/tools/read.py,sha256=Lp-JCBToro1stV6tKrnKHLQA-K0x4eMM_L3QrNq7VHw,12350
74
+ cli/tools/search.py,sha256=6rsqZMaa11-5cmf75KtGwB5pn-fNq66hRT_1ffxEI-A,14680
75
75
  cli/tools/session.py,sha256=LIZbmEhNdh6rAsT6Dbpb21UY8xF9oubvpjGwfnXxQK4,4573
76
76
  cli/tools/shell.py,sha256=vGsvzQLISo-daKF40ZhRJXS5lDA6OV1t9RWoyqdlpt4,12617
77
77
  cli/tools/status.py,sha256=mK2840JMQkJkbHGQU0f2Epr-vmkXwQKUzqmMVeOYu-0,14913
@@ -93,7 +93,7 @@ cli/ui/components/sessions.js,sha256=FIKtil76B8tCkAmcFV7hlj6GQ_DCJK2jCzvEmdK7NBE
93
93
  cli/ui/components/settings.js,sha256=8LVTV2TQl9tcRXhXbtBEJOCBdiyk-x2QASoVYZUAuEA,71442
94
94
  cli/ui/components/sidebar.js,sha256=cAY_jwYB-o1X_wWn__VXlG4IegVObuE3NmVsuFWqxtg,7417
95
95
  cli/ui/components/tasks.js,sha256=OxLhspzzEQjxxtSEpOpugO2KptD4xNrimf_xM0wiVv8,12752
96
- code_context_control-2.46.0.dist-info/licenses/LICENSE,sha256=l8Kh5QCNWNvR6kIt8L0BUZvc2LAFiHv2c-FnsGnUZf4,11301
96
+ code_context_control-2.46.1.dist-info/licenses/LICENSE,sha256=l8Kh5QCNWNvR6kIt8L0BUZvc2LAFiHv2c-FnsGnUZf4,11301
97
97
  core/__init__.py,sha256=TSDCEcM4V7gcZVM3w2ykJaqEUch4Dkon-rivV17T73s,2501
98
98
  core/config.py,sha256=9R8bIcHhjSPdrfcCeMPnS4YgLCyRNWwlt_Z75PZcBDE,14780
99
99
  core/ide.py,sha256=9LzsDVK2LL8RVpL40l6oNGiasZ3D8OCU_9i9A0gJKBo,6876
@@ -126,7 +126,7 @@ services/activity_log.py,sha256=PNGeEYlw1Aux-mRU4pKCQdbsSuzLvOg7MYiq-cb4n8g,4473
126
126
  services/agent_base.py,sha256=a-gdSd_jtZtbjXo1WS8CnWCagXgKaGZd5ShcG6s0kT4,4809
127
127
  services/agents.py,sha256=zwbnRjvKo9tEC2g-HK2KW-uy1r6g_5GSehDZHstcMEk,79613
128
128
  services/artifact_defs.py,sha256=PxBPrhD6raU2HcesZvwgq_Nw4EvqJaVcczw2mcqOe-Q,9355
129
- services/artifact_store.py,sha256=qI4W9NKS7Z5o-nOmCYbXklJguelh2Ufm-5D8S7Yxs_s,28081
129
+ services/artifact_store.py,sha256=PAkirolhn6z-agr-V7aJgezfJFHeR5oAjmqC4FBA3yA,28081
130
130
  services/auto_memory.py,sha256=v__ZS1e68533_Yv491mZtvuZnheC63q6_uTvWhBw3Lw,14290
131
131
  services/benchmark_dashboard.py,sha256=iR-DnqnoKbqHMJ4d-ZkIvJBYfzwTa7r-jzO6j2BYDfQ,27711
132
132
  services/bitbucket_client.py,sha256=JByovvtVZ6F4NcU611KVuTgKlT1rIsX2A2VlBDfvRV8,17509
@@ -164,12 +164,12 @@ services/proxy_state.py,sha256=u5rd0k6CrOsywZA8FpRu_hMLwhR0TAJhZjy5MdWbCGc,6107
164
164
  services/retention.py,sha256=I2_RV233kWBBXox5rc_w-1h1aPua93o9huuPf-pJVuE,18629
165
165
  services/retrieval_broker.py,sha256=9X67VZ_6AkbAzopHuuMFKmP4CGZLnW576kjSKMenBnw,5261
166
166
  services/router.py,sha256=Cz10nx2fKTbaGn14mSBePWIDrw5rdcs_1JFYXeik084,15626
167
- services/runtime.py,sha256=cR4hYYauNF6BE7SjbmXfpj4fCdWfX5H4bE2Fi4oiEXg,12094
167
+ services/runtime.py,sha256=RI_xvNx2SoO5PKJmGwYMPQK8QYcCqwX8DNzaFRQ9ngM,12094
168
168
  services/session_benchmark.py,sha256=GX3H8OwKC0X9Kk5U-vfY6Y7qq9Qaz2HwadNA7mjO8RY,105047
169
169
  services/session_manager.py,sha256=qUo7ool6dDWXfVgFpokIRcWqkWh10OzMcp7aZTdmTHY,51632
170
170
  services/session_preloader.py,sha256=DsTAXMKVtrX9yu1sEFojYDi9-jkSAj1Ylt9JTy57Dow,9883
171
- services/subprojects.py,sha256=xkW0okEWuYyF4m2dZxeHdbCxn6VdvM4_68zo360TNbs,24779
172
- services/task_store.py,sha256=XWdWhBhIghsEDOiwUHdCfH2co4mmi6CQ48vCxau9RQ4,24743
171
+ services/subprojects.py,sha256=DxD-3f4wCrwAg7F8znbvWFJf_lizgmulVDqozKGSztI,24965
172
+ services/task_store.py,sha256=DHDLsmiH-92mmAvH5Q0AKa_8kqwMupZvxu3mWVZ_FLo,24742
173
173
  services/telemetry.py,sha256=KbWCe7F8lGY9DufVPWGyGFo-IBcPgWh0kd3ySJnIgFE,11377
174
174
  services/text_index.py,sha256=r3o4CobTG9jAO9PWazgbWYLY9oi_FgEJ3xwEXrF4KM0,2783
175
175
  services/tool_classifier.py,sha256=Fgvq0ZcpnCskwtO8a3YI1MiecPNnw6UbPyJQIUwgfiQ,6512
@@ -200,8 +200,8 @@ tui/screens/search_view.py,sha256=MMHjVdlk3HZSuDBSvq8IGrqv_Mh5Us6YqXQ80bcWSMk,19
200
200
  tui/screens/session_view.py,sha256=eZ1eDwHTvPOck1wCCviixtOaCxIkBT_95ytNNNriGNA,5991
201
201
  tui/screens/stats.py,sha256=p81PjzdaIv7hllb8f45-rlVe4lJZwSdIMqu7e86_u5s,6223
202
202
  tui/screens/ui_view.py,sha256=1QJCgLh2YfgWIpvzRG1KOGXYEaOYX6ojN61Azjf2oX0,2125
203
- code_context_control-2.46.0.dist-info/METADATA,sha256=cqDwpwwRowe-Ieeg5s2Ql2900KcOpdzNkv2Wg9pQrd0,23785
204
- code_context_control-2.46.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
205
- code_context_control-2.46.0.dist-info/entry_points.txt,sha256=7kX_WUsDCF2hbXzvbNyscyaBb9AeA-DJY5v_5hN0DlU,93
206
- code_context_control-2.46.0.dist-info/top_level.txt,sha256=wRt41zBybVF3qAiNXHz9BURbkKvUvfhmWWtKMhaw6eE,29
207
- code_context_control-2.46.0.dist-info/RECORD,,
203
+ code_context_control-2.46.1.dist-info/METADATA,sha256=Gqn5nbiiyphjNm0oz2ohgTxveh5KQyzUDVd14POqUxw,23785
204
+ code_context_control-2.46.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
205
+ code_context_control-2.46.1.dist-info/entry_points.txt,sha256=7kX_WUsDCF2hbXzvbNyscyaBb9AeA-DJY5v_5hN0DlU,93
206
+ code_context_control-2.46.1.dist-info/top_level.txt,sha256=wRt41zBybVF3qAiNXHz9BURbkKvUvfhmWWtKMhaw6eE,29
207
+ code_context_control-2.46.1.dist-info/RECORD,,
@@ -32,9 +32,9 @@ from typing import Optional
32
32
 
33
33
  from services.artifact_defs import (
34
34
  ArtifactUnit,
35
+ _norm,
35
36
  classify_path,
36
37
  discover_units,
37
- _norm,
38
38
  )
39
39
 
40
40
  SCHEMA_VERSION = 1
services/runtime.py CHANGED
@@ -13,6 +13,7 @@ from core.config import load_delegate_config, load_hybrid_config
13
13
  from core.ide import get_profile, load_ide_config
14
14
  from services.activity_log import ActivityLog
15
15
  from services.agents import create_agents
16
+ from services.artifact_store import ArtifactStore
16
17
  from services.claude_md import ClaudeMdManager
17
18
  from services.compressor import CodeCompressor
18
19
  from services.context_snapshot import ContextSnapshot
@@ -39,7 +40,6 @@ from services.session_preloader import SessionPreloader
39
40
  from services.task_store import TaskStore
40
41
  from services.validation_cache import ValidationCache
41
42
  from services.vector_store import VectorStore
42
- from services.artifact_store import ArtifactStore
43
43
  from services.watcher import CodeWatcher
44
44
 
45
45
 
services/subprojects.py CHANGED
@@ -80,7 +80,7 @@ def get_subprojects(parent_path) -> list:
80
80
  # ── Index-exclusion helpers (hot path for indexer/doc_index/watcher) ──────
81
81
 
82
82
  def exclusion_prefixes(project_path) -> list:
83
- """Normcased path-part tuples for designated sub-project folders.
83
+ """Lowercased path-part tuples for designated sub-project folders.
84
84
 
85
85
  Fast path: ``[]`` when the project has no sub-projects, so scan loops
86
86
  pay nothing in the common case.
@@ -91,7 +91,7 @@ def exclusion_prefixes(project_path) -> list:
91
91
  prefixes = []
92
92
  for entry in subs:
93
93
  rel = entry.get("rel_path") or ""
94
- parts = tuple(os.path.normcase(p) for p in PurePosixPath(rel).parts)
94
+ parts = tuple(p.lower() for p in PurePosixPath(rel).parts)
95
95
  if parts:
96
96
  prefixes.append(parts)
97
97
  return prefixes
@@ -101,7 +101,7 @@ def is_excluded(rel_parts, prefixes) -> bool:
101
101
  """True when a project-relative path (as parts) sits under any prefix."""
102
102
  if not prefixes:
103
103
  return False
104
- normed = tuple(os.path.normcase(p) for p in rel_parts)
104
+ normed = tuple(p.lower() for p in rel_parts)
105
105
  return any(normed[: len(pre)] == pre for pre in prefixes)
106
106
 
107
107
 
@@ -116,8 +116,11 @@ def make_excluder(project_path):
116
116
  root = Path(project_path).resolve()
117
117
 
118
118
  def _excluded(fpath) -> bool:
119
+ # Resolve fpath too: callers may pass paths through a symlink
120
+ # (macOS /var/folders) or an 8.3 short name (Windows), which would
121
+ # never be relative to the resolved root.
119
122
  try:
120
- return is_excluded(Path(fpath).relative_to(root).parts, prefixes)
123
+ return is_excluded(Path(fpath).resolve().relative_to(root).parts, prefixes)
121
124
  except (ValueError, OSError):
122
125
  return False
123
126
 
services/task_store.py CHANGED
@@ -288,7 +288,7 @@ class TaskStore:
288
288
  def purge_archived(self, entity="task") -> dict:
289
289
  key = {"task": "tasks", "milestone": "milestones", "note": "notes"}.get(entity)
290
290
  if not key:
291
- return {"error": f"entity must be task|milestone|note"}
291
+ return {"error": "entity must be task|milestone|note"}
292
292
  with self._lock:
293
293
  doc = self._load()
294
294
  before = len(doc[key])