Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Network log in-app pane
|
||||
## Summary
|
||||
The network activity log no longer writes to disk. When the user opens the network log console from Privacy settings or the existing keybinding, a read-only pane displays a snapshot of the most recent network requests and responses captured in memory.
|
||||
## Figma
|
||||
Figma: none provided
|
||||
## Behavior
|
||||
1. While the app is running, the most recent 50 network log items (request and response entries) are retained in memory. No network log file is written to disk anywhere on the user's system.
|
||||
2. Each log item is a single formatted entry containing a timestamp plus the debug-formatted request or response, matching the format previously written to `warp_network.log`.
|
||||
3. The feature is only exposed when `ContextFlag::NetworkLogConsole` is enabled. When the flag is disabled, the Privacy settings link, the keybinding, and the pane are all unavailable.
|
||||
4. Clicking "View network logging" in Privacy settings opens the network log pane as a right-split of the active pane group.
|
||||
5. Triggering the `input:insert_network_logging_workflow` keybinding ("Show Warp network log") opens the same pane with the same layout behavior.
|
||||
6. If a network log pane already exists in the current window, both entrypoints focus that pane instead of opening a second one. At most one network log pane exists per window.
|
||||
7. On open, the pane renders a one-shot snapshot of the in-memory items at that moment, in chronological order, one item per line. The pane does not update live as new requests are made.
|
||||
8. Reopening the pane (closing and relaunching, or focusing from either entrypoint after new activity) re-seeds the view with the current snapshot.
|
||||
9. When the in-memory log is empty at open time, the pane opens with an empty editor body. No error or placeholder toast is shown.
|
||||
10. The pane content is read-only: the user cannot type into it, delete lines, or otherwise mutate the log. Standard read-only code editor affordances remain available: scroll, select, copy, and find-in-editor.
|
||||
11. The pane header shows "Network log" as its title and supports the standard pane chrome (close, split, focus, drag between tabs) like other panes.
|
||||
12. Closing the pane does not affect the underlying in-memory log. New requests continue to be captured and will appear the next time the pane is opened.
|
||||
13. The pane is not restored across app restart. On relaunch, the pane is absent until the user explicitly reopens it via settings or the keybinding, and the in-memory log starts fresh.
|
||||
14. The previously available "Tail Warp network log" workflow is removed from the command palette and workflow list. Users will no longer find a workflow that runs `tail -f` on a network log file.
|
||||
15. The existing Privacy settings copy describing the "native console" for viewing network communications continues to apply; clicking the link opens the new pane rather than running a shell command in a terminal.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Network log in-app pane — Tech spec
|
||||
Companion to `PRODUCT.md` in this directory; refer there for user-visible behavior.
|
||||
## Context
|
||||
- `app/src/server/network_logging.rs` — `init(..)` registers HTTP client `set_before_request_fn`/`set_after_response_fn` hooks that push `NetworkLogItem`s into a bounded `async_channel` (size 100). A background task writes items to `log_file_path()` (`warp_network.log`), truncating and reopening after every 50 items. `pub fn log_file_path()` is exposed for the tail workflow.
|
||||
- `app/src/server/server_api.rs (1214-1222)` — `ServerApiProvider::new` invokes `network_logging::init` when `ContextFlag::NetworkLogConsole.is_enabled()`.
|
||||
- `app/src/workflows/local_workflows.rs (213-229)` — `network_logging_workflow()` builds a hardcoded `WorkflowSource::App` workflow whose command is `tail -f <log>`. Injected into `app_workflows()`.
|
||||
- `app/src/settings_view/privacy_page.rs` — `NetworkLogWidget` renders the "View network logging" link and dispatches `PrivacyPageAction::LaunchNetworkLogging` → bubbles to `SettingsViewEvent::LaunchNetworkLogging`.
|
||||
- `app/src/terminal/input.rs (1754-1760, 7302-7332, 13749)` — `input:insert_network_logging_workflow` binding ("Show Warp network log") → `InputAction::InsertNetworkLoggingWorkflow` → `Input::insert_network_logging_workflow` opens the tail workflow info box.
|
||||
- `app/src/workspace/view.rs (12646-12648, 12769-12793)` — `launch_network_logging_workflow_in_active_tab` clears the active input and runs the workflow.
|
||||
- Pane plumbing: `app/src/pane_group/pane/mod.rs (133-153, 432-504)` — `IPaneType` enum, `PaneId::from_*_pane_ctx/view` helpers, `PaneId::render` arms. `execution_profile_editor_pane.rs` is the closest minimal template. `AIFactManager` / `ExecutionProfileEditorManager` demonstrate singleton "one pane per window" managers.
|
||||
- `CodeEditorView` (`app/src/code/editor/view.rs`) supports `buffer: None`, `reset(InitialBufferState, ctx)`, and `set_interaction_state(InteractionState::ReadOnly, ctx)`; its model is defined in `app/src/code/editor/model.rs`.
|
||||
- `app/src/app_state.rs (118-139)` — `LeafContents` enum. `app/src/pane_group/mod.rs (1770-1939)` — restore match; panes we don't restore return `Err(anyhow!(..))`.
|
||||
## Proposed changes
|
||||
### In-memory model
|
||||
- Add `NetworkLogModel` in `app/src/server/network_logging.rs`: singleton entity with a `VecDeque<NetworkLogItem>` capped at `NETWORK_LOGGING_MAX_ITEMS = 50` (matches current file-rotation threshold). `push(item, ctx)` pops the front when over capacity; `snapshot_text(&self) -> String` joins items with `\n`.
|
||||
- `pub(crate)` on `NetworkLogItem`; keep its `Display` impl and the existing timestamp + `{:?}` request/response format so pane output matches what `warp_network.log` used to contain.
|
||||
- Rewrite `init(..)` to take the `ModelContext<ServerApiProvider>`. Keep the bounded channel and client hooks unchanged. Replace the disk-writing background task with `ctx.spawn_stream_local(rx, |_, item, ctx| NetworkLogModel::handle(ctx).update(ctx, |m, ctx| m.push(item, ctx)), |_, _| {})`. This mirrors the existing `event_receiver` pattern in `ServerApiProvider::new`.
|
||||
- Delete `truncate_and_restart_log`, `log_file_path()`, the `WARP_LOGS_DIR` branch, and the `local_fs` cfg split. Remove dead `warp_core::paths` / `PathBuf` imports.
|
||||
- Register the singleton in `app/src/lib.rs::initialize_app` (before `ServerApiProvider`): `ctx.add_singleton_model(|_| NetworkLogModel::default())`.
|
||||
### View, pane, and manager
|
||||
- `app/src/server/network_log_view.rs`: `NetworkLogView` owns a `ViewHandle<CodeEditorView>` and a `ModelHandle<PaneConfiguration>` titled "Network log". On `new`, build `CodeEditorView` with `buffer: None` + default `CodeEditorRenderOptions`, seed with `NetworkLogModel::as_ref(ctx).snapshot_text()` via `editor.reset(InitialBufferState::plain_text(text), ctx)`, and call `set_interaction_state(InteractionState::ReadOnly, ctx)`. No subscription to the model — single snapshot per open.
|
||||
- `BackingView` impl: default header/chrome, no toolbelt, no overflow menu. `focus(ctx)` forwards to the editor.
|
||||
- `app/src/pane_group/pane/network_log_pane.rs`: `NetworkLogPane` mirroring `ExecutionProfileEditorPane`. `snapshot() -> LeafContents::NetworkLog` (new unit variant). `attach` registers with `NetworkLogPaneManager`; `detach` deregisters. `shareable_link()` → `ShareableLink::Base`.
|
||||
- `app/src/pane_group/pane/mod.rs`: add `IPaneType::NetworkLog` (+ `Display`), `PaneId::from_network_log_pane_ctx` / `..._view`, and a `ChildView<PaneView<NetworkLogView>>` arm in `PaneId::render`. `pub(super) mod network_log_pane;` + re-export.
|
||||
- `app/src/server/network_log_pane_manager.rs`: `NetworkLogPaneManager` (singleton) with `HashMap<WindowId, PaneViewLocator>` and `find_pane` / `register_pane` / `deregister_pane` (pattern copied from `ExecutionProfileEditorManager`). Register in `initialize_app`.
|
||||
- `app/src/app_state.rs`: `LeafContents::NetworkLog` (unit). `app/src/pane_group/mod.rs`: restore arm returns `Err(anyhow!("Network log panes are not restored"))`. `app/src/persistence/sqlite.rs`: add a round-trippable tag for the new variant only if the serde mapping requires it; no restore path needed.
|
||||
### Wiring and cleanup
|
||||
- `app/src/workspace/view.rs`: add `open_network_log_pane(&mut self, ctx)` following `open_execution_profile_editor_pane`: find-existing via the manager and focus, else construct `NetworkLogPane::new(ctx)` and `add_pane_with_direction(Direction::Right, pane, true, ctx)`. Replace the body of `launch_network_logging_workflow_in_active_tab` with a call to `open_network_log_pane` (and rename the method + its single caller at `12647`).
|
||||
- `app/src/terminal/input.rs`: delete `Input::insert_network_logging_workflow` and the matching `InputAction::InsertNetworkLoggingWorkflow` arm. Repoint the `input:insert_network_logging_workflow` binding (keep id + "Show Warp network log" description, keep the `NetworkLogConsole` enablement gate) to a new `WorkspaceAction::OpenNetworkLogPane` that the workspace handles by calling `open_network_log_pane`. Using a `WorkspaceAction` avoids adding a one-off `Input` event just to bubble it up.
|
||||
- `app/src/workflows/local_workflows.rs`: delete `network_logging_workflow` and remove its call in `app_workflows()`; the prompt-chip dogfood workflow stays.
|
||||
- Privacy page: no copy changes; `PrivacyPageAction::LaunchNetworkLogging` keeps bubbling up `SettingsViewEvent::LaunchNetworkLogging`, which now calls `open_network_log_pane`.
|
||||
## Testing and validation
|
||||
Behavior numbers below reference `PRODUCT.md`.
|
||||
- Unit test in `network_logging.rs`: push > 50 items into `NetworkLogModel`, assert len capped at 50, `snapshot_text` contains the newest 50 in chronological order. Covers invariants 1, 2, 7.
|
||||
- Unit test: `NetworkLogModel::default()` + `snapshot_text()` returns `""`; used to validate invariant 9 (empty open) at the model layer.
|
||||
- Grep + build verification that no code under `app/src` or `crates/` still references `warp_network.log`, `log_file_path`, or `network_logging_workflow`. Covers invariants 1, 14.
|
||||
- Manual validation (dogfood build, `NetworkLogConsole` enabled by default):
|
||||
- Open Privacy settings → "View network logging" → pane opens as right-split with snapshot. Close and reopen; new requests appear after reopen. Covers invariants 4, 7, 8, 10, 11, 12.
|
||||
- Trigger the `Show Warp network log` keybinding → same pane opens / focuses. Open from both entrypoints consecutively → only one pane exists per window. Covers invariants 5, 6.
|
||||
- Disable `ContextFlag::NetworkLogConsole` (e.g. warp-home-link-only mode) → settings link hidden, keybinding unavailable. Covers invariant 3.
|
||||
- Confirm the pane is read-only: attempted typing produces no edits; find, select, copy still work. Covers invariant 10.
|
||||
- Open pane, quit app, relaunch → pane is absent, in-memory log starts empty. Covers invariant 13.
|
||||
- Search command palette and workflow list for "Tail Warp network log" → no results. Covers invariant 14.
|
||||
- Presubmit: `./script/presubmit` (covers `cargo fmt` + `cargo clippy --workspace --all-targets --all-features --tests -- -D warnings` + `cargo nextest`). Must pass before PR, per repo rules.
|
||||
- WASM build: `cargo check --target wasm32-unknown-unknown -p warp` (or the repo's standard wasm command) to confirm the removed `local_fs` cfg split didn't leave wasm-only gaps.
|
||||
## Risks and mitigations
|
||||
- **Log items can leak sensitive tokens into memory and into the pane UI.** The formatting path is unchanged from the existing on-disk log, so redaction behavior is inherited — not improved. Flag as follow-up if stronger redaction is desired.
|
||||
- **Pane type addition touches `LeafContents` and the restore match.** Missing an arm is caught at compile time thanks to exhaustive matching, but the sqlite serde tag must round-trip so existing snapshots keep loading. Verify by restoring an app-state snapshot that contains non-network-log panes after the change.
|
||||
- **Keybinding id `input:insert_network_logging_workflow` is retained for backwards compat with user custom keybindings** even though the handler no longer inserts a workflow. Acceptable trade-off; renaming would break users' customized bindings.
|
||||
Reference in New Issue
Block a user