cycode 3.17.1.dev11__py3-none-any.whl → 3.17.2.dev1__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.
- cycode/__init__.py +1 -1
- cycode/cli/apps/ai_guardrails/ides/__init__.py +19 -0
- cycode/cli/apps/ai_guardrails/ides/_plugin_utils.py +16 -0
- cycode/cli/apps/ai_guardrails/ides/claude_code.py +18 -8
- cycode/cli/apps/ai_guardrails/ides/codex.py +4 -13
- cycode/cli/apps/ai_guardrails/session_start_command.py +79 -22
- cycode/cyclient/ai_security_manager_client.py +6 -4
- {cycode-3.17.1.dev11.dist-info → cycode-3.17.2.dev1.dist-info}/METADATA +1 -1
- {cycode-3.17.1.dev11.dist-info → cycode-3.17.2.dev1.dist-info}/RECORD +12 -12
- {cycode-3.17.1.dev11.dist-info → cycode-3.17.2.dev1.dist-info}/WHEEL +0 -0
- {cycode-3.17.1.dev11.dist-info → cycode-3.17.2.dev1.dist-info}/entry_points.txt +0 -0
- {cycode-3.17.1.dev11.dist-info → cycode-3.17.2.dev1.dist-info}/licenses/LICENCE +0 -0
cycode/__init__.py
CHANGED
|
@@ -5,4 +5,4 @@ import time as _time
|
|
|
5
5
|
# end-to-end scan duration from the moment the user actually triggered it.
|
|
6
6
|
_BOOT_WALL: float = _time.time()
|
|
7
7
|
|
|
8
|
-
__version__ = '3.17.
|
|
8
|
+
__version__ = '3.17.2.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -34,6 +34,25 @@ def get_ide(name: str) -> IDE:
|
|
|
34
34
|
return ide
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
def collect_all_session_contexts() -> tuple[dict[str, dict], dict]:
|
|
38
|
+
"""Sweep every registered IDE's session context, regardless of which IDE triggered the hook.
|
|
39
|
+
|
|
40
|
+
Returns ``(config_files_by_ide, plugins)``: the global MCP config file of each IDE that has
|
|
41
|
+
one (keyed by IDE name), and the enabled plugins merged across IDEs (first registered IDE
|
|
42
|
+
wins on a duplicate plugin key - plugins are IDE-agnostic marketplace artifacts).
|
|
43
|
+
"""
|
|
44
|
+
config_files_by_ide: dict[str, dict] = {}
|
|
45
|
+
plugins: dict = {}
|
|
46
|
+
for ide in IDES.values():
|
|
47
|
+
global_config_file, enabled_plugins = ide.get_session_context()
|
|
48
|
+
if global_config_file:
|
|
49
|
+
config_files_by_ide[ide.name] = global_config_file
|
|
50
|
+
for plugin_key, plugin in (enabled_plugins or {}).items():
|
|
51
|
+
plugins.setdefault(plugin_key, plugin)
|
|
52
|
+
|
|
53
|
+
return config_files_by_ide, plugins
|
|
54
|
+
|
|
55
|
+
|
|
37
56
|
def resolve_ides(name: str) -> list[IDE]:
|
|
38
57
|
"""Resolve an ``--ide`` argument to one or all IDE instances.
|
|
39
58
|
|
|
@@ -15,6 +15,22 @@ from cycode.logger import get_logger
|
|
|
15
15
|
logger = get_logger('AI Guardrails Plugins')
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
def resolve_cached_plugin_dir(cache_root: Path, marketplace: str, plugin_name: str) -> Optional[Path]:
|
|
19
|
+
"""Find ``<cache_root>/<marketplace>/<plugin>/<version-or-hash>/``.
|
|
20
|
+
|
|
21
|
+
Both Claude Code and Codex cache installed plugin content in this layout (the trailing
|
|
22
|
+
segment is a version for Claude, a content hash for Codex). If multiple are cached, pick
|
|
23
|
+
the most recently modified (name as a deterministic tie-breaker).
|
|
24
|
+
"""
|
|
25
|
+
base = cache_root / marketplace / plugin_name
|
|
26
|
+
if not base.is_dir():
|
|
27
|
+
return None
|
|
28
|
+
candidates = [d for d in base.iterdir() if d.is_dir()]
|
|
29
|
+
if not candidates:
|
|
30
|
+
return None
|
|
31
|
+
return max(candidates, key=lambda d: (d.stat().st_mtime, d.name))
|
|
32
|
+
|
|
33
|
+
|
|
18
34
|
def load_plugin_json(path: Path) -> Optional[dict]:
|
|
19
35
|
"""Load a JSON file inside a plugin directory; None if missing or invalid."""
|
|
20
36
|
if not path.exists():
|
|
@@ -10,6 +10,7 @@ from cycode.cli.apps.ai_guardrails.consts import CYCODE_SCAN_PROMPT_COMMAND, CYC
|
|
|
10
10
|
from cycode.cli.apps.ai_guardrails.ides._plugin_utils import (
|
|
11
11
|
build_global_config_file,
|
|
12
12
|
load_plugin_json,
|
|
13
|
+
resolve_cached_plugin_dir,
|
|
13
14
|
walk_enabled_plugins,
|
|
14
15
|
)
|
|
15
16
|
from cycode.cli.apps.ai_guardrails.ides.base import IDE, DecisionAction, HookDecision
|
|
@@ -164,6 +165,11 @@ def load_claude_settings(settings_path: Optional[Path] = None) -> Optional[dict]
|
|
|
164
165
|
return None
|
|
165
166
|
|
|
166
167
|
|
|
168
|
+
def _plugins_cache_dir() -> Path:
|
|
169
|
+
"""Claude Code's local plugin content cache: ``~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/``."""
|
|
170
|
+
return Path.home() / '.claude' / 'plugins' / 'cache'
|
|
171
|
+
|
|
172
|
+
|
|
167
173
|
def _resolve_marketplace_path(marketplace: dict) -> Optional[Path]:
|
|
168
174
|
"""Resolve filesystem path for a directory-type marketplace."""
|
|
169
175
|
source = marketplace.get('source', {})
|
|
@@ -194,25 +200,29 @@ def _read_claude_plugin(plugin_dir: Path) -> tuple[dict, dict]:
|
|
|
194
200
|
if servers:
|
|
195
201
|
entry['mcp_server_names'] = list(servers.keys())
|
|
196
202
|
entry['mcp_config_file_path'] = str(mcp_config_path)
|
|
197
|
-
entry['mcp_config_file'] = json.dumps(
|
|
203
|
+
entry['mcp_config_file'] = json.dumps({'mcpServers': servers})
|
|
198
204
|
return entry, servers
|
|
199
205
|
|
|
200
206
|
|
|
201
207
|
def resolve_plugins(settings: dict) -> dict:
|
|
202
208
|
"""Walk Claude Code's ``enabledPlugins`` via the shared plugin walker.
|
|
203
209
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
(manifest + ``.mcp.json``) is the shared ``_read_claude_plugin``.
|
|
210
|
+
Directory-type marketplaces resolve through ``extraKnownMarketplaces``; all
|
|
211
|
+
other source types (git, github, ...) resolve through the local plugin cache.
|
|
212
|
+
The rest of the work (manifest + ``.mcp.json``) is the shared ``_read_claude_plugin``.
|
|
207
213
|
"""
|
|
208
214
|
enabled = settings.get('enabledPlugins') or {}
|
|
209
215
|
marketplaces = settings.get('extraKnownMarketplaces') or {}
|
|
210
216
|
|
|
211
|
-
def _locate(
|
|
217
|
+
def _locate(plugin_name: str, marketplace_name: str) -> Optional[Path]:
|
|
218
|
+
# Directory-type marketplaces point straight at the plugin source; every other source
|
|
219
|
+
# type (git, github, ...) is cloned into the local plugin cache.
|
|
212
220
|
marketplace = marketplaces.get(marketplace_name)
|
|
213
|
-
if
|
|
214
|
-
|
|
215
|
-
|
|
221
|
+
if marketplace:
|
|
222
|
+
marketplace_path = _resolve_marketplace_path(marketplace)
|
|
223
|
+
if marketplace_path is not None:
|
|
224
|
+
return marketplace_path
|
|
225
|
+
return resolve_cached_plugin_dir(_plugins_cache_dir(), marketplace_name, plugin_name)
|
|
216
226
|
|
|
217
227
|
return walk_enabled_plugins(
|
|
218
228
|
plugin_entries=enabled,
|
|
@@ -17,6 +17,7 @@ from cycode.cli.apps.ai_guardrails.consts import CYCODE_SCAN_PROMPT_COMMAND, CYC
|
|
|
17
17
|
from cycode.cli.apps.ai_guardrails.ides._plugin_utils import (
|
|
18
18
|
build_global_config_file,
|
|
19
19
|
load_plugin_json,
|
|
20
|
+
resolve_cached_plugin_dir,
|
|
20
21
|
walk_enabled_plugins,
|
|
21
22
|
)
|
|
22
23
|
from cycode.cli.apps.ai_guardrails.ides.base import IDE, DecisionAction, HookDecision
|
|
@@ -100,18 +101,8 @@ def _email_from_auth(auth_path: Optional[Path] = None) -> Optional[str]:
|
|
|
100
101
|
|
|
101
102
|
|
|
102
103
|
def _resolve_codex_plugin_dir(plugin_name: str, marketplace: str) -> Optional[Path]:
|
|
103
|
-
"""Find ``~/.codex/plugins/cache/<marketplace>/<plugin>/<hash>/``.
|
|
104
|
-
|
|
105
|
-
The trailing segment is a content hash. If multiple are cached, pick the
|
|
106
|
-
most recently modified.
|
|
107
|
-
"""
|
|
108
|
-
base = _codex_home() / 'plugins' / 'cache' / marketplace / plugin_name
|
|
109
|
-
if not base.is_dir():
|
|
110
|
-
return None
|
|
111
|
-
candidates = [d for d in base.iterdir() if d.is_dir()]
|
|
112
|
-
if not candidates:
|
|
113
|
-
return None
|
|
114
|
-
return max(candidates, key=lambda d: d.stat().st_mtime)
|
|
104
|
+
"""Find ``~/.codex/plugins/cache/<marketplace>/<plugin>/<hash>/``."""
|
|
105
|
+
return resolve_cached_plugin_dir(_codex_home() / 'plugins' / 'cache', marketplace, plugin_name)
|
|
115
106
|
|
|
116
107
|
|
|
117
108
|
def _read_codex_plugin(plugin_dir: Path) -> tuple[dict, dict]:
|
|
@@ -141,7 +132,7 @@ def _read_codex_plugin(plugin_dir: Path) -> tuple[dict, dict]:
|
|
|
141
132
|
if servers:
|
|
142
133
|
entry['mcp_server_names'] = list(servers.keys())
|
|
143
134
|
entry['mcp_config_file_path'] = str(mcp_config_path)
|
|
144
|
-
entry['mcp_config_file'] = json.dumps(
|
|
135
|
+
entry['mcp_config_file'] = json.dumps({'mcpServers': servers})
|
|
145
136
|
return entry, servers
|
|
146
137
|
|
|
147
138
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""Handle AI guardrails session start: auth, conversation creation, session context."""
|
|
2
2
|
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
3
5
|
import sys
|
|
6
|
+
import time
|
|
7
|
+
from pathlib import Path
|
|
4
8
|
from typing import TYPE_CHECKING, Annotated, Optional
|
|
5
9
|
|
|
6
10
|
import typer
|
|
7
11
|
|
|
8
|
-
from cycode.cli.apps.ai_guardrails.ides import DEFAULT_IDE_NAME, get_ide
|
|
9
|
-
from cycode.cli.apps.ai_guardrails.ides.base import IDE
|
|
12
|
+
from cycode.cli.apps.ai_guardrails.ides import DEFAULT_IDE_NAME, collect_all_session_contexts, get_ide
|
|
10
13
|
from cycode.cli.apps.ai_guardrails.scan.utils import read_stdin_text, safe_json_parse
|
|
11
14
|
from cycode.cli.apps.auth.auth_common import get_authorization_info
|
|
12
15
|
from cycode.cli.apps.auth.auth_manager import AuthManager
|
|
@@ -26,23 +29,76 @@ if TYPE_CHECKING:
|
|
|
26
29
|
|
|
27
30
|
logger = get_logger('AI Guardrails')
|
|
28
31
|
|
|
32
|
+
_SESSION_CONTEXT_CACHE_FILE = '.session-context-cache'
|
|
33
|
+
_SESSION_CONTEXT_TTL_SECONDS = 7 * 24 * 60 * 60
|
|
29
34
|
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
|
|
36
|
+
def _session_context_cache_path() -> Path:
|
|
37
|
+
return Path.home() / '.cycode' / _SESSION_CONTEXT_CACHE_FILE
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _session_context_digest(report: dict) -> str:
|
|
41
|
+
"""Deterministic hash of the outgoing payload (not the raw config files, which churn)."""
|
|
42
|
+
canonical = json.dumps(report, sort_keys=True, separators=(',', ':'), default=str)
|
|
43
|
+
return hashlib.sha256(canonical.encode('utf-8')).hexdigest()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _should_skip_report(digest: str, tenant_id: Optional[str]) -> bool:
|
|
47
|
+
"""Skip when the same payload was already sent for this tenant and the TTL hasn't expired."""
|
|
32
48
|
try:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
cache = json.loads(_session_context_cache_path().read_text(encoding='utf-8'))
|
|
50
|
+
return (
|
|
51
|
+
cache.get('hash') == digest
|
|
52
|
+
and cache.get('tenant_id') == tenant_id
|
|
53
|
+
and time.time() - float(cache.get('sent_at', 0)) < _SESSION_CONTEXT_TTL_SECONDS
|
|
54
|
+
)
|
|
55
|
+
except Exception:
|
|
56
|
+
# Missing/corrupt cache reads as a miss - over-sending is harmless
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _save_report_cache(digest: str, tenant_id: Optional[str]) -> None:
|
|
61
|
+
try:
|
|
62
|
+
cache_path = _session_context_cache_path()
|
|
63
|
+
cache_path.parent.mkdir(parents=True, exist_ok=True)
|
|
64
|
+
cache_path.write_text(
|
|
65
|
+
json.dumps({'hash': digest, 'tenant_id': tenant_id, 'sent_at': time.time()}), encoding='utf-8'
|
|
45
66
|
)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
logger.debug('Failed to write session context cache', exc_info=e)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _report_session_context(
|
|
72
|
+
ai_client: 'AISecurityManagerClient',
|
|
73
|
+
user_email: Optional[str],
|
|
74
|
+
tenant_id: Optional[str],
|
|
75
|
+
) -> None:
|
|
76
|
+
"""Report the device + cross-IDE session context to the AI security manager. Never raises.
|
|
77
|
+
|
|
78
|
+
The device context is always reported. MCP configs are collected from every registered IDE,
|
|
79
|
+
not just the triggering one. Unchanged payloads are skipped via a hash cache until the TTL expires.
|
|
80
|
+
"""
|
|
81
|
+
try:
|
|
82
|
+
config_files_by_ide, enabled_plugins = collect_all_session_contexts()
|
|
83
|
+
report = {
|
|
84
|
+
'hostname': get_hostname(),
|
|
85
|
+
'platform_name': get_platform_name(),
|
|
86
|
+
'os_version': get_os_version(),
|
|
87
|
+
'serial_number': get_serial_number(),
|
|
88
|
+
'last_login_user': get_last_login_user(),
|
|
89
|
+
# Sorted by path so the digest is stable regardless of IDE registry order.
|
|
90
|
+
'config_files': sorted(config_files_by_ide.values(), key=lambda f: f['path']),
|
|
91
|
+
'enabled_plugins': enabled_plugins,
|
|
92
|
+
'user_email': user_email,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
digest = _session_context_digest(report)
|
|
96
|
+
if _should_skip_report(digest, tenant_id):
|
|
97
|
+
logger.debug('Session context unchanged; skipping report')
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
if ai_client.report_session_context(**report):
|
|
101
|
+
_save_report_cache(digest, tenant_id)
|
|
46
102
|
except Exception as e:
|
|
47
103
|
logger.debug('Failed to report session context', exc_info=e)
|
|
48
104
|
|
|
@@ -61,7 +117,7 @@ def session_start_command(
|
|
|
61
117
|
"""Handle session start: ensure auth, create conversation, report session context."""
|
|
62
118
|
ide_integration = get_ide(ide)
|
|
63
119
|
|
|
64
|
-
#
|
|
120
|
+
# Ensure authentication
|
|
65
121
|
auth_info = get_authorization_info(ctx)
|
|
66
122
|
if auth_info is None:
|
|
67
123
|
logger.debug('Not authenticated, starting authentication')
|
|
@@ -70,10 +126,11 @@ def session_start_command(
|
|
|
70
126
|
except Exception as err:
|
|
71
127
|
handle_auth_exception(ctx, err)
|
|
72
128
|
return
|
|
129
|
+
auth_info = get_authorization_info(ctx)
|
|
73
130
|
else:
|
|
74
131
|
logger.debug('Already authenticated')
|
|
75
132
|
|
|
76
|
-
#
|
|
133
|
+
# Read stdin payload (backward compat: old hooks pipe no stdin)
|
|
77
134
|
if sys.stdin.isatty():
|
|
78
135
|
logger.debug('No stdin payload (TTY), skipping session initialization')
|
|
79
136
|
return
|
|
@@ -84,7 +141,7 @@ def session_start_command(
|
|
|
84
141
|
logger.debug('Empty or invalid stdin payload, skipping session initialization')
|
|
85
142
|
return
|
|
86
143
|
|
|
87
|
-
#
|
|
144
|
+
# Build session payload + initialize API client
|
|
88
145
|
session_payload = ide_integration.build_session_payload(payload)
|
|
89
146
|
|
|
90
147
|
try:
|
|
@@ -93,11 +150,11 @@ def session_start_command(
|
|
|
93
150
|
logger.debug('Failed to initialize AI security client', exc_info=e)
|
|
94
151
|
return
|
|
95
152
|
|
|
96
|
-
#
|
|
153
|
+
# Create conversation
|
|
97
154
|
try:
|
|
98
155
|
ai_client.create_conversation(session_payload)
|
|
99
156
|
except Exception as e:
|
|
100
157
|
logger.debug('Failed to create conversation during session start', exc_info=e)
|
|
101
158
|
|
|
102
|
-
#
|
|
103
|
-
_report_session_context(ai_client,
|
|
159
|
+
# Report session context (device + cross-IDE MCP servers and plugins)
|
|
160
|
+
_report_session_context(ai_client, session_payload.ide_user_email, auth_info.tenant_id)
|
|
@@ -98,11 +98,11 @@ class AISecurityManagerClient:
|
|
|
98
98
|
os_version: Optional[str] = None,
|
|
99
99
|
serial_number: Optional[str] = None,
|
|
100
100
|
last_login_user: Optional[str] = None,
|
|
101
|
-
|
|
101
|
+
config_files: Optional[list[dict]] = None,
|
|
102
102
|
enabled_plugins: Optional[dict] = None,
|
|
103
103
|
user_email: Optional[str] = None,
|
|
104
|
-
) ->
|
|
105
|
-
"""Report session context to the backend."""
|
|
104
|
+
) -> bool:
|
|
105
|
+
"""Report session context to the backend. Returns whether the report was accepted."""
|
|
106
106
|
body: dict = {
|
|
107
107
|
'hostname': hostname,
|
|
108
108
|
'platform_name': platform_name,
|
|
@@ -110,12 +110,14 @@ class AISecurityManagerClient:
|
|
|
110
110
|
'serial_number': serial_number,
|
|
111
111
|
'last_login_user': last_login_user,
|
|
112
112
|
'user_email': user_email,
|
|
113
|
-
'
|
|
113
|
+
'config_files': config_files,
|
|
114
114
|
'enabled_plugins': enabled_plugins,
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
try:
|
|
118
118
|
self.client.post(self._build_endpoint_path(self._SESSION_CONTEXT_PATH), body=body)
|
|
119
|
+
return True
|
|
119
120
|
except Exception as e:
|
|
120
121
|
logger.debug('Failed to report session context', exc_info=e)
|
|
121
122
|
# Don't fail the session if reporting fails
|
|
123
|
+
return False
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
cycode/__init__.py,sha256=
|
|
1
|
+
cycode/__init__.py,sha256=EAGqyauQgWjbkbDVGhIc99Qu6DCg7Q4U-NYHKc2VN7A,396
|
|
2
2
|
cycode/__main__.py,sha256=Z3bD5yrA7yPvAChcADQrqCaZd0ChGI1gdiwALwbWJ6U,104
|
|
3
3
|
cycode/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
cycode/cli/app.py,sha256=AlR2durAEbsa47PDfIj7JtMvJDWA_Dq6wPtVuMJYSCs,10250
|
|
@@ -8,11 +8,11 @@ cycode/cli/apps/ai_guardrails/__init__.py,sha256=NsqB1Ca83BIjJMcDSt6suec6Ed0iNna
|
|
|
8
8
|
cycode/cli/apps/ai_guardrails/command_utils.py,sha256=NVwd0-2RGRKIqhsQ-4LNDR1D0gVm_o7n-z5LxG2bqAo,800
|
|
9
9
|
cycode/cli/apps/ai_guardrails/consts.py,sha256=Js2QtSNYG9Kt0eo3vepRd5TFciCeJHEC9NN18zqKvlE,620
|
|
10
10
|
cycode/cli/apps/ai_guardrails/hooks_manager.py,sha256=c8okVel9KjeXWm5QTnvTraWsTwzrUTqqKd6C80C34Y4,9003
|
|
11
|
-
cycode/cli/apps/ai_guardrails/ides/__init__.py,sha256=
|
|
12
|
-
cycode/cli/apps/ai_guardrails/ides/_plugin_utils.py,sha256=
|
|
11
|
+
cycode/cli/apps/ai_guardrails/ides/__init__.py,sha256=BDUvQYoavmMtuhoUESCSONpd_ssPjxEH8NCZD1_hsCA,2565
|
|
12
|
+
cycode/cli/apps/ai_guardrails/ides/_plugin_utils.py,sha256=XPIc9pZFEgdGVTSSAl9yqI48F88GKlFnJ5FsLUhHjCE,3981
|
|
13
13
|
cycode/cli/apps/ai_guardrails/ides/base.py,sha256=siFgELUNn1YBXY-jbx3yvhCbbqMXZQG1mFlxTAnwqS8,6995
|
|
14
|
-
cycode/cli/apps/ai_guardrails/ides/claude_code.py,sha256=
|
|
15
|
-
cycode/cli/apps/ai_guardrails/ides/codex.py,sha256=
|
|
14
|
+
cycode/cli/apps/ai_guardrails/ides/claude_code.py,sha256=Hxg76KuwaFRrRR_rB6okx68HTpH_HU0bUyC0P4k02Eg,14276
|
|
15
|
+
cycode/cli/apps/ai_guardrails/ides/codex.py,sha256=HC2PhB4J3-k3IHgT_nBsDtLGXNBeOkg5FjWFKzAreak,11942
|
|
16
16
|
cycode/cli/apps/ai_guardrails/ides/cursor.py,sha256=wyHbh0QaSjC0EbwcWi-kZR4SN5lgkOLJ5S55EgSO2sw,5606
|
|
17
17
|
cycode/cli/apps/ai_guardrails/install_command.py,sha256=vGZSIvHHVMS9_zhV_6lEhxqtmr5H6uykSq4AS5nxQYw,4278
|
|
18
18
|
cycode/cli/apps/ai_guardrails/scan/__init__.py,sha256=qJc82XiQGiAuc1sYY8Ij_A-qXpxgLPuayQq8xWlouMA,48
|
|
@@ -23,7 +23,7 @@ cycode/cli/apps/ai_guardrails/scan/policy.py,sha256=BZoNNdDQ9tqnfwhB4X1-bDtudaOQ
|
|
|
23
23
|
cycode/cli/apps/ai_guardrails/scan/scan_command.py,sha256=uiBCDGcshqgvwkdqrlwNbaGZQnjpAvuTZ9T7UI09YJY,6178
|
|
24
24
|
cycode/cli/apps/ai_guardrails/scan/types.py,sha256=lDttkYFBfOkdMEEaRbq1IT2QTK0R-7Ht3T8vZdyB3b4,1038
|
|
25
25
|
cycode/cli/apps/ai_guardrails/scan/utils.py,sha256=QzR_zmivDYwg2-F8g4bFfsycHhNo-pPuJly0P_l0gm8,2879
|
|
26
|
-
cycode/cli/apps/ai_guardrails/session_start_command.py,sha256=
|
|
26
|
+
cycode/cli/apps/ai_guardrails/session_start_command.py,sha256=05Li-ON2U1BU_8CR2YYw1y5HVvoWPTf19ne--EgPqmQ,5921
|
|
27
27
|
cycode/cli/apps/ai_guardrails/status_command.py,sha256=Uqss68TEPCYPXpLix6Bh-4J3g-khxWsAqlIGYH5x4bQ,3203
|
|
28
28
|
cycode/cli/apps/ai_guardrails/uninstall_command.py,sha256=dOmePfZmlHAPy2zEJM1yMtSuDqvzDwtqgmLKYK-T9PI,2698
|
|
29
29
|
cycode/cli/apps/ai_remediation/__init__.py,sha256=8vYthY9RQeJqEni3AIF5sryz8n-XJQ6VNqG4aEFBAdY,553
|
|
@@ -188,7 +188,7 @@ cycode/cli/utils/version_checker.py,sha256=0f5PaTk02ZkDxzBqZOeMV9mU_CWcx6HKW80jU
|
|
|
188
188
|
cycode/cli/utils/yaml_utils.py,sha256=R-tqzl0C-zoa42rS7nfWeHu3GJ0jpbQUyyqYYU2hleM,1818
|
|
189
189
|
cycode/config.py,sha256=jHORGZQcAXkAGSf2XreC-RQoc8sdNWja69QKtPWTbWo,1044
|
|
190
190
|
cycode/cyclient/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
191
|
-
cycode/cyclient/ai_security_manager_client.py,sha256=
|
|
191
|
+
cycode/cyclient/ai_security_manager_client.py,sha256=K3fvBC_d-8iDnVnMSVPXiDtuuapiWGT2xg1Kx203XU0,4808
|
|
192
192
|
cycode/cyclient/ai_security_manager_service_config.py,sha256=83pQzgOb93JW6E-dznJkI4c0NEXmQRlx9YZKMmjVwp8,808
|
|
193
193
|
cycode/cyclient/auth_client.py,sha256=TwbmZ358Ancf-Q-IZolvfljZ8691_6botsqd0R0PLPk,2105
|
|
194
194
|
cycode/cyclient/base_token_auth_client.py,sha256=mn5580d7A8Z2_zcdFKIJk78ADK7mViwTcV-4QCpRCGo,4369
|
|
@@ -209,8 +209,8 @@ cycode/cyclient/report_client.py,sha256=Scq30NeJPzgXv0hPLO1U05AdE9i_2iu6cIrSKpEJ
|
|
|
209
209
|
cycode/cyclient/scan_client.py,sha256=6TK5FQkfrvV7PHqRnUzEn1PBNd2oPYVamvIixcUfe3c,16755
|
|
210
210
|
cycode/cyclient/scan_config_base.py,sha256=mXsPZGYCtp85rv5GIige40yQZXuRcEKUW-VQJ0vgFzk,1201
|
|
211
211
|
cycode/logger.py,sha256=EfZGRK6VC5rE_LAjIcRrHFiQCueylCDXoG6bvGkrIME,2111
|
|
212
|
-
cycode-3.17.
|
|
213
|
-
cycode-3.17.
|
|
214
|
-
cycode-3.17.
|
|
215
|
-
cycode-3.17.
|
|
216
|
-
cycode-3.17.
|
|
212
|
+
cycode-3.17.2.dev1.dist-info/METADATA,sha256=r9d8aVWGVmkdo07gw6df0k1z-Ji4dKraxrjODW5Pl1I,89246
|
|
213
|
+
cycode-3.17.2.dev1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
214
|
+
cycode-3.17.2.dev1.dist-info/entry_points.txt,sha256=iDcVJM8ByLElVgvBgtYxDjw1kT7O8Mo0LcWZIT5L3Ig,45
|
|
215
|
+
cycode-3.17.2.dev1.dist-info/licenses/LICENCE,sha256=2Wx4N6mD_4xB7-E3hPkZ3MPhpJy__k_I8MaCSO-PDRo,1068
|
|
216
|
+
cycode-3.17.2.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|