agentleFS
Sign inSign up

luvus

RizRiyz/luvus/AGENTS.md

Shared maintainer guidance for coding agents working in the Luvus repository. This file is the repository-level source of truth. Tool-specific instruction files may add guidance, but they must not contradict it. Luvus changes quickly. Before describing behavior or editing a subsystem: 1. Check git status --short --branch and preserve every unrelated change. 2. Inspect the current implementation and its focused tests. 3. Use cargo run --quiet -- help all or src/cli.rs for the installed command surface. 4. Use website/src/content/docs/ for…

AGENTS.md927 starsChanged 35 days ago
# AGENTS.md

Shared maintainer guidance for coding agents working in the Luvus repository.
This file is the repository-level source of truth. Tool-specific instruction
files may add guidance, but they must not contradict it.

## Start with current evidence

Luvus changes quickly. Before describing behavior or editing a subsystem:

1. Check `git status --short --branch` and preserve every unrelated change.
2. Inspect the current implementation and its focused tests.
3. Use `cargo run --quiet -- help all` or `src/cli.rs` for the installed command
   surface.
4. Use `website/src/content/docs/` for public product documentation.
5. Treat ignored files under `docs/` as plans and historical handoffs, not as
   proof that a feature exists.

When remote state matters, compare the checkout with `origin/main`. Do not
silently change branches, fetch, rebase, or rewrite the user's work merely to
make the checkout match upstream.

## Product model

Luvus is mission control for AI coding agents. It is a single Rust binary with
several roles:

- With no command, it starts or attaches a thin TUI client.
- A detached server owns workspaces, tabs, panes, PTYs, terminal grids, agent
  state, persistence, modules, orchestration, API dispatch, and rendering.
- CLI commands send bounded JSON requests to the selected server and exit.
- Named sessions are independent server namespaces selected with
  `--session <name>`, `session attach <name>`, or the on-demand desktop/mobile
  session switcher. Switching starts the target if needed without detaching
  other clients.
- `--local` is a monolithic development escape hatch.
- `--remote <host>` attaches directly through an SSH byte bridge. Saved machine
  profiles place remote workspaces beside Local in one TUI; each profile selects
  one remote named session. Remote endpoint connections and viewport state
  belong to the client, while the remote server retains its own PTYs.
- `web` starts an optional foreground browser bridge for the selected session.
  It is loopback-only and read-only by default; `web --control` opts into
  terminal and workspace control. Normal TUI/server startup does not open an
  HTTP port. Stopping the bridge revokes its authority without stopping the
  server, PTYs, or other clients.
- `uhp access` starts a temporary loopback NDJSON gateway for independent
  transport providers. It is read-only by default; control is explicit,
  scoped, and paired. Finite authority advertises `authority.expires_at`;
  `--no-expiry` is process-bound and advertises
  `authority.expires_on_close:true`. Shutdown revokes authority in either mode.

There are two local endpoints per server:

- the newline-delimited JSON control API;
- the binary client transport for input, full frames, frame diffs, clipboard,
  notifications, sound, detach, and shutdown messages.

Clients are disposable. The server is the single writer of application state.
Detaching a client leaves panes alive. Stopping the server ends its live PTYs;
the next server restores layout and resumes supported native agent sessions
where possible.

## Non-negotiable development safety

- Work in the current project directory. Do not create another worktree, clone,
  or development directory under `/tmp`, `/private/tmp`, or elsewhere unless
  the user explicitly requests it.
- Never stop, restart, attach to, benchmark, or delete the user's production
  Luvus server during development.
- Debug builds normally use `~/.luvus-dev/`; installed release builds use
  `~/.luvus/`. An inherited `LUVUS_SOCKET_PATH` or session selector can still
  route a debug command to another running server.
- Before a debug lifecycle or integration test, run outside a managed Luvus
  pane or explicitly isolate the home and remove inherited socket/session
  selectors. On Unix, a safe pattern is:

  ```bash
  env -u LUVUS_SOCKET_PATH -u LUVUS_SESSION \
      LUVUS_HOME="$HOME/.luvus-dev" \
      ./target/debug/luvus --session agent-test server restart
  ```

- Use the exact binary under test. Confirm the executable, selected home,
  session, and socket before interpreting runtime results.
- Never use destructive Git commands, discard user changes, or stage unrelated
  files.
