Skip to content
Merged
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: 1 addition & 1 deletion .agents/skills/change-maple-agent-mode/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Do not commit, push, open a PR, merge, release, or clean unrelated work unless t

Keep Maple's two inference paths distinct:

- Research chat is a browser-capable React path. `UnifiedChat.tsx` uses the OpenAI JavaScript client with `@opensecret/react`'s authenticated and encrypted `aiCustomFetch`, targeting OpenSecret's Conversations and Responses APIs.
- Research chat is a browser-capable React path. `UnifiedChat.tsx` uses the OpenAI JavaScript client with `@mapleai/sdk`'s authenticated and encrypted `aiCustomFetch`, targeting OpenSecret's Conversations and Responses APIs.
- Agent Mode is desktop-only. `AgentMode.tsx` calls typed frontend services, which invoke Tauri commands and receive `agent-event` envelopes. Native Rust owns `MapleAgentService`, the embedded Goose managers and local sessions, Maple's provider, developer tools, permissions, and cancellation. `MapleProvider` sends encrypted OpenSecret SDK requests to `/v1/chat/completions`.
- ACP is a secondary local adapter over the same `MapleAgentService`. It must not initialize a second Goose runtime or call through the Tauri adapter.
- The local OpenAI-compatible proxy is a separate user-facing feature. Neither Research chat nor Agent Mode should silently route through it.
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/develop-maple-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ identify an arbitrary running development instance.
`app/src/backend.rs` adapts the transport-neutral runtime under
`crates/maple-agent/` to GPUI. Keep window/UI concerns in `app`, and shared
account/session/tool policy in the runtime. The runtime consumes the existing
local `opensecret` SDK and `maple-proxy`; registry names and publication are
separate work. Research's Tauri runtime remains independently owned.
local `maple-sdk` and `maple-proxy` packages; registry publication is separate
work. Research's Tauri runtime remains independently owned.

