ai-editor-client 1.0.65__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.
@@ -0,0 +1,212 @@
1
+ Metadata-Version: 2.4
2
+ Name: ai-editor-client
3
+ Version: 1.0.65
4
+ Summary: Async JSON-RPC client for the ai-editor MCP server (mcp-proxy-adapter JsonRpcClient)
5
+ Author-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: mcp-proxy-adapter>=8.10.15
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=8.0; extra == "dev"
11
+ Requires-Dist: pytest-asyncio>=0.25.0; extra == "dev"
12
+
13
+ # code-analysis-client
14
+
15
+ Async Python client for the **code-analysis** server. It wraps `mcp-proxy-adapter`'s `JsonRpcClient`, so you get the adapter's built-in methods (queue, transfer, `help`, `health`, …) plus thin helpers to run any registered server command. On the thin AI Editor Server, file editing uses `universal_file_*` commands only; queue polling helpers remain for generic RPC but are not part of the file workflow surface.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pip install code-analysis-client
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```python
26
+ import asyncio
27
+ from code_analysis_client import CodeAnalysisAsyncClient
28
+
29
+
30
+ async def main() -> None:
31
+ client = CodeAnalysisAsyncClient(
32
+ protocol="https",
33
+ host="127.0.0.1",
34
+ port=15001,
35
+ cert="/path/client.crt",
36
+ key="/path/client.key",
37
+ ca="/path/ca.crt",
38
+ timeout=120.0,
39
+ )
40
+ async with client:
41
+ h = await client.rpc.help()
42
+ r = await client.call("list_projects", {"include_deleted": False})
43
+ print(h, r)
44
+
45
+
46
+ asyncio.run(main())
47
+ ```
48
+
49
+ Build client settings from the same JSON shape as the pipeline adapter settings (`host`, `port`, `protocol`, optional `ssl` with `cert` / `key` / `ca` or `*_path` aliases), or from a full server `config.json` object.
50
+
51
+ ```python
52
+ from code_analysis_client import CodeAnalysisAsyncClient
53
+
54
+ client = CodeAnalysisAsyncClient.from_server_config(config_dict, timeout=60.0)
55
+ ```
56
+
57
+ Queued/long commands: use `client.call_unified(..., expect_queue=True, auto_poll=True)` or the underlying `client.rpc.execute_command_unified(...)`.
58
+
59
+ ## Validation using the server schema
60
+
61
+ The authoritative input schema is whatever the running server returns from **`help`** with `cmdname` set to the command. The client calls that, optionally caches the result, performs the same shallow checks as the server's `BaseMCPCommand` (types, `required`, `enum`, `additionalProperties`), then runs the command.
62
+
63
+ ```python
64
+ async with CodeAnalysisAsyncClient(host="127.0.0.1", port=15001) as client:
65
+ # Explicit
66
+ out = await client.call_validated(
67
+ "list_projects",
68
+ {"include_deleted": False},
69
+ )
70
+ # Dynamic wrapper: same as call_validated("list_projects", {...})
71
+ out = await client.commands.list_projects(include_deleted=False)
72
+ # After server reload
73
+ client.clear_command_schema_cache()
74
+ ```
75
+
76
+ Use `call_unified_validated` when you need queue polling. Pass `refresh_schema=True` on a single call to bypass the in-memory schema cache.
77
+
78
+ ## File Workflow (C-009)
79
+
80
+ The thin AI Editor Server exposes file editing only through `UniversalFileClient` (`client.universal_files`). One file at a time follows **open → edit → write → close**. Optional read-only inspection during an open file uses `preview` (`universal_file_preview`). Every stage requires the same CA Session `session_id`, `project_id`, and (where applicable) `file_path`.
81
+
82
+ ### Workflow stages
83
+
84
+ 1. **Open** (`universal_file_open`) — agent supplies CA `session_id`; server locks file on upstream CA, creates local Editor Session Directory and File Subtree, stores Origin Snapshot, creates Edit Subdirectory. Use `create=True` with `initial_content` for new files.
85
+ 2. **Edit** (`universal_file_edit`) — mutations apply only to the Edit Subdirectory; Origin Snapshot unchanged.
86
+ 3. **Write** (`universal_file_write`) — compares Origin Snapshot to edited content; `write_mode="preview"` returns local diff without upstream upload; commit mode uploads to CA on change and refreshes Origin Snapshot on success.
87
+ 4. **Close** (`universal_file_close`) — unlocks file on CA, removes local File Subtree; removes Editor Session Directory when last file in session closes.
88
+
89
+ ### Minimal async example
90
+
91
+ ```python
92
+ import asyncio
93
+ import uuid
94
+
95
+ from ai_editor_client import CodeAnalysisAsyncClient
96
+
97
+
98
+ async def main() -> None:
99
+ # Created upstream via CA session_create (outside this client package).
100
+ ca_session_id = str(uuid.uuid4())
101
+
102
+ async with CodeAnalysisAsyncClient.from_server_config_path("config.json") as client:
103
+ uf = client.universal_files
104
+ project_id = "..."
105
+ file_path = "src/example.py"
106
+
107
+ await uf.open(
108
+ session_id=ca_session_id,
109
+ project_id=project_id,
110
+ file_path=file_path,
111
+ )
112
+ await uf.preview(
113
+ session_id=ca_session_id,
114
+ project_id=project_id,
115
+ file_path=file_path,
116
+ )
117
+ await uf.edit(
118
+ session_id=ca_session_id,
119
+ project_id=project_id,
120
+ file_path=file_path,
121
+ operations=[{"action": "replace", "start_line": 1, "end_line": 1, "code": "# edited\n"}],
122
+ )
123
+ await uf.write(
124
+ session_id=ca_session_id,
125
+ project_id=project_id,
126
+ file_path=file_path,
127
+ write_mode="preview",
128
+ )
129
+ await uf.close(
130
+ session_id=ca_session_id,
131
+ project_id=project_id,
132
+ file_path=file_path,
133
+ )
134
+
135
+
136
+ asyncio.run(main())
137
+ ```
138
+
139
+ Full runnable script: `client/examples/ex_universal_files.py`.
140
+
141
+ ### CA Session ID contract (C-003)
142
+
143
+ - The **agent** creates the CA Session on Code Analysis Server (`session_create`) **before** calling any editor `universal_file_*` command. That RPC is **not** part of the thin editor MCP surface and is **not** wrapped by `UniversalFileClient`.
144
+ - The agent passes the **same** `session_id` string to every `universal_file_open`, `universal_file_edit`, `universal_file_write`, `universal_file_close`, and `universal_file_preview` call for the workflow.
145
+ - Do **not** treat the `open` response as the source of `session_id` for later calls. If the server echoes `session_id`, it must match the agent-supplied value; the agent already owns the identifier.
146
+ - The agent decides when to `write` (commit or preview) and `close`; the client library does not manage CA session lifecycle.
147
+
148
+ ## High-level facades (thin AI Editor Server / C-016)
149
+
150
+ The supported public MCP commands for file workflow are `UNIVERSAL_FILE_COMMANDS` plus `health` only (`CLIENT_FACADE_COMMANDS` in `ai_editor_client.server_api`). CST commands (`cst_*`, `list_cst_blocks`, `query_cst`) and legacy direct file I/O are in `REMOVED_COMMANDS` — not on the thin server, not documented as supported. `client.universal_files` is the **only** supported high-level facade for file editing.
151
+
152
+ | Facade | Property | Server commands | Status |
153
+ |--------|----------|-----------------|--------|
154
+ | Universal file workflow | `client.universal_files` | `universal_file_open`, `universal_file_edit`, `universal_file_write`, `universal_file_close`, `universal_file_preview` | **Supported** (C-009 / C-016) |
155
+ | Infrastructure | `client.call("health", {})` or adapter `health` | `health` | **Supported** |
156
+ | Generic RPC | `client.call` / `client.commands.<name>` | any command returned by live `help()` on connected server | Escape hatch; thin server exposes only rows above for files |
157
+ | Legacy sessions + transfer | `client.file_sessions` | `session_*`, `subordinate_session_*`, `project_file_transfer_*`, `project_file_advisory_lock_batch` | **Deprecated** — `DEPRECATED_CLIENT_FACADE_COMMANDS`; not registered on thin editor server |
158
+
159
+ Canonical command lists: `ai_editor_client.server_api` exports `UNIVERSAL_FILE_COMMANDS`, `INFRASTRUCTURE_COMMANDS`, `CLIENT_FACADE_COMMANDS`, `DEPRECATED_CLIENT_FACADE_COMMANDS`, and `REMOVED_COMMANDS`.
160
+
161
+ Sync checks (in-process registry):
162
+
163
+ ```bash
164
+ pytest tests/test_client_server_api_sync.py -v
165
+ ```
166
+
167
+ These tests assert `CLIENT_FACADE_COMMANDS` matches the live server registry (C-016) and `REMOVED_COMMANDS` are absent from the server (C-022).
168
+
169
+ Package version is in ``client/ai_editor_client/version.txt`` (synced with the
170
+ root ``code-analysis`` project via ``scripts/sync_code_analysis_client_version.py``).
171
+
172
+ ## Examples (this repository)
173
+
174
+ Runnable scripts live under `client/examples/`. **Long-form "man page" style
175
+ documentation** is embedded in the **module docstrings** of those Python files
176
+ (see `client/examples/README.md` for how to read them).
177
+
178
+ | Script | Purpose |
179
+ |--------|---------|
180
+ | `ex_universal_files.py` | **Primary:** C-009 File Workflow demo — all `UniversalFileClient` methods with agent-supplied CA `session_id` (C-003) |
181
+ | `ex_minimal_validated.py` | Smallest validated RPC example (`health` / generic call) |
182
+ | `ex_config_only.py` | Parse `config.json` without TCP |
183
+ | `run_all_examples.py` | Runs sibling live scripts (includes universal files demo) |
184
+ | `ex_session_view_subordinates.py` | **Deprecated** — legacy CA session API; not thin editor MCP |
185
+ | `ex_file_sessions.py` | **Deprecated** — legacy sessions/transfer; not thin editor MCP |
186
+
187
+ For file editing on thin AI Editor Server, start with `ex_universal_files.py`; do not use `ex_file_sessions.py` or `ex_session_view_subordinates.py` as file workflow templates.
188
+
189
+ ```bash
190
+ aiedmgr --config config.json start
191
+ python client/examples/ex_universal_files.py
192
+ ```
193
+
194
+ ## Development
195
+
196
+ From the repository root:
197
+
198
+ ```bash
199
+ pip install -e ./client
200
+ pytest tests/test_code_analysis_client.py
201
+ ```
202
+
203
+ ### Releasing to PyPI (version = root ``code-analysis`` project)
204
+
205
+ The client wheel version is read from ``client/code_analysis_client/version.txt``.
206
+ That file must match ``[project].version`` in the **repository root**
207
+ ``pyproject.toml``. Sync before build:
208
+
209
+ ```bash
210
+ python scripts/sync_code_analysis_client_version.py
211
+ cd client && python -m build && twine check dist/* && twine upload dist/*
212
+ ```
@@ -0,0 +1,200 @@
1
+ # code-analysis-client
2
+
3
+ Async Python client for the **code-analysis** server. It wraps `mcp-proxy-adapter`'s `JsonRpcClient`, so you get the adapter's built-in methods (queue, transfer, `help`, `health`, …) plus thin helpers to run any registered server command. On the thin AI Editor Server, file editing uses `universal_file_*` commands only; queue polling helpers remain for generic RPC but are not part of the file workflow surface.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install code-analysis-client
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ import asyncio
15
+ from code_analysis_client import CodeAnalysisAsyncClient
16
+
17
+
18
+ async def main() -> None:
19
+ client = CodeAnalysisAsyncClient(
20
+ protocol="https",
21
+ host="127.0.0.1",
22
+ port=15001,
23
+ cert="/path/client.crt",
24
+ key="/path/client.key",
25
+ ca="/path/ca.crt",
26
+ timeout=120.0,
27
+ )
28
+ async with client:
29
+ h = await client.rpc.help()
30
+ r = await client.call("list_projects", {"include_deleted": False})
31
+ print(h, r)
32
+
33
+
34
+ asyncio.run(main())
35
+ ```
36
+
37
+ Build client settings from the same JSON shape as the pipeline adapter settings (`host`, `port`, `protocol`, optional `ssl` with `cert` / `key` / `ca` or `*_path` aliases), or from a full server `config.json` object.
38
+
39
+ ```python
40
+ from code_analysis_client import CodeAnalysisAsyncClient
41
+
42
+ client = CodeAnalysisAsyncClient.from_server_config(config_dict, timeout=60.0)
43
+ ```
44
+
45
+ Queued/long commands: use `client.call_unified(..., expect_queue=True, auto_poll=True)` or the underlying `client.rpc.execute_command_unified(...)`.
46
+
47
+ ## Validation using the server schema
48
+
49
+ The authoritative input schema is whatever the running server returns from **`help`** with `cmdname` set to the command. The client calls that, optionally caches the result, performs the same shallow checks as the server's `BaseMCPCommand` (types, `required`, `enum`, `additionalProperties`), then runs the command.
50
+
51
+ ```python
52
+ async with CodeAnalysisAsyncClient(host="127.0.0.1", port=15001) as client:
53
+ # Explicit
54
+ out = await client.call_validated(
55
+ "list_projects",
56
+ {"include_deleted": False},
57
+ )
58
+ # Dynamic wrapper: same as call_validated("list_projects", {...})
59
+ out = await client.commands.list_projects(include_deleted=False)
60
+ # After server reload
61
+ client.clear_command_schema_cache()
62
+ ```
63
+
64
+ Use `call_unified_validated` when you need queue polling. Pass `refresh_schema=True` on a single call to bypass the in-memory schema cache.
65
+
66
+ ## File Workflow (C-009)
67
+
68
+ The thin AI Editor Server exposes file editing only through `UniversalFileClient` (`client.universal_files`). One file at a time follows **open → edit → write → close**. Optional read-only inspection during an open file uses `preview` (`universal_file_preview`). Every stage requires the same CA Session `session_id`, `project_id`, and (where applicable) `file_path`.
69
+
70
+ ### Workflow stages
71
+
72
+ 1. **Open** (`universal_file_open`) — agent supplies CA `session_id`; server locks file on upstream CA, creates local Editor Session Directory and File Subtree, stores Origin Snapshot, creates Edit Subdirectory. Use `create=True` with `initial_content` for new files.
73
+ 2. **Edit** (`universal_file_edit`) — mutations apply only to the Edit Subdirectory; Origin Snapshot unchanged.
74
+ 3. **Write** (`universal_file_write`) — compares Origin Snapshot to edited content; `write_mode="preview"` returns local diff without upstream upload; commit mode uploads to CA on change and refreshes Origin Snapshot on success.
75
+ 4. **Close** (`universal_file_close`) — unlocks file on CA, removes local File Subtree; removes Editor Session Directory when last file in session closes.
76
+
77
+ ### Minimal async example
78
+
79
+ ```python
80
+ import asyncio
81
+ import uuid
82
+
83
+ from ai_editor_client import CodeAnalysisAsyncClient
84
+
85
+
86
+ async def main() -> None:
87
+ # Created upstream via CA session_create (outside this client package).
88
+ ca_session_id = str(uuid.uuid4())
89
+
90
+ async with CodeAnalysisAsyncClient.from_server_config_path("config.json") as client:
91
+ uf = client.universal_files
92
+ project_id = "..."
93
+ file_path = "src/example.py"
94
+
95
+ await uf.open(
96
+ session_id=ca_session_id,
97
+ project_id=project_id,
98
+ file_path=file_path,
99
+ )
100
+ await uf.preview(
101
+ session_id=ca_session_id,
102
+ project_id=project_id,
103
+ file_path=file_path,
104
+ )
105
+ await uf.edit(
106
+ session_id=ca_session_id,
107
+ project_id=project_id,
108
+ file_path=file_path,
109
+ operations=[{"action": "replace", "start_line": 1, "end_line": 1, "code": "# edited\n"}],
110
+ )
111
+ await uf.write(
112
+ session_id=ca_session_id,
113
+ project_id=project_id,
114
+ file_path=file_path,
115
+ write_mode="preview",
116
+ )
117
+ await uf.close(
118
+ session_id=ca_session_id,
119
+ project_id=project_id,
120
+ file_path=file_path,
121
+ )
122
+
123
+
124
+ asyncio.run(main())
125
+ ```
126
+
127
+ Full runnable script: `client/examples/ex_universal_files.py`.
128
+
129
+ ### CA Session ID contract (C-003)
130
+
131
+ - The **agent** creates the CA Session on Code Analysis Server (`session_create`) **before** calling any editor `universal_file_*` command. That RPC is **not** part of the thin editor MCP surface and is **not** wrapped by `UniversalFileClient`.
132
+ - The agent passes the **same** `session_id` string to every `universal_file_open`, `universal_file_edit`, `universal_file_write`, `universal_file_close`, and `universal_file_preview` call for the workflow.
133
+ - Do **not** treat the `open` response as the source of `session_id` for later calls. If the server echoes `session_id`, it must match the agent-supplied value; the agent already owns the identifier.
134
+ - The agent decides when to `write` (commit or preview) and `close`; the client library does not manage CA session lifecycle.
135
+
136
+ ## High-level facades (thin AI Editor Server / C-016)
137
+
138
+ The supported public MCP commands for file workflow are `UNIVERSAL_FILE_COMMANDS` plus `health` only (`CLIENT_FACADE_COMMANDS` in `ai_editor_client.server_api`). CST commands (`cst_*`, `list_cst_blocks`, `query_cst`) and legacy direct file I/O are in `REMOVED_COMMANDS` — not on the thin server, not documented as supported. `client.universal_files` is the **only** supported high-level facade for file editing.
139
+
140
+ | Facade | Property | Server commands | Status |
141
+ |--------|----------|-----------------|--------|
142
+ | Universal file workflow | `client.universal_files` | `universal_file_open`, `universal_file_edit`, `universal_file_write`, `universal_file_close`, `universal_file_preview` | **Supported** (C-009 / C-016) |
143
+ | Infrastructure | `client.call("health", {})` or adapter `health` | `health` | **Supported** |
144
+ | Generic RPC | `client.call` / `client.commands.<name>` | any command returned by live `help()` on connected server | Escape hatch; thin server exposes only rows above for files |
145
+ | Legacy sessions + transfer | `client.file_sessions` | `session_*`, `subordinate_session_*`, `project_file_transfer_*`, `project_file_advisory_lock_batch` | **Deprecated** — `DEPRECATED_CLIENT_FACADE_COMMANDS`; not registered on thin editor server |
146
+
147
+ Canonical command lists: `ai_editor_client.server_api` exports `UNIVERSAL_FILE_COMMANDS`, `INFRASTRUCTURE_COMMANDS`, `CLIENT_FACADE_COMMANDS`, `DEPRECATED_CLIENT_FACADE_COMMANDS`, and `REMOVED_COMMANDS`.
148
+
149
+ Sync checks (in-process registry):
150
+
151
+ ```bash
152
+ pytest tests/test_client_server_api_sync.py -v
153
+ ```
154
+
155
+ These tests assert `CLIENT_FACADE_COMMANDS` matches the live server registry (C-016) and `REMOVED_COMMANDS` are absent from the server (C-022).
156
+
157
+ Package version is in ``client/ai_editor_client/version.txt`` (synced with the
158
+ root ``code-analysis`` project via ``scripts/sync_code_analysis_client_version.py``).
159
+
160
+ ## Examples (this repository)
161
+
162
+ Runnable scripts live under `client/examples/`. **Long-form "man page" style
163
+ documentation** is embedded in the **module docstrings** of those Python files
164
+ (see `client/examples/README.md` for how to read them).
165
+
166
+ | Script | Purpose |
167
+ |--------|---------|
168
+ | `ex_universal_files.py` | **Primary:** C-009 File Workflow demo — all `UniversalFileClient` methods with agent-supplied CA `session_id` (C-003) |
169
+ | `ex_minimal_validated.py` | Smallest validated RPC example (`health` / generic call) |
170
+ | `ex_config_only.py` | Parse `config.json` without TCP |
171
+ | `run_all_examples.py` | Runs sibling live scripts (includes universal files demo) |
172
+ | `ex_session_view_subordinates.py` | **Deprecated** — legacy CA session API; not thin editor MCP |
173
+ | `ex_file_sessions.py` | **Deprecated** — legacy sessions/transfer; not thin editor MCP |
174
+
175
+ For file editing on thin AI Editor Server, start with `ex_universal_files.py`; do not use `ex_file_sessions.py` or `ex_session_view_subordinates.py` as file workflow templates.
176
+
177
+ ```bash
178
+ aiedmgr --config config.json start
179
+ python client/examples/ex_universal_files.py
180
+ ```
181
+
182
+ ## Development
183
+
184
+ From the repository root:
185
+
186
+ ```bash
187
+ pip install -e ./client
188
+ pytest tests/test_code_analysis_client.py
189
+ ```
190
+
191
+ ### Releasing to PyPI (version = root ``code-analysis`` project)
192
+
193
+ The client wheel version is read from ``client/code_analysis_client/version.txt``.
194
+ That file must match ``[project].version`` in the **repository root**
195
+ ``pyproject.toml``. Sync before build:
196
+
197
+ ```bash
198
+ python scripts/sync_code_analysis_client_version.py
199
+ cd client && python -m build && twine check dist/* && twine upload dist/*
200
+ ```
@@ -0,0 +1,180 @@
1
+ """
2
+ Public async client for ai-editor-server (JSON-RPC via mcp-proxy-adapter).
3
+
4
+ ``UniversalFileClient`` (via :attr:`~ai_editor_client.client.CodeAnalysisAsyncClient.universal_files`)
5
+ is the single supported file-workflow facade for the thin MCP Workflow Surface (C-016).
6
+ ``FileSessionClient``, ``EditorFileClient``, ``EditorFileHandle``, and ``LocalEditWorkspace``
7
+ are deprecated parallel facades (C-020) and emit :class:`DeprecationWarning` on instantiation.
8
+
9
+ Author: Vasiliy Zdanovskiy
10
+ email: vasilyvz@gmail.com
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import warnings
16
+ from pathlib import Path
17
+ from typing import Optional
18
+
19
+ from ai_editor_client.client import CodeAnalysisAsyncClient
20
+ from ai_editor_client.commands_proxy import ValidatedCommandsProxy
21
+ from ai_editor_client.config import (
22
+ adapter_settings_from_server_config,
23
+ adapter_settings_to_jsonrpc_kwargs,
24
+ load_server_config,
25
+ )
26
+ from ai_editor_client.editor_file import (
27
+ EditorFileClient as _EditorFileClient,
28
+ EditorFileHandle as _EditorFileHandle,
29
+ )
30
+ from ai_editor_client.exceptions import ClientValidationError
31
+ from ai_editor_client.file_session import (
32
+ FileSessionClient as _FileSessionClient,
33
+ SessionNotFoundError,
34
+ )
35
+ from ai_editor_client.local_edit_workspace import (
36
+ EditorFileWorkflowError,
37
+ LocalEditWorkspace as _LocalEditWorkspace,
38
+ )
39
+ from ai_editor_client.server_api import (
40
+ CLIENT_FACADE_COMMANDS,
41
+ CST_REMOVED_COMMANDS,
42
+ FILE_SESSION_COMMANDS,
43
+ FILE_SESSION_FACADE_METHODS,
44
+ LEGACY_REMOVED_COMMANDS,
45
+ REMOVED_COMMANDS,
46
+ TRANSFER_FACADE_METHODS,
47
+ UNIVERSAL_FILE_COMMANDS,
48
+ )
49
+ from ai_editor_client.universal_file import UniversalFileClient
50
+ from ai_editor_client.server_schema import (
51
+ fetch_command_schema_from_server,
52
+ parse_schema_from_help_payload,
53
+ )
54
+ from ai_editor_client.validation import (
55
+ prepare_params_for_schema,
56
+ validate_params_against_schema,
57
+ )
58
+
59
+ _DEPRECATED_EXPORTS: frozenset[str] = frozenset(
60
+ {
61
+ "FileSessionClient",
62
+ "EditorFileClient",
63
+ "EditorFileHandle",
64
+ "LocalEditWorkspace",
65
+ }
66
+ )
67
+
68
+
69
+ def _emit_deprecated_export_warning(class_name: str) -> None:
70
+ warnings.warn(
71
+ (
72
+ f"{class_name} export is deprecated; use UniversalFileClient via "
73
+ "CodeAnalysisAsyncClient.universal_files (C-016). Removal under C-020."
74
+ ),
75
+ DeprecationWarning,
76
+ stacklevel=3,
77
+ )
78
+
79
+
80
+ class _DeprecatedFileSessionClient(_FileSessionClient):
81
+ def __init__(self, client: CodeAnalysisAsyncClient) -> None:
82
+ _emit_deprecated_export_warning("FileSessionClient")
83
+ super().__init__(client)
84
+
85
+
86
+ class _DeprecatedEditorFileClient(_EditorFileClient):
87
+ def __init__(self, file_sessions: FileSessionClient) -> None:
88
+ _emit_deprecated_export_warning("EditorFileClient")
89
+ super().__init__(file_sessions)
90
+
91
+
92
+ class _DeprecatedEditorFileHandle(_EditorFileHandle):
93
+ def __init__(
94
+ self,
95
+ ca_session_id: str,
96
+ project_id: str,
97
+ file_id: str,
98
+ file_path: str,
99
+ baseline_path: Path,
100
+ workspace: Optional[_LocalEditWorkspace] = None,
101
+ is_closed: bool = False,
102
+ ) -> None:
103
+ _emit_deprecated_export_warning("EditorFileHandle")
104
+ super().__init__(
105
+ ca_session_id=ca_session_id,
106
+ project_id=project_id,
107
+ file_id=file_id,
108
+ file_path=file_path,
109
+ baseline_path=baseline_path,
110
+ workspace=workspace,
111
+ is_closed=is_closed,
112
+ )
113
+
114
+
115
+ class _DeprecatedLocalEditWorkspace(_LocalEditWorkspace):
116
+ def __init__(
117
+ self,
118
+ workspace_id: str,
119
+ baseline_path: Path,
120
+ session_dir: Path,
121
+ working_path: Path,
122
+ is_open: bool = True,
123
+ ) -> None:
124
+ _emit_deprecated_export_warning("LocalEditWorkspace")
125
+ super().__init__(
126
+ workspace_id=workspace_id,
127
+ baseline_path=baseline_path,
128
+ session_dir=session_dir,
129
+ working_path=working_path,
130
+ is_open=is_open,
131
+ )
132
+
133
+
134
+ FileSessionClient = _DeprecatedFileSessionClient
135
+ EditorFileClient = _DeprecatedEditorFileClient
136
+ EditorFileHandle = _DeprecatedEditorFileHandle
137
+ LocalEditWorkspace = _DeprecatedLocalEditWorkspace
138
+
139
+ __all__ = [
140
+ "CLIENT_FACADE_COMMANDS",
141
+ "CST_REMOVED_COMMANDS",
142
+ "ClientValidationError",
143
+ "CodeAnalysisAsyncClient",
144
+ "EditorFileClient",
145
+ "EditorFileHandle",
146
+ "EditorFileWorkflowError",
147
+ "FILE_SESSION_COMMANDS",
148
+ "FILE_SESSION_FACADE_METHODS",
149
+ "FileSessionClient",
150
+ "LEGACY_REMOVED_COMMANDS",
151
+ "LocalEditWorkspace",
152
+ "REMOVED_COMMANDS",
153
+ "SessionNotFoundError",
154
+ "TRANSFER_FACADE_METHODS",
155
+ "UNIVERSAL_FILE_COMMANDS",
156
+ "UniversalFileClient",
157
+ "ValidatedCommandsProxy",
158
+ "adapter_settings_from_server_config",
159
+ "adapter_settings_to_jsonrpc_kwargs",
160
+ "fetch_command_schema_from_server",
161
+ "load_server_config",
162
+ "parse_schema_from_help_payload",
163
+ "prepare_params_for_schema",
164
+ "validate_params_against_schema",
165
+ ]
166
+
167
+
168
+ def _read_package_version() -> str:
169
+ vf = Path(__file__).resolve().parent / "version.txt"
170
+ if vf.is_file():
171
+ return vf.read_text(encoding="utf-8").strip()
172
+ try:
173
+ import importlib.metadata as _imd
174
+
175
+ return _imd.version("ai-editor-client")
176
+ except Exception:
177
+ return "0.0.0"
178
+
179
+
180
+ __version__ = _read_package_version()