Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ See [中文说明](README.zh.md), [security boundary](SECURITY.md), and [validat

The sidebar provides Overview, Connections, Memories, and Observation, with Settings & diagnostics at the bottom. Overview is the initial page. Observation contains Runtime state, Current-Scope inventory & usage, and This session tabs. Their data views are explicitly unavailable until integrated; opening the page or switching tabs does not run connection checks or local diagnostics. English/Chinese and existing theme settings apply to Observation.

The native host collects a bounded, in-memory window of HTTP requests and Memory/Scope user operations independently of page navigation. Trusted typed IPC provides an allowlisted summary, reset and safe JSON preview. The window retains at most 512 terminal records; it preserves cancellation and unknown-write outcomes and contains no content or target identities. See the [session observation contract](../docs/en/development/desktop-session-observations.md) for measurement units, coverage, reset and failure isolation. The This session page and clipboard flow require separate UI integration.


## Shared feedback and current context

Expand Down
2 changes: 2 additions & 0 deletions desktop/README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

侧栏提供总览、连接、记忆、观察入口,“设置与诊断”位于侧栏底部。默认进入总览。“观察”包含运行状态、当前 Scope 库存与用量、本次会话三个标签页。数据视图接入前明确显示尚未可用;进入页面或切换标签不会执行连接检查或本机诊断。观察页面沿用现有中英文和主题设置。

原生宿主独立于页面导航,采集有界的内存窗口,分别记录 HTTP 请求和 Memory/Scope 用户操作。可信的类型化 IPC 提供白名单摘要、重置和安全 JSON 预览。窗口最多保留 512 条终态记录,保留取消及未知写入的区别,不包含内容或目标身份。测量单位、覆盖范围、重置和故障隔离见[会话观察契约](../docs/zh/development/desktop-session-observations.md)。本次会话页面和剪贴板流程仍需独立的 UI 集成。


## 统一反馈与当前上下文

Expand Down
3 changes: 3 additions & 0 deletions desktop/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Typed adapters separate liveness, readiness, identity and capabilities. Native c
| Complete request, including response body | 15 seconds |
| Response body | 1 MiB, checked both by declared size and streamed bytes |
| Concurrent reads per client | 4; excess fails as busy |
| Session observations | 512 terminal records shared across HTTP requests and native Memory/Scope actions; memory only |

Session observation commands require the same trusted main-window boundary and work independently of connection state. Rust projects only fixed operation/unit/outcome enums, elapsed milliseconds, UTC timestamps, counts, HTTP status and existing safe error codes. It never serializes connection or write state for export; content, queries, credentials, endpoints, private paths and target identities never enter the collector. The preview serializes only that projection. Retention/reset and process-lifetime loss metadata expose incomplete coverage; nonblocking recording cannot change business results or suppress cancellation. HTTP response success and native write certainty are separate measurements. Installer/Ops and local diagnostic output are outside collection. The [session observation contract](../docs/en/development/desktop-session-observations.md) defines the complete field allowlist and coverage.

Error responses are enum codes. Transport exception text, endpoint URLs, bodies and credentials are never returned or logged. No product logging, telemetry, crash uploader or persistent business cache is configured. The app does not read databases, start a Server or inspect process environments. Explicit local diagnostics verify a pinned absolute executable and digest, then run one of two native-defined diagnostic commands. Registration requires no version, and legacy version fields are ignored. Diagnostic responses must match the supported output schema. A subsequent fixed `--version` query collects bounded display metadata; failure, unsupported output or an unavailable version does not reject an otherwise valid diagnostic result. Each invocation has a combined 256 KiB output budget and a deadline. Windows helpers enter an owned kill-on-close Job before resuming. macOS runs a read-only snapshot of the digest-verified launcher in a private process group, which is terminated after completion, cancellation or timeout; raw output is projected to allowlisted status fields and discarded. Normal application exit closes diagnostic admission and waits for active worker process cleanup before Tauri exits. A local CLI pin does not authenticate its publisher or freeze its Python dependencies; the configured installation must be trusted.

Expand Down
21 changes: 21 additions & 0 deletions desktop/VALIDATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ cargo test --locked --manifest-path desktop/src-tauri/Cargo.toml

[Desktop CI](../.github/workflows/desktop.yml) also builds a Server wheel, runs real Server and CLI tests, checks Windows credentials and process containment, builds the installer, and exercises installation, the installed UI and uninstallation. Consult the PR checks for the exact commit being reviewed. Reports, logs and screenshots are generated under ignored `.artifacts/` and uploaded as Actions artifacts; do not copy them into the repository.

## Native session observation checks

Windows x64 checks for the native session collector use Rust 1.95.0, Node 24.14.1 and pnpm 11.13.1.
`cargo fmt --check`, `cargo clippy --locked --all-targets -- -D warnings`, all 62 native tests and generated IPC
checking pass. The new regressions exercise real loopback HTTP sockets with synthetic responses, including
readiness 503, request versus user-operation counting, millisecond latency, cancellation, unknown writes,
invalid decoded receipts, reset during an in-flight write, bounded retention, safe projection and collector
contention/poisoning. Mock Tauri IPC checks exercise the actual capability configuration and reject untrusted
windows and origins; session commands also work without connection state.

Desktop lint, TypeScript checking, all 98 UI tests and the frontend production build pass. The Desktop OpenAPI
contract checks pass without contract changes. Website lint and link validation pass, including both locale
versions of the [session observation contract](../docs/en/development/desktop-session-observations.md).
`uv lock --locked` and `uv run --locked pytest tests/test_desktop_contract.py -q` pass.

Repository hooks pass except `ty check` on Windows, which reports POSIX-only attributes in unchanged Python files
under `src/powercontext/builtin/code/` and `tests/builtin/test_native_code.py`. The explicit Linux-target check,
`uv run --locked ty check --python-platform linux`, passes. The native tests do not qualify an actual Server,
installed application, clipboard interaction or macOS execution. The This session UI and installed copy flow
remain separate delivery work; native collection does not make the placeholder page operational.

## Compatibility scope

[compatibility.json](src-tauri/src/connections/compatibility.json) preserves the recorded Server sources, normalized OpenAPI contract digests and qualification-wheel digests for the historical profiles below. The current contract is qualified by `sqlite-atomic-1da99747-v1` below; ordinary builds require explicitly selecting it and checking the connection before business operations become available. The `sqlite-atomic-d9a78567-v1`, `sqlite-atomic-caf2a35a-v1`, `sqlite-atomic-683e2db0-v1` and `sqlite-atomic-cab054db-v1` records qualify their corresponding Server source deployments and do not match this bundled contract. Historical records are disabled in the selector, and saved unavailable selections remain visible until explicitly replaced. CI builds have their own artifact identities and do not change product qualification.
Expand Down
3 changes: 3 additions & 0 deletions desktop/src-tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ fn main() {
"cancel_scope_reads",
"default_scope",
"select_scope",
"session_summary",
"reset_session_observations",
"preview_session_diagnostics",
]),
))
.expect("desktop build configuration is invalid");
Expand Down
5 changes: 4 additions & 1 deletion desktop/src-tauri/capabilities/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"allow-list-scopes",
"allow-cancel-scope-reads",
"allow-default-scope",
"allow-select-scope"
"allow-select-scope",
"allow-session-summary",
"allow-reset-session-observations",
"allow-preview-session-diagnostics"
]
}
12 changes: 12 additions & 0 deletions desktop/src-tauri/examples/export_ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ use powercontext_desktop::{
diagnostics::{DiagnosticItem, DiagnosticKind, DiagnosticReport, HostDiagnostic},
error::SafeError,
ipc::FoundationInfo,
session_observations::{
ObservationOutcome, ObservationUnit, ObservedOperation, OperationSummary, OutcomeCounts,
SessionCoverage, SessionObservation, SessionSummary,
},
transport::{
ApiFailure, AtomicMemoryDetail, MemorySaveResponse, MemorySearchHit, MemorySearchResponse,
wire,
Expand Down Expand Up @@ -72,6 +76,14 @@ fn main() {
MemorySearchHit::decl(&config),
MemorySearchResponse::decl(&config),
AtomicMemoryDetail::decl(&config),
ObservationUnit::decl(&config),
ObservedOperation::decl(&config),
ObservationOutcome::decl(&config),
SessionObservation::decl(&config),
OutcomeCounts::decl(&config),
OperationSummary::decl(&config),
SessionCoverage::decl(&config),
SessionSummary::decl(&config),
]
.into_iter()
.chain(wire::declarations(&config))
Expand Down
28 changes: 28 additions & 0 deletions desktop/src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
},
error::SafeError,
ipc::authorize_window,
session_observations::{SessionObservations, SessionSummary},
transport::{
ApiFailure,
wire::{ScopeDescriptor, ScopePage},
Expand All @@ -29,6 +30,33 @@ use crate::{
pub struct HostState {
pub manager: Result<ConnectionManager, SafeError>,
}

#[tauri::command]
pub fn session_summary<R: tauri::Runtime>(
window: tauri::WebviewWindow<R>,
state: tauri::State<'_, SessionObservations>,
) -> Result<SessionSummary, SafeError> {
authorize_window(window.label())?;
state.summary()
}

#[tauri::command]
pub fn reset_session_observations<R: tauri::Runtime>(
window: tauri::WebviewWindow<R>,
state: tauri::State<'_, SessionObservations>,
) -> Result<(), SafeError> {
authorize_window(window.label())?;
state.reset()
}

#[tauri::command]
pub fn preview_session_diagnostics<R: tauri::Runtime>(
window: tauri::WebviewWindow<R>,
state: tauri::State<'_, SessionObservations>,
) -> Result<String, SafeError> {
authorize_window(window.label())?;
state.diagnostic_text()
}
fn manager<'a, R: tauri::Runtime>(
window: &tauri::WebviewWindow<R>,
state: &'a HostState,
Expand Down
Loading
Loading