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.
Files changed (44) hide show
  1. package/backend/pyproject.toml +1 -1
  2. package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
  3. package/backend/src/flowent/__pycache__/_version.cpython-313.pyc +0 -0
  4. package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
  5. package/backend/src/flowent/__pycache__/channels.cpython-313.pyc +0 -0
  6. package/backend/src/flowent/__pycache__/cli.cpython-313.pyc +0 -0
  7. package/backend/src/flowent/__pycache__/context.cpython-313.pyc +0 -0
  8. package/backend/src/flowent/__pycache__/llm.cpython-313.pyc +0 -0
  9. package/backend/src/flowent/__pycache__/logging.cpython-313.pyc +0 -0
  10. package/backend/src/flowent/__pycache__/main.cpython-313.pyc +0 -0
  11. package/backend/src/flowent/__pycache__/mcp.cpython-313.pyc +0 -0
  12. package/backend/src/flowent/__pycache__/mcp_import.cpython-313.pyc +0 -0
  13. package/backend/src/flowent/__pycache__/patch.cpython-313.pyc +0 -0
  14. package/backend/src/flowent/__pycache__/paths.cpython-313.pyc +0 -0
  15. package/backend/src/flowent/__pycache__/sandbox.cpython-313.pyc +0 -0
  16. package/backend/src/flowent/__pycache__/skills.cpython-313.pyc +0 -0
  17. package/backend/src/flowent/__pycache__/storage.cpython-313.pyc +0 -0
  18. package/backend/src/flowent/__pycache__/tools.cpython-313.pyc +0 -0
  19. package/backend/src/flowent/main.py +20 -8
  20. package/backend/src/flowent/mcp_import.py +28 -13
  21. package/backend/src/flowent/static/assets/index-BhHdc2d_.js +81 -0
  22. package/backend/src/flowent/static/assets/index-C89n9qe2.css +2 -0
  23. package/backend/src/flowent/static/index.html +2 -2
  24. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  25. package/backend/tests/__pycache__/test_agent_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  26. package/backend/tests/__pycache__/test_channels.cpython-313-pytest-9.0.3.pyc +0 -0
  27. package/backend/tests/__pycache__/test_health.cpython-313-pytest-9.0.3.pyc +0 -0
  28. package/backend/tests/__pycache__/test_llm_providers.cpython-313-pytest-9.0.3.pyc +0 -0
  29. package/backend/tests/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  30. package/backend/tests/__pycache__/test_mcp.cpython-313-pytest-9.0.3.pyc +0 -0
  31. package/backend/tests/__pycache__/test_persistence.cpython-313-pytest-9.0.3.pyc +0 -0
  32. package/backend/tests/__pycache__/test_skills.cpython-313-pytest-9.0.3.pyc +0 -0
  33. package/backend/tests/__pycache__/test_startup_requirements.cpython-313-pytest-9.0.3.pyc +0 -0
  34. package/backend/tests/__pycache__/test_workspace_chat.cpython-313-pytest-9.0.3.pyc +0 -0
  35. package/backend/tests/test_mcp.py +32 -20
  36. package/backend/uv.lock +1 -1
  37. package/dist/frontend/assets/index-BhHdc2d_.js +81 -0
  38. package/dist/frontend/assets/index-C89n9qe2.css +2 -0
  39. package/dist/frontend/index.html +2 -2
  40. package/package.json +1 -1
  41. package/backend/src/flowent/static/assets/index-DqTHSMBo.js +0 -81
  42. package/backend/src/flowent/static/assets/index-d3FBbOXX.css +0 -2
  43. package/dist/frontend/assets/index-DqTHSMBo.js +0 -81
  44. package/dist/frontend/assets/index-d3FBbOXX.css +0 -2
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flowent"
3
- version = "0.1.0"
3
+ version = "0.1.1"
4
4
  description = "A workflow orchestration platform for multi-agent collaboration."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -105,7 +105,14 @@ class SkillSettingsRequest(BaseModel):
105
105
  class McpImportRequest(BaseModel):
106
106
  model_config = ConfigDict(extra="forbid")
107
107
 
108
- duplicate_action: Literal["replace", "skip"] = "skip"
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.get("/api/mcp/import/preview")
372
- async def preview_mcp_import() -> McpImportDiscovery:
373
- return discover_imported_mcp_servers(Path.cwd())
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(Path.cwd()).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 request.duplicate_action == "skip" and server.id in existing_servers:
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, source in candidate_mcp_config_files(workspace, user_home):
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, source, workspace)
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=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=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
- (cwd / ".mcp.json", "claude_code"),
76
- (cwd / ".claude" / "settings.local.json", "claude_code"),
77
- (cwd / ".claude" / "settings.json", "claude_code"),
78
- (home / ".claude.json", "claude_code"),
79
- (home / ".claude" / "settings.json", "claude_code"),
80
- (cwd / ".codex" / "config.toml", "codex"),
81
- (home / ".codex" / "config.toml", "codex"),
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: