synapse-orch-ai 1.8.3 → 1.8.4

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 (65) hide show
  1. package/backend/core/config.py +2 -2
  2. package/backend/core/json_store.py +2 -2
  3. package/backend/core/mcp_client.py +4 -4
  4. package/backend/core/messaging/store.py +2 -2
  5. package/backend/core/orchestration/state.py +7 -3
  6. package/backend/core/orchestration/steps.py +3 -3
  7. package/backend/core/personal_details.py +2 -2
  8. package/backend/core/react_engine.py +1 -1
  9. package/backend/core/routes/data.py +6 -6
  10. package/backend/core/routes/import_export.py +2 -2
  11. package/backend/core/routes/settings.py +6 -6
  12. package/backend/core/routes/tools.py +1 -1
  13. package/backend/core/scale/context.py +1 -1
  14. package/backend/core/scale/sync.py +1 -1
  15. package/backend/core/server.py +3 -3
  16. package/backend/core/tools.py +1 -1
  17. package/backend/services/code_indexer.py +2 -2
  18. package/backend/services/google.py +7 -7
  19. package/backend/services/synthetic_data.py +1 -1
  20. package/backend/tools/bash.py +1 -1
  21. package/backend/tools/code_search.py +2 -2
  22. package/backend/tools/sandbox.py +1 -1
  23. package/backend/tools/sql_agent.py +1 -1
  24. package/frontend-build/.next/BUILD_ID +1 -1
  25. package/frontend-build/.next/build-manifest.json +3 -3
  26. package/frontend-build/.next/prerender-manifest.json +3 -3
  27. package/frontend-build/.next/server/app/_global-error.html +1 -1
  28. package/frontend-build/.next/server/app/_global-error.rsc +1 -1
  29. package/frontend-build/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  30. package/frontend-build/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  31. package/frontend-build/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  32. package/frontend-build/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  33. package/frontend-build/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  34. package/frontend-build/.next/server/app/_not-found.html +1 -1
  35. package/frontend-build/.next/server/app/_not-found.rsc +1 -1
  36. package/frontend-build/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  37. package/frontend-build/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  38. package/frontend-build/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  39. package/frontend-build/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  40. package/frontend-build/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  41. package/frontend-build/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  42. package/frontend-build/.next/server/app/index.html +1 -1
  43. package/frontend-build/.next/server/app/index.rsc +1 -1
  44. package/frontend-build/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  45. package/frontend-build/.next/server/app/index.segments/_full.segment.rsc +1 -1
  46. package/frontend-build/.next/server/app/index.segments/_head.segment.rsc +1 -1
  47. package/frontend-build/.next/server/app/index.segments/_index.segment.rsc +1 -1
  48. package/frontend-build/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  49. package/frontend-build/.next/server/app/login.html +1 -1
  50. package/frontend-build/.next/server/app/login.rsc +1 -1
  51. package/frontend-build/.next/server/app/login.segments/_full.segment.rsc +1 -1
  52. package/frontend-build/.next/server/app/login.segments/_head.segment.rsc +1 -1
  53. package/frontend-build/.next/server/app/login.segments/_index.segment.rsc +1 -1
  54. package/frontend-build/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  55. package/frontend-build/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  56. package/frontend-build/.next/server/app/login.segments/login.segment.rsc +1 -1
  57. package/frontend-build/.next/server/middleware-build-manifest.js +3 -3
  58. package/frontend-build/.next/server/pages/404.html +1 -1
  59. package/frontend-build/.next/server/pages/500.html +1 -1
  60. package/frontend-build/.next/server/server-reference-manifest.js +1 -1
  61. package/frontend-build/.next/server/server-reference-manifest.json +1 -1
  62. package/package.json +1 -1
  63. /package/frontend-build/.next/static/{a-CFL11mzxHaVjsbJG19x → WjvzoOqaNaXuc-wYMNArI}/_buildManifest.js +0 -0
  64. /package/frontend-build/.next/static/{a-CFL11mzxHaVjsbJG19x → WjvzoOqaNaXuc-wYMNArI}/_clientMiddlewareManifest.js +0 -0
  65. /package/frontend-build/.next/static/{a-CFL11mzxHaVjsbJG19x → WjvzoOqaNaXuc-wYMNArI}/_ssgManifest.js +0 -0
