@agentsdock/server 1.0.11-beta.2 → 1.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsdock/server",
3
- "version": "1.0.11-beta.2",
3
+ "version": "1.0.11",
4
4
  "description": "AgentsDock's self-hosted Python server and explicit installation CLI",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/server/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.11-beta.2
1
+ 1.0.11
@@ -32364,6 +32364,9 @@ SEMANTIC_TIMELINE_EVENT_BUDGET_PER_ITEM = 4
32364
32364
  SEMANTIC_TIMELINE_ESSENTIAL_LIMIT_PER_ITEM = 32
32365
32365
  SEMANTIC_TIMELINE_ESSENTIAL_PAGE_OVERFLOW_LIMIT = 128
32366
32366
  SEMANTIC_TIMELINE_TRACE_ANCHOR_PAGE_OVERFLOW_LIMIT = 128
32367
+ # Same-ID history corrections clear previously cached replay bubbles. They
32368
+ # need their own bounded allowance, not the slots reserved for chat content.
32369
+ SEMANTIC_TIMELINE_REPAIR_PAGE_OVERFLOW_LIMIT = 256
32367
32370
  JOB_RUN_HISTORY_TEXT_LIMIT = 64 * 1024
32368
32371
  SEMANTIC_TIMELINE_ESSENTIAL_DETAIL_TYPES = {
32369
32372
  "artifact_created",
@@ -35760,9 +35763,6 @@ def collect_semantic_timeline_events(
35760
35763
  deduplicated[identity] = event
35761
35764
  return True
35762
35765
 
35763
- for event in page_repairs:
35764
- append_with_limit(event, event_limit)
35765
-
35766
35766
  # Every selected semantic item gets one representative before any item
35767
35767
  # receives detail. The page-size clamp in read_semantic_timeline_page()
35768
35768
  # guarantees that this baseline always fits.
@@ -35777,6 +35777,22 @@ def collect_semantic_timeline_events(
35777
35777
  for event in secondary:
35778
35778
  append_with_limit(event, event_limit)
35779
35779
 
35780
+ # Reserve both sides of ordinary turns before emitting repair receipts.
35781
+ # A single imported run can contain hundreds of corrected boundaries:
35782
+ # charging them to the ordinary budget used to leave only trace anchors
35783
+ # for recent turns. Extend that budget only by receipts actually added,
35784
+ # retaining its remaining detail capacity and the absolute response cap.
35785
+ repair_allowance = min(
35786
+ SEMANTIC_TIMELINE_REPAIR_PAGE_OVERFLOW_LIMIT,
35787
+ MAX_EVENT_RESPONSE_LIMIT - event_limit,
35788
+ )
35789
+ repair_limit = len(deduplicated) + repair_allowance
35790
+ repair_count = 0
35791
+ for event in page_repairs:
35792
+ if append_with_limit(event, repair_limit):
35793
+ repair_count += 1
35794
+ event_limit += repair_count
35795
+
35780
35796
  # Files and reviewable diffs are semantic output, not optional trace
35781
35797
  # detail. Give each selected item a generous but bounded overflow and also
35782
35798
  # cap total page overflow. This preserves normal multi-video workflows
@@ -50729,6 +50745,10 @@ def public_session(sess: dict[str, Any], *, summary: bool = False) -> dict[str,
50729
50745
  if sess.get("title") == "New chat" and not public["backend_locked"]:
50730
50746
  public["empty_chat_cleanup"] = "client-v1"
50731
50747
  public["codex_provider"] = codex_provider.session_choice(sess.get("codex_provider"))
50748
+ if summary and "codex_goal" in sess:
50749
+ goal = sess.get("codex_goal")
50750
+ public["codex_goal_status"] = goal.get("status") if isinstance(goal, dict) else None
50751
+ public["codex_goal_updated_at"] = goal.get("updatedAt") if isinstance(goal, dict) else None
50732
50752
  connection = sess.get("provider_connection") or "default"
50733
50753
  # Keep legacy native summaries sparse, but retain a stored default as the
50734
50754
  # tombstone that clears a previously selected custom API in client caches.
@@ -81506,6 +81526,22 @@ async def codex_provider_mcp(request: Request) -> Response:
81506
81526
  })
81507
81527
 
81508
81528
 
81529
+ @app.get("/api/connection-addresses")
81530
+ async def connection_addresses(request: Request) -> dict[str, Any]:
81531
+ require_native_admin_control(request)
81532
+ # Discover only on explicit QR sharing, never on the frequently polled health path.
81533
+ from server_instances import candidate_addresses, connection_choices, tailscale_status
81534
+
81535
+ def discover() -> list[str]:
81536
+ choices = connection_choices(
81537
+ SERVER_BIND_ADDRESS, SERVER_PORT,
81538
+ candidate_addresses(SERVER_BIND_ADDRESS, SERVER_PORT), tailscale_status(),
81539
+ )
81540
+ return list(dict.fromkeys(filter(None, [choices["tailscale"], *choices["lan"]])))[:6]
81541
+
81542
+ return {"version": 1, "server_identity": server_identity(), "urls": await asyncio.to_thread(discover)}
81543
+
81544
+
81509
81545
  @app.get("/api/health")
81510
81546
  async def health() -> dict[str, Any]:
81511
81547
  await reconcile_idle_queued_turns_from_health_poll()
@@ -91026,7 +91062,15 @@ def claude_completed_fork_boundary(
91026
91062
  # final projected message can identify the inclusive native cutoff.
91027
91063
  expected_text = projected_text if projected_text and final_text.endswith(projected_text) else final_text
91028
91064
  recorded_uuid = str(final_projection.get("provider_message_id") or "") if expected_text == projected_text else ""
91029
- cutoff_time = parse_job_timestamp(str(terminal.get("ts") or ""))
91065
+ cutoff_ts = str(terminal.get("ts") or "")
91066
+ cutoff_time = parse_job_timestamp(cutoff_ts)
91067
+ # now_iso() truncates server events to whole seconds; native Claude
91068
+ # records retain milliseconds. Only an exact completed-message UUID can
91069
+ # disambiguate another turn in that same second. Keep legacy text-only
91070
+ # matching and explicitly fractional timestamps on the strict cutoff.
91071
+ cutoff_second_is_truncated = bool(recorded_uuid and re.fullmatch(
91072
+ r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", cutoff_ts,
91073
+ ))
91030
91074
  started = next((
91031
91075
  event for event in reversed(events[:-1])
91032
91076
  if event.get("type") == "turn_started" and str(event.get("run_id") or "") == run_id
@@ -91047,7 +91091,11 @@ def claude_completed_fork_boundary(
91047
91091
  if not record_uuid or (recorded_uuid and record_uuid != recorded_uuid):
91048
91092
  continue
91049
91093
  record_time = parse_job_timestamp(str(record.get("timestamp") or ""))
91050
- if cutoff_time is None or record_time is None or record_time > cutoff_time:
91094
+ if cutoff_time is None or record_time is None:
91095
+ continue
91096
+ if record_time > cutoff_time and not (
91097
+ cutoff_second_is_truncated and record_time < cutoff_time + 1
91098
+ ):
91051
91099
  continue
91052
91100
  if not recorded_uuid and (start_time is None or record_time < start_time):
91053
91101
  continue
package/server/install.sh CHANGED
@@ -1387,6 +1387,13 @@ print_token_for_copy() {
1387
1387
  local copy_reply=""
1388
1388
  local clipboard_command=()
1389
1389
  printf '\nAccess token (%s):\n%s\n\n' "$INSTANCE_NAME" "$access_token"
1390
+ # Render locally, only in an interactive terminal. No credentials in argv.
1391
+ local pairing_script="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/npm/agentsdock/pair.cjs"
1392
+ if [[ -f "$pairing_script" ]] && command -v node >/dev/null 2>&1; then
1393
+ node "$pairing_script" "$INSTANCE_NAME" || true
1394
+ else
1395
+ printf 'Show a connection QR with: agentsdock pair %s\n' "$INSTANCE_NAME"
1396
+ fi
1390
1397
  # A remote clipboard is not the user's local clipboard. Do not emit OSC 52
1391
1398
  # sequences or attempt to modify a remote desktop's clipboard over SSH.
1392
1399
  if [[ -n "${SSH_CONNECTION:-}${SSH_CLIENT:-}${SSH_TTY:-}" ]]; then
@@ -1839,7 +1846,7 @@ if [[ "$TEAM_HUB_MODE" == "host" && "$TEAM_HUB_OPERATION_PENDING" != "true" \
1839
1846
  fi
1840
1847
  fi
1841
1848
 
1842
- RELEASE_FILES=(activation_transaction.py execution_activation.py execution_legacy_runner.py execution_preparation.py update_preparation.py update_handoff.py update_recovery.py execution_update_status.py execution_uninstall.py execution_recovery.py execution_recovery_status.py execution_http.py execution_durability.py execution_control.py execution_install.py execution_maintenance.py execution_manage.py execution_ownership.py execution_service.py execution_transport.py agent_server.py local_session_ownership.py cursor_history.py workspace_git.py team_hub_host.py secure_peer_runtime.py team_mail_runtime.py team_mail_websocket.py team_mail_grants.py secure_peer_delivery.py agentsdock_jobs.py agentsdock_chats.py chat_mailbox.py agentsdock_emergency.py agentsdock_publish.py agentsdock_mail.py agentsdock_team.py provider_commands.py provider_usage.py claude_sdk_client.py claude_model_catalog.py claude_goals.py claude_background_reconciliation.py codex_app_server.py codex_auth.py codex_provider.py codex_response_stream.py provider_connections.py cursor_api_key.py side_questions.py title_generation.py codex_side_question.py codex_side_chat_progress.py claude_side_question.py cursor_agent_client.py cursor_provider_mcp.py opencode_agent_client.py gemini_acp_client.py gemini_history.py gemini_content.py gemini_import.py gemini_runtime.py gemini_runner.py gemini_permissions.py gemini_api.py cursor_process_guard.py transcript_reader.py claude_history_repair.py claude_history_provenance.py codex_history_repair.py public_chat_shares.py public_chat_transcript.py public_chat_share_routes.py interactive_chat_shares.py interactive_chat_share_routes.py interactive_chat_share_web.py interactive_chat_projection.py interactive_chat_runtime.py interactive_chat_native.py shared_chat_videos.py shared_chat_video_stream.py interactive_chat_controls.py install.sh uninstall.sh instances.sh server_instances.py update_runner.py pyproject.toml uv.lock VERSION release-public-key.pem LICENSE NOTICE)
1849
+ RELEASE_FILES=(activation_transaction.py execution_activation.py execution_legacy_runner.py execution_preparation.py update_preparation.py update_handoff.py update_recovery.py execution_update_status.py execution_uninstall.py execution_recovery.py execution_recovery_status.py execution_http.py execution_durability.py execution_control.py execution_install.py execution_maintenance.py execution_manage.py execution_ownership.py execution_service.py execution_transport.py agent_server.py local_session_ownership.py cursor_history.py workspace_git.py team_hub_host.py secure_peer_runtime.py team_mail_runtime.py team_mail_websocket.py team_mail_grants.py secure_peer_delivery.py agentsdock_jobs.py agentsdock_chats.py chat_mailbox.py agentsdock_emergency.py agentsdock_publish.py agentsdock_mail.py agentsdock_team.py provider_commands.py provider_usage.py claude_sdk_client.py claude_model_catalog.py claude_goals.py claude_background_reconciliation.py codex_app_server.py codex_auth.py codex_provider.py codex_response_stream.py provider_connections.py cursor_api_key.py side_questions.py title_generation.py codex_side_question.py codex_side_chat_progress.py claude_side_question.py cursor_agent_client.py cursor_provider_mcp.py opencode_agent_client.py gemini_acp_client.py gemini_history.py gemini_content.py gemini_import.py gemini_runtime.py gemini_runner.py gemini_permissions.py gemini_api.py cursor_process_guard.py transcript_reader.py claude_history_repair.py claude_history_provenance.py codex_history_repair.py public_chat_shares.py public_chat_transcript.py public_chat_share_routes.py interactive_chat_shares.py interactive_chat_share_routes.py interactive_chat_share_web.py interactive_chat_projection.py interactive_chat_runtime.py interactive_chat_native.py shared_chat_videos.py shared_chat_analytics_web.py shared_chat_video_stream.py interactive_chat_controls.py install.sh uninstall.sh instances.sh server_instances.py npm/agentsdock/pair.cjs npm/agentsdock/qr-renderer.cjs npm/agentsdock/QR-NOTICES.txt update_runner.py pyproject.toml uv.lock VERSION release-public-key.pem LICENSE NOTICE)
1843
1850
  RELEASE_DIRECTORIES=(agentsdock_team_hub)
1844
1851
  TEAM_HUB_RELEASE_FILES=(
1845
1852
  __init__.py
@@ -1880,6 +1887,12 @@ TEAM_HUB_RELEASE_FILES=(
1880
1887
  migrations/0023_team_message_search.sql
1881
1888
  )
1882
1889
 
1890
+ for directory in npm npm/agentsdock; do
1891
+ if [[ ! -d "$SOURCE_DIR/$directory" || -L "$SOURCE_DIR/$directory" ]]; then
1892
+ echo "$directory is missing beside install.sh or is not a real directory." >&2
1893
+ exit 1
1894
+ fi
1895
+ done
1883
1896
  for name in "${RELEASE_FILES[@]}"; do
1884
1897
  if [[ ! -f "$SOURCE_DIR/$name" || -L "$SOURCE_DIR/$name" ]]; then
1885
1898
  echo "$name is missing beside install.sh or is not a regular release file." >&2
@@ -3785,12 +3798,13 @@ validate_staged_release_runtime() (
3785
3798
  "$STAGE_DIR/interactive_chat_runtime.py" \
3786
3799
  "$STAGE_DIR/interactive_chat_native.py" \
3787
3800
  "$STAGE_DIR/shared_chat_videos.py" \
3801
+ "$STAGE_DIR/shared_chat_analytics_web.py" \
3788
3802
  "$STAGE_DIR/shared_chat_video_stream.py" \
3789
3803
  "$STAGE_DIR/interactive_chat_controls.py" \
3790
3804
  "$STAGE_DIR/update_runner.py"
3791
3805
  "$STAGE_DIR/.venv/bin/python" -m py_compile "$STAGE_DIR/server_instances.py"
3792
3806
  "$STAGE_DIR/.venv/bin/python" -m compileall -q "$STAGE_DIR/agentsdock_team_hub"
3793
- PYTHONPATH="$STAGE_DIR" "$STAGE_DIR/.venv/bin/python" -c 'import execution_activation, execution_preparation, update_preparation, update_handoff, update_recovery, execution_update_status, execution_uninstall, execution_recovery, execution_recovery_status, execution_http, execution_durability, execution_control, execution_install, execution_maintenance, execution_manage, execution_ownership, execution_service, execution_transport; import workspace_git, claude_model_catalog, server_instances, local_session_ownership, cursor_history; import codex_auth, codex_provider, codex_response_stream, provider_connections, cursor_api_key, side_questions, title_generation, codex_side_question, codex_side_chat_progress, claude_side_question, agentsdock_team_hub, cursor_agent_client, cursor_provider_mcp, opencode_agent_client, gemini_acp_client, gemini_history, gemini_content, gemini_import, gemini_runtime, gemini_runner, gemini_permissions, gemini_api, cursor_process_guard, secure_peer_delivery, secure_peer_runtime, team_mail_runtime, team_mail_websocket, team_mail_grants, team_hub_host, agentsdock_mail, agentsdock_team, transcript_reader, claude_history_repair, claude_history_provenance, claude_goals, claude_background_reconciliation, codex_history_repair, public_chat_shares, public_chat_transcript, public_chat_share_routes, interactive_chat_shares, interactive_chat_share_routes, interactive_chat_share_web, interactive_chat_projection, interactive_chat_runtime, interactive_chat_native, shared_chat_videos, shared_chat_video_stream, interactive_chat_controls, chat_mailbox, provider_commands, provider_usage; from agentsdock_team_hub import secure_peer, secure_peer_hub' >/dev/null
3807
+ PYTHONPATH="$STAGE_DIR" "$STAGE_DIR/.venv/bin/python" -c 'import execution_activation, execution_preparation, update_preparation, update_handoff, update_recovery, execution_update_status, execution_uninstall, execution_recovery, execution_recovery_status, execution_http, execution_durability, execution_control, execution_install, execution_maintenance, execution_manage, execution_ownership, execution_service, execution_transport; import workspace_git, claude_model_catalog, server_instances, local_session_ownership, cursor_history; import codex_auth, codex_provider, codex_response_stream, provider_connections, cursor_api_key, side_questions, title_generation, codex_side_question, codex_side_chat_progress, claude_side_question, agentsdock_team_hub, cursor_agent_client, cursor_provider_mcp, opencode_agent_client, gemini_acp_client, gemini_history, gemini_content, gemini_import, gemini_runtime, gemini_runner, gemini_permissions, gemini_api, cursor_process_guard, secure_peer_delivery, secure_peer_runtime, team_mail_runtime, team_mail_websocket, team_mail_grants, team_hub_host, agentsdock_mail, agentsdock_team, transcript_reader, claude_history_repair, claude_history_provenance, claude_goals, claude_background_reconciliation, codex_history_repair, public_chat_shares, public_chat_transcript, public_chat_share_routes, interactive_chat_shares, interactive_chat_share_routes, interactive_chat_share_web, interactive_chat_projection, interactive_chat_runtime, interactive_chat_native, shared_chat_videos, shared_chat_analytics_web, shared_chat_video_stream, interactive_chat_controls, chat_mailbox, provider_commands, provider_usage; from agentsdock_team_hub import secure_peer, secure_peer_hub' >/dev/null
3794
3808
  )
3795
3809
 
3796
3810
  abort_unclaimed_team_hub_reactivation() {
@@ -4108,6 +4122,7 @@ if [[ "$stage_identity" != *$'\n'* \
4108
4122
  exit 1
4109
4123
  fi
4110
4124
  for name in "${RELEASE_FILES[@]}"; do
4125
+ mkdir -p "$(dirname -- "$STAGE_DIR/$name")"
4111
4126
  install -m 644 "$SOURCE_DIR/$name" "$STAGE_DIR/$name"
4112
4127
  done
4113
4128
  mkdir -p "$STAGE_DIR/agentsdock_team_hub/migrations"
@@ -47,7 +47,7 @@ HTTP_COOKIE = "AgentsDock-Chat"
47
47
  HEADERS = {
48
48
  "Cache-Control": "no-store", "Referrer-Policy": "no-referrer", "X-Content-Type-Options": "nosniff",
49
49
  "X-Robots-Tag": "noindex, nofollow, noarchive", "Cross-Origin-Resource-Policy": "same-origin",
50
- "Content-Security-Policy": "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'",
50
+ "Content-Security-Policy": "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://api.mixpanel.com; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'",
51
51
  }
52
52
 
53
53