- Do not commit, amend, push, tag, open a PR, merge, publish, or edit releases
  unless the user explicitly authorizes that action.
- Do not add AI co-author trailers unless the user explicitly requests one for
  that commit.
- After implementation, report changed files, verification performed, remaining
  caveats, and a copyable Conventional Commit message.

## Architecture and code map

`src/main.rs` performs process-role and session routing. The important ownership
boundaries are:

- `src/app/`: `App`, input, dispatch, settings, dashboards, workers, and domain
  state. Application mutations converge on the server/local event-loop thread.
- `src/layout.rs`: pure binary space-partition pane geometry. Layout leaves store
  IDs; live panes and native views remain flat in `App`.
- `src/terminal/pty.rs`: portable PTY creation, reader/writer/reaper lifecycle,
  environment propagation, and cancellation. `src/terminal/host_input.rs`
  narrowly reconstructs Windows console bracketed paste before dispatch.
- `src/terminal/appearance.rs` and `src/terminal/theme_probe.rs`: child terminal
  appearance negotiation and terminal-theme probing.
- `src/terminal/vt/`: the `VtEngine` boundary and current Alacritty adapter.
  `vendor/vte/` and `vendor/alacritty_terminal/` are intentional local patched
  crates published under Luvus package names.
- `src/ipc/server.rs`: headless event loop, client ownership, rendering cadence,
  backpressure, and frame delivery.
- `src/ipc/client.rs`: terminal client, input forwarding, frame application, and
  client-side effects.
- `src/ipc/federated.rs` and `src/machine/`: client-owned local/remote endpoint
  switching, SSH transport and recovery, per-local-session saved-machine
  catalogs, and explicit remote setup/provisioning.
- `src/ipc/api.rs` and `src/ipc/transport.rs`: bounded local API handling plus
  Unix-socket and Windows-named-pipe transport.
- `src/ui/`: Ratatui rendering, panes, sidebars, docks, tab bar, settings,
  Git/files/diff, document previews, Mission Control, session overlays, and
  hit-test geometry.
- `src/detect.rs`: agent identity and state evidence. Detection is native Luvus
  behavior and must not depend on an installed agent skill.
- `src/agent.rs`: stable native-session, resume, fork, and usage facade.
  `src/agent/registry.rs` is the immutable built-in descriptor registry;
  `src/agent/types.rs` defines its operation records. Every compiled-in agent
  owns `src/agent/<agent>/`, including detection-only agents. Put non-trivial
  discovery, integration, and embedded assets in that directory, not in the
  registry or facade.
- `src/integration.rs`: shared safe-editing mechanics and the optional
  agent-integration facade. Agent-specific hooks, plugins, extensions, paths,
  and lifecycle semantics belong to their adapter. Hooks augment detection;
  they do not replace it.
- `src/cli.rs`, `src/api/`, and `src/app/dispatch.rs`: parsing/help, public UHP
  contracts, and validated state mutation for one control surface.
- `src/config.rs` and `src/persist.rs`: configuration, migration, selected-session
  paths, snapshots, and restore. Named-session discovery and switching live in
  `src/session.rs` and `src/app/session_menu.rs`.
- `src/git/`, `src/diff/`, and `src/files/`: GitHub/local Git data, semantic diff
  review and notes, file browsing, and bounded Markdown/Mermaid parsing and
  layout under `src/files/preview/`; app/UI preview ownership stays in
  `src/app/preview.rs` and `src/ui/preview.rs`.
- `src/search/` and `src/app/search.rs`: bounded global finder, fuzzy file-path
  indexing, and FILES filtering; directory reads stay off the app loop.
- `src/module/`: manifest-driven extensions that run out of process and call the
  same local API as other clients.
- `src/bar/`: Top and Bottom Luvus Bar declarations and rendering.
- `src/mission/`: usage and pricing data for Mission Control.
- `src/orch/` and `src/app/board.rs`: tasks, leases, quality gates, worktrees,
  and multi-agent orchestration. Worktree mode is isolated; workspace mode
  intentionally shares the existing checkout.
- `src/logging/`: bounded, private, redacted, rotating runtime logs.
- `src/uhp/`: the foreground, transport-neutral UHP access gateway, one-use
  pairing, delegated authority, and shutdown cleanup. It does not own a public
  transport or run when `uhp access` is absent.