@@ -129,7 +129,7 @@ def load_settings():
129
129
  file_settings = {}
130
130
  else:
131
131
  try:
132
- with open(SETTINGS_FILE, 'r') as f:
132
+ with open(SETTINGS_FILE, 'r', encoding="utf-8") as f:
133
133
  file_settings = json.load(f)
134
134
  except Exception as e:
135
135
  print(f"DEBUG: Error loading settings: {e}")
@@ -168,7 +168,7 @@ def get_or_create_jwt_secret() -> str:
168
168
 
169
169
  if env_file.exists():
170
170
  try:
171
- for line in env_file.read_text().splitlines():
171
+ for line in env_file.read_text(encoding="utf-8").splitlines():
172
172
  line = line.strip()
173
173
  if line.startswith(f"{var}=") and len(line) > len(f"{var}="):
174
174
  val = line.split("=", 1)[1].strip()
@@ -32,7 +32,7 @@ class JsonStore:
32
32
  if not os.path.exists(self.path):
33
33
  return self.default_factory()
34
34
  try:
35
- with open(self.path, "r") as f:
35
+ with open(self.path, "r", encoding="utf-8") as f:
36
36
  data = json.load(f)
37
37
  if self._cache_ttl > 0:
38
38
  self._cache = data
@@ -43,7 +43,7 @@ class JsonStore:
43
43
 
44
44
  def save(self, data):
45
45
  with self._lock:
46
- with open(self.path, "w") as f:
46
+ with open(self.path, "w", encoding="utf-8") as f:
47
47
  json.dump(data, f, indent=4)
48
48
  if self._cache_ttl > 0:
49
49
  self._cache = data
@@ -69,14 +69,14 @@ class FileTokenStorage(TokenStorage):
69
69
  if not os.path.exists(path):
70
70
  return None
71
71
  try:
72
- with open(path) as f:
72
+ with open(path, encoding="utf-8") as f:
73
73
  return json.load(f)
74
74
  except Exception:
75
75
  return None
76
76
 
77
77
  def _write(self, path: str, data: dict):
78
78
  os.makedirs(MCP_TOKENS_DIR, exist_ok=True)
79
- with open(path, "w") as f:
79
+ with open(path, "w", encoding="utf-8") as f:
80
80
  json.dump(data, f, indent=2)
81
81
 
82
82
  async def get_tokens(self) -> Optional[OAuthToken]:
@@ -181,7 +181,7 @@ class MCPClientManager:
181
181
  if not os.path.exists(MCP_SERVERS_FILE):
182
182
  return []
183
183
  try:
184
- with open(MCP_SERVERS_FILE) as f:
184
+ with open(MCP_SERVERS_FILE, encoding="utf-8") as f:
185
185
  return json.load(f)
186
186
  except Exception as e:
187
187
  print(f"Error loading MCP servers config: {e}")
@@ -189,7 +189,7 @@ class MCPClientManager:
189
189
 
190
190
  def save_servers(self):
191
191
  os.makedirs(os.path.dirname(MCP_SERVERS_FILE), exist_ok=True)
192
- with open(MCP_SERVERS_FILE, "w") as f:
192
+ with open(MCP_SERVERS_FILE, "w", encoding="utf-8") as f:
193
193
  json.dump(self.servers_config, f, indent=4)
194
194
 
195
195
  def _set_status(self, name: str, status: str):
@@ -17,7 +17,7 @@ def _load_raw() -> list[dict]:
17
17
  if not os.path.exists(CHANNELS_FILE):
18
18
  return []
19
19
  try:
20
- with open(CHANNELS_FILE, "r") as f:
20
+ with open(CHANNELS_FILE, "r", encoding="utf-8") as f:
21
21
  data = json.load(f)
22
22
  return data if isinstance(data, list) else []
23
23
  except Exception:
@@ -26,7 +26,7 @@ def _load_raw() -> list[dict]:
26
26
 
27
27
  def _save_raw(data: list[dict]) -> None:
28
28
  os.makedirs(DATA_DIR, exist_ok=True)
29
- with open(CHANNELS_FILE, "w") as f:
29
+ with open(CHANNELS_FILE, "w", encoding="utf-8") as f:
30
30
  json.dump(data, f, indent=2)
31
31
 
32
32
 
@@ -41,7 +41,11 @@ class SharedState:
41
41
  # Atomic write: write to temp, then rename
42
42
  fd, tmp_path = tempfile.mkstemp(dir=RUNS_DIR, suffix=".tmp")
43
43
  try:
44
- with os.fdopen(fd, "w") as f:
44
+ # encoding="utf-8" is required: model_dump_json emits raw non-ASCII
45
+ # characters, and without an explicit encoding os.fdopen uses the
46
+ # platform default (cp1252 on Windows), which raises
47
+ # UnicodeEncodeError when a run's state contains non-ASCII text.
48
+ with os.fdopen(fd, "w", encoding="utf-8") as f:
45
49
  f.write(self.run.model_dump_json(indent=2))
46
50
  os.replace(tmp_path, target)
47
51
  except Exception:
@@ -55,7 +59,7 @@ class SharedState:
55
59
  path = RUNS_DIR / f"{run_id}.json"
56
60
  if not path.exists():
57
61
  raise FileNotFoundError(f"No checkpoint found for run {run_id}")
58
- data = json.loads(path.read_text())
62
+ data = json.loads(path.read_text(encoding="utf-8"))
59
63
  run = OrchestrationRun.model_validate(data)
60
64
  return cls(run)
61
65
 
@@ -66,7 +70,7 @@ class SharedState:
66
70
  runs = []
67
71
  for f in sorted(RUNS_DIR.glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True)[:limit]:
68
72
  try:
69
- data = json.loads(f.read_text())
73
+ data = json.loads(f.read_text(encoding="utf-8"))
70
74
  runs.append({
71
75
  "run_id": data.get("run_id"),
72
76
  "orchestration_id": data.get("orchestration_id"),
@@ -493,7 +493,7 @@ class ToolStepExecutor:
493
493
  tmp_dir = tempfile.mkdtemp(prefix="pytool_")
494
494
  script_path = f"{tmp_dir}/script.py"
495
495
  try:
496
- with open(script_path, "w") as f:
496
+ with open(script_path, "w", encoding="utf-8") as f:
497
497
  f.write(injected_code)
498
498
 
499
499
  docker_cmd = [
@@ -1161,7 +1161,7 @@ class TransformStepExecutor:
1161
1161
  tmp_dir = tempfile.mkdtemp(prefix="transform_host_")
1162
1162
  script_path = str(Path(tmp_dir) / "transform.py")
1163
1163
  try:
1164
- with open(script_path, "w") as f:
1164
+ with open(script_path, "w", encoding="utf-8") as f:
1165
1165
  f.write(script_content)
1166
1166
 
1167
1167
  proc = await asyncio.create_subprocess_exec(
@@ -1210,7 +1210,7 @@ class TransformStepExecutor:
1210
1210
  tmp_dir = tempfile.mkdtemp(prefix="transform_")
1211
1211
  script_path = f"{tmp_dir}/transform.py"
1212
1212
  try:
1213
- with open(script_path, "w") as f:
1213
+ with open(script_path, "w", encoding="utf-8") as f:
1214
1214
  f.write(script_content)
1215
1215
 
1216
1216
  docker_cmd = [
@@ -29,7 +29,7 @@ def load_personal_details() -> dict:
29
29
  return defaults
30
30
 
31
31
  try:
32
- with open(PERSONAL_DETAILS_FILE, "r") as f:
32
+ with open(PERSONAL_DETAILS_FILE, "r", encoding="utf-8") as f:
33
33
  data = json.load(f)
34
34
 
35
35
  # Merge root
@@ -54,7 +54,7 @@ def save_personal_details(details: dict) -> dict:
54
54
  addr = d.get("address") if isinstance(d.get("address"), dict) else {}
55
55
  normalized["address"] = {**defaults["address"], **addr}
56
56
 
57
- with open(PERSONAL_DETAILS_FILE, "w") as f:
57
+ with open(PERSONAL_DETAILS_FILE, "w", encoding="utf-8") as f:
58
58
  json.dump(normalized, f, indent=4)
59
59
 
60
60
  return normalized
@@ -1208,7 +1208,7 @@ async def run_agent_step(
1208
1208
  tmp_dir = _tempfile.mkdtemp(prefix="pytool_")
1209
1209
  script_path = f"{tmp_dir}/script.py"
1210
1210
  try:
1211
- with open(script_path, "w") as _f:
1211
+ with open(script_path, "w", encoding="utf-8") as _f:
1212
1212
  _f.write(injected_code)
1213
1213
 
1214
1214
  docker_cmd = [
@@ -120,7 +120,7 @@ async def _get_github_token() -> "str | None":
120
120
  hosts_path = config_dir / "hosts.json"
121
121
  if hosts_path.exists():
122
122
  try:
123
- data = _json.loads(hosts_path.read_text())
123
+ data = _json.loads(hosts_path.read_text(encoding="utf-8"))
124
124
  t = (data.get("github.com", {}).get("oauth_token")
125
125
  or data.get("github.com", {}).get("token"))
126
126
  if t:
@@ -131,7 +131,7 @@ async def _get_github_token() -> "str | None":
131
131
  config_path = Path.home() / ".copilot" / "config.json"
132
132
  if config_path.exists():
133
133
  try:
134
- data = _json.loads(config_path.read_text())
134
+ data = _json.loads(config_path.read_text(encoding="utf-8"))
135
135
  if t := (data.get("oauth_token") or data.get("token")):
136
136
  return t
137
137
  except Exception:
@@ -839,7 +839,7 @@ async def clear_memory_items(req: MemoryClearRequest):
839
839
  repos = []
840
840
  if os.path.exists(repos_path):
841
841
  try:
842
- with open(repos_path) as f:
842
+ with open(repos_path, encoding="utf-8") as f:
843
843
  repos = json.load(f)
844
844
  except Exception:
845
845
  pass
@@ -849,7 +849,7 @@ async def clear_memory_items(req: MemoryClearRequest):
849
849
  drop_index(repo["id"])
850
850
  except Exception as e:
851
851
  print(f"Error dropping index for repo {repo.get('id')}: {e}")
852
- with open(repos_path, "w") as f:
852
+ with open(repos_path, "w", encoding="utf-8") as f:
853
853
  json.dump([], f)
854
854
  results["repos"] = f"Cleared {len(repos)} repo(s)"
855
855
 
@@ -859,11 +859,11 @@ async def clear_memory_items(req: MemoryClearRequest):
859
859
  configs = []
860
860
  if os.path.exists(configs_path):
861
861
  try:
862
- with open(configs_path) as f:
862
+ with open(configs_path, encoding="utf-8") as f:
863
863
  configs = json.load(f)
864
864
  except Exception:
865
865
  pass
866
- with open(configs_path, "w") as f:
866
+ with open(configs_path, "w", encoding="utf-8") as f:
867
867
  json.dump([], f)
868
868
  results["db_configs"] = f"Cleared {len(configs)} config(s)"
869
869
 
@@ -48,7 +48,7 @@ def _load_mcp_servers() -> List[dict]:
48
48
  if not os.path.exists(MCP_SERVERS_FILE):
49
49
  return []
50
50
  try:
51
- with open(MCP_SERVERS_FILE) as f:
51
+ with open(MCP_SERVERS_FILE, encoding="utf-8") as f:
52
52
  return json.load(f)
53
53
  except Exception:
54
54
  return []
@@ -253,7 +253,7 @@ async def import_bundle(req: ImportRequest):
253
253
 
254
254
  if mcp_changed:
255
255
  os.makedirs(os.path.dirname(MCP_SERVERS_FILE), exist_ok=True)
256
- with open(MCP_SERVERS_FILE, "w") as f:
256
+ with open(MCP_SERVERS_FILE, "w", encoding="utf-8") as f:
257
257
  json.dump(existing_mcp, f, indent=4)
258
258
 
259
259
  # Always sync manager with authoritative disk state and attempt connections
@@ -270,7 +270,7 @@ async def upload_google_creds(request: Request):
270
270
  else:
271
271
  parsed = data
272
272
 
273
- with open(CREDENTIALS_FILE, 'w') as f:
273
+ with open(CREDENTIALS_FILE, 'w', encoding="utf-8") as f:
274
274
  json.dump(parsed, f, indent=4)
275
275
 
276
276
  return {"status": "success", "message": "Credentials saved successfully."}
@@ -290,7 +290,7 @@ async def upload_google_token(request: Request):
290
290
  else:
291
291
  parsed = data
292
292
 
293
- with open(TOKEN_FILE, 'w') as f:
293
+ with open(TOKEN_FILE, 'w', encoding="utf-8") as f:
294
294
  json.dump(parsed, f, indent=4)
295
295
 
296
296
  return {"status": "success", "message": "Token saved successfully."}
@@ -308,7 +308,7 @@ async def get_config():
308
308
  return {"has_credentials": False, "is_connected": False}
309
309
 
310
310
  try:
311
- with open(CREDENTIALS_FILE, 'r') as f:
311
+ with open(CREDENTIALS_FILE, 'r', encoding="utf-8") as f:
312
312
  creds = json.load(f)
313
313
  app_info = creds.get("web") or creds.get("installed", {})
314
314
 
@@ -320,7 +320,7 @@ async def get_config():
320
320
  user_email = None
321
321
  if has_token:
322
322
  try:
323
- with open(TOKEN_FILE, 'r') as tf:
323
+ with open(TOKEN_FILE, 'r', encoding="utf-8") as tf:
324
324
  token_data = json.load(tf)
325
325
  user_email = token_data.get("id_token_hint") or token_data.get("email")
326
326
  # google-auth stores it in the token as a raw JWT — try to decode the id_token
@@ -382,7 +382,7 @@ async def get_examples():
382
382
  if not os.path.exists(index_path):
383
383
  return []
384
384
  try:
385
- with open(index_path, "r") as f:
385
+ with open(index_path, "r", encoding="utf-8") as f:
386
386
  return json.load(f)
387
387
  except Exception as e:
388
388
  raise HTTPException(status_code=500, detail=f"Failed to load examples index: {e}")
@@ -400,7 +400,7 @@ async def get_example_bundle(example_id: str):
400
400
  if not os.path.exists(bundle_path):
401
401
  raise HTTPException(status_code=404, detail=f"Example pack '{example_id}' not found")
402
402
  try:
403
- with open(bundle_path, "r") as f:
403
+ with open(bundle_path, "r", encoding="utf-8") as f:
404
404
  return json.load(f)
405
405
  except Exception as e:
406
406
  raise HTTPException(status_code=500, detail=f"Failed to load example bundle: {e}")
@@ -307,7 +307,7 @@ async def test_python_tool(req: PythonTestRequest):
307
307
  script_path = os.path.join(tmp_dir, "script.py")
308
308
 
309
309
  try:
310
- with open(script_path, "w") as f:
310
+ with open(script_path, "w", encoding="utf-8") as f:
311
311
  f.write(injected_code)
312
312
 
313
313
  cmd = [
@@ -86,7 +86,7 @@ async def resolve_mcp_servers() -> list[dict]:
86
86
  try:
87
87
  from core.mcp_client import MCP_SERVERS_FILE
88
88
  import json
89
- with open(MCP_SERVERS_FILE) as f:
89
+ with open(MCP_SERVERS_FILE, encoding="utf-8") as f:
90
90
  return json.load(f)
91
91
  except Exception:
92
92
  return []
@@ -188,7 +188,7 @@ async def sync_mcp_servers_to_pg(
188
188
  Sensitive fields (token) are stripped before storing."""
189
189
  try:
190
190
  from core.mcp_client import MCP_SERVERS_FILE
191
- with open(MCP_SERVERS_FILE) as f:
191
+ with open(MCP_SERVERS_FILE, encoding="utf-8") as f:
192
192
  items = json.load(f)
193
193
  if not isinstance(items, list):
194
194
  items = []
@@ -97,7 +97,7 @@ def _get_repo_paths() -> list[str]:
97
97
  if not REPOS_FILE.exists():
98
98
  return []
99
99
  try:
100
- repos = json.loads(REPOS_FILE.read_text())
100
+ repos = json.loads(REPOS_FILE.read_text(encoding="utf-8"))
101
101
  return [r["path"] for r in repos if r.get("path") and os.path.isdir(r["path"])]
102
102
  except Exception as e:
103
103
  print(f"Warning: Could not load repo paths: {e}")
@@ -121,7 +121,7 @@ def _get_google_oauth_env() -> dict[str, str]:
121
121
  except Exception as e:
122
122
  print(f"Warning: Token refresh at startup failed: {e}")
123
123
  try:
124
- creds = json.loads(creds_file.read_text())
124
+ creds = json.loads(creds_file.read_text(encoding="utf-8"))
125
125
  installed = creds.get("installed", creds.get("web", {}))
126
126
  client_id = installed.get("client_id", "")
127
127
  client_secret = installed.get("client_secret", "")
@@ -139,7 +139,7 @@ def _get_google_oauth_env() -> dict[str, str]:
139
139
  if token_file.exists():
140
140
  try:
141
141
  import base64
142
- token_data = json.loads(token_file.read_text())
142
+ token_data = json.loads(token_file.read_text(encoding="utf-8"))
143
143
  email = token_data.get("email")
144
144
  if not email and token_data.get("token"):
145
145
  id_token = token_data["token"]
@@ -269,7 +269,7 @@ def build_system_prompt(agent_system_template, tools_json, session_id, session_s
269
269
  from core.config import TOKEN_FILE
270
270
  import os
271
271
  if os.path.exists(TOKEN_FILE):
272
- with open(TOKEN_FILE, "r") as f:
272
+ with open(TOKEN_FILE, "r", encoding="utf-8") as f:
273
273
  token_data = json.load(f)
274
274
  google_email = token_data.get("email")
275
275
  if not google_email and token_data.get("id_token"):
@@ -425,13 +425,13 @@ def _update_repo_status(repo_id: str, **fields):
425
425
  if not os.path.exists(repos_file):
426
426
  return
427
427
  with _repos_lock:
428
- with open(repos_file, "r") as f:
428
+ with open(repos_file, "r", encoding="utf-8") as f:
429
429
  repos = json.load(f)
430
430
  for r in repos:
431
431
  if r["id"] == repo_id:
432
432
  r.update(fields)
433
433
  break
434
- with open(repos_file, "w") as f:
434
+ with open(repos_file, "w", encoding="utf-8") as f:
435
435
  json.dump(repos, f, indent=4)
436
436
 
437
437
 
@@ -85,10 +85,10 @@ def _sync_token_to_mcp(token_data: dict, email: str | None = None) -> None:
85
85
  """Mirror token.json into google-credentials/ so workspace-mcp sees fresh creds."""
86
86
  try:
87
87
  os.makedirs(GOOGLE_CREDENTIALS_DIR, exist_ok=True)
88
- with open(GOOGLE_CREDENTIALS_DIR / "token.json", "w") as f:
88
+ with open(GOOGLE_CREDENTIALS_DIR / "token.json", "w", encoding="utf-8") as f:
89
89
  json.dump(token_data, f, indent=2)
90
90
  if email:
91
- with open(GOOGLE_CREDENTIALS_DIR / f"{email}.json", "w") as f:
91
+ with open(GOOGLE_CREDENTIALS_DIR / f"{email}.json", "w", encoding="utf-8") as f:
92
92
  json.dump(token_data, f, indent=2)
93
93
  except Exception as e:
94
94
  print(f"Warning: Failed to sync token to workspace-mcp dir: {e}")
@@ -108,7 +108,7 @@ def get_google_credentials():
108
108
  creds.refresh(Request())
109
109
  # Preserve fields like `email` that aren't part of creds.to_json()
110
110
  try:
111
- with open(TOKEN_FILE, "r") as f:
111
+ with open(TOKEN_FILE, "r", encoding="utf-8") as f:
112
112
  prior = json.load(f)
113
113
  except Exception:
114
114
  prior = {}
@@ -117,7 +117,7 @@ def get_google_credentials():
117
117
  merged = {**prior, **refreshed}
118
118
  if email:
119
119
  merged["email"] = email
120
- with open(TOKEN_FILE, "w") as token:
120
+ with open(TOKEN_FILE, "w", encoding="utf-8") as token:
121
121
  json.dump(merged, token, indent=2)
122
122
  _sync_token_to_mcp(merged, email)
123
123
  return creds
@@ -190,7 +190,7 @@ def finish_auth(code, redirect_uri):
190
190
  except Exception as e:
191
191
  print(f"Warning: Could not fetch user email after OAuth: {e}")
192
192
 
193
- with open(TOKEN_FILE, "w") as token:
193
+ with open(TOKEN_FILE, "w", encoding="utf-8") as token:
194
194
  json.dump(token_data, token, indent=2)
195
195
 
196
196
  print(f"DEBUG: token.json saved to {TOKEN_FILE}")
@@ -205,12 +205,12 @@ def finish_auth(code, redirect_uri):
205
205
  # 2. Save the token with the email formatted name
206
206
  if email:
207
207
  mcp_token_path = os.path.join(mcp_cred_dir, f"{email}.json")
208
- with open(mcp_token_path, "w") as token:
208
+ with open(mcp_token_path, "w", encoding="utf-8") as token:
209
209
  json.dump(token_data, token, indent=2)
210
210
  print(f"DEBUG: Synchronized token to workspace-mcp via {mcp_token_path}")
211
211
  # 3. Always save generic token.json just in case
212
212
  mcp_generic_token = os.path.join(mcp_cred_dir, "token.json")
213
- with open(mcp_generic_token, "w") as token:
213
+ with open(mcp_generic_token, "w", encoding="utf-8") as token:
214
214
  json.dump(token_data, token, indent=2)
215
215
 
216
216
  except Exception as e:
@@ -122,7 +122,7 @@ async def generate_synthetic_data(request: SyntheticDataRequest):
122
122
  record = json.loads(json_str)
123
123
 
124
124
  # Append to file immediatey (streaming save)
125
- with open(filepath, "a") as f:
125
+ with open(filepath, "a", encoding="utf-8") as f:
126
126
  f.write(json.dumps(record) + "\n")
127
127
 
128
128
  current_job["completed"] += 1
@@ -56,7 +56,7 @@ def _get_allowed_dirs() -> list[str]:
56
56
  repos_file = Path(DATA_DIR) / "repos.json"
57
57
  if repos_file.exists():
58
58
  try:
59
- repos = json.loads(repos_file.read_text())
59
+ repos = json.loads(repos_file.read_text(encoding="utf-8"))
60
60
  dirs += [
61
61
  r["path"]
62
62
  for r in repos
@@ -20,7 +20,7 @@ def _load_repo_paths() -> dict[str, str]:
20
20
  try:
21
21
  from core.config import DATA_DIR
22
22
  repos_file = os.path.join(DATA_DIR, "repos.json")
23
- with open(repos_file) as f:
23
+ with open(repos_file, encoding="utf-8") as f:
24
24
  repos = json.load(f)
25
25
  return {r["id"]: r["path"].rstrip("/") for r in repos if r.get("id") and r.get("path")}
26
26
  except Exception:
@@ -113,7 +113,7 @@ def _load_indexed_repo_ids() -> list[str]:
113
113
  try:
114
114
  from core.config import DATA_DIR
115
115
  repos_file = os.path.join(DATA_DIR, "repos.json")
116
- with open(repos_file) as f:
116
+ with open(repos_file, encoding="utf-8") as f:
117
117
  repos = json.load(f)
118
118
  return [r["id"] for r in repos if r.get("status") == "indexed" and r.get("id")]
119
119
  except Exception:
@@ -635,7 +635,7 @@ async def _handle_execute(args: dict) -> list[TextContent]:
635
635
  script_path = os.path.join(tmp_dir, "script.py")
636
636
 
637
637
  try:
638
- with open(script_path, "w") as f:
638
+ with open(script_path, "w", encoding="utf-8") as f:
639
639
  f.write(code)
640
640
 
641
641
  docker_cmd = _build_docker_cmd(
@@ -33,7 +33,7 @@ def _load_db_configs() -> list[dict]:
33
33
  if not os.path.exists(path):
34
34
  return []
35
35
  try:
36
- with open(path) as f:
36
+ with open(path, encoding="utf-8") as f:
37
37
  return json.load(f)
38
38
  except Exception:
39
39
  return []
@@ -1 +1 @@
1
- a-CFL11mzxHaVjsbJG19x
1
+ WjvzoOqaNaXuc-wYMNArI
@@ -7,9 +7,9 @@
7
7
  "static/chunks/03~yq9q893hmn.js"
8
8
  ],
9
9
  "lowPriorityFiles": [
10
- "static/a-CFL11mzxHaVjsbJG19x/_buildManifest.js",
11
- "static/a-CFL11mzxHaVjsbJG19x/_ssgManifest.js",
12
- "static/a-CFL11mzxHaVjsbJG19x/_clientMiddlewareManifest.js"
10
+ "static/WjvzoOqaNaXuc-wYMNArI/_buildManifest.js",
11
+ "static/WjvzoOqaNaXuc-wYMNArI/_ssgManifest.js",
12
+ "static/WjvzoOqaNaXuc-wYMNArI/_clientMiddlewareManifest.js"
13
13
  ],
14
14
  "rootMainFiles": [
15
15
  "static/chunks/0qmh881w772ef.js",
@@ -131,8 +131,8 @@
131
131
  "dynamicRoutes": {},
132
132
  "notFoundRoutes": [],
133
133
  "preview": {
134
- "previewModeId": "e10c825355c45b4ac6f734d5b0478e3e",
135
- "previewModeSigningKey": "c0137ec592306a86413e22c2003489d9e5d62816a6375bc6b7e142ff9c28c1b2",
136
- "previewModeEncryptionKey": "f5d891366c48ce01a2fbaaa6f4b9e7ba573e79bd2618e480e1a9745c065a5268"
134
+ "previewModeId": "1c0685efa521b0dbf779b45854109763",
135
+ "previewModeSigningKey": "b6cc2030a87c67166aa72e4b6b47c2a8a7458d02ab4755889ca0ec472d0d48b7",
136
+ "previewModeEncryptionKey": "fd5063f9886ee40652ea64012174055070a38c72eee5ec20b08bfcaa2039c4b0"
137
137
  }
138
138
  }
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0qmh881w772ef.js"/><script src="/_next/static/chunks/02i7dfk78~t~2.js" async=""></script><script src="/_next/static/chunks/0c7h~x4_chf35.js" async=""></script><script src="/_next/static/chunks/00xhsd~k-wxkl.js" async=""></script><script src="/_next/static/chunks/turbopack-09lztqg9--eu..js" async=""></script><script src="/_next/static/chunks/01xlw8hd842-c.js" async=""></script><script src="/_next/static/chunks/0m92kh92cfh_..js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0qmh881w772ef.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"a-CFL11mzxHaVjsbJG19x\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0qmh881w772ef.js"/><script src="/_next/static/chunks/02i7dfk78~t~2.js" async=""></script><script src="/_next/static/chunks/0c7h~x4_chf35.js" async=""></script><script src="/_next/static/chunks/00xhsd~k-wxkl.js" async=""></script><script src="/_next/static/chunks/turbopack-09lztqg9--eu..js" async=""></script><script src="/_next/static/chunks/01xlw8hd842-c.js" async=""></script><script src="/_next/static/chunks/0m92kh92cfh_..js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0qmh881w772ef.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"WjvzoOqaNaXuc-wYMNArI\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
@@ -6,7 +6,7 @@
6
6
  8:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"ViewportBoundary"]
7
7
  a:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"MetadataBoundary"]
8
8
  c:I[68027,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"default",1]
9
- 0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"a-CFL11mzxHaVjsbJG19x"}
9
+ 0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"WjvzoOqaNaXuc-wYMNArI"}
10
10
  d:[]
11
11
  7:"$Wd"
12
12
  9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]