engineering-platform 2.3.0__tar.gz → 2.3.1__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.
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/PKG-INFO +1 -1
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/pyproject.toml +1 -1
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/ENGINEERING_PLATFORM_CONFIG.json +10 -3
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/ENGINEERING_PLATFORM_VERSION.json +4 -4
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/dashboard.css +5 -1
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/dashboard.js +102 -20
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/dashboard_locales.mjs +10 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/component_logging.py +21 -3
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_version.py +1 -1
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_readiness.py +7 -6
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/providers.py +2 -2
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server.py +41 -4
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/templates/workspace-config.json +18 -4
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform.egg-info/PKG-INFO +1 -1
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/README.md +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/setup.cfg +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/__init__.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/__main__.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/agent_state.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/agent_trust.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/dashboard_status_store.mjs +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/operations-console/apple-touch-icon-dark.png +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/operations-console/apple-touch-icon-light.png +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/operations-console/icon-dark.png +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/operations-console/icon-light.png +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/operations-console/icon-transparent.png +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/assets/operations-console/manifest.webmanifest +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/capability_preflight.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/capability_review.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/central_data_transfer.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/central_database.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/central_store_migration.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/codex_capacity.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/codex_chat.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/codex_observability.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/component_lock.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/console_presentation.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/console_route_ownership.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/contracts/__init__.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/contracts/ep_consumer.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/contracts/models.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/contracts/projection.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/dashboard_browser_validation.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/dashboard_state.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/dashboard_supervisor.swift +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/dashboard_translation.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/dependabot_producer.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/drift_diagnostics.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/emergency_recovery.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/engineering_memory.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/ep_consumer_credentials.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/evidence_projection.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_activity.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_context.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_errors.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_evidence.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_executor.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_finalization.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_host.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_lease.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_lifecycle.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_models.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_readiness.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_reporting.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_repository.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_timeout_policy.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_timing.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_transaction.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/external_producer_binding.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/file_inbox.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/forensic_attribution.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/forensic_attribution_v2.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/forensic_delta.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/golden_scenario.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/historical_dashboard_configuration.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/host_admin.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/host_preflight.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/installation_relocation.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/investigation_ledger.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/legacy_inbox_migration.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/lifecycle_worker.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/live_status.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/local_api.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/local_api_keychain.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/local_repository_binding.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/managed_autonomy.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/managed_codex_runtime.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/parity_context.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/parity_lifecycle_dispatcher.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_admin.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_api.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_bootstrap.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_components.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/pr_check_repair.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/pr_evidence_backfill.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/producer.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/project_agent.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/project_agent_service.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/project_topology.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/prompt_history.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_context.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_context_benchmark.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_context_scope.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_interruption.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_process_identity.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_recovery.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_usage.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/qualification.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/qualification_runtime.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/recommendation_handoff.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/report_analysis.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/repository_attachment.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/repository_handoff.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/resources.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/reviewer_evidence.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/schemas/producer-readback-v1.2.schema.json +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/schemas/producer-readback-v1.schema.json +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/schemas/repository-attachment.schema.json +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server_console_services.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server_relay.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server_service.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/status_model.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/status_reconciliation.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/storage.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/submission_cli.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/submission_intake.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/submission_service.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/telemetry.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/validation_identity.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/validation_profile.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/version_preparation_delivery.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/workspace_preflight.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/worktree_provenance.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/worktree_tooling.py +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform.egg-info/SOURCES.txt +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform.egg-info/dependency_links.txt +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform.egg-info/entry_points.txt +0 -0
- {engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform.egg-info/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"platform": {
|
|
4
4
|
"id": "engineering-platform",
|
|
5
5
|
"name": "Engineering Platform",
|
|
6
|
-
"version": "2.3.
|
|
6
|
+
"version": "2.3.1",
|
|
7
7
|
"generation": 2,
|
|
8
8
|
"documentation_namespace": "engineering-platform",
|
|
9
9
|
"capability_registry_version": 1
|
|
@@ -11,8 +11,15 @@
|
|
|
11
11
|
"workspace": {
|
|
12
12
|
"id": "engineering-platform",
|
|
13
13
|
"name": "Engineering Platform",
|
|
14
|
-
"repository": {
|
|
15
|
-
|
|
14
|
+
"repository": {
|
|
15
|
+
"provider": "github",
|
|
16
|
+
"owner": "pcvantol",
|
|
17
|
+
"name": "engineering-platform",
|
|
18
|
+
"default_branch": "main"
|
|
19
|
+
},
|
|
20
|
+
"branding": {
|
|
21
|
+
"dashboard_title": "EP Operations"
|
|
22
|
+
},
|
|
16
23
|
"workspace_authorization": {
|
|
17
24
|
"allowed_roots": [],
|
|
18
25
|
"allowed_repositories": [],
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bootstrap_contract": "2026.12",
|
|
3
3
|
"checkpoint_format": 1,
|
|
4
|
-
"dashboard_version": "2.3.
|
|
4
|
+
"dashboard_version": "2.3.1",
|
|
5
5
|
"handoff_protocol": 1,
|
|
6
6
|
"memory_format": 2,
|
|
7
7
|
"minimum_codex_cli": "0.146.0",
|
|
8
8
|
"inbox_protocol": 1,
|
|
9
|
-
"platform_version": "2.3.
|
|
9
|
+
"platform_version": "2.3.1",
|
|
10
10
|
"report_format": 2,
|
|
11
|
-
"runner_version": "2.3.
|
|
11
|
+
"runner_version": "2.3.1",
|
|
12
12
|
"status_model": 1,
|
|
13
13
|
"storage_schema": 41,
|
|
14
|
-
"watcher_version": "2.3.
|
|
14
|
+
"watcher_version": "2.3.1"
|
|
15
15
|
}
|
|
@@ -1298,7 +1298,11 @@ html[data-theme="light"] #componentLogControls :is(input[type="date"],input[type
|
|
|
1298
1298
|
area. Do not add a later global bubble scroller: it would force short
|
|
1299
1299
|
messages to reserve scrollbar chrome and defeat the 2/3 area limit. */
|
|
1300
1300
|
@media (max-width:620px){.dashboard-status-banner{position:static}}
|
|
1301
|
-
.platform-attention{background:#5b4316;border-bottom:1px solid #f4c34f;color:#fff4d6;margin:0 0 18px}.platform-attention[hidden]{display:none}.platform-attention>summary{align-items:center;cursor:pointer;display:flex;gap:9px;list-style:none;padding:10px 16px}.platform-attention>summary::-webkit-details-marker{display:none}.platform-attention>summary::after{content:"▸";margin-left:auto}.platform-attention[open]>summary::after{content:"▾"}.platform-attention>summary strong{color:#ffd768}.platform-attention>summary span{background:#f4c34f;border-radius:999px;color:#2a2415;font-size:12px;font-weight:800;min-width:1.4rem;padding:2px 5px;text-align:center}.platform-attention__items{display:grid;gap:8px;padding:0 12px 12px}.platform-attention__items .dashboard-status-banner{margin:0;position:static}.platform-attention__items .dashboard-status-banner--provider-readiness{align-items:flex-start}.platform-attention__items .provider-readiness-banner__action{align-self:center}
|
|
1301
|
+
.platform-attention{background:#5b4316;border-bottom:1px solid #f4c34f;color:#fff4d6;margin:0 0 18px}.platform-attention[hidden]{display:none}.platform-attention>summary{align-items:center;cursor:pointer;display:flex;gap:9px;list-style:none;padding:10px 16px}.platform-attention>summary::-webkit-details-marker{display:none}.platform-attention>summary::after{content:"▸";font-size:24px;font-weight:700;line-height:1;margin-left:auto}.platform-attention[open]>summary::after{content:"▾"}.platform-attention>summary strong{color:#ffd768}.platform-attention>summary span{background:#f4c34f;border-radius:999px;color:#2a2415;font-size:12px;font-weight:800;min-width:1.4rem;padding:2px 5px;text-align:center}.platform-attention__items{display:grid;gap:8px;padding:0 12px 12px}.platform-attention__items .dashboard-status-banner{margin:0;position:static}.platform-attention__items .dashboard-status-banner--provider-readiness{align-items:flex-start}.platform-attention__items .provider-readiness-banner__action{align-self:center}
|
|
1302
|
+
|
|
1303
|
+
/* An expanded provider failure is its own red banner, not content inside an
|
|
1304
|
+
amber frame. Keep the amber summary, but leave the failure card unframed. */
|
|
1305
|
+
.platform-attention[open]{background:transparent;border:0}.platform-attention[open]>summary{background:#5b4316;border-bottom:1px solid #f4c34f}.platform-attention[open] .platform-attention__items{padding:8px 0 0}
|
|
1302
1306
|
|
|
1303
1307
|
/* Buttons are controls, not text links: every visible action gets a modest
|
|
1304
1308
|
fill derived from its own ink/border colour. Semantic local-file links and
|
|
@@ -3522,6 +3522,21 @@ function healthComponentLabel(component) {
|
|
|
3522
3522
|
);
|
|
3523
3523
|
return definition?.name_key ? t(definition.name_key) : component;
|
|
3524
3524
|
}
|
|
3525
|
+
function componentLogDetails(entry) {
|
|
3526
|
+
const details = String(entry?.details || ""),
|
|
3527
|
+
component = typeof entry?.target_component === "string" && entry.target_component
|
|
3528
|
+
? entry.target_component
|
|
3529
|
+
: entry?.component,
|
|
3530
|
+
version = latestPlatformHealth?.components?.[component]?.version;
|
|
3531
|
+
// Old records did not persist a component version. The display therefore
|
|
3532
|
+
// identifies the observed current version, without rewriting historical
|
|
3533
|
+
// evidence or inventing one when health has no version.
|
|
3534
|
+
if (
|
|
3535
|
+
typeof version !== "string" || !version ||
|
|
3536
|
+
/(?:^| · )(?:target_)?component_version:/.test(details)
|
|
3537
|
+
) return details || "—";
|
|
3538
|
+
return (details ? details + " · " : "") + "component_version: " + version;
|
|
3539
|
+
}
|
|
3525
3540
|
const LEGACY_TRANSPORT_STATUS_CODES = Object.freeze({
|
|
3526
3541
|
HEALTHY: "HTTP_INGRESS_HEALTHY", DOWN: "HTTP_INGRESS_DOWN", AVAILABLE: "CLI_INGRESS_AVAILABLE",
|
|
3527
3542
|
DEGRADED: "FILE_INGRESS_DEGRADED", RUNNING: "FILE_INGRESS_RUNNING", NOT_READY: "FILE_INGRESS_NOT_READY", STOPPED: "FILE_INGRESS_STOPPED",
|
|
@@ -4698,7 +4713,7 @@ function componentLogText(entries) {
|
|
|
4698
4713
|
entry.level,
|
|
4699
4714
|
entry.event,
|
|
4700
4715
|
entry.runId || "—",
|
|
4701
|
-
entry
|
|
4716
|
+
componentLogDetails(entry),
|
|
4702
4717
|
JSON.stringify(entry),
|
|
4703
4718
|
].join("\t"));
|
|
4704
4719
|
return [header, ...rows].join("\n");
|
|
@@ -4886,7 +4901,7 @@ function renderComponentLogs() {
|
|
|
4886
4901
|
],
|
|
4887
4902
|
["", logEventLabel(entry.event)],
|
|
4888
4903
|
["", entry.runId || "—"],
|
|
4889
|
-
["", entry
|
|
4904
|
+
["", componentLogDetails(entry)],
|
|
4890
4905
|
]) {
|
|
4891
4906
|
const cell = document.createElement("td");
|
|
4892
4907
|
cell.className = name;
|
|
@@ -6274,6 +6289,32 @@ syncStickyHeaderOffset();
|
|
|
6274
6289
|
syncFooterOffset();
|
|
6275
6290
|
const providerReadinessActions = new Map();
|
|
6276
6291
|
let providerInteractiveRepairInProgress = false;
|
|
6292
|
+
const PROVIDER_READINESS_RECOVERY_MAX_ATTEMPTS = 3,
|
|
6293
|
+
PROVIDER_READINESS_RECOVERY_DELAY_MS = 2_000;
|
|
6294
|
+
let providerReadinessRecoveryAttempts = 0, providerReadinessRecoveryTimer = null;
|
|
6295
|
+
function resetProviderReadinessRecovery() {
|
|
6296
|
+
providerReadinessRecoveryAttempts = 0;
|
|
6297
|
+
if (providerReadinessRecoveryTimer !== null)
|
|
6298
|
+
window.clearTimeout(providerReadinessRecoveryTimer);
|
|
6299
|
+
providerReadinessRecoveryTimer = null;
|
|
6300
|
+
}
|
|
6301
|
+
function scheduleProviderReadinessRecovery(providers) {
|
|
6302
|
+
const hasTransientFailure = PROVIDER_READINESS_KEYS.some(
|
|
6303
|
+
(key) => providerReadinessState(providers, key) === "CHECK_FAILED",
|
|
6304
|
+
);
|
|
6305
|
+
if (!hasTransientFailure) return resetProviderReadinessRecovery();
|
|
6306
|
+
if (providerReadinessRecoveryAttempts >= PROVIDER_READINESS_RECOVERY_MAX_ATTEMPTS) {
|
|
6307
|
+
providerReadinessRecoveryTimer = null;
|
|
6308
|
+
return;
|
|
6309
|
+
}
|
|
6310
|
+
if (providerReadinessRecoveryTimer !== null)
|
|
6311
|
+
window.clearTimeout(providerReadinessRecoveryTimer);
|
|
6312
|
+
providerReadinessRecoveryAttempts += 1;
|
|
6313
|
+
providerReadinessRecoveryTimer = window.setTimeout(
|
|
6314
|
+
() => void refreshProviderLoginStatus(),
|
|
6315
|
+
providerReadinessRecoveryAttempts * PROVIDER_READINESS_RECOVERY_DELAY_MS,
|
|
6316
|
+
);
|
|
6317
|
+
}
|
|
6277
6318
|
function providerDisplayName(provider) {
|
|
6278
6319
|
return provider === "CODEX" || provider === "codex" ? "Codex" : "GitHub";
|
|
6279
6320
|
}
|
|
@@ -6362,14 +6403,17 @@ async function refreshProviderLoginStatus() {
|
|
|
6362
6403
|
fetch("/api/provider-login-status", probeOptions),
|
|
6363
6404
|
fetch("/api/execution-runtime-status", probeOptions),
|
|
6364
6405
|
]);
|
|
6406
|
+
let providers = CHECK_FAILED_PROVIDERS;
|
|
6365
6407
|
try {
|
|
6366
6408
|
if (providerResult.status !== "fulfilled") throw Error();
|
|
6367
6409
|
const response = providerResult.value, payload = await response.json();
|
|
6368
6410
|
if (!response.ok || !payload || typeof payload.providers !== "object") throw Error();
|
|
6369
|
-
|
|
6411
|
+
providers = payload.providers;
|
|
6412
|
+
renderProviderLoginStatus(block, providers);
|
|
6370
6413
|
} catch {
|
|
6371
|
-
renderProviderLoginStatus(block,
|
|
6414
|
+
renderProviderLoginStatus(block, providers);
|
|
6372
6415
|
}
|
|
6416
|
+
scheduleProviderReadinessRecovery(providers);
|
|
6373
6417
|
try {
|
|
6374
6418
|
if (runtimeResult.status !== "fulfilled") throw Error();
|
|
6375
6419
|
const response = runtimeResult.value, runtime = await response.json();
|
|
@@ -7126,22 +7170,34 @@ renderPlatformHealth = (payload) => {
|
|
|
7126
7170
|
components ? { ...payload, components: components } : payload,
|
|
7127
7171
|
);
|
|
7128
7172
|
};
|
|
7129
|
-
|
|
7173
|
+
function componentUptimeSeconds(payload, component) {
|
|
7174
|
+
const uptime = Number(payload?.components?.[component]?.uptime_seconds);
|
|
7175
|
+
return Number.isFinite(uptime) && uptime >= 0 ? uptime : null;
|
|
7176
|
+
}
|
|
7177
|
+
async function confirmComponentRestart(component, previousUptimeSeconds = null) {
|
|
7130
7178
|
for (let attempt = 0; attempt < 5; attempt++) {
|
|
7131
7179
|
await new Promise((resolve) => setTimeout(resolve, 1250));
|
|
7132
7180
|
try {
|
|
7133
7181
|
const response = await fetch("/health", { cache: "no-store" }),
|
|
7134
7182
|
payload = await response.json();
|
|
7135
7183
|
if (response.ok && payload?.components?.[component]?.healthy) {
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7184
|
+
const currentUptimeSeconds = componentUptimeSeconds(payload, component),
|
|
7185
|
+
restartConfirmed = previousUptimeSeconds === null ||
|
|
7186
|
+
(currentUptimeSeconds !== null && currentUptimeSeconds < previousUptimeSeconds);
|
|
7187
|
+
if (restartConfirmed) {
|
|
7188
|
+
restartingPlatformComponents.delete(component);
|
|
7189
|
+
renderPlatformHealth(payload);
|
|
7190
|
+
$("componentModalStatus").textContent = t("ui.component_restart_available");
|
|
7191
|
+
return true;
|
|
7192
|
+
}
|
|
7140
7193
|
}
|
|
7141
7194
|
renderPlatformHealth(payload);
|
|
7142
7195
|
} catch {}
|
|
7143
7196
|
}
|
|
7144
|
-
$("componentModalStatus").textContent =
|
|
7197
|
+
$("componentModalStatus").textContent = previousUptimeSeconds === null
|
|
7198
|
+
? t("ui.component_restart_unconfirmed")
|
|
7199
|
+
: t("ui.component_restart_waiting");
|
|
7200
|
+
return false;
|
|
7145
7201
|
}
|
|
7146
7202
|
const formatComponentUptimeForMeasuredValues = formatComponentUptime;
|
|
7147
7203
|
formatComponentUptime = (value) => {
|
|
@@ -8470,7 +8526,13 @@ async function restartPlatformComponent(button) {
|
|
|
8470
8526
|
t("component.restart_title"),
|
|
8471
8527
|
);
|
|
8472
8528
|
if (!confirmed) return;
|
|
8529
|
+
const previousUptimeSeconds = componentUptimeSeconds(
|
|
8530
|
+
latestPlatformHealthPayload,
|
|
8531
|
+
component,
|
|
8532
|
+
);
|
|
8473
8533
|
button.disabled = true;
|
|
8534
|
+
restartingPlatformComponents.add(component);
|
|
8535
|
+
$("componentModalStatus").textContent = t("ui.component_restart_started");
|
|
8474
8536
|
try {
|
|
8475
8537
|
const response = await fetch(
|
|
8476
8538
|
"/api/components/" + encodeURIComponent(component) + "/restart",
|
|
@@ -8481,7 +8543,11 @@ async function restartPlatformComponent(button) {
|
|
|
8481
8543
|
},
|
|
8482
8544
|
),
|
|
8483
8545
|
payload = await response.json();
|
|
8484
|
-
if (!response.ok)
|
|
8546
|
+
if (!response.ok) {
|
|
8547
|
+
restartingPlatformComponents.delete(component);
|
|
8548
|
+
$("componentModalStatus").textContent = t("ui.component_restart_failed");
|
|
8549
|
+
return;
|
|
8550
|
+
}
|
|
8485
8551
|
if (component === "dashboard") {
|
|
8486
8552
|
$("componentModalStatus").textContent =
|
|
8487
8553
|
t("ui.component_restart_started");
|
|
@@ -8489,9 +8555,12 @@ async function restartPlatformComponent(button) {
|
|
|
8489
8555
|
window.setTimeout(() => window.location.reload(), 750);
|
|
8490
8556
|
return;
|
|
8491
8557
|
}
|
|
8492
|
-
|
|
8558
|
+
void confirmComponentRestart(component, previousUptimeSeconds);
|
|
8493
8559
|
} catch {
|
|
8494
|
-
|
|
8560
|
+
// Restarting the relay can close this connection before its response is
|
|
8561
|
+
// delivered. Never mistake that expected hand-off for proof of failure;
|
|
8562
|
+
// require a fresh health observation instead.
|
|
8563
|
+
void confirmComponentRestart(component, previousUptimeSeconds);
|
|
8495
8564
|
} finally {
|
|
8496
8565
|
button.disabled = false;
|
|
8497
8566
|
}
|
|
@@ -8668,12 +8737,25 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
8668
8737
|
}).observe(status, { childList: true, characterData: true, subtree: true });
|
|
8669
8738
|
});
|
|
8670
8739
|
|
|
8740
|
+
const RELOCATION_ERROR_CODES = new Set([
|
|
8741
|
+
"LOCATION_REQUIRED", "LOCATION_NOT_WRITABLE", "PLATFORM_DATA_DESTINATION_INVALID",
|
|
8742
|
+
"PLATFORM_DATA_DESTINATION_FILESYSTEM_UNAVAILABLE", "PLATFORM_DATA_DESTINATION_FILESYSTEM_UNSUPPORTED",
|
|
8743
|
+
"PLATFORM_DATA_COPY_VERIFICATION_FAILED", "PLATFORM_DATA_DESTINATION_NOT_PREPARED",
|
|
8744
|
+
"PLATFORM_DATA_DESTINATION_NOT_EMPTY", "PLATFORM_DATA_UNAVAILABLE", "PLATFORM_DATA_DESTINATION_EXISTS",
|
|
8745
|
+
"RELOCATION_KIND_RETIRED", "RELOCATION_ALREADY_PENDING", "RELOCATION_REQUEST_INVALID",
|
|
8746
|
+
"PLATFORM_DATA_RELOCATION_BLOCKED",
|
|
8747
|
+
]);
|
|
8748
|
+
function relocationErrorText(code) {
|
|
8749
|
+
return t(`configuration.relocation_error.${RELOCATION_ERROR_CODES.has(code) ? code : "UNKNOWN"}`);
|
|
8750
|
+
}
|
|
8671
8751
|
document.addEventListener("DOMContentLoaded", () => {
|
|
8672
|
-
const
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
status.textContent
|
|
8677
|
-
|
|
8678
|
-
|
|
8752
|
+
for (const id of ["centralDatabaseRelocateStatus", "fileInboxRelocateStatus"]) {
|
|
8753
|
+
const status = $(id);
|
|
8754
|
+
if (!status) continue;
|
|
8755
|
+
new MutationObserver(() => {
|
|
8756
|
+
const code = status.textContent?.trim() || "";
|
|
8757
|
+
if (!/^[A-Z][A-Z0-9_]+$/.test(code)) return;
|
|
8758
|
+
status.textContent = relocationErrorText(code);
|
|
8759
|
+
}).observe(status, { childList: true, characterData: true, subtree: true });
|
|
8760
|
+
}
|
|
8679
8761
|
});
|
|
@@ -586,6 +586,7 @@ export const DASHBOARD_MESSAGES = {
|
|
|
586
586
|
"ui.component_restart_failed": "The component could not be restarted.",
|
|
587
587
|
"ui.component_restart_requested": "Restart request sent. The component will be available again shortly.",
|
|
588
588
|
"ui.component_restart_started": "Component restart started.",
|
|
589
|
+
"ui.component_restart_unconfirmed": "The component is reachable again, but the restart could not be confirmed.",
|
|
589
590
|
"ui.component_restart_waiting": "The component has not returned healthy yet; monitoring continues.",
|
|
590
591
|
"ui.component_status": "Component status",
|
|
591
592
|
"ui.confirm_action": "Confirm action",
|
|
@@ -1231,6 +1232,7 @@ export const DASHBOARD_MESSAGES = {
|
|
|
1231
1232
|
"ui.component_restart_failed": "De component kon niet worden herstart.",
|
|
1232
1233
|
"ui.component_restart_requested": "Herstartverzoek verzonden. De component komt zo opnieuw beschikbaar.",
|
|
1233
1234
|
"ui.component_restart_started": "Componentherstart is gestart.",
|
|
1235
|
+
"ui.component_restart_unconfirmed": "De component is weer bereikbaar, maar de herstart kon niet worden bevestigd.",
|
|
1234
1236
|
"ui.component_restart_waiting": "De component komt nog niet gezond terug; controle loopt door.",
|
|
1235
1237
|
"ui.component_status": "Componentstatus",
|
|
1236
1238
|
"ui.confirm_action": "Bevestig actie",
|
|
@@ -4127,3 +4129,11 @@ Object.assign(DASHBOARD_MESSAGES.nl,{"configuration.relocation_filesystem_unsupp
|
|
|
4127
4129
|
Object.assign(DASHBOARD_MESSAGES.de,{"configuration.relocation_filesystem_unsupported":"Wählen Sie für eine Verschiebung auf ein anderes Laufwerk oder Volume einen APFS-formatierten Ordner."});
|
|
4128
4130
|
Object.assign(DASHBOARD_MESSAGES.fr,{"configuration.relocation_filesystem_unsupported":"Pour déplacer les données vers un autre disque ou volume, choisissez un dossier formaté en APFS."});
|
|
4129
4131
|
Object.assign(DASHBOARD_MESSAGES.es,{"configuration.relocation_filesystem_unsupported":"Para reubicar en otro disco o volumen, elija una carpeta con formato APFS."});
|
|
4132
|
+
Object.assign(DASHBOARD_MESSAGES.en,{"configuration.relocation_error.LOCATION_REQUIRED":"Choose a folder before relocating.","configuration.relocation_error.LOCATION_NOT_WRITABLE":"Choose a local folder that is available and writable.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_INVALID":"The selected folder cannot contain the current platform data.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNAVAILABLE":"The destination filesystem could not be checked.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNSUPPORTED":"Choose an APFS-formatted folder for a relocation to another disk or volume.","configuration.relocation_error.PLATFORM_DATA_COPY_VERIFICATION_FAILED":"The copied platform data could not be verified safely.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_PREPARED":"Choose the new folder again before relocating.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_EMPTY":"The prepared destination folder is no longer empty.","configuration.relocation_error.PLATFORM_DATA_UNAVAILABLE":"The current platform data is unavailable.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_EXISTS":"The selected folder already contains platform data.","configuration.relocation_error.RELOCATION_KIND_RETIRED":"This relocation option is no longer available.","configuration.relocation_error.RELOCATION_ALREADY_PENDING":"Another relocation is already waiting to restart.","configuration.relocation_error.RELOCATION_REQUEST_INVALID":"The relocation request is invalid.","configuration.relocation_error.PLATFORM_DATA_RELOCATION_BLOCKED":"Relocation is unavailable while platform work is active.","configuration.relocation_error.UNKNOWN":"The relocation could not be completed."});
|
|
4133
|
+
Object.assign(DASHBOARD_MESSAGES.nl,{"configuration.relocation_error.LOCATION_REQUIRED":"Kies eerst een map voordat je verplaatst.","configuration.relocation_error.LOCATION_NOT_WRITABLE":"Kies een lokale map die beschikbaar en beschrijfbaar is.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_INVALID":"De gekozen map mag de huidige platformgegevens niet bevatten.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNAVAILABLE":"Het bestandssysteem van de doelmap kon niet worden gecontroleerd.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNSUPPORTED":"Kies voor verplaatsing naar een andere schijf of volume een APFS-geformatteerde map.","configuration.relocation_error.PLATFORM_DATA_COPY_VERIFICATION_FAILED":"De gekopieerde platformgegevens konden niet veilig worden gecontroleerd.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_PREPARED":"Kies de nieuwe map opnieuw voordat je verplaatst.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_EMPTY":"De voorbereide doelmap is niet meer leeg.","configuration.relocation_error.PLATFORM_DATA_UNAVAILABLE":"De huidige platformgegevens zijn niet beschikbaar.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_EXISTS":"De gekozen map bevat al platformgegevens.","configuration.relocation_error.RELOCATION_KIND_RETIRED":"Deze verplaatsingsoptie is niet meer beschikbaar.","configuration.relocation_error.RELOCATION_ALREADY_PENDING":"Er wacht al een andere verplaatsing op een herstart.","configuration.relocation_error.RELOCATION_REQUEST_INVALID":"De verplaatsingsaanvraag is ongeldig.","configuration.relocation_error.PLATFORM_DATA_RELOCATION_BLOCKED":"Verplaatsen is niet beschikbaar terwijl platformwerk actief is.","configuration.relocation_error.UNKNOWN":"De verplaatsing kon niet worden uitgevoerd."});
|
|
4134
|
+
Object.assign(DASHBOARD_MESSAGES.de,{"configuration.relocation_error.LOCATION_REQUIRED":"Wählen Sie vor dem Verschieben einen Ordner aus.","configuration.relocation_error.LOCATION_NOT_WRITABLE":"Wählen Sie einen verfügbaren, beschreibbaren lokalen Ordner aus.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_INVALID":"Der ausgewählte Ordner darf die aktuellen Plattformdaten nicht enthalten.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNAVAILABLE":"Das Dateisystem des Zielordners konnte nicht geprüft werden.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNSUPPORTED":"Wählen Sie für eine Verschiebung auf ein anderes Laufwerk oder Volume einen APFS-formatierten Ordner.","configuration.relocation_error.PLATFORM_DATA_COPY_VERIFICATION_FAILED":"Die kopierten Plattformdaten konnten nicht sicher geprüft werden.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_PREPARED":"Wählen Sie vor dem Verschieben den neuen Ordner erneut aus.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_EMPTY":"Der vorbereitete Zielordner ist nicht mehr leer.","configuration.relocation_error.PLATFORM_DATA_UNAVAILABLE":"Die aktuellen Plattformdaten sind nicht verfügbar.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_EXISTS":"Der ausgewählte Ordner enthält bereits Plattformdaten.","configuration.relocation_error.RELOCATION_KIND_RETIRED":"Diese Verschiebungsoption ist nicht mehr verfügbar.","configuration.relocation_error.RELOCATION_ALREADY_PENDING":"Eine andere Verschiebung wartet bereits auf einen Neustart.","configuration.relocation_error.RELOCATION_REQUEST_INVALID":"Die Verschiebungsanfrage ist ungültig.","configuration.relocation_error.PLATFORM_DATA_RELOCATION_BLOCKED":"Eine Verschiebung ist nicht verfügbar, während Plattformarbeit aktiv ist.","configuration.relocation_error.UNKNOWN":"Die Verschiebung konnte nicht abgeschlossen werden."});
|
|
4135
|
+
Object.assign(DASHBOARD_MESSAGES.fr,{"configuration.relocation_error.LOCATION_REQUIRED":"Choisissez un dossier avant de déplacer les données.","configuration.relocation_error.LOCATION_NOT_WRITABLE":"Choisissez un dossier local disponible et accessible en écriture.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_INVALID":"Le dossier sélectionné ne peut pas contenir les données actuelles de la plateforme.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNAVAILABLE":"Le système de fichiers de destination n’a pas pu être vérifié.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNSUPPORTED":"Pour déplacer les données vers un autre disque ou volume, choisissez un dossier formaté en APFS.","configuration.relocation_error.PLATFORM_DATA_COPY_VERIFICATION_FAILED":"La copie des données de la plateforme n’a pas pu être vérifiée de manière sûre.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_PREPARED":"Choisissez à nouveau le nouveau dossier avant de déplacer les données.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_EMPTY":"Le dossier de destination préparé n’est plus vide.","configuration.relocation_error.PLATFORM_DATA_UNAVAILABLE":"Les données actuelles de la plateforme sont indisponibles.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_EXISTS":"Le dossier sélectionné contient déjà des données de plateforme.","configuration.relocation_error.RELOCATION_KIND_RETIRED":"Cette option de déplacement n’est plus disponible.","configuration.relocation_error.RELOCATION_ALREADY_PENDING":"Un autre déplacement attend déjà un redémarrage.","configuration.relocation_error.RELOCATION_REQUEST_INVALID":"La demande de déplacement n’est pas valide.","configuration.relocation_error.PLATFORM_DATA_RELOCATION_BLOCKED":"Le déplacement est indisponible pendant que le travail de la plateforme est actif.","configuration.relocation_error.UNKNOWN":"Le déplacement n’a pas pu être terminé."});
|
|
4136
|
+
Object.assign(DASHBOARD_MESSAGES.es,{"configuration.relocation_error.LOCATION_REQUIRED":"Elija una carpeta antes de reubicar los datos.","configuration.relocation_error.LOCATION_NOT_WRITABLE":"Elija una carpeta local disponible y con permiso de escritura.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_INVALID":"La carpeta seleccionada no puede contener los datos actuales de la plataforma.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNAVAILABLE":"No se pudo comprobar el sistema de archivos de destino.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_FILESYSTEM_UNSUPPORTED":"Para reubicar en otro disco o volumen, elija una carpeta con formato APFS.","configuration.relocation_error.PLATFORM_DATA_COPY_VERIFICATION_FAILED":"No se pudo verificar de forma segura la copia de los datos de la plataforma.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_PREPARED":"Elija de nuevo la carpeta nueva antes de reubicar los datos.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_NOT_EMPTY":"La carpeta de destino preparada ya no está vacía.","configuration.relocation_error.PLATFORM_DATA_UNAVAILABLE":"Los datos actuales de la plataforma no están disponibles.","configuration.relocation_error.PLATFORM_DATA_DESTINATION_EXISTS":"La carpeta seleccionada ya contiene datos de la plataforma.","configuration.relocation_error.RELOCATION_KIND_RETIRED":"Esta opción de reubicación ya no está disponible.","configuration.relocation_error.RELOCATION_ALREADY_PENDING":"Ya hay otra reubicación esperando para reiniciar.","configuration.relocation_error.RELOCATION_REQUEST_INVALID":"La solicitud de reubicación no es válida.","configuration.relocation_error.PLATFORM_DATA_RELOCATION_BLOCKED":"La reubicación no está disponible mientras el trabajo de la plataforma está activo.","configuration.relocation_error.UNKNOWN":"No se pudo completar la reubicación."});
|
|
4137
|
+
Object.assign(DASHBOARD_MESSAGES.de,{"ui.component_restart_unconfirmed":"Die Komponente ist wieder erreichbar, aber der Neustart konnte nicht bestätigt werden."});
|
|
4138
|
+
Object.assign(DASHBOARD_MESSAGES.fr,{"ui.component_restart_unconfirmed":"Le composant est de nouveau accessible, mais le redémarrage n’a pas pu être confirmé."});
|
|
4139
|
+
Object.assign(DASHBOARD_MESSAGES.es,{"ui.component_restart_unconfirmed":"El componente vuelve a estar disponible, pero no se pudo confirmar el reinicio."});
|
|
@@ -15,9 +15,10 @@ from collections.abc import Iterable, Iterator, Mapping
|
|
|
15
15
|
|
|
16
16
|
from .agent_state import redact_diagnostic
|
|
17
17
|
from . import central_database as central_database_module
|
|
18
|
-
from .storage import EngineeringStorageError, open_storage
|
|
18
|
+
from .storage import ENGINEERING_STORAGE_SCHEMA_VERSION, EngineeringStorageError, open_storage
|
|
19
19
|
from .providers import GitProvider
|
|
20
20
|
from .platform_components import PLATFORM_COMPONENT_IDS
|
|
21
|
+
from .platform_version import CURRENT_PLATFORM_VERSION
|
|
21
22
|
|
|
22
23
|
LOG_LEVEL_ENVIRONMENT = "ENGINEERING_PLATFORM_LOG_LEVEL"
|
|
23
24
|
SERVER_DATA_ROOT_ENVIRONMENT = "EP_SERVER_DATA_ROOT"
|
|
@@ -38,6 +39,8 @@ LIFECYCLE_CONTEXT_KEYS = frozenset(
|
|
|
38
39
|
"launchd_label",
|
|
39
40
|
"launch_agent_path",
|
|
40
41
|
"target_component",
|
|
42
|
+
"component_version",
|
|
43
|
+
"target_component_version",
|
|
41
44
|
"shutdown_signal",
|
|
42
45
|
"configuration_scope",
|
|
43
46
|
"configuration_key",
|
|
@@ -367,18 +370,33 @@ def log_event(
|
|
|
367
370
|
context: Mapping[str, object] | None = None,
|
|
368
371
|
) -> None:
|
|
369
372
|
"""Write one redacted, structured event without exposing arbitrary extras."""
|
|
373
|
+
component = logger.name.rsplit(".", 1)[-1]
|
|
374
|
+
payload_context = dict(context or {})
|
|
375
|
+
payload_context.setdefault("component_version", _component_version(component))
|
|
376
|
+
target = payload_context.get("target_component")
|
|
377
|
+
if isinstance(target, str) and target in PLATFORM_COMPONENT_IDS:
|
|
378
|
+
payload_context.setdefault("target_component_version", _component_version(target))
|
|
370
379
|
logger.log(
|
|
371
380
|
level,
|
|
372
381
|
redact_diagnostic(event, limit=500),
|
|
373
382
|
extra={
|
|
374
|
-
"component":
|
|
383
|
+
"component": component,
|
|
375
384
|
"run_id": run_id or "",
|
|
376
385
|
"diagnostic": diagnostic,
|
|
377
|
-
"context":
|
|
386
|
+
"context": payload_context,
|
|
378
387
|
},
|
|
379
388
|
)
|
|
380
389
|
|
|
381
390
|
|
|
391
|
+
def _component_version(component: str) -> str:
|
|
392
|
+
"""Return the bounded version identity recorded beside a component name."""
|
|
393
|
+
if component == "platform_database":
|
|
394
|
+
return str(ENGINEERING_STORAGE_SCHEMA_VERSION)
|
|
395
|
+
if component in {"http_ingress", "cli_ingress", "file_inbox_ingress"}:
|
|
396
|
+
return "1"
|
|
397
|
+
return CURRENT_PLATFORM_VERSION
|
|
398
|
+
|
|
399
|
+
|
|
382
400
|
def component_lifecycle_context(
|
|
383
401
|
root: Path,
|
|
384
402
|
*,
|
|
@@ -12,7 +12,7 @@ from .storage import ENGINEERING_STORAGE_SCHEMA_VERSION
|
|
|
12
12
|
|
|
13
13
|
SEMVER = re.compile(r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$")
|
|
14
14
|
CONTRACT = re.compile(r"^(\d{4})\.(0[1-9]|1[0-2])$")
|
|
15
|
-
CURRENT_PLATFORM_VERSION = "2.3.
|
|
15
|
+
CURRENT_PLATFORM_VERSION = "2.3.1"
|
|
16
16
|
MANIFEST_FIELDS = frozenset(
|
|
17
17
|
{
|
|
18
18
|
"platform_version",
|
|
@@ -15,6 +15,7 @@ from .providers import CodexCliProvider, LocalProcessProvider, codex_cli_executa
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
_VERSION = re.compile(r"\b\d+(?:\.\d+)+(?:[-+][0-9A-Za-z.]+)?\b")
|
|
18
|
+
CODEX_READINESS_TIMEOUT_SECONDS = 2
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
def _classify(result: subprocess.CompletedProcess[str] | None) -> str:
|
|
@@ -54,8 +55,8 @@ def runtime_details(root: Path) -> dict[str, dict[str, str]]:
|
|
|
54
55
|
"""Project token-free CLI provenance for the host-wide Console projection."""
|
|
55
56
|
codex_path = codex_cli_executable() or ""
|
|
56
57
|
try:
|
|
57
|
-
codex_version = _version(CodexCliProvider().command("--version")) if codex_path else ""
|
|
58
|
-
except OSError:
|
|
58
|
+
codex_version = _version(CodexCliProvider().command("--version", timeout=CODEX_READINESS_TIMEOUT_SECONDS)) if codex_path else ""
|
|
59
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
59
60
|
codex_version = ""
|
|
60
61
|
github_path = shutil.which("gh") or ""
|
|
61
62
|
try:
|
|
@@ -79,8 +80,8 @@ def host_status(root: Path, *, require_github: bool = True) -> dict[str, dict[st
|
|
|
79
80
|
codex = CodexCliProvider()
|
|
80
81
|
codex_installed = codex.status().qualified
|
|
81
82
|
try:
|
|
82
|
-
codex_result = codex.command("login", "status") if codex_installed else None
|
|
83
|
-
except OSError:
|
|
83
|
+
codex_result = codex.command("login", "status", timeout=CODEX_READINESS_TIMEOUT_SECONDS) if codex_installed else None
|
|
84
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
84
85
|
codex_result = None
|
|
85
86
|
# A server can be queried immediately after launchd restarts it (notably
|
|
86
87
|
# after a platform-data import). The managed CLI may transiently fail
|
|
@@ -89,8 +90,8 @@ def host_status(root: Path, *, require_github: bool = True) -> dict[str, dict[st
|
|
|
89
90
|
# as a provider fault, while still failing closed if it persists.
|
|
90
91
|
if codex_installed and _classify(codex_result) == "CHECK_FAILED":
|
|
91
92
|
try:
|
|
92
|
-
codex_result = codex.command("login", "status")
|
|
93
|
-
except OSError:
|
|
93
|
+
codex_result = codex.command("login", "status", timeout=CODEX_READINESS_TIMEOUT_SECONDS)
|
|
94
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
94
95
|
codex_result = None
|
|
95
96
|
result = {
|
|
96
97
|
"codex": {"provider": "CODEX", "state": "UNAVAILABLE" if not codex_installed else _classify(codex_result)},
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/providers.py
RENAMED
|
@@ -216,10 +216,10 @@ class CodexCliProvider(LocalProcessProvider):
|
|
|
216
216
|
available = bool(self._executable) and Path(self._executable).is_file() and os.access(self._executable, os.X_OK)
|
|
217
217
|
return ProviderStatus("codex_cli", "configured", available, "available" if available else "codex unavailable")
|
|
218
218
|
|
|
219
|
-
def command(self, *args: str) -> subprocess.CompletedProcess[str]:
|
|
219
|
+
def command(self, *args: str, timeout: float | None = None) -> subprocess.CompletedProcess[str]:
|
|
220
220
|
if not self._executable:
|
|
221
221
|
raise FileNotFoundError("Engineering Platform managed Codex CLI is unavailable")
|
|
222
|
-
return subprocess.run((self._executable, *args), text=True, capture_output=True, check=False)
|
|
222
|
+
return subprocess.run((self._executable, *args), text=True, capture_output=True, check=False, timeout=timeout)
|
|
223
223
|
|
|
224
224
|
def app_server(self) -> subprocess.Popen[str]:
|
|
225
225
|
"""Open the provider-owned interactive Codex app-server channel."""
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server.py
RENAMED
|
@@ -69,7 +69,7 @@ from .component_logging import (
|
|
|
69
69
|
)
|
|
70
70
|
from .ep_consumer_credentials import verifier
|
|
71
71
|
from .parity_context import ParityProjectStore, project_context
|
|
72
|
-
from .platform_version import EngineeringPlatformManifest
|
|
72
|
+
from .platform_version import CURRENT_PLATFORM_VERSION, EngineeringPlatformManifest
|
|
73
73
|
from .providers import (
|
|
74
74
|
GitHubProvider,
|
|
75
75
|
CodexCliProvider,
|
|
@@ -150,6 +150,13 @@ def _http_json_openapi_document() -> dict[str, object]:
|
|
|
150
150
|
"description": "Canonical authenticated submission ingress and platform health.",
|
|
151
151
|
},
|
|
152
152
|
"paths": {
|
|
153
|
+
"/v1/producer-compatibility": {
|
|
154
|
+
"get": {
|
|
155
|
+
"summary": "Read the immutable producer compatibility declaration",
|
|
156
|
+
"description": "Read-only installation identity and supported producer contracts; it never admits or executes a submission.",
|
|
157
|
+
"responses": {"200": {"description": "Compatibility declaration v1.0"}},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
153
160
|
"/health": {
|
|
154
161
|
"get": {
|
|
155
162
|
"summary": "Read aggregated Engineering Platform component health",
|
|
@@ -1751,6 +1758,7 @@ def status(data_root: Path) -> dict[str, object]:
|
|
|
1751
1758
|
running = bool(runtime and _alive(runtime.get("pid")))
|
|
1752
1759
|
components = _transport_components(data_root, server_running=running)
|
|
1753
1760
|
components["dashboard_relay"] = _dashboard_relay_component(server_running=running)
|
|
1761
|
+
platform_version = _console_platform_version()
|
|
1754
1762
|
# One Server-native inventory feeds Components, the titlebar popout and
|
|
1755
1763
|
# detail modals. It deliberately contains no watcher/check-out model.
|
|
1756
1764
|
for definition in PLATFORM_COMPONENTS:
|
|
@@ -1760,6 +1768,7 @@ def status(data_root: Path) -> dict[str, object]:
|
|
|
1760
1768
|
"group": definition.group, "critical": definition.critical, "restart_supported": definition.restart_supported,
|
|
1761
1769
|
"log_component": definition.id,
|
|
1762
1770
|
})
|
|
1771
|
+
components[definition.id].setdefault("version", platform_version)
|
|
1763
1772
|
continue
|
|
1764
1773
|
healthy = True if definition.id == "platform_database" else running
|
|
1765
1774
|
components[definition.id] = {
|
|
@@ -1768,10 +1777,10 @@ def status(data_root: Path) -> dict[str, object]:
|
|
|
1768
1777
|
"log_component": definition.id, "healthy": healthy,
|
|
1769
1778
|
"status_code": definition.active_status if healthy else definition.inactive_status,
|
|
1770
1779
|
"detail_code": definition.detail_code,
|
|
1771
|
-
|
|
1780
|
+
"version": str(SERVER_STORE_SCHEMA_VERSION) if definition.id == "platform_database" else platform_version,
|
|
1772
1781
|
}
|
|
1773
1782
|
server_component = components["ep_server"]
|
|
1774
|
-
server_component["version"] =
|
|
1783
|
+
server_component["version"] = platform_version
|
|
1775
1784
|
started_at = runtime.get("started_at") if runtime else None
|
|
1776
1785
|
if isinstance(started_at, str):
|
|
1777
1786
|
try:
|
|
@@ -2693,6 +2702,19 @@ class _HealthHandler(http.server.BaseHTTPRequestHandler):
|
|
|
2693
2702
|
# traceback that obscures qualification diagnostics.
|
|
2694
2703
|
return
|
|
2695
2704
|
|
|
2705
|
+
def _send_artifact_bytes(self, payload: bytes, instance_id: str) -> None:
|
|
2706
|
+
"""Return the verified immutable artifact bytes without JSON re-encoding."""
|
|
2707
|
+
self.send_response(200)
|
|
2708
|
+
self.send_header("Content-Type", "application/json")
|
|
2709
|
+
self.send_header("Content-Length", str(len(payload)))
|
|
2710
|
+
self.send_header("EP-Server-Instance", instance_id)
|
|
2711
|
+
self.send_header("Cache-Control", "no-store")
|
|
2712
|
+
self.end_headers()
|
|
2713
|
+
try:
|
|
2714
|
+
self.wfile.write(payload)
|
|
2715
|
+
except (BrokenPipeError, ConnectionResetError):
|
|
2716
|
+
return
|
|
2717
|
+
|
|
2696
2718
|
def _send_ndjson(self, entries: list[dict[str, object]]) -> None:
|
|
2697
2719
|
encoded = ("\n".join(json.dumps(entry, sort_keys=True) for entry in entries) + ("\n" if entries else "")).encode("utf-8")
|
|
2698
2720
|
self.send_response(200)
|
|
@@ -3493,6 +3515,21 @@ class _HealthHandler(http.server.BaseHTTPRequestHandler):
|
|
|
3493
3515
|
if request.path in {HTTP_JSON_OPENAPI_PATH, "/openapi.json", "/swagger.json"}:
|
|
3494
3516
|
self._send(200, _http_json_openapi_document())
|
|
3495
3517
|
return
|
|
3518
|
+
if request.path == "/v1/producer-compatibility":
|
|
3519
|
+
# This is an installation identity and contract declaration only.
|
|
3520
|
+
# It performs no project lookup, admission, execution, or provider
|
|
3521
|
+
# interaction, so consumers can preflight before POSTing a request.
|
|
3522
|
+
identity = initialize(self.server.data_root).instance_id # type: ignore[attr-defined]
|
|
3523
|
+
self._send(200, {
|
|
3524
|
+
"contract_version": "1.0",
|
|
3525
|
+
"producer": {"id": "engineering-platform", "version": CURRENT_PLATFORM_VERSION},
|
|
3526
|
+
"instance": {"id": identity},
|
|
3527
|
+
"contracts": {
|
|
3528
|
+
"producer_readback": [submission_service.PRODUCER_READBACK_CONTRACT_VERSION],
|
|
3529
|
+
"terminal_evidence": [submission_service.TERMINAL_EVIDENCE_CONTRACT_VERSION],
|
|
3530
|
+
},
|
|
3531
|
+
}, identity)
|
|
3532
|
+
return
|
|
3496
3533
|
if request.path == "/diagnostics/topology":
|
|
3497
3534
|
try:
|
|
3498
3535
|
self._send(200, operations_projection(self.server.data_root), initialize(self.server.data_root).instance_id) # type: ignore[attr-defined]
|
|
@@ -3541,7 +3578,7 @@ class _HealthHandler(http.server.BaseHTTPRequestHandler):
|
|
|
3541
3578
|
if payload is None:
|
|
3542
3579
|
self._send(404, {"error": "EVIDENCE_ARTIFACT_NOT_FOUND"})
|
|
3543
3580
|
else:
|
|
3544
|
-
self.
|
|
3581
|
+
self._send_artifact_bytes(payload, initialize(self.server.data_root).instance_id) # type: ignore[attr-defined]
|
|
3545
3582
|
except (sqlite3.Error, ValueError, json.JSONDecodeError):
|
|
3546
3583
|
self._send(503, {"error": "CENTRAL_UNAVAILABLE"})
|
|
3547
3584
|
return
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"platform": {
|
|
4
4
|
"id": "engineering-platform",
|
|
5
5
|
"name": "Engineering Platform",
|
|
6
|
-
"version": "2.3.
|
|
6
|
+
"version": "2.3.1",
|
|
7
7
|
"generation": 2,
|
|
8
8
|
"documentation_namespace": "engineering-platform",
|
|
9
9
|
"capability_registry_version": 1
|
|
@@ -11,8 +11,15 @@
|
|
|
11
11
|
"workspace": {
|
|
12
12
|
"id": "replace-workspace-id",
|
|
13
13
|
"name": "Replace Workspace Name",
|
|
14
|
-
"repository": {
|
|
15
|
-
|
|
14
|
+
"repository": {
|
|
15
|
+
"provider": "github",
|
|
16
|
+
"owner": "replace-owner",
|
|
17
|
+
"name": "replace-repository",
|
|
18
|
+
"default_branch": "main"
|
|
19
|
+
},
|
|
20
|
+
"branding": {
|
|
21
|
+
"dashboard_title": "Replace Workspace Name"
|
|
22
|
+
},
|
|
16
23
|
"workspace_authorization": {
|
|
17
24
|
"allowed_roots": [],
|
|
18
25
|
"allowed_repositories": [],
|
|
@@ -21,5 +28,12 @@
|
|
|
21
28
|
"case_sensitivity": "host"
|
|
22
29
|
}
|
|
23
30
|
},
|
|
24
|
-
"providers": {
|
|
31
|
+
"providers": {
|
|
32
|
+
"runtime": "codex_cli",
|
|
33
|
+
"repository": "github",
|
|
34
|
+
"service_manager": "launchd",
|
|
35
|
+
"remote_submission": "icloud_inbox",
|
|
36
|
+
"private_remote_access": "tailscale",
|
|
37
|
+
"dashboard": "private_http"
|
|
38
|
+
}
|
|
25
39
|
}
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/__init__.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/__main__.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/agent_state.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/agent_trust.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/codex_capacity.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/codex_chat.py
RENAMED
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/component_lock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/execution_host.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/file_inbox.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/forensic_delta.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/host_admin.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/host_preflight.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/live_status.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/local_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/parity_context.py
RENAMED
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_admin.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/platform_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/producer.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/project_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/prompt_history.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/provider_usage.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/qualification.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/resources.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server_relay.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/server_service.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/status_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/storage.py
RENAMED
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/submission_cli.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_platform-2.3.0 → engineering_platform-2.3.1}/src/engineering_platform/telemetry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|