- `src/web/`: the production browser bridge, loopback HTTP/WebSocket server,
  pairing and device authority, UHP forwarding, and embedded assets. `web/`
  owns the TypeScript browser client, UHP client, development bridge, and
  focused web tests. Build the browser source before updating embedded assets;
  do not hand-edit the generated bundle.
- `src/platform.rs` and `src/platform/windows.rs`: operating-system boundaries.

The main concurrency invariant is one mutable `App` owner. Background threads
may perform PTY, filesystem, Git, process, session, module, or network work, but
must return results through `AppEvent` or another bounded channel. The terminal
engine's narrow `Arc<Mutex<dyn VtEngine>>` sharing is an exception; keep its
lock scopes short and never hold it across unrelated slow work.

## State and public-contract invariants

- A normal layout leaf belongs to a live pane or a native view, never both.
- Workspace indices are 0-based at public boundaries. Tab positions are
  1-based publicly and 0-based internally. Pane IDs are stable opaque IDs for a
  server lifetime. Keep those conventions explicit in validation and docs.
- A server can remain alive with no workspace. Code that assumes an active
  workspace must guard that state before calling helpers such as `ws()` or
  `layout()`.
- Every client has its own viewport and render baseline. Passive or differently
  sized clients must not overwrite shared interactive geometry, focus, PTY size,
  cursor state, or scroll position.
- Validate all API input before mutation. Keep errors structured and keep
  ordinary requests to one newline-delimited JSON request and response.
- Owner-only socket/named-pipe security, peer validation, frame limits, bounded
  waits, and process identity checks are security boundaries, not optional
  cleanup.
- User configuration and snapshots must remain forward-tolerant through serde
  defaults and conservative migrations. Never hardcode a maintainer's home
  path, username, agent installation, or terminal.
- `session.persist_pane_screen` defaults to `true`. When disabled, restore
  layout and resumable agent metadata without persisting or loading visible
  terminal screens; scrollback is never part of the snapshot. Interactive
  nested Luvus clients require the separate opt-in `allow_nested` setting.
- `direct_keybindings` is separate from prefix `keybindings`, empty by default,
  and stores semantic chords such as `alt+right`, never raw escape bytes. Direct
  shortcuts are global in normal mode; overlays, modal text input,
  scroll/copy/resize modes, and the configured prefix retain precedence. Help
  must show effective bindings after user overrides, not only defaults.
- Pane focus history crosses tabs and workspaces, skips closed panes, and clears
  the forward branch after a new ordinary focus change.
- Named-session listing and startup are user-triggered background work. Fence
  results by generation so a closed or replaced selector cannot apply stale
  discovery or launch results; do not add idle session polling.
- Saved machines are not workspaces or named sessions. Their owner-local
  catalog is scoped to the selected local session; each machine selects one
  remote session. Prepare SSH, compatible-binary checks, and endpoint proof off
  the app loop. Installation or replacement requires fresh approval, and setup
  must not restart an already-running remote server. Inactive endpoints must
  not own input, cursor, effects, or PTY size; route actions to the selected
  endpoint and destination workspace rather than a same-index Local workspace.
- The global finder and FILES filtering use bounded, Git-aware file-path
  indexes; never turn a query into synchronous filesystem traversal on the app
  loop. File actions must preserve the selected workspace and focused pane,
  validate paths before mutation, and keep confirmation for deletion.
- Active-agent automations initially bind to an exact pane and terminal
  lifetime. When a resumable built-in adapter supplies a trusted native session
  ID, the private durable identity may rebind after restart only to one exact
  agent/session/workspace/cwd match with fresh readiness evidence. Public
  projections expose only `binding` and `target_state`, never native session
  IDs or recovery paths. Process-bound targets retain fail-closed restart
  behavior. Active targets create no ORCH worker, report prompt queueing as
  `delivered` rather than task completion, and fail closed on ambiguity,
  identity drift, or stale terminal routes. Busy `wait` targets and restoring
  targets wake from existing lifecycle events; do not add polling.
- File, DIFF, Markdown, and Mermaid views are native layout leaves, not hidden
  PTYs. Keep reads/layout off-loop, generation-checked, bounded, reusable, and
  independent of the configured file editor.
