flowent 0.1.0 → 0.1.1
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.
- package/backend/pyproject.toml +1 -1
- package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/_version.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/channels.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/cli.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/context.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/llm.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/logging.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/main.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/mcp.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/mcp_import.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/patch.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/paths.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/sandbox.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/skills.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/storage.cpython-313.pyc +0 -0
- package/backend/src/flowent/__pycache__/tools.cpython-313.pyc +0 -0
- package/backend/src/flowent/main.py +20 -8
- package/backend/src/flowent/mcp_import.py +28 -13
- package/backend/src/flowent/static/assets/index-BhHdc2d_.js +81 -0
- package/backend/src/flowent/static/assets/index-C89n9qe2.css +2 -0
- package/backend/src/flowent/static/index.html +2 -2
- package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_agent_tools.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_channels.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_health.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_llm_providers.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_mcp.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_persistence.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_skills.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_startup_requirements.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/__pycache__/test_workspace_chat.cpython-313-pytest-9.0.3.pyc +0 -0
- package/backend/tests/test_mcp.py +32 -20
- package/backend/uv.lock +1 -1
- package/dist/frontend/assets/index-BhHdc2d_.js +81 -0
- package/dist/frontend/assets/index-C89n9qe2.css +2 -0
- package/dist/frontend/index.html +2 -2
- package/package.json +1 -1
- package/backend/src/flowent/static/assets/index-DqTHSMBo.js +0 -81
- package/backend/src/flowent/static/assets/index-d3FBbOXX.css +0 -2
- package/dist/frontend/assets/index-DqTHSMBo.js +0 -81
- package/dist/frontend/assets/index-d3FBbOXX.css +0 -2
package/backend/pyproject.toml
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -105,7 +105,14 @@ class SkillSettingsRequest(BaseModel):
|
|
|
105
105
|
class McpImportRequest(BaseModel):
|
|
106
106
|
model_config = ConfigDict(extra="forbid")
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
server_id: str
|
|
109
|
+
source: Literal["claude_code", "codex"]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class McpImportPreviewRequest(BaseModel):
|
|
113
|
+
model_config = ConfigDict(extra="forbid")
|
|
114
|
+
|
|
115
|
+
source: Literal["claude_code", "codex"]
|
|
109
116
|
|
|
110
117
|
|
|
111
118
|
def stream_event(event: str, data: dict[str, object]) -> str:
|
|
@@ -368,19 +375,24 @@ def create_app(
|
|
|
368
375
|
saved_server = store.save_mcp_server(server)
|
|
369
376
|
return await mcp_manager.sync_server(saved_server)
|
|
370
377
|
|
|
371
|
-
@app.
|
|
372
|
-
async def preview_mcp_import(
|
|
373
|
-
|
|
378
|
+
@app.post("/api/mcp/import/preview")
|
|
379
|
+
async def preview_mcp_import(
|
|
380
|
+
request: McpImportPreviewRequest,
|
|
381
|
+
) -> McpImportDiscovery:
|
|
382
|
+
return discover_imported_mcp_servers(Path.cwd(), source=request.source)
|
|
374
383
|
|
|
375
384
|
@app.post("/api/mcp/import")
|
|
376
385
|
async def import_mcp_servers(request: McpImportRequest) -> list[StoredMcpServer]:
|
|
377
|
-
imported_servers = discover_imported_mcp_servers(
|
|
386
|
+
imported_servers = discover_imported_mcp_servers(
|
|
387
|
+
Path.cwd(),
|
|
388
|
+
source=request.source,
|
|
389
|
+
).servers
|
|
378
390
|
existing_servers = {server.id for server in store.read_mcp_servers()}
|
|
379
391
|
for server in imported_servers:
|
|
380
|
-
if
|
|
392
|
+
if server.id != request.server_id:
|
|
393
|
+
continue
|
|
394
|
+
if server.id in existing_servers:
|
|
381
395
|
continue
|
|
382
|
-
if request.duplicate_action == "replace" and server.id in existing_servers:
|
|
383
|
-
await mcp_manager.delete_server(server.id)
|
|
384
396
|
store.save_mcp_server(server)
|
|
385
397
|
existing_servers.add(server.id)
|
|
386
398
|
return mcp_manager.servers_with_status(store.read_mcp_servers())
|
|
@@ -33,21 +33,26 @@ class McpImportDiscovery(BaseModel):
|
|
|
33
33
|
def discover_imported_mcp_servers(
|
|
34
34
|
cwd: Path | None = None,
|
|
35
35
|
home: Path | None = None,
|
|
36
|
+
source: McpImportSource | None = None,
|
|
36
37
|
) -> McpImportDiscovery:
|
|
37
38
|
workspace = (cwd or Path.cwd()).resolve(strict=False)
|
|
38
39
|
user_home = (home or Path.home()).resolve(strict=False)
|
|
39
40
|
sources: list[McpImportSourceResult] = []
|
|
40
41
|
|
|
41
|
-
for path,
|
|
42
|
+
for path, config_source in candidate_mcp_config_files(
|
|
43
|
+
workspace,
|
|
44
|
+
user_home,
|
|
45
|
+
source,
|
|
46
|
+
):
|
|
42
47
|
if not path.is_file():
|
|
43
48
|
continue
|
|
44
49
|
try:
|
|
45
|
-
servers = parse_mcp_config_file(path,
|
|
50
|
+
servers = parse_mcp_config_file(path, config_source, workspace)
|
|
46
51
|
sources.append(
|
|
47
52
|
McpImportSourceResult(
|
|
48
53
|
path=str(path.resolve(strict=False)),
|
|
49
54
|
servers=servers,
|
|
50
|
-
source=
|
|
55
|
+
source=config_source,
|
|
51
56
|
)
|
|
52
57
|
)
|
|
53
58
|
except Exception as error:
|
|
@@ -55,7 +60,7 @@ def discover_imported_mcp_servers(
|
|
|
55
60
|
McpImportSourceResult(
|
|
56
61
|
error=str(error),
|
|
57
62
|
path=str(path.resolve(strict=False)),
|
|
58
|
-
source=
|
|
63
|
+
source=config_source,
|
|
59
64
|
)
|
|
60
65
|
)
|
|
61
66
|
|
|
@@ -70,16 +75,26 @@ def discover_imported_mcp_servers(
|
|
|
70
75
|
def candidate_mcp_config_files(
|
|
71
76
|
cwd: Path,
|
|
72
77
|
home: Path,
|
|
78
|
+
source: McpImportSource | None = None,
|
|
73
79
|
) -> list[tuple[Path, McpImportSource]]:
|
|
74
|
-
candidates: list[tuple[Path, McpImportSource]] = [
|
|
75
|
-
|
|
76
|
-
(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
candidates: list[tuple[Path, McpImportSource]] = []
|
|
81
|
+
if source in (None, "claude_code"):
|
|
82
|
+
candidates.extend(
|
|
83
|
+
[
|
|
84
|
+
(cwd / ".mcp.json", "claude_code"),
|
|
85
|
+
(cwd / ".claude" / "settings.local.json", "claude_code"),
|
|
86
|
+
(cwd / ".claude" / "settings.json", "claude_code"),
|
|
87
|
+
(home / ".claude.json", "claude_code"),
|
|
88
|
+
(home / ".claude" / "settings.json", "claude_code"),
|
|
89
|
+
]
|
|
90
|
+
)
|
|
91
|
+
if source in (None, "codex"):
|
|
92
|
+
candidates.extend(
|
|
93
|
+
[
|
|
94
|
+
(cwd / ".codex" / "config.toml", "codex"),
|
|
95
|
+
(home / ".codex" / "config.toml", "codex"),
|
|
96
|
+
]
|
|
97
|
+
)
|
|
83
98
|
seen: set[tuple[Path, McpImportSource]] = set()
|
|
84
99
|
unique_candidates: list[tuple[Path, McpImportSource]] = []
|
|
85
100
|
for path, source in candidates:
|