## Build with the component environment

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/develop-maple-proxy/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ publish, inspect the exact package first:
cargo package --locked --manifest-path proxy/Cargo.toml
```

If the proxy references a new `opensecret` version, publish that SDK crate
If the proxy references a new `maple-sdk` version, publish that SDK crate
first. Do not publish either crate from Maple's application Release workflow.
Root proxy container CI builds without pushing. After a successful stable Maple
Release, `.github/workflows/proxy-publish.yml` independently compares that
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/develop-maple/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ through their public API URLs; do not depend on their source trees.

- Put React, routes, contexts, and browser-facing services under `apps/maple-research/frontend/src/`.
- Put privileged/native behavior under `apps/maple-research/frontend/src-tauri/src/` and expose the narrowest typed Tauri command or event needed by the UI.
- Use `@opensecret/react` and the existing OpenSecret client paths for authentication, encryption, and API calls. Read `apps/maple-research/frontend/package.json` to determine whether the application consumes a published version or the in-tree `file:../../../sdk` package; do not infer that boundary from prose. Do not duplicate protocol or cryptographic logic in components.
- Use `@mapleai/sdk` and the existing OpenSecret client paths for authentication, encryption, and API calls. Read `apps/maple-research/frontend/package.json` to determine whether the application consumes a published version or the in-tree `file:../../../sdk` package; do not infer that boundary from prose. Do not duplicate protocol or cryptographic logic in components.
- Follow nearby state ownership, cancellation, error, and cleanup patterns. Preserve account isolation and handle logout, navigation, retries, and stale async completion explicitly.
- Treat all network, file, deep-link, shell, tool, and Tauri-command inputs as untrusted. Validate again at the enforcing boundary.
- Keep feature flags as rollout/UI controls, never authorization controls.
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/develop-opensecret-sdk/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: develop-opensecret-sdk
description: Develop and review the OpenSecret TypeScript/React and Rust SDKs under Maple's sdk directory. Use for SDK API, authentication, attestation, encrypted transport, tests, in-tree OpenSecret integration, package contents, versions, or an explicitly authorized npm or crates.io publishing handoff; use develop-maple for application-only work.
description: Develop and review the Maple TypeScript/React and Rust SDKs under Maple's sdk directory. Use for SDK API, authentication, attestation, encrypted transport, tests, in-tree OpenSecret integration, package contents, versions, or an explicitly authorized npm or crates.io publishing handoff; use develop-maple for application-only work.
---

# Develop the OpenSecret SDK
# Develop the Maple SDK

Work from `MaplePrivacyLabs/Maple/sdk`. Read the repository-root `AGENTS.md`,
`sdk/README.md`, the affected implementation and tests, and the root
Expand All @@ -12,8 +12,8 @@ Work from `MaplePrivacyLabs/Maple/sdk`. Read the repository-root `AGENTS.md`,
The SDK source is part of the Maple repository, but its TypeScript and Rust
package boundaries remain independently versioned and publishable:

- `src/` builds `@opensecret/react` for browser and React consumers.
- `rust/` builds the `opensecret` crate for native consumers.
- `src/` builds `@mapleai/sdk` for browser and React consumers.
- `rust/` builds the `maple-sdk` crate (imported as `maple_sdk`) for native consumers.
- `apps/maple-research/frontend/package.json` is authoritative for whether Maple's browser client
consumes a published TypeScript version or the in-tree `file:../../../sdk` package.
- desktop Maple and `proxy/` consume the in-tree Rust crate through versioned
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/release-maple/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ commit, external effect, and authority provided by the user.
- The same Maple GitHub Release receives four native `maple-proxy` archives and
their checksum manifest. Never create a separate proxy Release or proxy tag;
`/releases/latest` must continue to identify the Maple application release.
- Maple GitHub Releases do not publish `opensecret` or `maple-proxy` to
- Maple GitHub Releases do not publish `maple-sdk` or `maple-proxy` to
crates.io. A successful stable release starts a non-gating GHCR sibling that
builds only for a new or missing non-baseline proxy version. It treats exact
version tags as immutable, verifies release provenance and container inputs,
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ current source and tests take precedence over historical design documents.
- `apps/maple-agent/`: GPUI desktop-v2 prototype, ACP and proxy CLI. Read its
[guide](apps/maple-agent/AGENTS.md) and `$develop-maple-agent`. Its runtime and
update discovery are separate from Research and its existing Agent Mode.
- `sdk/`: TypeScript/React and Rust OpenSecret SDKs. Read
- `sdk/`: TypeScript/React and Rust Maple SDKs for the OpenSecret backend. Read
`$develop-opensecret-sdk` and the SDK documentation.
- `proxy/`: the separate OpenAI-compatible relay, also consumed by the desktop
app. Read `$develop-maple-proxy` and the proxy documentation.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Maple

Maple is a monorepo for the Maple applications, their OpenSecret SDKs, local proxy,
Maple is a monorepo for the Maple applications, Maple SDKs, local proxy,
OpenSecret backend, and updater service. The existing web, desktop, and mobile client lives under
[`apps/maple-research/`](apps/maple-research/README.md), including Research chat
and desktop Agent Mode. Its directory name does not change the shipped Maple
Expand All @@ -12,7 +12,7 @@ application identity.
| --- | --- |
| [`apps/maple-research/`](apps/maple-research/README.md) | React/Vite frontend and Tauri desktop/mobile application, app documentation, and distribution configuration |
| [`apps/maple-agent/`](apps/maple-agent/README.md) | GPUI desktop-v2 prototype, ACP agent, and CLI proxy; independent from the shipped Research app |
| [`sdk/`](sdk/README.md) | OpenSecret TypeScript/React and Rust SDKs, consumed in tree by Maple |
| [`sdk/`](sdk/README.md) | Maple TypeScript/React and Rust SDKs, consumed in tree by Maple |
| [`proxy/`](proxy/README.md) | Standalone OpenAI-compatible proxy, also consumed by desktop Maple |
| [`services/updates/`](services/updates/README.md) | Desktop updater Worker and verified release-metadata publishing |
| [`services/opensecret/`](services/opensecret/README.md) | Confidential authentication, inference, conversations, and related backend APIs; local Nitro tooling and signed PCR files |
Expand Down
76 changes: 38 additions & 38 deletions apps/maple-agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/maple-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ once_cell = "1.18.0"
http = "1"
reqwest = { version = "0.13", features = ["stream"] }
# Shared monorepo crates retain their independent package names and versions.
opensecret = { version = "3.6.2", path = "../../sdk/rust" }
maple-sdk = { version = "3.6.2", path = "../../sdk/rust" }
maple-proxy = { version = "0.3.4", path = "../../proxy" }

[profile.dev]
Expand Down
6 changes: 3 additions & 3 deletions apps/maple-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ app/ The maple-gpui binary. Owns the window, login, chat,
settings, notifications, and the backend adapter.
crates/maple-agent/ Maple's transport-neutral agent runtime, extracted from
the Tauri app with Tauri removed. Owns embedded Goose,
the Maple provider over the OpenSecret SDK, developer
the Maple provider over the Maple Rust SDK, developer
tools, permission policy, account-scoped session
storage, and the ACP server.
crates/maple-billing/ HTTP client for the Maple billing API.
Expand Down Expand Up @@ -450,9 +450,9 @@ the namespace. Local `just release` and `just dist` only build local files.

## Shared dependencies and provenance

The component consumes the existing in-tree `opensecret` SDK at `../../sdk/rust`
The component consumes the in-tree `maple-sdk` crate at `../../sdk/rust`
and `maple-proxy` at `../../proxy` through workspace dependencies. The SDK fork
patch is removed; no SDK rename or registry publication is needed for local
patch is removed; registry publication is not needed for local
builds. Keep the component lockfile and Nix source fileset aligned with these
path dependencies. The pure package includes the required SDK attestation
assets as well as Rust source.
Expand Down
2 changes: 1 addition & 1 deletion apps/maple-agent/app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ semver = "1"
log = { workspace = true }
env_logger = "0.11"
webbrowser = "1"
opensecret = { workspace = true }
maple-sdk = { workspace = true }
uuid = { version = "1", features = ["v4"] }
unicode-segmentation = { version = "1", optional = true }
pulldown-cmark = { version = "0.13", default-features = false, optional = true }
Expand Down
2 changes: 1 addition & 1 deletion apps/maple-agent/app/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use maple_agent::maple_api::{
MapleApiAuthEventSink, MapleApiAuthRequest, MapleApiAuthSnapshot, MapleApiAuthState,
};
use maple_agent::open_secret_config::configured_pcr0_environment;
use opensecret::OpenSecretClient;
use maple_sdk::OpenSecretClient;
use tokio::runtime::Runtime;
use tokio::sync::mpsc;
use uuid::Uuid;
Expand Down
2 changes: 1 addition & 1 deletion apps/maple-agent/crates/maple-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ reqwest = { workspace = true }
chrono = { version = "0.4", default-features = false, features = ["clock"] }
goose = { git = "https://github.com/AnthonyRonning/goose.git", rev = "785d655d110746147117d23690e09cc7023aa9dc", package = "goose", default-features = false }
goose-providers = { git = "https://github.com/AnthonyRonning/goose.git", rev = "785d655d110746147117d23690e09cc7023aa9dc", package = "goose-providers", default-features = false }
opensecret = { workspace = true }
maple-sdk = { workspace = true }
maple-proxy = { workspace = true }
rand = "0.8.6"
rmcp = { version = "=3.1.2", default-features = false, features = ["client", "transport-streamable-http-client-reqwest"] }
Expand Down
16 changes: 8 additions & 8 deletions apps/maple-agent/crates/maple-agent/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4564,7 +4564,7 @@ static MODEL_CATALOG_REFRESH_IN_FLIGHT: AtomicBool = AtomicBool::new(false);
/// Resolve the catalog's vision flag without inventing one when metadata is absent.
/// An explicit alias capability (including false) overrides its target model.
fn catalog_supports_vision(
catalog: &opensecret::ModelCatalogResponse,
catalog: &maple_sdk::ModelCatalogResponse,
model_id: &str,
) -> Option<bool> {
let mut concrete_id = model_id;
Expand Down Expand Up @@ -10284,10 +10284,10 @@ mod tests {
impl provider::MapleInferenceTransport for InertMapleTransport {
async fn send_inference_request(
self: Arc<Self>,
_request: opensecret::InferenceRequest,
_request: maple_sdk::InferenceRequest,
_cancel_token: CancellationToken,
) -> opensecret::Result<opensecret::InferenceResponse> {
Err(opensecret::Error::Other(
) -> maple_sdk::Result<maple_sdk::InferenceResponse> {
Err(maple_sdk::Error::Other(
"test transport should not be called".to_string(),
))
}
Expand All @@ -10305,15 +10305,15 @@ mod tests {
impl provider::MapleInferenceTransport for TerminalMapleTransport {
async fn send_inference_request(
self: Arc<Self>,
_request: opensecret::InferenceRequest,
_request: maple_sdk::InferenceRequest,
_cancel_token: CancellationToken,
) -> opensecret::Result<opensecret::InferenceResponse> {
) -> maple_sdk::Result<maple_sdk::InferenceResponse> {
match self.0 {
TerminalMapleFailure::Session => Err(opensecret::Error::Session(
TerminalMapleFailure::Session => Err(maple_sdk::Error::Session(
"private exhausted session detail".to_string(),
)),
TerminalMapleFailure::AttestationVerification => {
Err(opensecret::Error::AttestationVerificationFailed(
Err(maple_sdk::Error::AttestationVerificationFailed(
"private attestation detail".to_string(),
))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,7 @@ mod tests {
use goose::providers::base::{ProviderUsage, Usage};
use goose::session::SessionManager;
use goose::session::SessionType;
use opensecret::{
use maple_sdk::{
WebExtractPage, WebExtractRequest, WebExtractResponse, WebSearchRequest, WebSearchResponse,
WebSearchResult,
};
Expand Down Expand Up @@ -2594,7 +2594,7 @@ mod tests {
self: Arc<Self>,
_request: WebSearchRequest,
_cancel_token: CancellationToken,
) -> opensecret::Result<WebSearchResponse> {
) -> maple_sdk::Result<WebSearchResponse> {
Ok(WebSearchResponse {
trace_id: None,
results: vec![WebSearchResult {
Expand All @@ -2611,7 +2611,7 @@ mod tests {
self: Arc<Self>,
request: WebExtractRequest,
_cancel_token: CancellationToken,
) -> opensecret::Result<WebExtractResponse> {
) -> maple_sdk::Result<WebExtractResponse> {
Ok(WebExtractResponse {
trace_id: None,
pages: vec![WebExtractPage {
Expand Down
Loading
Loading