- UHP access binds loopback only and reveals no owner socket or upstream token
  in its descriptor. Pairing is one-use. Finite authority uses
  `authority.expires_at`; process-bound authority uses
  `authority.expires_on_close:true`. Shutdown revokes both modes. The external
  provider owns secure transport exposure while Luvus owns pairing and scoped
  upstream authority.
- Luvus Web is a separate disposable client. Keep its native bridge bound to
  loopback, require explicit control, and use one-use pairing plus independent
  per-device tickets and limits. A public phone URL needs an external trusted
  TLS/WSS tunnel and exact allowed origin; changing the pairing address does
  not create a tunnel or widen origin policy. The browser must never receive
  owner-socket paths or upstream credentials. Uploads paste a server-side path,
  never a local browser path. One bridge selects one upstream session, so a web
  session switch moves all devices on that bridge, not attached TUI clients.
  Keep browser input and terminal output bounded, with reliable action
  responses and coalesced visual frames. Agent session-title changes need a
  snapshot-refresh event. The browser bridge does not inherit the TUI client's
  saved SSH-machine connections; remote browser access requires a bridge on
  the destination host behind a trusted TLS/WSS tunnel.
- A configured module worktree provider may create worktrees and optionally
  remove them, but remains out of process and cannot bypass validation or
  mutate `App` directly. Internal rollback and task merge remain Git-backed.
- Cross-workspace operations must mutate the resolved destination workspace and
  tab, never whichever node happens to be active. Preserve explicit workspace
  closures across reattach instead of recreating the launch directory.
- Selection text preserves indentation and hard line breaks, joins soft wraps,
  and uses terminal display cells for wide characters across panes and native
  file/preview views. Preserve OSC 8 hyperlink targets and forward bounded
  pane-originated OSC 52 clipboard writes through the client clipboard path;
  never enable OSC 52 clipboard reads implicitly.

## CLI API UHP and documentation parity

`luvus help all` is the command inventory. Major surfaces include workspaces,
tabs, panes, agents, files, Git, semantic diff notes, Mission Control,
worktrees, tasks, leases, modules, bars, UI docks, themes, sessions, machines,
skills, integrations, document previews, direct shortcuts, search, waits,
logs, and UHP access. `web` is the optional browser-client command;
`luvus help web` is its option reference. `luvus help machine` covers saved SSH
profiles; `--remote` is the direct-attach path.

When adding or changing a user-visible control:

1. Update CLI parsing, compact help, focused subcommand help, and validation.
2. Update API dispatch and response/error behavior.
3. Update UHP capabilities and schema when the control is public automation.
4. Add parser and dispatch tests, including indexing and pass-through arguments.
5. Update the relevant public documentation. UHP `index.mdx`,
   `getting-started.mdx`, `examples.mdx`, `remote-access.mdx`, `methods.mdx`,
   `terminal.mdx`, and `conformance.mdx` live together under
   `website/src/content/docs/docs/uhp/`; other product references remain under
   `website/src/content/docs/docs/reference/` and the affected guides.
6. Update the bundled agent guidance when an automation workflow changed:
   `skills/luvus/`, `plugins/luvus/skills/luvus/`, and
   `website/public/agent-readme.md`.

Human-facing CLI text is localized in `src/i18n/cli.rs`. Settings text is in
`src/i18n/settings.rs`. Command names, flags, JSON fields, UHP methods, paths,
and literal user data stay canonical. Do not ship a partial translation for a
registered language. `LUVUS_*`, `.luvus`/`.luvus-dev`, and
`luvus-module.toml` are the current namespaces; do not restore removed Bohay
compatibility implicitly.

## Agent skills and integrations

Do not use the bundled Luvus skill as a substitute for reading this codebase.
The skill is a user-facing automation interface for controlling a running Luvus
instance and delegating work. Use it only when the user explicitly asks to
operate Luvus or delegate through it.

The supported user model is:

```text
luvus skill enable
luvus skill status
luvus skill disable
luvus skill show
```

`src/skill.rs` is authoritative for installation and compatibility behavior.
Do not manually copy skills into agent directories as an implementation fix.
Agent detection and sidebar status must continue to work without skills or
hooks installed.

## Adding or changing built-in agent support

First choose the smallest correct support level:

- A user or managed detection manifest can add identity and screen-state rules
  without recompiling Luvus. That agent is detection-only and must not silently
  gain session parsing, command execution, integrations, or skill installation.
- Native discovery, resume, fork, usage, or an integration requires built-in
  Rust code that has been reviewed and an owning `src/agent/<agent>/` adapter.
- A module or external UHP reporter is preferable when the feature does not
  need trusted in-process access to an agent's private native store.

For a built-in adapter:

1. Create `src/agent/<agent>/mod.rs` and assemble one immutable
   `AgentDescriptor`. Keep the canonical `id` lowercase and stable; aliases
   normalize user input but do not create additional agents. Set
   `launch_command` to the exact executable for a fresh interactive session;
   do not put flags or shell syntax in this field. Put a required static
   ORCH prompt subcommand or flag such as `ask` in `task_prompt_args`; never
   embed user data.
   Scheduled execution is separate: set `automation` only when the upstream
   agent has a documented one-shot entrypoint and reviewed per-run arguments
   for at least one `read_only`, `workspace`, or `full_access` policy. Leave
   unsupported policies as `None`; never guess approval input or rewrite the
   user's permanent agent configuration.
2. Declare identity evidence accurately. Put unmistakable executable names in
   `distinct`, ordinary words in `ambiguous`, versioned executable logic in a
   narrow `binary_matcher`, and exact interpreter package names—including npm
   scope—in `interpreter_packages`. Use `overlap_priority` only for a reviewed
   collision such as OMP versus Pi; never rely accidentally on registry order.
3. Add `sessions.rs` only when the upstream agent has a stable native store.
   Keep reads bounded and offline, match canonical CWDs portably, obtain session
   IDs from structured metadata, and declare only operations the upstream CLI
   safely exposes. `sessions.fork = None` is the correct value when no external
   native fork exists.
4. Add `integration.rs` and assets only for an optional, documented upstream
   hook/plugin/extension surface. Install and uninstall must be idempotent and
   surgical, preserve unrelated configuration and secrets, and leave native
   detection functional when the integration is absent.
5. Register the descriptor once in `src/agent/registry.rs`. Add it to the
   presentation-ordered integration projection only when `integration` exists.
   Do not add agent-name matches to UI, IPC, dispatch, Settings, or CLI code.
6. Keep generic process/title/screen authority and manifest merging in
   `src/detect.rs`. Built-in screen-state rules currently live there. Native
   Mission Control usage readers currently live behind `src/agent/usage.rs`;
   add one only when stable persisted counters exist, and never estimate token
   usage from transcript prose.

Required parity work:

- Add registry tests for unique IDs, aliases, interpreter packages, capability
  projection, presentation order, static automation argv, supported and
  unsupported automation access policies, and every intentional identity overlap.
- Add detection fixtures for direct binaries, interpreter launchers, scoped
  packages, wrappers, false-positive prose, and both Unix and Windows path
  forms. Detection must work with skills and integrations absent.
- Add bounded session-store fixtures and resume/fork command tests when those
  operations exist. Add temporary-home install/status/uninstall tests for an
  integration, proving unrelated user files survive.
- Exercise managed/user manifest precedence, reload, and a manifest-defined
  unknown agent whenever identity plumbing changes.
- Update `README.md`, the supported-agent reference and guide, Settings/CLI
  integration projections, and the homepage grid when user-visible support
  changes. If automation behavior changes, also update UHP/schema fixtures,
  both bundled skill copies, and `website/public/agent-readme.md`.
- Run focused adapter/detection/integration tests, formatting, strict Clippy,
  the locked suite, and the locked release build. Use isolated live tests only
  for third-party agents actually available, and do not claim an untested OS.

Descriptors are static metadata. Adding an adapter must not add a dependency,
thread, timer, watcher, per-pane scan, network request, or render-path work.
The contributor-facing walkthrough is
`website/src/content/docs/docs/extend/adding-agent-support.mdx`; ignored
`docs/107-modular-agent-adapter-architecture.md` records the migration design,
not the current public contract.

## Modules and dependencies

Prefer a module when a feature can live outside core without weakening the user
experience. Modules are directories with `luvus-module.toml`, executable argv
commands, settings, actions, event hooks, panes, docks, bar widgets, and
optional worktree providers. They receive canonical `LUVUS_*` context. They
must not receive direct in-process access to `App`.

New dependencies require a concrete benefit and review of maintenance,
licensing, supply-chain exposure, binary size, compile time, and cross-platform
support. Prefer existing core dependencies and owner-maintained upstream crates.
Do not replace the patched terminal crates casually. Luvus is Apache-2.0;
preserve notices and accept only compatible code and assets.

## Performance expectations

Luvus should remain fast and memory-efficient with many panes and agents:

- Keep the app loop event-driven. Avoid unconditional polling and periodic full
  fleet scans.
- Never run Git, GitHub, filesystem traversal, process discovery, module
  execution, or network work synchronously on the app loop.
- Avoid per-frame allocation, cloning whole terminal grids, and rendering when
  no visible client state changed.
- Hidden PTY output may update terminal state without forcing a whole-client
  render. Preserve frame coalescing and one-pending-frame backpressure.
- Keep terminal history bounded by the Scrollback Memory setting. The current
  Alacritty adapter maps a byte budget to a conservative row count, so reported
  memory values are estimates rather than exact allocator usage.
- Keep caches generation-based or event-invalidated, with explicit bounds.
- Compare performance using equivalent layouts, terminal sizes, workloads, and
  warm-up. Separate idle CPU, active CPU, physical footprint, live heap, peak,
  thread count, descriptors, and retained history. Debug and release results
  are not interchangeable.

## Cross-platform behavior

- Keep platform code behind narrow `cfg` boundaries and fail closed when the OS
  cannot prove process, path, or peer identity.
- Windows child processes launched by detached Luvus must not flash console or
  PowerShell windows. Reuse the no-window process helpers.
- Preserve Windows modifier, AltGr, IME, path, named-pipe, and npm-shim behavior.
- Treat Crossterm key events as the input contract. Keep Windows-only ambiguous
  sequence reconstruction in `host_input`; do not teach app commands raw ANSI
  strings. Preserve multiline paste, Alt+Backspace, Ctrl+Slash, distinct
  Ctrl+Shift letters, and AltGr text in nested applications.
- Preserve Unix socket ownership and permissions, signal/process lifecycle, and
  long-socket-path handling.
- A platform-specific fix needs tests on that platform when available and must
  not silently change macOS/Linux/FreeBSD/Windows behavior outside its scope.

## Testing and verification

Use the narrowest relevant test while iterating. Do not repeatedly run the full
suite for a small local change.

```bash
cargo build
cargo test <focused-name> -- --nocapture
cargo fmt --all --check
cargo clippy --all-targets -- -D warnings
cargo test --locked
cargo build --release --locked
```

Run formatting after Rust edits. Before final handoff, run focused regression
tests plus the broad checks proportionate to risk. Platform, PTY, IPC, rendering,
and lifecycle changes also need a real debug-client/server test in an isolated
development home. Do not claim an untested platform is verified.

For web changes, use `npm --prefix web run check` and the focused web tests.
Native bridge integration uses `web/scripts/test-native.mjs` with the exact
debug binary and an isolated temporary Luvus home; do not aim it at a running
production session. Preserve coverage without turning ordinary CI tests into
unbounded input bursts or timing benchmarks.

The CI matrix currently covers formatting and Clippy on Ubuntu and Windows,
locked tests on Ubuntu and macOS, FreeBSD amd64, targeted Windows
protocol/ConPTY boundaries, UHP fixtures and live conformance, web
client/bridge checks, patched terminal crates, packageability, RustSec audit,
and Nix flake evaluation/build.

## Repository and contribution conventions

- `website/` is the Astro site and public documentation source.
- `web/` is the browser source and development harness; `src/web/assets/`
  contains the assets embedded in the production binary.
- `.github/` contains CI, release automation, issue templates, and the PR body
  template.
- `docs/` and `CLAUDE.md` are intentionally ignored local maintainer material.
- `changelog/v<version>.md` is embedded by the binary and feeds release content.
- `community/themes/` contains reviewed community themes.
- `protocol/uhp/v1/` is the versioned public automation contract.

Keep changes focused on one user-facing outcome. Avoid opportunistic cleanup.
Use concise Conventional Commit messages such as:

```text
fix(input): preserve navigation modifiers on Windows
feat(cli): add pane move command
perf(render): skip unchanged client projections
docs: clarify module setup
```

Before calling work complete, inspect the final diff, confirm no unrelated file
entered it, and explain what was verified and what remains unverified.

Discussion

Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.

Posts are public.Sign in to post

No one has posted yet. Be the first.