Compare commits

..

17 Commits

Author SHA1 Message Date
Saoud Rizwan 2ee18e7f0c chore(cli): release v3.0.39 2026-07-08 21:15:22 -07:00
Saoud Rizwan 0b65506a2b chore(sdk): release v0.0.59 2026-07-08 20:00:37 -07:00
Saoud Rizwan 3502608081 fix(telemetry): emit telemetry from the detached hub daemon process (#12177)
* feat(sdk): emit telemetry from the hub daemon process

The detached hub daemon hosts the LocalRuntimeHost that emits
task.conversation_turn and task.tokens for every hub-backed session
(CLI in prefer-hub mode, desktop app, connectors), but the daemon
entrypoint never created a telemetry handle - startHubWebSocketServer
received telemetry: undefined and every capture in the daemon-side
runtime was a no-op. Sessions billed normally on the backend while
reporting nothing to OTel.

- create a ConfiguredTelemetryHandle in the daemon entry and pass it to
  the websocket server and schedule runtime handlers
- identify from the cached cline account at startup and re-resolve
  periodically, since the long-lived daemon often starts before login
  or outlives an account switch
- flush and dispose the handle on graceful and fatal shutdown

* fix(sdk): flush daemon telemetry when server startup fails

If startHubWebSocketServer throws, dispose the telemetry handle before
rethrowing so failed daemon starts are visible in telemetry instead of
dying silently.

* fix(sdk): bound daemon telemetry flush and reuse settings manager

- Race dispose's flush against a 5s deadline so a hung exporter can't
  keep a crashed daemon alive holding the hub port (before this PR the
  daemon exited immediately on fatal errors; the flush must not change
  that materially).
- Construct ProviderSettingsManager once instead of every identity
  refresh; its constructor runs legacy-migration and provider
  registration side effects, and getProviderSettings re-reads the file
  per call anyway.
- Test the dispose-on-startup-failure path and the cline-hub-daemon
  platform metadata.

* fix(sdk): label daemon telemetry cline_type as hub

Review feedback from @abeatrix: daemon-hosted sessions can be triggered
by the CLI, desktop app, or connectors, so daemon-emitted events should
not share the CLI process's cline_type. Existing values are "cli" and
"VSCode Extension"; the daemon now reports "hub" (with the finer
platform=cline-hub-daemon kept as-is).
2026-07-08 19:35:26 -07:00
Saoud Rizwan ed3107f9ec Revert "docs: add Cline free models page (#12183)" (#12185)
This reverts commit 6bce48aad4.
2026-07-08 19:32:36 -07:00
Renee Huang 6bce48aad4 docs: add Cline free models page (#12183)
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
2026-07-08 19:22:32 -07:00
Bee 1e1b6af51c fix(sdk): set versioned Cline client-identity headers for Cline provider (#12182)
* fix(sdk): set versioned Cline client-identity headers for Cline provider

* address feedback

* feat: add platform metadata to client context

Include platform, platformVersion, and isMultiRoot in extension client
context for CLI, ACP, and VS Code sessions. This provides downstream
core/session logic with richer runtime information and distinguishes ACP
clients from the standard CLI client.

* lint

* clean up

* fix: resolve client host identity via HostProvider for standalone compatibility

cline-session-factory.ts is also bundled into the standalone cline-core
(JetBrains), where the 'vscode' module resolves to the generated Proxy-stub
module: vscode.env.appName and vscode.version return Proxy objects, which
would flow into X-PLATFORM/X-PLATFORM-VERSION header values and fail at
request serialization.

Resolve the identity through HostProvider.env.getHostVersion() instead —
the VS Code hostbridge returns the identical values (vscode.env.appName,
vscode.version, ClineClient.VSCode, extension version), and JetBrains'
hostbridge returns its real host values, so the standalone stops reporting
itself as the VS Code extension as a bonus. Multi-root detection goes
through HostProvider.workspace.getWorkspacePaths() for the same reason.
Both resolvers degrade gracefully (undefined/false) if the host bridge is
unavailable, in which case the header builder falls back to source-derived
values.

* Add unit test as proof

---------

Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
2026-07-08 19:08:25 -07:00
Saoud Rizwan ee49900232 chore(greptile): update telemetry review rules for the monorepo layout (#12180)
The .greptile config was written for the pre-merge standalone cline/sdk
repo and never updated after the monorepo merge:

- the sdk-telemetry-doc-update rule enforced an Event Catalog in DOC.md,
  a file that does not exist in this repo (it now emits a false P2 on
  every PR touching core-events.ts, e.g. #12177)
- rules.md cited PR #357, apps/vscode/src/hub-daemon.ts, and
  apps/vscode/src/telemetry.ts - none of which exist here
- the 'Hub Daemon Metadata Forwarding' section described an argv-based
  metadata payload that was never implemented in this repo; replaced
  with the actual daemon-owned telemetry pattern from #12177
- the opted-out-test rule now describes the real convention: assert the
  event flows through capture (no-op for OptedOutTelemetryService), not
  captureRequired
2026-07-08 16:43:14 -07:00
Saoud Rizwan a1d5589d19 feat: allow selecting Cline free models on the ClinePass provider (#12140)
* feat(llms): include Cline free models in the cline-pass catalog

* feat(vscode): show Subscribed/Free model tabs on the ClinePass provider

* feat(cli): show Subscribed/Free sections in the ClinePass model picker

* fix(cli): drop redundant browse-all entry from ClinePass picker

* fix(cli): show only subscribed models in ClinePass onboarding picker

* feat(cli): include free models and quota explainer in ClinePass onboarding picker

* fix: shorten ClinePass free section copy

* fix(cli): strip redundant free markers from sectioned picker names

* fix: drop free from ClinePass free section copy

* fix: tighten ClinePass free section copy

* refactor: address review feedback on ClinePass free models

- single buildFeaturedModelEntries(providerId) dispatcher, builders private
- rename isClineProvider to isClineManagedProvider (includes cline-pass)
- use isClineManagedProvider in the free-model cost check
- themed tab border, pretty names on free model cards
- clearer cline-pass cost test name

* fix: address ClinePass free-model review blockers

- Stop re-sorting the cline-pass live catalog by release date in
  mergeKnownModels: free models carry OpenRouter release dates, so the
  sort could put a free model first and make it the fallback default
  when the bundled default id rotates out of the live clinePass bucket.
  Preserve the normalize-time order (pass models first) and pin it with
  an end-to-end resolveProviderConfig test.
- Add the browse-all escape to the CLI ClinePass picker when the
  clinePass bucket is empty (bundled fallback after a fetch failure),
  so a subscriber isn't left with a free-models-only picker.
- Rename ErrorRow's local isClineManagedProvider to
  isClineUsageBillingProvider: it only matches the cline provider,
  unlike the shared util of the same name that also matches cline-pass.
2026-07-08 15:08:27 -07:00
Tomás Barreiro 721fda2e99 Add ClinePass limit error (#12162)
* Add ClinePass limit error

* refactor regex

---------

Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
2026-07-08 14:54:20 -07:00
Saoud Rizwan 5e78861eb5 fix(vscode): update ClinePass onboarding option copy (#12173) 2026-07-08 13:21:12 -07:00
Robin Newhouse 29798f59f3 Persist VS Code manual compaction sidecar (#11900)
* Persist VS Code manual compaction sidecar

* Fix compaction test isolation

* Address PR feedback on compaction comments

* Fix compaction test core mock hoisting

* fix(vscode): avoid compaction session rebuild

* fix(core): validate active compaction from persisted transcript

* fix(vscode): harden manual compaction sidecar flow
2026-07-08 13:18:22 -07:00
Ara 177d0eb07f Remove Cline model picker recommendation copy (#12170) 2026-07-08 12:15:53 -07:00
Bee 869a87a220 fix(core): use no-emit TypeScript config for checks (#12139)
* fix(core): use no-emit TypeScript config for checks

Update the core package TypeScript config to run checks without emitting files,
allowing broader workspace sources via the package parent rootDir. Simplify the
dev config so it only extends the main package config and avoids duplicated
compiler overrides.

* feedback

* remove dead code
2026-07-08 11:15:16 -07:00
Max 0cfd0bbe05 Fix VS Code F5 webview debug flow (#12027)
* fix vscode f5 settings

- fixed the hot module reloading issue while debugging the extension.
- also fixed issue where deb:webview task wasn't showing as complete

* fix vscode webview dev cleanup

---------

Co-authored-by: Max Paulus 🥪 <max@cline.bot>
2026-07-08 10:53:41 -07:00
yanalialiuk 08f656532f docs: add Atomic Chat local provider setup guide (#11966)
* docs: add Atomic Chat local provider setup guide

Document Atomic Chat alongside Ollama and LM Studio in the local models
overview and add a dedicated provider configuration page.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Update overview.mdx

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Renee Huang <100229782+reneehuang1@users.noreply.github.com>
2026-07-08 10:48:58 -07:00
Tomás Barreiro 10dece6677 Remove all ClinePass GLM 5.1 references (#12107)
* Remove all ClinePass GLM 5.1 references

* fix other references
2026-07-08 14:59:10 +02:00
Sufiyan Khan 885a2936b6 docs(authorizing): remove model-specific wording from generic setup step (#12156)
Step 4 in the IDE setup flow says 'Choose your desired Claude model'
but applies to all providers (OpenAI, Gemini, DeepSeek, local, etc.).
Drop 'Claude' to keep it provider-agnostic.
2026-07-08 21:22:33 +09:00
134 changed files with 4075 additions and 1343 deletions
-8
View File
@@ -39,14 +39,6 @@
"sdk/packages/core/src/auth/**"
],
"severity": "high"
},
{
"id": "sdk-telemetry-doc-update",
"rule": "Any PR that adds new event constants to CORE_TELEMETRY_EVENTS in packages/core/src/services/telemetry/core-events.ts, adds new capture* helper functions, or changes the payload shape of an existing event must update the Event Catalog section in DOC.md. Flag PRs that modify core-events.ts without a corresponding change to DOC.md.",
"scope": [
"sdk/packages/core/src/services/telemetry/core-events.ts"
],
"severity": "medium"
}
]
}
+1 -5
View File
@@ -16,13 +16,9 @@
"path": "sdk/packages/core/src/services/telemetry/OpenTelemetryProvider.ts",
"description": "OpenTelemetry-backed provider that wires logs/metrics/traces exporters. Contains createConfiguredTelemetryService and createConfiguredTelemetryHandle, the canonical factories every host should use."
},
{
"path": "DOC.md",
"description": "Public API and event documentation. The Event Catalog and 'Activation funnel' sections must be kept in sync with core-events.ts. Host integration rules (CLI dir ordering, hub daemon metadata forwarding) are documented here."
},
{
"path": "sdk/ARCHITECTURE.md",
"description": "Architecture reference. Telemetry design decisions, completion semantics (submit_and_exit anchoring), and hub-daemon telemetry forwarding are documented here. Use as ground truth for design intent."
"description": "Architecture reference. Telemetry design decisions and completion semantics (submit_and_exit anchoring) are documented here. Use as ground truth for design intent."
},
{
"path": "sdk/AGENTS.md",
+20 -17
View File
@@ -36,8 +36,11 @@ event names. It exports:
1. Add the constant to `CORE_TELEMETRY_EVENTS`
2. Add a typed `capture*()` helper alongside it (with a typed `properties` parameter)
3. Update the Event Catalog section in `DOC.md`
4. Add a unit test in `core-events.test.ts` asserting the event is dropped when telemetry is opted out
3. Add a unit test in `core-events.test.ts` asserting the event flows through the
opt-out-respecting `capture` path and never `captureRequired` (opt-out is enforced by
`OptedOutTelemetryService`, whose `capture` is a no-op — the test convention is
"emits X as a normal opt-out-respecting event"). Events that intentionally bypass
opt-out must use `captureRequired` and assert that explicitly.
## The Activation Funnel
@@ -82,7 +85,7 @@ The CLI accepts `--config <dir>`. The CLI **must** apply `setClineDir(...)` and
and any other on-disk telemetry state lands under `~/.cline` instead of the user's chosen
config dir.
The canonical pattern is in `apps/cli/src/main.ts` (PR #357):
The canonical pattern is in `apps/cli/src/main.ts`:
```ts
if (configDir) setClineDir(configDir);
@@ -90,18 +93,18 @@ setHomeDir(homedir());
captureCliExtensionActivated(); // <-- after dir overrides
```
## Hub Daemon Metadata Forwarding
## Hub Daemon Telemetry
Hosts that spawn a detached `@cline/core/hub/daemon-entry` process must forward telemetry
metadata into the daemon argv so the daemon can reconstruct an equivalent
`ITelemetryService`. The expected payload is base64-encoded JSON with snake_case keys:
The detached hub daemon (`sdk/packages/core/src/hub/daemon/entry.ts`) hosts the
`LocalRuntimeHost` that emits `task.conversation_turn` and `task.tokens` for every
hub-backed session, so the daemon must own its own `ITelemetryService`. It builds one via
`createHubDaemonTelemetry()` (`sdk/packages/core/src/hub/daemon/telemetry.ts`), which
identifies from the cached cline account (re-resolved periodically, since the daemon often
starts before login) and flushes on every shutdown path, including startup failure.
```
{ extension_version, cline_type, platform, platform_version, os_type, os_version, is_remote_workspace }
```
The reference implementation is `apps/vscode/src/hub-daemon.ts` (PR #357). Without this
forwarding, hub-backed sessions silently drop their lifecycle telemetry.
Flag changes that remove this wiring, construct runtime hosts inside the daemon without
passing its telemetry handle, or add daemon exit paths that skip the flush — hub-backed
sessions would silently drop their lifecycle telemetry (this exact bug shipped once).
## Auth Lifecycle Completeness
@@ -120,10 +123,10 @@ canonical examples of all four phases.
## Single Telemetry Service Per Host
On VS Code, the telemetry handle is built **once** in `activate()`
(`apps/vscode/src/telemetry.ts`) and the same instance is passed into the sidebar, panel
command, and daemon spawn payload. Do not let individual controllers construct their own
`ITelemetryService` — that fragments distinct-id state, opt-out tracking, and flush ownership.
On VS Code, all callers go through the lazy `telemetryService` proxy in
`apps/vscode/src/services/telemetry/index.ts`, which constructs the service once on first
use. Do not let individual controllers construct their own `ITelemetryService` — that
fragments distinct-id state, opt-out tracking, and flush ownership.
The CLI follows the same pattern via the `getCliTelemetryService()` singleton in
`apps/cli/src/utils/telemetry.ts`, which is memoized by the activation gate in
+7 -7
View File
@@ -68,7 +68,7 @@
"command": "bun run build:webview",
"group": "build",
"problemMatcher": [],
"isBackground": true,
"isBackground": false,
"label": "npm: build:webview",
"dependsOn": [
"npm: protos"
@@ -89,7 +89,7 @@
"command": "bun run build:webview:test",
"group": "build",
"problemMatcher": [],
"isBackground": true,
"isBackground": false,
"label": "npm: build:webview:test",
"dependsOn": [
"npm: protos"
@@ -114,16 +114,16 @@
{
"pattern": [
{
"regexp": ".",
"regexp": "^(?!)((?:.*))$",
"kind": "file",
"file": 1,
"location": 2,
"message": 3
"message": 1
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "."
"beginsPattern": "^Building webview for|^\\s*VITE",
"endsPattern": "^.*Local:\\s+http://localhost:[0-9]+/"
}
}
],
+10
View File
@@ -1,5 +1,15 @@
# Cline CLI Changelog
## 3.0.39
- You can now select Cline free models on the ClinePass provider in the model picker
- Removed the retired ClinePass GLM 5.1 model
- Fixed OpenAI Codex model metadata under the GPT Subscription provider
- `str_replace` edits now report accurate diffs
- Fixed context compaction so canonical session history is preserved
- The detached hub daemon now emits telemetry, and telemetry identity now includes `user_id`
- Cline provider requests now send versioned client-identity headers
## 3.0.38
- New plan/act accent palette: act mode is now blue (`#79b8ff`) and plan mode amber, replacing the old cyan/yellow — applied across dialogs, the model selector, config, onboarding, markdown, and syntax highlighting, with light-theme variants tuned for contrast
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@cline/cli",
"displayName": "cline",
"version": "3.0.38",
"version": "3.0.39",
"description": "Autonomous coding agent CLI - capable of creating/editing files, running commands, using the browser, and more",
"type": "module",
"publishConfig": {
+19 -1
View File
@@ -511,6 +511,7 @@ export class AcpAgent implements Agent {
private async buildConfig(session: SessionState): Promise<Config> {
const cwd = session.cwd || process.cwd();
const workspaceRoot = resolveWorkspaceRoot(cwd);
// Resolve credentials: env vars take precedence, then session provider.
const providerId = process.env.CLINE_PROVIDER ?? session.currentProviderId;
const apiKey = process.env.CLINE_API_KEY ?? this.authResult?.apiKey ?? "";
@@ -519,6 +520,7 @@ export class AcpAgent implements Agent {
providerId,
mode: session.currentMode,
});
const cliBuildInfo = getCliBuildInfo();
return {
providerId,
@@ -537,7 +539,23 @@ export class AcpAgent implements Agent {
enableAgentTeams: false,
enableTools: true,
cwd,
workspaceRoot: resolveWorkspaceRoot(cwd),
workspaceRoot,
extensionContext: {
client: {
name: "cline-acp",
version: cliBuildInfo.version,
platform: "cli",
platformVersion: cliBuildInfo.version,
isMultiRoot: false,
},
workspace: {
rootPath: workspaceRoot,
cwd,
workspaceName: cwd,
ide: "Terminal Shell",
platform: process.platform,
},
},
};
}
}
@@ -125,12 +125,12 @@ describe("buildConnectorStartRequest", () => {
io: { writeln: vi.fn(), writeErr: vi.fn() },
loggerConfig: { enabled: false, level: "info", destination: "stdout" },
systemRules: "Rules",
defaultModel: "cline-pass/glm-5.1",
defaultModel: "cline-pass/glm-5.2",
});
expect(request.provider).toBe("cline-pass");
expect(request.apiKey).toBe("workos:resolved-token");
expect(request.model).toBe("cline-pass/glm-5.1");
expect(request.model).toBe("cline-pass/glm-5.2");
});
it("uses auth material resolved by provider settings manager", async () => {
@@ -153,11 +153,11 @@ describe("buildConnectorStartRequest", () => {
io: { writeln: vi.fn(), writeErr: vi.fn() },
loggerConfig: { enabled: false, level: "info", destination: "stdout" },
systemRules: "Rules",
defaultModel: "cline-pass/glm-5.1",
defaultModel: "cline-pass/glm-5.2",
});
expect(request.provider).toBe("cline-pass");
expect(request.apiKey).toBe("workos:resolved-token");
expect(request.model).toBe("cline-pass/glm-5.1");
expect(request.model).toBe("cline-pass/glm-5.2");
});
});
+9 -1
View File
@@ -15,6 +15,7 @@ import {
getPreferredKanbanInstaller,
} from "./commands/update";
import { CLI_DEFAULT_CHECKPOINT_CONFIG } from "./runtime/defaults";
import { getCliBuildInfo } from "./utils/common";
import {
buildCliCompactionConfig,
CLI_COMPACTION_MODE_EXPECTED_TEXT,
@@ -1043,6 +1044,7 @@ export async function runCli(): Promise<void> {
reasoningEffort: args.reasoningEffort,
persistedReasoning: selectedProviderSettings?.reasoning,
});
const cliBuildInfo = getCliBuildInfo();
const { createCliLoggerAdapter } = await import("./logging/adapter");
const loggerAdapter = createCliLoggerAdapter({
runtime: "cli",
@@ -1093,7 +1095,13 @@ export async function runCli(): Promise<void> {
cwd,
workspaceRoot,
extensionContext: {
client: { name: "cline-cli" },
client: {
name: "cline-cli",
version: cliBuildInfo.version,
platform: "cli",
platformVersion: cliBuildInfo.version,
isMultiRoot: false,
},
workspace: {
rootPath: workspaceRoot,
cwd,
@@ -411,43 +411,43 @@ export function createInteractiveSessionRuntime(input: {
});
};
const restartWithMessages = async (
messages: Message[],
sessionMetadata?: Record<string, unknown>,
initialCompactionState?: SessionCompactionState,
): Promise<void> => {
sessionStartGeneration += 1;
pendingResumeSessionId = undefined;
startupError = undefined;
// Publish the restart as the in-flight startup. Teardown leaves a window
// with no active session, and without this barrier a concurrent
// ensureReady() (e.g. a message submitted right after a plan/act toggle)
// reads that window as "no session" and boots an empty session that then
// races the restarted one for the active slot.
const restart = (async () => {
await stopCurrentSession();
clearActiveSession();
await startFreshSession(
messages,
sessionMetadata,
initialCompactionState,
);
})().catch((error) => {
startupError = error;
throw error;
});
startupPromise = restart;
try {
await restart;
} finally {
// Restore the pre-restart steady state (startupPromise unset) so a
// failed restart stays retryable by the next ensureReady(). A newer
// startup that already replaced the barrier is left alone.
if (startupPromise === restart) {
startupPromise = undefined;
}
const restartWithMessages = async (
messages: Message[],
sessionMetadata?: Record<string, unknown>,
initialCompactionState?: SessionCompactionState,
): Promise<void> => {
sessionStartGeneration += 1;
pendingResumeSessionId = undefined;
startupError = undefined;
// Publish the restart as the in-flight startup. Teardown leaves a window
// with no active session, and without this barrier a concurrent
// ensureReady() (e.g. a message submitted right after a plan/act toggle)
// reads that window as "no session" and boots an empty session that then
// races the restarted one for the active slot.
const restart = (async () => {
await stopCurrentSession();
clearActiveSession();
await startFreshSession(
messages,
sessionMetadata,
initialCompactionState,
);
})().catch((error) => {
startupError = error;
throw error;
});
startupPromise = restart;
try {
await restart;
} finally {
// Restore the pre-restart steady state (startupPromise unset) so a
// failed restart stays retryable by the next ensureReady(). A newer
// startup that already replaced the barrier is left alone.
if (startupPromise === restart) {
startupPromise = undefined;
}
};
}
};
const restartWithCurrentMessages = async (): Promise<void> => {
const [{ messages, status }, compactionState] = await Promise.all([
@@ -0,0 +1,106 @@
import type {
ClineRecommendedModel,
ClineRecommendedModelsData,
} from "@cline/core";
export type ClineModelPickerTier = "recommended" | "subscribed" | "free";
export interface ClineModelPickerItem {
kind: "model";
model: ClineRecommendedModel;
tier: ClineModelPickerTier;
}
export interface ClineModelPickerBrowse {
kind: "browse";
}
export type ClineModelPickerEntry =
| ClineModelPickerItem
| ClineModelPickerBrowse;
export const CLINE_MODEL_PICKER_TIER_LABELS: Record<
ClineModelPickerTier,
string
> = {
recommended: "Recommended",
subscribed: "Subscribed",
free: "Free",
};
// Featured entries for the sectioned picker, keyed by provider: cline gets
// Recommended/Free with a browse-all escape into the full catalog; cline-pass
// gets Subscribed/Free (see buildClinePassModelEntries for why no browse-all).
export function buildFeaturedModelEntries(
providerId: string,
data: ClineRecommendedModelsData,
): ClineModelPickerEntry[] {
return providerId === "cline-pass"
? buildClinePassModelEntries(data)
: buildClineModelEntries(data);
}
function buildClineModelEntries(
data: ClineRecommendedModelsData,
): ClineModelPickerEntry[] {
const entries: ClineModelPickerEntry[] = [];
for (const m of data.recommended) {
entries.push({ kind: "model", model: m, tier: "recommended" });
}
for (const m of data.free) {
entries.push({ kind: "model", model: m, tier: "free" });
}
entries.push({ kind: "browse" });
return entries;
}
// Shown under the Free section header when picking a model for ClinePass
export const CLINE_PASS_FREE_SECTION_DESCRIPTION =
"Try with limited usage, separate from ClinePass quota.";
// ClinePass shows the subscription's models plus the Cline free models — both
// providers hit the same Cline API, so free models are selectable in place
// (they ride usage billing at $0 instead of the subscription quota).
// No "browse all" entry when the clinePass bucket is populated: unlike cline,
// the ClinePass catalog contains exactly these two buckets, so the sections
// already list every selectable model. An empty clinePass bucket means the
// fetch fell back to the bundled list (which has no pass models) — without an
// escape into the full catalog a subscriber could only pick free models, so
// browse-all comes back in that degraded mode.
function buildClinePassModelEntries(
data: ClineRecommendedModelsData,
): ClineModelPickerEntry[] {
const entries: ClineModelPickerEntry[] = [];
for (const m of data.clinePass) {
entries.push({ kind: "model", model: m, tier: "subscribed" });
}
for (const m of data.free) {
entries.push({ kind: "model", model: m, tier: "free" });
}
if (data.clinePass.length === 0) {
entries.push({ kind: "browse" });
}
return entries;
}
// The quota explainer only makes sense in the ClinePass picker, which is the
// only picker that has a "subscribed" section
export function freeTierDescriptionFor(
entries: ClineModelPickerEntry[],
): string | undefined {
const isClinePassPicker = entries.some(
(entry) => entry.kind === "model" && entry.tier === "subscribed",
);
return isClinePassPicker ? CLINE_PASS_FREE_SECTION_DESCRIPTION : undefined;
}
// OpenRouter marks free variants with "(free)" in names and ":free" in ids to
// disambiguate them from their paid twins. Inside the sectioned pickers the
// Free header already says it, so the markers are redundant — but keep them in
// flat lists (e.g. browse-all), where both variants appear side by side.
export function stripFreeMarker(displayName: string): string {
return displayName
.replace(/\s*\(free\)\s*$/i, "")
.replace(/:free$/i, "")
.trim();
}
@@ -0,0 +1,98 @@
import { describe, expect, it } from "vitest";
import {
buildFeaturedModelEntries,
CLINE_PASS_FREE_SECTION_DESCRIPTION,
freeTierDescriptionFor,
stripFreeMarker,
} from "./cline-model-entries";
const model = (id: string) => ({ id, name: id, description: "", tags: [] });
describe("cline model picker entries", () => {
it("builds Recommended/Free sections for the cline provider", () => {
const entries = buildFeaturedModelEntries("cline", {
recommended: [model("anthropic/claude-sonnet-5")],
free: [model("deepseek/deepseek-v4-flash")],
clinePass: [model("cline-pass/glm-5.1")],
});
expect(entries).toEqual([
{
kind: "model",
model: model("anthropic/claude-sonnet-5"),
tier: "recommended",
},
{
kind: "model",
model: model("deepseek/deepseek-v4-flash"),
tier: "free",
},
{ kind: "browse" },
]);
});
it("builds Subscribed/Free sections for the cline-pass provider", () => {
const entries = buildFeaturedModelEntries("cline-pass", {
recommended: [model("anthropic/claude-sonnet-5")],
free: [model("deepseek/deepseek-v4-flash")],
clinePass: [model("cline-pass/glm-5.1"), model("cline-pass/kimi-k2.6")],
});
expect(entries).toEqual([
{ kind: "model", model: model("cline-pass/glm-5.1"), tier: "subscribed" },
{
kind: "model",
model: model("cline-pass/kimi-k2.6"),
tier: "subscribed",
},
{
kind: "model",
model: model("deepseek/deepseek-v4-flash"),
tier: "free",
},
]);
});
it("adds the browse-all escape when the clinePass bucket is empty", () => {
// The fetch fell back to the bundled list (no pass models); the sections
// alone would leave a subscriber able to pick only free models.
const entries = buildFeaturedModelEntries("cline-pass", {
recommended: [],
free: [model("deepseek/deepseek-v4-flash")],
clinePass: [],
});
expect(entries).toEqual([
{
kind: "model",
model: model("deepseek/deepseek-v4-flash"),
tier: "free",
},
{ kind: "browse" },
]);
});
it("attaches the quota explainer only to the ClinePass picker's free section", () => {
const data = {
recommended: [model("anthropic/claude-sonnet-5")],
free: [model("deepseek/deepseek-v4-flash")],
clinePass: [model("cline-pass/glm-5.1")],
};
expect(
freeTierDescriptionFor(buildFeaturedModelEntries("cline-pass", data)),
).toBe(CLINE_PASS_FREE_SECTION_DESCRIPTION);
expect(
freeTierDescriptionFor(buildFeaturedModelEntries("cline", data)),
).toBe(undefined);
});
it("strips redundant free markers from display names", () => {
expect(stripFreeMarker("Laguna M.1 (free)")).toBe("Laguna M.1");
expect(stripFreeMarker("Trinity Large Preview (FREE)")).toBe(
"Trinity Large Preview",
);
expect(stripFreeMarker("laguna-m.1:free")).toBe("laguna-m.1");
expect(stripFreeMarker("DeepSeek V4 Flash")).toBe("DeepSeek V4 Flash");
});
});
@@ -1,7 +1,6 @@
// @jsxImportSource @opentui/react
import {
type ClineRecommendedModel,
type ClineRecommendedModelsData,
fetchClineRecommendedModels,
} from "@cline/core";
@@ -9,20 +8,23 @@ import type { ReactNode } from "react";
import { useEffect, useState } from "react";
import "opentui-spinner/react";
import { palette } from "../../palette";
import {
CLINE_MODEL_PICKER_TIER_LABELS,
type ClineModelPickerEntry,
freeTierDescriptionFor,
stripFreeMarker,
} from "./cline-model-entries";
export interface ClineModelPickerItem {
kind: "model";
model: ClineRecommendedModel;
tier: "recommended" | "free";
}
export interface ClineModelPickerBrowse {
kind: "browse";
}
export type ClineModelPickerEntry =
| ClineModelPickerItem
| ClineModelPickerBrowse;
export {
buildFeaturedModelEntries,
CLINE_MODEL_PICKER_TIER_LABELS,
type ClineModelPickerBrowse,
type ClineModelPickerEntry,
type ClineModelPickerItem,
type ClineModelPickerTier,
freeTierDescriptionFor,
stripFreeMarker,
} from "./cline-model-entries";
function tagColor(tag: string): string {
if (tag === "FREE") return palette.success;
@@ -39,12 +41,13 @@ function resolveDisplayName(
for (const key of candidates) {
if (!key) continue;
const hit = knownModels[key] as { name?: string } | undefined;
if (hit?.name) return hit.name;
if (hit?.name) return stripFreeMarker(hit.name);
}
}
return modelId.includes("/")
const fallback = modelId.includes("/")
? (modelId.split("/").pop() ?? modelId)
: modelId;
return stripFreeMarker(fallback);
}
export function useClineRecommendedModels() {
@@ -68,20 +71,6 @@ export function useClineRecommendedModels() {
return { data, loading };
}
export function buildClineModelEntries(
data: ClineRecommendedModelsData,
): ClineModelPickerEntry[] {
const entries: ClineModelPickerEntry[] = [];
for (const m of data.recommended) {
entries.push({ kind: "model", model: m, tier: "recommended" });
}
for (const m of data.free) {
entries.push({ kind: "model", model: m, tier: "free" });
}
entries.push({ kind: "browse" });
return entries;
}
export function ClineModelPicker(props: {
entries: ClineModelPickerEntry[];
selected: number;
@@ -103,6 +92,7 @@ export function ClineModelPicker(props: {
let lastTier: string | null = null;
let isFirstHeader = true;
const rows: ReactNode[] = [];
const freeTierDescription = freeTierDescriptionFor(entries);
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
@@ -112,14 +102,20 @@ export function ClineModelPicker(props: {
if (entry.kind === "model") {
if (entry.tier !== lastTier) {
lastTier = entry.tier;
const label = entry.tier === "recommended" ? "Recommended" : "Free";
const label = CLINE_MODEL_PICKER_TIER_LABELS[entry.tier];
rows.push(
<box
key={`tier-${entry.tier}`}
paddingX={1}
marginTop={isFirstHeader ? 0 : 1}
flexDirection="column"
>
<text fg="gray">{label}</text>
{entry.tier === "free" && freeTierDescription && (
<text fg="gray">
<em>{freeTierDescription}</em>
</text>
)}
</box>,
);
isFirstHeader = false;
@@ -3,7 +3,12 @@ import type { ChoiceContext } from "@opentui-ui/dialog";
import { useDialogKeyboard } from "@opentui-ui/dialog/react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { palette } from "../../palette";
import type { ClineModelPickerEntry } from "./cline-model-picker";
import {
CLINE_MODEL_PICKER_TIER_LABELS,
type ClineModelPickerEntry,
freeTierDescriptionFor,
stripFreeMarker,
} from "./cline-model-picker";
import { CHANGE_PROVIDER_ACTION } from "./model-selector";
import { ProviderRow } from "./provider-row";
@@ -29,12 +34,13 @@ function resolveDisplayName(
for (const key of candidates) {
if (!key) continue;
const hit = knownModels[key] as { name?: string } | undefined;
if (hit?.name) return hit.name;
if (hit?.name) return stripFreeMarker(hit.name);
}
}
return modelId.includes("/")
const fallback = modelId.includes("/")
? (modelId.split("/").pop() ?? modelId)
: modelId;
return stripFreeMarker(fallback);
}
export function ClineModelSelectorContent(
@@ -62,11 +68,13 @@ export function ClineModelSelectorContent(
key: string;
kind: "header" | "model" | "browse";
label: string;
description?: string;
tags: string[];
isCurrent: boolean;
entryIndex: number;
}[] = [];
let lastTier: string | null = null;
const freeTierDescription = freeTierDescriptionFor(entries);
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
if (!entry) continue;
@@ -76,7 +84,9 @@ export function ClineModelSelectorContent(
rows.push({
key: `tier-${entry.tier}`,
kind: "header",
label: entry.tier === "recommended" ? "Recommended" : "Free",
label: CLINE_MODEL_PICKER_TIER_LABELS[entry.tier],
description:
entry.tier === "free" ? freeTierDescription : undefined,
tags: [],
isCurrent: false,
entryIndex: -1,
@@ -156,8 +166,18 @@ export function ClineModelSelectorContent(
if (row.kind === "header") {
const isFirst = idx === 0;
return (
<box key={row.key} paddingX={1} marginTop={isFirst ? 0 : 1}>
<box
key={row.key}
paddingX={1}
marginTop={isFirst ? 0 : 1}
flexDirection="column"
>
<text fg="gray">{row.label}</text>
{row.description && (
<text fg="gray">
<em>{row.description}</em>
</text>
)}
</box>
);
}
+12 -3
View File
@@ -26,7 +26,7 @@ import {
ProviderPickerContent,
UseExistingOrReconfigureContent,
} from "../components/dialogs/provider-picker";
import { buildClineModelEntries } from "../components/model-selector/cline-model-picker";
import { buildFeaturedModelEntries } from "../components/model-selector/cline-model-picker";
import {
BROWSE_ALL_ACTION,
ClineModelSelectorDialogContent,
@@ -341,7 +341,13 @@ export function useModelSelector(opts: {
continue;
}
if (config.providerId === "cline") {
if (
config.providerId === "cline" ||
config.providerId === "cline-pass"
) {
// ClinePass gets the same sectioned picker with Subscribed/Free
// sections — free models are selectable while staying on ClinePass
const featuredProviderId = config.providerId;
const clineResult = await dialog.choice<string>({
style: { maxHeight: termHeight - 2 },
content: (ctx: ChoiceContext<string>) => (
@@ -351,7 +357,10 @@ export function useModelSelector(opts: {
currentProviderName={providerDisplayName}
knownModels={config.knownModels as Record<string, unknown>}
loadEntries={async () =>
buildClineModelEntries(await fetchClineRecommendedModels())
buildFeaturedModelEntries(
featuredProviderId,
await fetchClineRecommendedModels(),
)
}
/>
),
+36 -16
View File
@@ -29,7 +29,7 @@ import {
loadIndividualSubscriptionPlansFromProviderSettings,
} from "../../cline-account";
import {
buildClineModelEntries,
buildFeaturedModelEntries,
type ClineModelPickerEntry,
useClineRecommendedModels,
} from "../../components/model-selector/cline-model-picker";
@@ -206,11 +206,14 @@ export function useOnboardingController(props: OnboardingControllerProps) {
const modelList = useSearchableList(modelItems, createCustomModelItem);
// Cline featured model picker
// Cline featured model picker (ClinePass gets Subscribed/Free sections)
const recommended = useClineRecommendedModels();
const clineEntries: ClineModelPickerEntry[] = useMemo(
() => (recommended.data ? buildClineModelEntries(recommended.data) : []),
[recommended.data],
() =>
recommended.data
? buildFeaturedModelEntries(activeProviderId, recommended.data)
: [],
[recommended.data, activeProviderId],
);
const [clineModelSelected, setClineModelSelected] = useState(0);
const [clineModelReasoningIds, setClineModelReasoningIds] = useState<
@@ -221,20 +224,37 @@ export function useOnboardingController(props: OnboardingControllerProps) {
>(undefined);
useEffect(() => {
getLocalProviderModels("cline")
.then(({ models }) => {
const ids = new Set<string>();
for (const m of models) {
// The featured picker serves both cline and cline-pass, so pool reasoning
// support and display names from both catalogs
void Promise.allSettled(
["cline", "cline-pass"].map((providerId) =>
getLocalProviderModels(providerId),
),
).then((results) => {
const ids = new Set<string>();
for (const result of results) {
if (result.status !== "fulfilled") continue;
for (const m of result.value.models) {
if (m.supportsReasoning) ids.add(m.id);
}
setClineModelReasoningIds(ids);
})
.catch(() => {});
resolveProviderConfig("cline")
.then((resolved) => {
if (resolved?.knownModels) setClineKnownModels(resolved.knownModels);
})
.catch(() => {});
}
setClineModelReasoningIds(ids);
});
void Promise.allSettled(
["cline", "cline-pass"].map((providerId) =>
resolveProviderConfig(providerId),
),
).then((results) => {
const merged: Record<string, unknown> = {};
for (const result of results) {
if (result.status === "fulfilled" && result.value?.knownModels) {
Object.assign(merged, result.value.knownModels);
}
}
if (Object.keys(merged).length > 0) {
setClineKnownModels(merged);
}
});
}, []);
// Thinking level
@@ -135,9 +135,9 @@ describe("onboarding model helpers", () => {
expect(getOAuthProviderLabel("oca")).toBe("oca");
});
it("uses the featured Cline model picker only for the Cline provider", () => {
it("uses the featured Cline model picker for the Cline and ClinePass providers", () => {
expect(shouldUseFeaturedClineModelPicker("cline")).toBe(true);
expect(shouldUseFeaturedClineModelPicker("cline-pass")).toBe(false);
expect(shouldUseFeaturedClineModelPicker("cline-pass")).toBe(true);
expect(shouldUseFeaturedClineModelPicker("anthropic")).toBe(false);
});
});
+2 -1
View File
@@ -207,5 +207,6 @@ export function getOAuthProviderLabel(providerId: string): string {
}
export function shouldUseFeaturedClineModelPicker(providerId: string): boolean {
return providerId === "cline";
// ClinePass uses the featured picker too, with Subscribed/Free sections
return providerId === "cline" || providerId === "cline-pass";
}
@@ -53,6 +53,37 @@ describe("shouldZeroClineFreeModelCost", () => {
expect(fetchMock).not.toHaveBeenCalled();
});
it("zeros cost of free models selected on the cline-pass provider", async () => {
vi.stubGlobal(
"fetch",
vi.fn(async () => {
return new Response(
JSON.stringify({
free: [{ id: "deepseek/deepseek-v4-flash" }],
}),
{ status: 200, headers: { "content-type": "application/json" } },
);
}),
);
await expect(
shouldZeroClineFreeModelCost({
providerId: "cline-pass",
modelId: "deepseek/deepseek-v4-flash",
baseUrl: "https://cline.test/api/v1",
}),
).resolves.toBe(true);
// subscription (cline-pass/...) models are not in the free bucket
await expect(
shouldZeroClineFreeModelCost({
providerId: "cline-pass",
modelId: "cline-pass/glm-5.1",
baseUrl: "https://cline.test/api/v1",
}),
).resolves.toBe(false);
});
it("does not match a paid model by only the final path segment", async () => {
vi.stubGlobal(
"fetch",
+3 -1
View File
@@ -73,7 +73,9 @@ function getClineFreeModelIds(baseUrl: string): Promise<readonly string[]> {
export async function shouldZeroClineFreeModelCost(
config: Pick<Config, "providerId" | "modelId" | "baseUrl">,
): Promise<boolean> {
if (config.providerId !== "cline") return false;
// Free models are also selectable on ClinePass — they ride usage billing at $0
if (config.providerId !== "cline" && config.providerId !== "cline-pass")
return false;
const modelId = normalizeModelId(config.modelId);
if (!modelId) return false;
+3 -1
View File
@@ -694,7 +694,9 @@ export async function initializeSessionManager(
setHomeDirIfUnset(homedir());
const hubServer = await startHubWebSocketServer({
port: 0,
owner: resolveHubOwnerContext(`code-sidecar:${process.pid}:${randomUUID()}`),
owner: resolveHubOwnerContext(
`code-sidecar:${process.pid}:${randomUUID()}`,
),
runtimeHandlers: createLocalHubScheduleRuntimeHandlers(),
});
const sessionManager = await ClineCore.create({
@@ -15,8 +15,8 @@
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.398 0.195 277.366);
--primary-foreground: oklch(0.962 0.018 272.314);
--primary: oklch(0.398 0.195 277.366);
--primary-foreground: oklch(0.962 0.018 272.314);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
@@ -45,37 +45,37 @@
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.398 0.195 277.366);
--primary-foreground: oklch(0.962 0.018 272.314);
--secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.585 0.233 277.117);
--sidebar-primary-foreground: oklch(0.962 0.018 272.314);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.398 0.195 277.366);
--primary-foreground: oklch(0.962 0.018 272.314);
--secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.585 0.233 277.117);
--sidebar-primary-foreground: oklch(0.962 0.018 272.314);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@theme inline {
@@ -401,7 +401,11 @@ function parseEditorFileDiff(event: SessionHookEvent): SessionFileDiff | null {
};
}
if (command === "create" || command === "insert" || command === "str_replace") {
if (
command === "create" ||
command === "insert" ||
command === "str_replace"
) {
const newContent =
toStringValue(input.new_text) ??
toStringValue(input.file_text) ??
-35
View File
@@ -1,6 +1,5 @@
import fs from "node:fs"
import path from "node:path"
import { createRequire } from "node:module"
import { fileURLToPath } from "node:url"
import * as esbuild from "esbuild"
@@ -179,39 +178,6 @@ const e2eBuildConfig = {
plugins: [aliasResolverPlugin, esbuildProblemMatcherPlugin],
}
/**
* Copies the plugin sandbox bootstrap from the built @cline/core package into
* the extension's dist directory. The bootstrap runs in an isolated child
* process spawned by SubprocessSandbox and must be a separate file — it cannot
* be inlined into the main bundle. resolveBootstrap() (bundled into
* extension.js) searches for it at dist/extensions/plugin-sandbox-bootstrap.js.
*
* The bootstrap has external runtime dependencies (jiti for TypeScript
* transpilation, @cline/shared) that it resolves via Node's standard module
* resolution from its on-disk location. Both must be direct dependencies of
* the extension so they are present in node_modules and resolvable from
* dist/extensions/. The CLI build performs the same copy in apps/cli/bun.mts.
*/
function copyPluginSandboxBootstrap() {
if (e2eBuild) return
const projectRequire = createRequire(import.meta.url)
let corePackageDir
try {
corePackageDir = path.dirname(projectRequire.resolve("@cline/core/package.json"))
} catch {
console.warn("[esbuild] @cline/core not found — skipping plugin sandbox bootstrap copy")
return
}
const bootstrapSrc = path.join(corePackageDir, "dist", "extensions", "plugin-sandbox-bootstrap.js")
if (!fs.existsSync(bootstrapSrc)) {
console.warn(`[esbuild] plugin-sandbox-bootstrap.js not found at ${bootstrapSrc} — build @cline/core first`)
return
}
const bootstrapDest = path.join(__dirname, destDir, "extensions", "plugin-sandbox-bootstrap.js")
fs.mkdirSync(path.dirname(bootstrapDest), { recursive: true })
fs.copyFileSync(bootstrapSrc, bootstrapDest)
}
async function main() {
const config = standalone ? standaloneConfig : e2eBuild ? e2eBuildConfig : extensionConfig
const extensionCtx = await esbuild.context(config)
@@ -221,7 +187,6 @@ async function main() {
await extensionCtx.rebuild()
await extensionCtx.dispose()
}
copyPluginSandboxBootstrap()
}
main().catch((e) => {
+1 -3
View File
@@ -394,7 +394,7 @@
"test:e2e:optimal": "bun run test:e2e:build && node src/test/e2e/utils/build.mjs && playwright test",
"test:e2e:ui": "bun scripts/interactive-playwright.ts",
"install:all": "bun install",
"dev:webview": "cd webview-ui && bun run dev",
"dev:webview": "node scripts/clean-webview-vite-cache.mjs && cd webview-ui && bun run dev",
"build:webview": "bun run protos && cd webview-ui && bun run build",
"test:webview": "cd webview-ui && bun run test",
"publish:marketplace": "node scripts/publish-marketplace.mjs",
@@ -467,7 +467,6 @@
"@cline/agents": "workspace:*",
"@cline/core": "workspace:*",
"@cline/llms": "workspace:*",
"@cline/sdk": "workspace:*",
"@cline/shared": "workspace:*",
"@google/genai": "^1.30.0",
"@grpc/grpc-js": "^1.9.15",
@@ -520,7 +519,6 @@
"ignore": "^7.0.3",
"image-size": "^2.0.2",
"isbinaryfile": "^5.0.2",
"jiti": "^2.7.0",
"js-yaml": "^4.1.1",
"jschardet": "^3.1.4",
"json5": "^2.2.3",
+17
View File
@@ -10,6 +10,23 @@ option java_package = "bot.cline.proto";
// SlashService provides methods for managing slash commands
service SlashService {
// Sends button click message
rpc reportBug(StringRequest) returns (Empty);
rpc condense(StringRequest) returns (Empty);
// Get available slash commands for autocomplete (used by CLI)
rpc getAvailableSlashCommands(EmptyRequest) returns (SlashCommandsResponse);
}
// Slash command definition for autocomplete
message SlashCommandInfo {
string name = 1; // Command name without slash, e.g., "newtask", "smol"
string description = 2; // Human-readable description
string section = 3; // "default", "custom", or "cli"
bool cli_compatible = 4; // false for VS Code-only commands
}
// Response containing all available slash commands
message SlashCommandsResponse {
repeated SlashCommandInfo commands = 1;
}
+1
View File
@@ -30,6 +30,7 @@ enum ClineAsk {
USE_MCP_SERVER = 11;
NEW_TASK = 12;
CONDENSE = 13;
REPORT_BUG = 14;
SUMMARIZE_TASK = 15;
ACT_MODE_RESPOND = 16;
USE_SUBAGENTS = 17;
@@ -0,0 +1,6 @@
import { rm } from "node:fs/promises"
import path from "node:path"
const viteCachePath = path.join(import.meta.dirname, "..", "webview-ui", "node_modules", ".vite")
await rm(viteCachePath, { recursive: true, force: true })
@@ -228,6 +228,34 @@ describe("resolveModelInfo", () => {
expect(response.modelInfo).toBeUndefined()
})
it("resolves a free model id from the cline-pass catalog without coercing to the default", async () => {
const { resolveModelInfo } = await import("../resolveModelInfo")
const store = makeStore({ providerId: parseProviderId("cline-pass") })
const catalog = makeCatalog()
// The cline-pass catalog carries the endpoint's clinePass bucket plus the
// Cline free models (zero-priced, OpenRouter-style ids without the
// cline-pass/ prefix). Selecting a free model must not be replaced by the
// default pass model.
vi.mocked(catalog.peekModels).mockReturnValue(
peekResult(
"cline-pass",
[
["cline-pass/glm-5.1", { name: "GLM 5.1", supportsPromptCache: false, contextWindow: 200_000 }],
["kwaipilot/kat-coder-pro", { name: "KAT Coder Pro", supportsPromptCache: false, contextWindow: 256_000 }],
],
"cline-pass/glm-5.1",
),
)
const response = await resolveModelInfo(makeController(store, catalog), {
providerId: "cline-pass",
modelId: "kwaipilot/kat-coder-pro",
})
expect(response.modelId).toBe("kwaipilot/kat-coder-pro")
expect(response.source).toBe("sdk-known-models")
})
it("still honors a custom-provider model id that does match the catalog", async () => {
const { resolveModelInfo } = await import("../resolveModelInfo")
const store = makeStore({ providerId: parseProviderId("openai") })
@@ -0,0 +1,88 @@
import { EmptyRequest } from "@shared/proto/cline/common"
import { SlashCommandInfo, SlashCommandsResponse } from "@shared/proto/cline/slash"
import { BASE_SLASH_COMMANDS } from "@/shared/slashCommands"
import { Controller } from ".."
/**
* Returns all available slash commands for autocomplete.
*/
export async function getAvailableSlashCommands(controller: Controller, _request: EmptyRequest): Promise<SlashCommandsResponse> {
const commands: SlashCommandInfo[] = []
// Add built-in commands
for (const cmd of [...BASE_SLASH_COMMANDS]) {
commands.push(
SlashCommandInfo.create({
name: cmd.name,
description: cmd.description,
section: "default",
cliCompatible: cmd.cliCompatible,
}),
)
}
// Get workflow toggles from state
const localWorkflowToggles = controller.stateManager.getWorkspaceStateKey("workflowToggles") ?? {}
const globalWorkflowToggles = controller.stateManager.getGlobalSettingsKey("globalWorkflowToggles") ?? {}
const remoteWorkflowToggles = controller.stateManager.getGlobalStateKey("remoteWorkflowToggles") ?? {}
const remoteConfigSettings = controller.stateManager.getRemoteConfigSettings()
const remoteWorkflows = remoteConfigSettings?.remoteGlobalWorkflows ?? []
// Track local workflow names to avoid duplicates from global
const localNames = new Set<string>()
// Add local workflows (enabled only)
for (const [path, enabled] of Object.entries(localWorkflowToggles)) {
if (enabled) {
const fileName = fullPathToFileName(path)
localNames.add(fileName)
commands.push(
SlashCommandInfo.create({
name: fileName,
description: `Custom workflow: ${fileName}`,
section: "custom",
cliCompatible: true,
}),
)
}
}
// Add global workflows (enabled only, skip if local exists with same name)
for (const [path, enabled] of Object.entries(globalWorkflowToggles)) {
if (enabled) {
const fileName = fullPathToFileName(path)
if (!localNames.has(fileName)) {
commands.push(
SlashCommandInfo.create({
name: fileName,
description: `Custom workflow: ${fileName}`,
section: "custom",
cliCompatible: true,
}),
)
}
}
}
// Add remote workflows that are enabled
for (const workflow of remoteWorkflows) {
const enabled = workflow.alwaysEnabled || remoteWorkflowToggles[workflow.name] !== false
if (enabled) {
commands.push(
SlashCommandInfo.create({
name: workflow.name,
description: `Remote workflow: ${workflow.name}`,
section: "custom",
cliCompatible: true,
}),
)
}
}
return SlashCommandsResponse.create({ commands })
}
function fullPathToFileName(path: string): string {
// e.g. replace /path/to/workflow.md with workflow.md
return path.replace(/^.*[/\\]/, "")
}
@@ -0,0 +1,10 @@
import { Empty, StringRequest } from "@shared/proto/cline/common"
import { Controller } from ".."
/**
* Report bug slash command logic
*/
export async function reportBug(controller: Controller, _request: StringRequest): Promise<Empty> {
await controller.task?.handleWebviewAskResponse("yesButtonClicked")
return Empty.create()
}
@@ -27,7 +27,6 @@ export async function getStateToPostToWebview(controller: {
backgroundCommandTaskId?: string
workspaceManager?: any
checkpointRestoreInput?: ExtensionState["checkpointRestoreInput"]
getPluginSlashCommands?: () => Promise<{ name: string; description?: string }[]>
}): Promise<ExtensionState> {
const stateManager = controller.stateManager
@@ -109,15 +108,6 @@ export async function getStateToPostToWebview(controller: {
// Codex OAuth not available
}
// Plugin slash commands are fetched best-effort so autocomplete failures
// don't block state posting.
let pluginSlashCommands: { name: string; description?: string }[] = []
try {
pluginSlashCommands = (await controller.getPluginSlashCommands?.()) ?? []
} catch {
// Plugin command discovery is best-effort.
}
return {
version,
apiConfiguration,
@@ -165,7 +155,6 @@ export async function getStateToPostToWebview(controller: {
taskHistory: processedTaskHistory,
shouldShowAnnouncement,
favoritedModelIds,
pluginSlashCommands,
backgroundCommandRunning: controller.backgroundCommandRunning ?? false,
backgroundCommandTaskId: controller.backgroundCommandTaskId,
workspaceRoots: controller.workspaceManager?.getRoots?.() ?? [],
@@ -117,7 +117,6 @@ export abstract class WebviewProvider {
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" nonce="${nonce}" src="${scriptUrl}"></script>
<script src="http://localhost:8097"></script>
</body>
</html>
`
@@ -204,7 +203,6 @@ export abstract class WebviewProvider {
<!DOCTYPE html>
<html lang="en">
<head>
${process.env.IS_DEV ? '<script src="http://localhost:8097"></script>' : ""}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta http-equiv="Content-Security-Policy" content="${csp.join("; ")}">
+6 -6
View File
@@ -1,13 +1,13 @@
import { describe, expect, it } from "vitest"
import { isClineProvider } from "@/shared/utils/cline"
import { isClineManagedProvider } from "@/shared/utils/cline"
import { resolveWorkspaceRootPath } from "./workspace-root"
describe("isClineProvider", () => {
describe("isClineManagedProvider", () => {
it("treats both Cline account providers as Cline providers", () => {
expect(isClineProvider("cline")).toBe(true)
expect(isClineProvider("cline-pass")).toBe(true)
expect(isClineProvider("anthropic")).toBe(false)
expect(isClineProvider(undefined)).toBe(false)
expect(isClineManagedProvider("cline")).toBe(true)
expect(isClineManagedProvider("cline-pass")).toBe(true)
expect(isClineManagedProvider("anthropic")).toBe(false)
expect(isClineManagedProvider(undefined)).toBe(false)
})
})
+12 -64
View File
@@ -44,7 +44,7 @@ import { telemetryService } from "@/services/telemetry"
import type { ClineExtensionContext } from "@/shared/cline"
import { ShowMessageRequest, ShowMessageType } from "@/shared/proto/host/window"
import { Logger } from "@/shared/services/Logger"
import { isClineProvider } from "@/shared/utils/cline"
import { isClineManagedProvider } from "@/shared/utils/cline"
import { arePathsEqual, getDesktopDir } from "@/utils/path"
import { ClineAccountService } from "./account-service"
import { AuthService, LogoutReason } from "./auth-service"
@@ -71,7 +71,6 @@ import { SdkInteractionCoordinator } from "./sdk-interaction-coordinator"
import { SdkMcpCoordinator } from "./sdk-mcp-coordinator"
import { SdkMessageCoordinator, type SessionEventListener } from "./sdk-message-coordinator"
import { SdkModeCoordinator } from "./sdk-mode-coordinator"
import { type PluginSlashCommand, SdkPluginCommandCoordinator } from "./sdk-plugin-commands"
import { SdkProviderChangeCoordinator } from "./sdk-provider-change-coordinator"
import { SdkSessionConfigBuilder } from "./sdk-session-config-builder"
import { SdkSessionEventCoordinator } from "./sdk-session-event-coordinator"
@@ -167,7 +166,6 @@ export class Controller {
private compaction: SdkCompactionCoordinator
private sessionEvents: SdkSessionEventCoordinator
private sessionHistory: SdkSessionHistoryLoader
private pluginCommands: SdkPluginCommandCoordinator
private readonly sdkTelemetry: VscodeSdkTelemetryHandle
private readonly providerFailureTelemetryTurnGate = new ProviderFailureTelemetryTurnGate()
private readonly providerConfigStore: ProviderConfigStore
@@ -337,7 +335,7 @@ export class Controller {
const errorMessage = error instanceof Error ? error.message : String(error)
const providerId = this.getSessionProviderId(sessionId) ?? this.getActiveProviderId()
const isClineAuthError =
isClineProvider(providerId) &&
isClineManagedProvider(providerId) &&
(errorMessage.includes(CLINE_ACCOUNT_AUTH_ERROR_MESSAGE) ||
errorMessage.toLowerCase().includes("missing api key") ||
errorMessage.toLowerCase().includes("unauthorized"))
@@ -351,7 +349,7 @@ export class Controller {
failurePhase: PROVIDER_FAILURE_PHASE.PREFLIGHT,
})
this.emitClineAuthError()
} else if (isClineProvider(providerId) && this.isClineBalanceError(errorMessage)) {
} else if (isClineManagedProvider(providerId) && this.isClineBalanceError(errorMessage)) {
this.captureProviderFailure({
sessionId,
error,
@@ -454,7 +452,7 @@ export class Controller {
loadInitialMessages: (sessionHost, taskId) => this.sessionHistory.loadInitialMessages(sessionHost, taskId),
buildStartSessionInput,
resolveContextMentions: (text) => this.resolveContextMentions(text),
isClineProviderActive: () => this.isClineProviderActive(),
isClineManagedProviderActive: () => this.isClineManagedProviderActive(),
emitClineAuthError: () => this.emitClineAuthErrorWithTelemetry(),
resetMessageTranslator: () => this.resetMessageTranslatorAndFence(),
postStateToWebview: () => this.postStateToWebview(),
@@ -482,7 +480,6 @@ export class Controller {
},
postStateToWebview: () => this.postStateToWebview(),
})
this.pluginCommands = new SdkPluginCommandCoordinator()
this.taskStart = new SdkTaskStartCoordinator({
stateManager: this.stateManager,
sessions: this.sessions,
@@ -504,7 +501,7 @@ export class Controller {
createTempSessionHost: () => VscodeSessionHost.create({ mcpHub: this.mcpHub }),
loadInitialMessages: (reader, taskId) => this.sessionHistory.loadInitialMessages(reader, taskId),
resolveContextMentions: (text) => this.resolveContextMentions(text),
isClineProviderActive: () => this.isClineProviderActive(),
isClineManagedProviderActive: () => this.isClineManagedProviderActive(),
emitClineAuthError: (task) => this.emitClineAuthErrorWithTelemetry(task),
captureProviderApiError: (event) => this.captureProviderFailure(event),
postStateToWebview: () => this.postStateToWebview(),
@@ -514,10 +511,7 @@ export class Controller {
sessions: this.sessions,
messages: this.messages,
sessionConfigBuilder: this.sessionConfigBuilder,
getTask: () => this.task,
getWorkspaceRoot: () => this.getWorkspaceRoot(),
buildStartSessionInput,
resetMessageTranslator: () => this.resetMessageTranslatorAndFence(),
postStateToWebview: () => this.postStateToWebview(),
})
this.sessionEvents = new SdkSessionEventCoordinator({
@@ -578,16 +572,6 @@ export class Controller {
this.providerCatalog.invalidateProviderListings()
}
/**
* Return plugin-registered slash commands for autocomplete. Surfaced to
* the webview as `pluginSlashCommands` in ExtensionState (see
* getStateToPostToWebview) so the chat input's slash-command menu can
* show them.
*/
getPluginSlashCommands(): Promise<PluginSlashCommand[]> {
return this.pluginCommands.getSlashCommands()
}
private handleProviderConfigChange(event: ProviderConfigChange): void {
this.scheduleProviderConfigStatePost()
@@ -690,7 +674,6 @@ export class Controller {
// are disposed below — see StatePostDebouncer.dispose().
await this.statePostDebouncer.dispose()
await this.invalidateUserInstructionService()
await this.pluginCommands.dispose()
this.messages.cancelPendingSave()
// Clear MCP tool list change callback before disposing McpHub
this.mcpHub?.clearToolListChangeCallback()
@@ -751,48 +734,14 @@ export class Controller {
}
/**
* Expand a leading slash command. First checks plugin-registered commands
* (e.g. `/goal`), then falls back to workflow/skill expansion via the
* user-instruction service. For plugin commands:
* - If the handler returns `submitPrompt`, that becomes the prompt text.
* - If the handler returns `reply`, it is emitted as a say message.
* - If only `reply` is returned (no `submitPrompt`), returns empty string
* so the agent turn is suppressed (the reply was already shown).
* Returns the input unchanged if it is not a known command.
* Expand a leading `/workflow` or `/skill` slash command into its instruction
* body. Mirrors the CLI's `buildUserInputMessage`. Returns the input unchanged
* if it is not a known command or expansion fails.
*/
private async resolveSlashCommands(text: string): Promise<string> {
if (this.isDisposed) {
return text
}
// Check plugin commands first — they take precedence over
// workflow/skill expansion so plugin names cannot be shadowed.
try {
const result = await this.pluginCommands.resolveCommand(text)
if (result) {
if (result.reply) {
this.messages.emitSessionEvents(
[
{
ts: Date.now(),
type: "say",
say: "text",
text: result.reply,
partial: false,
},
],
{
type: "status",
payload: { sessionId: this.sessions.getActiveSession()?.sessionId ?? "", status: "running" },
},
)
}
return result.submitPrompt ?? ""
}
} catch (error) {
Logger.warn("[SdkController] Plugin command resolution failed, falling through:", error)
}
try {
const workspaceRoot = await this.getWorkspaceRoot()
const service = await this.ensureUserInstructionService(workspaceRoot)
@@ -945,8 +894,8 @@ export class Controller {
/**
* Check if the active API provider uses Cline account auth for the current mode.
*/
private isClineProviderActive(): boolean {
return isClineProvider(this.getActiveProviderId())
private isClineManagedProviderActive(): boolean {
return isClineManagedProvider(this.getActiveProviderId())
}
private captureProviderFailure(event: ProviderFailureTelemetry): void {
@@ -1187,8 +1136,8 @@ export class Controller {
* Manually compact (condense) the active task's conversation. Triggered by
* the compact button and the `/compact` (alias `/smol`) slash command.
* Mirrors the CLI's `/compact` local command: runs an SDK manual compaction
* and restarts the session with the compacted transcript so the model's
* working context is actually reduced.
* and persists the compaction sidecar so the model's working context is
* reduced on the next turn and later resumes.
*/
async compactTask(): Promise<void> {
await this.compaction.compactTask()
@@ -1851,7 +1800,6 @@ export class Controller {
mcpHub: this.mcpHub,
backgroundCommandRunning: this.backgroundCommandRunning,
backgroundCommandTaskId: this.backgroundCommandTaskId,
getPluginSlashCommands: () => this.pluginCommands.getSlashCommands(),
})
const sdkTaskHistory = (await this.taskHistory.listHistory({ limit: 100, hydrate: false }))
.map(sessionHistoryRecordToHistoryItem)
@@ -622,16 +622,16 @@ describe("buildSessionConfig", () => {
it("uses ClinePass model storage and omits empty nested apiKey so SDK OAuth can fill it", async () => {
mocks.stateManager.getApiConfiguration.mockReturnValue({
actModeApiProvider: "cline-pass",
actModeClinePassModelId: "cline-pass/glm-5.1",
actModeClinePassModelId: "cline-pass/glm-5.2",
} as any)
mocks.providerSettingsManager.getProviderSettings.mockReturnValue(undefined)
const config = await buildSessionConfig({ cwd: "/tmp/workspace" })
expect(config.providerId).toBe("cline-pass")
expect(config.modelId).toBe("cline-pass/glm-5.1")
expect(config.modelId).toBe("cline-pass/glm-5.2")
expect(config.apiKey).toBe("")
expect(config.providerConfig).toMatchObject({ providerId: "cline-pass", modelId: "cline-pass/glm-5.1" })
expect(config.providerConfig).toMatchObject({ providerId: "cline-pass", modelId: "cline-pass/glm-5.2" })
expect(config.providerConfig).not.toHaveProperty("apiKey")
})
+34 -2
View File
@@ -20,6 +20,7 @@ import {
import { getGeneratedModelsForProvider, MODEL_COLLECTIONS_BY_PROVIDER_ID } from "@cline/llms"
import { buildClineSystemPrompt } from "@cline/shared"
import type { ApiConfiguration } from "@shared/api"
import { ClineClient } from "@shared/cline"
import type { HistoryItem } from "@shared/HistoryItem"
import { DEFAULT_LANGUAGE_SETTINGS, getLanguageKey, type LanguageDisplay } from "@shared/Languages"
import { Logger } from "@shared/services/Logger"
@@ -27,6 +28,7 @@ import type { Settings } from "@shared/storage/state-keys"
import type { Mode } from "@shared/storage/types"
import { stringifyVsCodeLmModelSelector } from "@shared/vsCodeSelectorUtils"
import { StateManager } from "@/core/storage/StateManager"
import { HostProvider } from "@/hosts/host-provider"
import { ExtensionRegistryInfo } from "@/registry"
import { getFeatureFlagsService } from "@/services/feature-flags"
import { getDistinctId } from "@/services/logging/distinctId"
@@ -117,6 +119,31 @@ function createSdkLogger() {
}
}
/**
* Host identity for the session's client context, resolved through HostProvider
* rather than the `vscode` module directly: this file is also bundled into the
* standalone cline-core (JetBrains), where `vscode` is a Proxy-stub module and
* direct API reads would yield non-string values. The hostbridge returns the
* per-host values (e.g. "Cline for JetBrains" + IDE version on JetBrains).
*/
async function resolveHostIdentity() {
try {
return await HostProvider.env.getHostVersion({})
} catch (error) {
Logger.debug("Failed to resolve host version for client identity", error)
return undefined
}
}
async function resolveIsMultiRootWorkspace(): Promise<boolean> {
try {
const { paths } = await HostProvider.workspace.getWorkspacePaths({})
return paths.length > 1
} catch {
return false
}
}
function resolveWorkspaceName(workspacePath: string): string {
const trimmed = workspacePath.trim()
const withoutTrailingSeparators = trimmed.replace(/[\\/]+$/, "")
@@ -664,6 +691,8 @@ export async function buildSessionConfig(input: SessionConfigInput): Promise<Cor
// own provider id spelling (e.g. "openai-compatible" rather than the
// extension's "openai"). Convert before handing the id to core.
const sdkProviderId = toSdkProviderId(providerId)
const hostIdentity = await resolveHostIdentity()
const isMultiRoot = await resolveIsMultiRootWorkspace()
// Always pass a providerConfig so the proxy/CA-aware fetch reaches the SDK
// gateway; without it the agent loop uses bare global fetch and corporate
@@ -714,8 +743,11 @@ export async function buildSessionConfig(input: SessionConfigInput): Promise<Cor
extensionContext: {
user: distinctId ? { distinctId } : undefined,
client: {
name: "cline-vscode",
version: ExtensionRegistryInfo.version,
name: hostIdentity?.clineType || ClineClient.VSCode,
version: hostIdentity?.clineVersion || ExtensionRegistryInfo.version,
platform: hostIdentity?.platform || undefined,
platformVersion: hostIdentity?.version || undefined,
isMultiRoot,
},
workspace: {
rootPath: workspaceRoot,
@@ -1149,6 +1149,25 @@ describe("translateSessionEvent — agent_event error", () => {
expect(parsed.providerId).toBe("cline")
})
it("preserves ClinePass period limit errors for specialized webview rendering", () => {
const state = new MessageTranslatorState(undefined, () => "cline-pass")
const message = "You have reached your weekly Clinepass limit. The limit resets in 7d, please try again later."
const event: CoreSessionEvent = {
type: "agent_event",
payload: {
sessionId: "session-1",
event: {
type: "error",
error: { message },
} as AgentEvent,
},
}
const result = translateSessionEvent(event, state)
expect(result.messages).toHaveLength(2)
expect(result.messages[1].text).toBe(message)
})
it("rewrites Anthropic bare 'model: <id>' 404 into an actionable message", () => {
const state = new MessageTranslatorState(undefined, () => "anthropic")
const event: CoreSessionEvent = {
+2 -2
View File
@@ -43,14 +43,14 @@ describe("buildSdkProviderConfig", () => {
const providerConfig = buildSdkProviderConfig(
{
actModeApiProvider: "cline-pass",
actModeClinePassModelId: "cline-pass/glm-5.1",
actModeClinePassModelId: "cline-pass/glm-5.2",
},
"act",
)
expect(providerConfig).toMatchObject({
providerId: "cline-pass",
modelId: "cline-pass/glm-5.1",
modelId: "cline-pass/glm-5.2",
apiKey: "workos:shared-cline-token",
})
expect(mocks.providerSettingsManager.getProviderSettings).toHaveBeenCalledWith("cline")
@@ -1,8 +1,18 @@
import type { ClineMessage } from "@shared/ExtensionMessage"
import { createContextCompactionPrepareTurn } from "@cline/core"
import { beforeEach, describe, expect, it, vi } from "vitest"
import type { StateManager } from "@/core/storage/StateManager"
import { SdkCompactionCoordinator, type SdkCompactionCoordinatorOptions } from "./sdk-compaction-coordinator"
vi.mock("@cline/core", () => ({
createContextCompactionPrepareTurn: vi.fn(),
createSessionCompactionState: vi.fn((input: { compactedMessages: unknown[] }) => ({
version: 1,
messages: input.compactedMessages,
})),
}))
const mockCreateContextCompactionPrepareTurn = createContextCompactionPrepareTurn as unknown as ReturnType<typeof vi.fn>
vi.mock("@/shared/services/Logger", () => ({
Logger: {
debug: vi.fn(),
@@ -12,11 +22,6 @@ vi.mock("@/shared/services/Logger", () => ({
},
}))
const compactSessionMessages = vi.fn()
vi.mock("./sdk-compaction", () => ({
compactSessionMessages: (...args: unknown[]) => compactSessionMessages(...args),
}))
describe("SdkCompactionCoordinator", () => {
beforeEach(() => {
vi.clearAllMocks()
@@ -28,7 +33,7 @@ describe("SdkCompactionCoordinator", () => {
await coordinator.compactTask()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(compactSessionMessages).not.toHaveBeenCalled()
expect(mockCreateContextCompactionPrepareTurn).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: "There is no active task to compact." })],
expect.anything(),
@@ -41,7 +46,7 @@ describe("SdkCompactionCoordinator", () => {
await coordinator.compactTask()
expect(compactSessionMessages).not.toHaveBeenCalled()
expect(mockCreateContextCompactionPrepareTurn).not.toHaveBeenCalled()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: expect.stringContaining("Cannot compact while a response") })],
@@ -56,7 +61,7 @@ describe("SdkCompactionCoordinator", () => {
await coordinator.compactTask()
expect(compactSessionMessages).not.toHaveBeenCalled()
expect(mockCreateContextCompactionPrepareTurn).not.toHaveBeenCalled()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: "No messages to compact." })],
@@ -64,17 +69,29 @@ describe("SdkCompactionCoordinator", () => {
)
})
it("reports when the strategy declines to compact", async () => {
it("reports unsupported runtime without running compaction", async () => {
const activeSession = makeActiveSession()
;(activeSession.sdkHost as Partial<typeof activeSession.sdkHost>).updateSessionCompactionState = undefined
const { coordinator, options } = makeCoordinator({ activeSession })
compactSessionMessages.mockResolvedValueOnce({
compacted: false,
messages: [{ role: "user", content: "a" }],
})
await coordinator.compactTask()
expect(compactSessionMessages).toHaveBeenCalledOnce()
expect(activeSession.sdkHost.readMessages).not.toHaveBeenCalled()
expect(mockCreateContextCompactionPrepareTurn).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: expect.stringContaining("not supported") })],
expect.anything(),
)
})
it("reports when the strategy declines to compact", async () => {
const activeSession = makeActiveSession()
const { coordinator, options } = makeCoordinator({ activeSession })
mockCreateContextCompactionPrepareTurn.mockReturnValueOnce(vi.fn().mockResolvedValue(undefined))
await coordinator.compactTask()
expect(mockCreateContextCompactionPrepareTurn).toHaveBeenCalledOnce()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: "No compaction needed." })],
@@ -82,53 +99,74 @@ describe("SdkCompactionCoordinator", () => {
)
})
it("compacts and restarts the session, preserving the session id", async () => {
it("compacts and persists the sidecar without rebuilding the session", async () => {
const activeSession = makeActiveSession()
activeSession.sdkHost.readMessages.mockResolvedValueOnce([
{ role: "user", content: "1" },
{ role: "assistant", content: "2" },
{ role: "user", content: "3" },
])
const task = makeTask("old-session")
const { coordinator, options } = makeCoordinator({ activeSession, task })
compactSessionMessages.mockResolvedValueOnce({
compacted: true,
messages: [{ role: "user", content: "summary" }],
})
const { coordinator, options } = makeCoordinator({ activeSession })
mockCreateContextCompactionPrepareTurn.mockReturnValueOnce(
vi.fn().mockResolvedValue({ messages: [{ role: "user", content: "summary" }] }),
)
await coordinator.compactTask()
expect(options.buildStartSessionInput).toHaveBeenCalledWith(expect.objectContaining({ sessionId: "old-session" }), {
cwd: "/workspace",
mode: "act",
expect(activeSession.sdkHost.updateSessionCompactionState).toHaveBeenCalledWith("old-session", {
version: 1,
messages: [{ role: "user", content: "summary" }],
})
expect(options.sessions.replaceActiveSession).toHaveBeenCalledWith({
startInput: expect.objectContaining({
config: expect.objectContaining({ sessionId: "old-session" }),
interactive: true,
prompt: undefined,
}),
initialMessages: [{ role: "user", content: "summary" }],
disposeReason: "compactTask",
})
expect(task.taskId).toBe("new-session")
expect(options.resetMessageTranslator).toHaveBeenCalledOnce()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: "Compacted 3 messages to 1." })],
expect.anything(),
)
})
it("does not append compaction status to a different active session", async () => {
const activeSession = makeActiveSession()
const { coordinator, options } = makeCoordinator({ activeSession })
options.sessions.getActiveSession
.mockReturnValueOnce(activeSession)
.mockReturnValueOnce(makeActiveSession({ sessionId: "other-session" }))
mockCreateContextCompactionPrepareTurn.mockReturnValueOnce(
vi.fn().mockResolvedValue({ messages: [{ role: "user", content: "summary" }] }),
)
await coordinator.compactTask()
expect(activeSession.sdkHost.updateSessionCompactionState).toHaveBeenCalled()
expect(options.messages.appendAndEmit).not.toHaveBeenCalled()
})
it("does not restart or report success when sidecar persistence fails", async () => {
const activeSession = makeActiveSession()
activeSession.sdkHost.updateSessionCompactionState.mockResolvedValueOnce({ updated: false })
const { coordinator, options } = makeCoordinator({ activeSession })
mockCreateContextCompactionPrepareTurn.mockReturnValueOnce(
vi.fn().mockResolvedValue({ messages: [{ role: "user", content: "summary" }] }),
)
await coordinator.compactTask()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: "Couldn't compact the conversation. Please try again." })],
expect.anything(),
)
})
it("reports a failure when compaction throws", async () => {
const activeSession = makeActiveSession()
const { coordinator, options } = makeCoordinator({ activeSession })
compactSessionMessages.mockRejectedValueOnce(new Error("boom"))
mockCreateContextCompactionPrepareTurn.mockReturnValueOnce(vi.fn().mockRejectedValue(new Error("boom")))
await coordinator.compactTask()
expect(options.sessions.replaceActiveSession).not.toHaveBeenCalled()
expect(options.messages.appendAndEmit).toHaveBeenCalledWith(
[expect.objectContaining({ say: "info", text: "Compaction failed: boom" })],
[expect.objectContaining({ say: "info", text: "Couldn't compact the conversation. Please try again." })],
expect.anything(),
)
})
@@ -136,7 +174,6 @@ describe("SdkCompactionCoordinator", () => {
interface MakeCoordinatorInput {
activeSession: ReturnType<typeof makeActiveSession> | undefined
task: ReturnType<typeof makeTask>
}
function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
@@ -168,14 +205,7 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
sessionConfigBuilder: {
build: vi.fn().mockResolvedValue(config),
},
getTask: vi.fn(() => input.task),
getWorkspaceRoot: vi.fn().mockResolvedValue("/workspace"),
buildStartSessionInput: vi.fn((startConfig) => ({
config: startConfig,
prompt: undefined,
interactive: true,
})),
resetMessageTranslator: vi.fn(),
postStateToWebview: vi.fn().mockResolvedValue(undefined),
} as unknown as SdkCompactionCoordinatorOptions & {
sessions: SdkCompactionCoordinatorOptions["sessions"] & {
@@ -188,8 +218,6 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
sessionConfigBuilder: SdkCompactionCoordinatorOptions["sessionConfigBuilder"] & {
build: ReturnType<typeof vi.fn>
}
buildStartSessionInput: ReturnType<typeof vi.fn>
resetMessageTranslator: ReturnType<typeof vi.fn>
postStateToWebview: ReturnType<typeof vi.fn>
}
@@ -199,11 +227,12 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
}
}
function makeActiveSession(input: { isRunning?: boolean } = {}) {
function makeActiveSession(input: { isRunning?: boolean; sessionId?: string } = {}) {
return {
sessionId: "old-session",
sessionId: input.sessionId ?? "old-session",
sdkHost: {
readMessages: vi.fn().mockResolvedValue([{ role: "user", content: "1" }]),
updateSessionCompactionState: vi.fn().mockResolvedValue({ updated: true }),
send: vi.fn(),
abort: vi.fn().mockResolvedValue(undefined),
stop: vi.fn().mockResolvedValue(undefined),
@@ -214,15 +243,3 @@ function makeActiveSession(input: { isRunning?: boolean } = {}) {
isRunning: input.isRunning ?? false,
}
}
function makeTask(taskId: string, messages: Array<Partial<ClineMessage>> = []) {
return {
taskId,
messageStateHandler: {
getClineMessages: vi.fn(() => messages as ClineMessage[]),
},
} as unknown as {
taskId: string
messageStateHandler: { getClineMessages: () => ClineMessage[] }
}
}
@@ -6,9 +6,8 @@
//
// 1. Read the active session's transcript.
// 2. Run a manual SDK compaction over it (sdk-compaction.ts).
// 3. Restart the session with the compacted messages as initialMessages, so
// the model's working context is actually reduced (reusing the mode-rebuild
// replaceActiveSession path, which lazily persists on the next turn).
// 3. Persist the SDK compaction sidecar so the next turn and resumes keep
// using the compacted working context.
//
// Before this, the VSCode button sent the literal text "/compact" to the model,
// which the SDK does not treat as a runtime command, so the model improvised a
@@ -24,22 +23,16 @@ import type { SdkMessageCoordinator } from "./sdk-message-coordinator"
import type { SdkSessionConfigBuilder } from "./sdk-session-config-builder"
import type { SdkSessionLifecycle } from "./sdk-session-lifecycle"
import type { SdkSessionHost } from "./session-host"
import type { TaskProxy } from "./task-proxy"
import type { VscodeSessionHost } from "./vscode-session-host"
type StartInput = Parameters<VscodeSessionHost["start"]>[0]
type InitialMessages = StartInput["initialMessages"]
type SessionConfig = Awaited<ReturnType<SdkSessionConfigBuilder["build"]>>
const COMPACTION_FAILURE_MESSAGE = "Couldn't compact the conversation. Please try again."
const COMPACTION_UNSUPPORTED_MESSAGE = "Compaction is not supported by this runtime yet. Please update Cline and try again."
export interface SdkCompactionCoordinatorOptions {
stateManager: StateManager
sessions: SdkSessionLifecycle
messages: SdkMessageCoordinator
sessionConfigBuilder: SdkSessionConfigBuilder
getTask: () => TaskProxy | undefined
getWorkspaceRoot: () => Promise<string>
buildStartSessionInput: (config: SessionConfig, input: { cwd: string; mode: Mode }) => StartInput
resetMessageTranslator: () => void
postStateToWebview: () => Promise<void>
}
@@ -70,7 +63,10 @@ export class SdkCompactionCoordinator {
// A turn is still running; compacting mid-turn would race the live agent
// loop's own message persistence. Ask the user to wait until it finishes.
if (activeSession.isRunning) {
this.emitInfo("Cannot compact while a response is in progress. Try again once the current turn finishes.")
this.emitInfo(
"Cannot compact while a response is in progress. Try again once the current turn finishes.",
activeSession.sessionId,
)
await this.options.postStateToWebview()
return
}
@@ -80,7 +76,7 @@ export class SdkCompactionCoordinator {
await this.runCompaction(activeSession.sdkHost, activeSession.sessionId)
} catch (error) {
Logger.error("[SdkController] compactTask failed:", error)
this.emitInfo(`Compaction failed: ${error instanceof Error ? error.message : String(error)}`)
this.emitInfo(COMPACTION_FAILURE_MESSAGE, activeSession.sessionId)
await this.options.postStateToWebview()
} finally {
this.compactInFlight = false
@@ -88,10 +84,15 @@ export class SdkCompactionCoordinator {
}
private async runCompaction(sdkHost: SdkSessionHost, sessionId: string): Promise<void> {
if (!sdkHost.updateSessionCompactionState) {
this.emitInfo(COMPACTION_UNSUPPORTED_MESSAGE, sessionId)
await this.options.postStateToWebview()
return
}
const messages = (await sdkHost.readMessages(sessionId)) as SdkMessage[]
const messagesBefore = messages.length
if (messagesBefore === 0) {
this.emitInfo("No messages to compact.")
this.emitInfo("No messages to compact.", sessionId)
await this.options.postStateToWebview()
return
}
@@ -115,44 +116,23 @@ export class SdkCompactionCoordinator {
})
if (!result.compacted) {
this.emitInfo("No compaction needed.")
this.emitInfo("No compaction needed.", sessionId)
await this.options.postStateToWebview()
return
}
// Restart the session with the compacted transcript. Reusing the
// sessionId keeps the task identity (history item, task header) stable;
// replaceActiveSession waits for the old session's stop before starting
// the replacement (same sequencing as a mode rebuild).
config.sessionId = sessionId
const startInput = this.options.buildStartSessionInput(config, { cwd, mode })
const rebuildResult = await this.options.sessions.replaceActiveSession({
startInput,
initialMessages: result.messages as InitialMessages,
disposeReason: "compactTask",
})
if (!rebuildResult) {
this.emitInfo("Compaction could not be applied because the session was replaced.")
await this.options.postStateToWebview()
return
if (!result.compactionState) {
throw new Error("Compaction did not return durable state.")
}
const persisted = await sdkHost.updateSessionCompactionState(sessionId, result.compactionState)
if (!persisted.updated) {
throw new Error("Compaction sidecar could not be persisted.")
}
const { startResult } = rebuildResult
const task = this.options.getTask()
if (task && task.taskId !== startResult.sessionId) {
task.taskId = startResult.sessionId
}
// Fence the conversation boundary so any straggler events from the old
// session carry an older epoch and are dropped by the webview.
this.options.resetMessageTranslator()
this.emitInfo(this.formatCompactionStatus(messagesBefore, result.messages.length))
this.emitInfo(this.formatCompactionStatus(messagesBefore, result.messages.length), sessionId)
await this.options.postStateToWebview()
Logger.log(
`[SdkController] Compacted session ${sessionId}: ${messagesBefore} -> ${result.messages.length} messages (new session ${startResult.sessionId})`,
)
Logger.log(`[SdkController] Compacted session ${sessionId}: ${messagesBefore} -> ${result.messages.length} messages`)
}
private getCurrentMode(): Mode {
@@ -168,8 +148,13 @@ export class SdkCompactionCoordinator {
return `Compacted ${messagesBefore} messages to ${messagesAfter}.`
}
private emitInfo(text: string): void {
const sessionId = this.options.sessions.getActiveSession()?.sessionId ?? ""
private emitInfo(text: string, sessionId?: string): void {
const activeSessionId = this.options.sessions.getActiveSession()?.sessionId
if (sessionId && activeSessionId !== sessionId) {
Logger.warn(`[SdkController] compactTask: skipped info for inactive session ${sessionId}`)
return
}
const targetSessionId = sessionId ?? activeSessionId ?? ""
const infoMessage: ClineMessage = {
ts: Date.now(),
type: "say",
@@ -179,7 +164,7 @@ export class SdkCompactionCoordinator {
}
this.options.messages.appendAndEmit([infoMessage], {
type: "status",
payload: { sessionId, status: "running" },
payload: { sessionId: targetSessionId, status: "running" },
})
}
}
+23 -4
View File
@@ -1,15 +1,18 @@
import { beforeEach, describe, expect, it, vi } from "vitest"
import { compactSessionMessages } from "./sdk-compaction"
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"
const createContextCompactionPrepareTurn = vi.fn()
const createSessionCompactionState = vi.fn((input: unknown) => ({ version: 1, input }))
vi.mock("@cline/core", () => ({
createContextCompactionPrepareTurn: (...args: unknown[]) => createContextCompactionPrepareTurn(...args),
createSessionCompactionState: (input: unknown) => createSessionCompactionState(input),
}))
vi.mock("@/shared/services/Logger", () => ({
Logger: { debug: vi.fn(), error: vi.fn(), log: vi.fn(), warn: vi.fn() },
}))
let compactSessionMessages: typeof import("./sdk-compaction").compactSessionMessages
const baseConfig = {
providerConfig: { providerId: "anthropic", modelId: "claude" },
providerId: "anthropic",
@@ -21,6 +24,10 @@ const baseConfig = {
} as unknown as Parameters<typeof compactSessionMessages>[0]["config"]
describe("compactSessionMessages", () => {
beforeAll(async () => {
;({ compactSessionMessages } = await import("./sdk-compaction"))
})
beforeEach(() => {
vi.clearAllMocks()
})
@@ -33,7 +40,9 @@ describe("compactSessionMessages", () => {
})
it("builds a manual-mode prepareTurn and force-enables compaction", async () => {
const compact = vi.fn().mockResolvedValue({ messages: [{ role: "user", content: "summary" }] })
const compact = vi
.fn()
.mockResolvedValue({ messages: [{ role: "user", content: "summary" }], systemPrompt: "rewritten system" })
createContextCompactionPrepareTurn.mockReturnValueOnce(compact)
const messages = [
@@ -53,7 +62,17 @@ describe("compactSessionMessages", () => {
{ mode: "manual" },
)
expect(compact).toHaveBeenCalledOnce()
expect(result).toEqual({ compacted: true, messages: [{ role: "user", content: "summary" }] })
expect(createSessionCompactionState).toHaveBeenCalledWith({
sourceMessages: messages,
compactedMessages: [{ role: "user", content: "summary" }],
conversationId: "s1",
systemPrompt: "rewritten system",
})
expect(result).toEqual({
compacted: true,
messages: [{ role: "user", content: "summary" }],
compactionState: { version: 1, input: expect.anything() },
})
})
it("returns compacted=false when prepareTurn is unavailable", async () => {
+21 -7
View File
@@ -4,14 +4,18 @@
// apps/cli/src/runtime/interactive/compaction.ts (`compactInteractiveMessages`):
// it builds a manual-mode compaction `prepareTurn` via the SDK's
// `createContextCompactionPrepareTurn` and runs it against the current session
// transcript, returning the compacted messages.
// transcript, returning the compacted working-context sidecar state.
//
// The CLI then restarts the session with the compacted messages; the VSCode
// adapter does the same in SdkCompactionCoordinator. Keeping the actual
// compaction effect in the SDK (rather than asking the model to "summarize the
// conversation") is what makes the compact button real instead of improvised.
// The VSCode coordinator persists that sidecar without replacing the canonical
// transcript, so the active session and later resumes use compacted working
// context while saved messages remain intact.
import { type CoreSessionConfig, createContextCompactionPrepareTurn } from "@cline/core"
import {
type CoreSessionConfig,
createContextCompactionPrepareTurn,
createSessionCompactionState,
type SessionCompactionState,
} from "@cline/core"
import type { Message as SdkMessage, ModelInfo as SdkModelInfo } from "@cline/llms"
import { Logger } from "@/shared/services/Logger"
@@ -35,6 +39,7 @@ export interface CompactSessionMessagesInput {
export interface CompactSessionMessagesResult {
compacted: boolean
messages: SdkMessage[]
compactionState?: SessionCompactionState
}
/**
@@ -103,5 +108,14 @@ export async function compactSessionMessages(input: CompactSessionMessagesInput)
if (!result) {
return { compacted: false, messages: input.messages }
}
return { compacted: true, messages: result.messages }
return {
compacted: true,
messages: result.messages,
compactionState: createSessionCompactionState({
sourceMessages: input.messages,
compactedMessages: result.messages,
conversationId: input.sessionId,
systemPrompt: result.systemPrompt,
}),
}
}
@@ -312,7 +312,7 @@ describe("SdkFollowupCoordinator", () => {
const task = makeTask("task-1")
const { coordinator, options } = makeCoordinator({ task })
options.sessionConfigBuilder.build.mockRejectedValue(new Error("missing api key"))
options.isClineProviderActive.mockReturnValue(true)
options.isClineManagedProviderActive.mockReturnValue(true)
await coordinator.askResponse("continue")
@@ -383,7 +383,7 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
loadInitialMessages: vi.fn().mockResolvedValue([{ role: "user", content: "hello" }]),
buildStartSessionInput: vi.fn(() => ({ prompt: "start" })),
resolveContextMentions: vi.fn(async (text: string) => `resolved: ${text}`),
isClineProviderActive: vi.fn(() => false),
isClineManagedProviderActive: vi.fn(() => false),
emitClineAuthError: vi.fn(),
resetMessageTranslator: vi.fn(),
postStateToWebview: vi.fn().mockResolvedValue(undefined),
@@ -416,7 +416,7 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
getWorkspaceRoot: ReturnType<typeof vi.fn>
loadInitialMessages: ReturnType<typeof vi.fn>
resolveContextMentions: ReturnType<typeof vi.fn>
isClineProviderActive: ReturnType<typeof vi.fn>
isClineManagedProviderActive: ReturnType<typeof vi.fn>
emitClineAuthError: ReturnType<typeof vi.fn>
resetMessageTranslator: ReturnType<typeof vi.fn>
postStateToWebview: ReturnType<typeof vi.fn>
@@ -30,7 +30,7 @@ export interface SdkFollowupCoordinatorOptions {
loadInitialMessages: (sessionHost: SdkSessionHost, taskId: string) => Promise<unknown[] | undefined>
buildStartSessionInput: (config: SessionConfig, input: { cwd: string; mode: Mode }) => StartInput
resolveContextMentions: (text: string) => Promise<string>
isClineProviderActive: () => boolean
isClineManagedProviderActive: () => boolean
emitClineAuthError: () => void
resetMessageTranslator: () => void
postStateToWebview: () => Promise<void>
@@ -119,7 +119,7 @@ export class SdkFollowupCoordinator {
const errorMsg = error instanceof Error ? error.message : String(error)
const isClineAuth =
this.options.isClineProviderActive() &&
this.options.isClineManagedProviderActive() &&
(errorMsg.includes(CLINE_ACCOUNT_AUTH_ERROR_MESSAGE) ||
errorMsg.toLowerCase().includes("missing api key") ||
errorMsg.toLowerCase().includes("unauthorized"))
-156
View File
@@ -1,156 +0,0 @@
// SdkPluginCommandCoordinator — discovers and executes plugin-registered
// slash commands, mirroring the CLI's createWorkspaceChatCommandHost.
//
// Plugins register commands via `api.registerCommand({ name, handler })` in
// their setup(). The ContributionRegistry runs setup() and collects the
// registered commands. This coordinator:
// 1. Lazily loads plugins via resolveAndLoadAgentPlugins (sandbox mode)
// 2. Initializes a ContributionRegistry to run setup() and gather commands
// 3. Exposes getSlashCommands() for autocomplete
// 4. Exposes resolveCommand(text) to execute a /command and return its result
import {
type AgentExtensionCommand,
type AgentExtensionCommandResult,
createContributionRegistry,
noopBasicLogger,
resolveAndLoadAgentPlugins,
} from "@cline/core"
import type { AgentTool, Message } from "@cline/shared"
import { Logger } from "@shared/services/Logger"
export interface PluginSlashCommand {
name: string
description?: string
}
export interface PluginCommandResult {
reply?: string
submitPrompt?: string
}
interface LoadedPlugins {
commands: AgentExtensionCommand[]
shutdown: () => Promise<void>
}
export class SdkPluginCommandCoordinator {
private loadedPromise: Promise<LoadedPlugins | undefined> | undefined
/**
* Lazily load plugins and initialize the contribution registry. The result
* is cached so subsequent calls reuse the same sandbox process. Returns
* undefined if no plugins are installed or loading fails.
*/
private ensureLoaded(): Promise<LoadedPlugins | undefined> {
if (this.loadedPromise) {
return this.loadedPromise
}
this.loadedPromise = (async () => {
let loaded: Awaited<ReturnType<typeof resolveAndLoadAgentPlugins>>
try {
loaded = await resolveAndLoadAgentPlugins({
logger: noopBasicLogger,
})
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
Logger.warn(`[PluginCommands] Plugin loading failed; continuing without plugin commands (${message})`)
return undefined
}
if (!loaded.extensions.length) {
await loaded.shutdown?.().catch(() => {})
return undefined
}
const registry = createContributionRegistry<(typeof loaded.extensions)[number], AgentTool, Message[]>({
extensions: loaded.extensions,
})
try {
await registry.initialize()
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
Logger.warn(`[PluginCommands] Contribution registry initialization failed (${message})`)
await loaded.shutdown?.().catch(() => {})
return undefined
}
return {
commands: registry.getRegistrySnapshot().commands,
shutdown: async () => {
await loaded.shutdown?.().catch(() => {})
},
}
})()
return this.loadedPromise
}
/**
* Return plugin-registered slash commands for autocomplete. Returns an
* empty array if no plugins are installed or loading fails.
*/
async getSlashCommands(): Promise<PluginSlashCommand[]> {
const loaded = await this.ensureLoaded()
if (!loaded) {
return []
}
return loaded.commands
.filter((cmd) => typeof cmd.handler === "function")
.map((cmd) => ({
name: cmd.name,
description: cmd.description,
}))
}
/**
* Resolve a leading /command from a plugin. Returns null if the text does
* not match a plugin command. Returns { reply?, submitPrompt? } from the
* command handler.
*/
async resolveCommand(text: string): Promise<PluginCommandResult | null> {
if (!text.startsWith("/") || text.length < 2) {
return null
}
const match = text.match(/^\/(\S+)/)
if (!match?.[1]) {
return null
}
const name = match[1]
const remainder = text.slice(name.length + 1).trim()
const loaded = await this.ensureLoaded()
if (!loaded) {
return null
}
const command = loaded.commands.find((cmd) => cmd.name === name && typeof cmd.handler === "function")
if (!command?.handler) {
return null
}
try {
const result: AgentExtensionCommandResult = await command.handler(remainder)
if (typeof result === "string") {
return { reply: result }
}
return {
reply: result.reply,
submitPrompt: result.submitPrompt,
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
Logger.warn(`[PluginCommands] Command "/${name}" failed: ${message}`)
return { reply: `Command /${name} failed: ${message}` }
}
}
/**
* Shut down the plugin sandbox process. Called on extension disposal.
*/
async dispose(): Promise<void> {
const promise = this.loadedPromise
this.loadedPromise = undefined
if (promise) {
const loaded = await promise.catch(() => undefined)
await loaded?.shutdown().catch(() => {})
}
}
}
@@ -4,6 +4,7 @@ import type { StateManager } from "@/core/storage/StateManager"
import { CLINE_RECOMMENDED_MODELS_FALLBACK } from "@/shared/cline/recommended-models"
import type { ClineApiReqInfo, TurnPhase } from "@/shared/ExtensionMessage"
import { Logger } from "@/shared/services/Logger"
import { isClineManagedProvider } from "@/shared/utils/cline"
import type { MessageTranslatorState, TranslationResult } from "./message-translator"
import { translateSessionEvent } from "./message-translator"
import { PROVIDER_FAILURE_ERROR_TYPE, PROVIDER_FAILURE_PHASE, type ProviderFailureTelemetry } from "./provider-failure-telemetry"
@@ -250,11 +251,12 @@ export class SdkSessionEventCoordinator {
const apiConfig = stateManager.getApiConfiguration()
const mode = stateManager.getGlobalSettingsKey("mode") === "plan" ? "plan" : "act"
const provider = mode === "plan" ? apiConfig.planModeApiProvider : apiConfig.actModeApiProvider
if (provider !== "cline") {
// Free models are also selectable on ClinePass — they ride usage billing at $0
if (!isClineManagedProvider(provider)) {
return false
}
const modelId = mode === "plan" ? apiConfig.planModeClineModelId : apiConfig.actModeClineModelId
const modelId = this.getCurrentClineModelId()
if (!modelId) {
return false
}
@@ -283,6 +285,10 @@ export class SdkSessionEventCoordinator {
}
const apiConfig = stateManager.getApiConfiguration()
const mode = stateManager.getGlobalSettingsKey("mode") === "plan" ? "plan" : "act"
const provider = mode === "plan" ? apiConfig.planModeApiProvider : apiConfig.actModeApiProvider
if (provider === "cline-pass") {
return mode === "plan" ? apiConfig.planModeClinePassModelId : apiConfig.actModeClinePassModelId
}
return mode === "plan" ? apiConfig.planModeClineModelId : apiConfig.actModeClineModelId
}
@@ -173,7 +173,7 @@ describe("SdkTaskStartCoordinator", () => {
it("emits Cline auth errors when reinitialization fails due auth", async () => {
const { coordinator, options } = makeCoordinator()
options.sessionConfigBuilder.build.mockRejectedValue(new Error("missing api key"))
options.isClineProviderActive.mockReturnValue(true)
options.isClineManagedProviderActive.mockReturnValue(true)
await coordinator.reinitExistingTaskFromId("task-1")
@@ -252,7 +252,7 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
createTempSessionHost: vi.fn().mockResolvedValue(tempHost),
loadInitialMessages: vi.fn().mockResolvedValue([{ role: "user", content: "hello" }]),
resolveContextMentions: vi.fn(async (text: string) => `resolved: ${text}`),
isClineProviderActive: vi.fn(() => false),
isClineManagedProviderActive: vi.fn(() => false),
emitClineAuthError: vi.fn(),
captureProviderApiError: vi.fn(),
postStateToWebview: vi.fn().mockResolvedValue(undefined),
@@ -277,7 +277,7 @@ function makeCoordinator(input: Partial<MakeCoordinatorInput> = {}) {
createTempSessionHost: ReturnType<typeof vi.fn>
loadInitialMessages: ReturnType<typeof vi.fn>
resolveContextMentions: ReturnType<typeof vi.fn>
isClineProviderActive: ReturnType<typeof vi.fn>
isClineManagedProviderActive: ReturnType<typeof vi.fn>
emitClineAuthError: ReturnType<typeof vi.fn>
captureProviderApiError: ReturnType<typeof vi.fn>
postStateToWebview: ReturnType<typeof vi.fn>
@@ -51,7 +51,7 @@ export interface SdkTaskStartCoordinatorOptions {
createTempSessionHost: () => Promise<SdkSessionHost>
loadInitialMessages: (reader: SdkSessionHost, taskId: string) => Promise<unknown[] | undefined>
resolveContextMentions: (text: string) => Promise<string>
isClineProviderActive: () => boolean
isClineManagedProviderActive: () => boolean
emitClineAuthError: (task?: string) => void
captureProviderApiError?: (event: ProviderFailureTelemetry) => void
postStateToWebview: () => Promise<void>
@@ -255,7 +255,7 @@ export class SdkTaskStartCoordinator {
const reinitErrorMsg = error instanceof Error ? error.message : String(error)
const isClineAuthReinit =
this.options.isClineProviderActive() &&
this.options.isClineManagedProviderActive() &&
(reinitErrorMsg.includes(CLINE_ACCOUNT_AUTH_ERROR_MESSAGE) ||
reinitErrorMsg.toLowerCase().includes("missing api key") ||
reinitErrorMsg.toLowerCase().includes("unauthorized"))
+2
View File
@@ -11,6 +11,7 @@ import type {
RestoreResult,
SendSessionInput,
SessionAccumulatedUsage,
SessionCompactionState,
SessionHistoryRecord,
SessionPendingPrompt,
SessionRecord,
@@ -33,6 +34,7 @@ export interface SdkSessionHost {
listHistory(options?: ClineCoreListHistoryOptions): Promise<SessionHistoryRecord[]>
delete(sessionId: string): Promise<boolean>
readMessages(sessionId: string): Promise<SdkInitialMessages>
updateSessionCompactionState?(sessionId: string, state: SessionCompactionState): Promise<{ updated: boolean }>
restore(input: RestoreInput): Promise<RestoreResult>
update(
sessionId: string,
@@ -20,6 +20,7 @@ import {
type RestoreResult,
type SendSessionInput,
type SessionAccumulatedUsage,
type SessionCompactionState,
type SessionHistoryRecord,
type SessionPendingPrompt,
type SessionRecord,
@@ -199,6 +200,10 @@ export class VscodeSessionHost implements SdkSessionHost {
return this.inner.readMessages(sessionId)
}
async updateSessionCompactionState(sessionId: string, state: SessionCompactionState): Promise<{ updated: boolean }> {
return this.inner.updateSessionCompactionState(sessionId, state)
}
async restore(input: RestoreInput): Promise<RestoreResult> {
return this.inner.restore(input)
}
@@ -2,6 +2,7 @@ import {
getClineOrgIndividualInferenceSubscriptionMessage,
isClineNotSubscribedMessage,
isClineOrgIndividualInferenceSubscriptionMessage,
isClinePassLimitMessage,
} from "@cline/llms"
import { serializeError } from "serialize-error"
import { CLINE_ACCOUNT_AUTH_ERROR_MESSAGE } from "../../shared/ClineAccount"
@@ -14,6 +15,7 @@ export enum ClineErrorType {
QuotaExceeded = "quotaExceeded",
Entitlement = "entitlement",
OrgClinePassRestriction = "orgClinePassRestriction",
ClinePassLimit = "clinePassLimit",
}
interface ErrorDetails {
@@ -183,6 +185,13 @@ export class ClineError extends Error {
return ClineErrorType.Entitlement
}
if (
(detailMessage ? isClinePassLimitMessage(detailMessage) : false) ||
(rawMessage ? isClinePassLimitMessage(rawMessage) : false)
) {
return ClineErrorType.ClinePassLimit
}
// Check auth errors
const isAuthStatus = status !== undefined && status > 400 && status < 429
if (code === "ERR_BAD_REQUEST" || err instanceof AuthInvalidTokenError || isAuthStatus) {
@@ -44,5 +44,24 @@ describe("ClineError", () => {
ClineError.getErrorType(err)!.should.equal(ClineErrorType.OrgClinePassRestriction)
})
it("should classify ClinePass period limit messages separately", () => {
const err = new ClineError(
"You have reached your weekly Clinepass limit. The limit resets in 7d, please try again later.",
)
ClineError.getErrorType(err)!.should.equal(ClineErrorType.ClinePassLimit)
})
it("should classify nested ClinePass period limit messages separately", () => {
const err = new ClineError({
message: "403 Error 403",
error: {
message: "You have reached your monthly ClinePass limit. The limit resets in 12h, please try again later.",
},
})
ClineError.getErrorType(err)!.should.equal(ClineErrorType.ClinePassLimit)
})
})
})
@@ -1583,7 +1583,7 @@ export class TelemetryService {
/**
* Records when slash commands or workflows are activated
* @param ulid Unique identifier for the task
* @param commandName The name of the command (e.g., "newtask", "newrule", or custom workflow name)
* @param commandName The name of the command (e.g., "newtask", "reportbug", or custom workflow name)
* @param commandType Whether it's a built-in command, custom workflow, or MCP prompt
*/
public captureSlashCommandUsed(ulid: string, commandName: string, commandType: "builtin" | "workflow" | "mcp_prompt") {
+1 -3
View File
@@ -16,7 +16,6 @@ import { OnboardingModelGroup } from "./proto/cline/state"
import { Mode } from "./storage/types"
import { TelemetrySetting } from "./TelemetrySetting"
import { UserInfo } from "./UserInfo"
import type { SlashCommand } from "./slashCommands"
// webview will hold state
export interface ExtensionMessage {
type: "grpc_response" // New type for gRPC responses
@@ -115,8 +114,6 @@ export interface ExtensionState {
worktreesEnabled?: ClineFeatureSetting
customPrompt?: string
favoritedModelIds: string[]
/** Plugin-registered slash commands surfaced for autocomplete. */
pluginSlashCommands?: SlashCommand[]
// NEW: Add workspace information
workspaceRoots: WorkspaceRoot[]
primaryRootIndex: number
@@ -214,6 +211,7 @@ export type ClineAsk =
| "new_task"
| "condense"
| "summarize_task"
| "report_bug"
| "use_subagents"
export type ClineSay =
+2 -22
View File
@@ -142,8 +142,7 @@ export const openRouterDefaultModelInfo: ModelInfo = {
"Claude Sonnet 4.5 is an Anthropic model for coding, agentic search, and AI agent workflows. It supports planning and implementation tasks across the software development lifecycle.\n\nRead more in the [blog post here](https://www.anthropic.com/claude/sonnet)",
}
export type ClinePassModelId = keyof typeof clinePassModels
export const clinePassDefaultModelId = "cline-pass/glm-5.1"
export const clinePassDefaultModelId = "cline-pass/glm-5.2"
export const clinePassModelInfoSaneDefaults: ModelInfo = {
maxTokens: 8_192,
contextWindow: 128_000,
@@ -156,21 +155,6 @@ export const clinePassModelInfoSaneDefaults: ModelInfo = {
cacheWritesPrice: 0,
description: "",
}
export const clinePassModels = {
"cline-pass/glm-5.1": {
name: "cline-pass/glm-5.1",
maxTokens: 131_072,
contextWindow: 202_752,
supportsImages: false,
supportsPromptCache: true,
supportsReasoning: true,
inputPrice: 0.98,
outputPrice: 3.08,
cacheReadsPrice: 0.182,
cacheWritesPrice: 0,
description: "",
},
} as const satisfies Record<string, ModelInfo>
export function getModelSlug(modelId: string): string {
return modelId.split("/").at(-1) ?? modelId
@@ -187,11 +171,7 @@ export function buildModelInfoNameMap(models: Record<string, ModelInfo>): Record
}
export function resolveClinePassModelInfo(modelId: string, modelInfoByName?: Record<string, ModelInfo>): ModelInfo {
return (
clinePassModels[modelId as keyof typeof clinePassModels] ??
modelInfoByName?.[getModelSlug(modelId)] ??
clinePassModelInfoSaneDefaults
)
return modelInfoByName?.[getModelSlug(modelId)] ?? clinePassModelInfoSaneDefaults
}
export const openAiModelInfoSafeDefaults: OpenAiCompatibleModelInfo = {
@@ -24,6 +24,7 @@ function convertClineAskToProtoEnum(ask: AppClineAsk | undefined): ClineAsk | un
new_task: ClineAsk.NEW_TASK,
condense: ClineAsk.CONDENSE,
summarize_task: ClineAsk.SUMMARIZE_TASK,
report_bug: ClineAsk.REPORT_BUG,
use_subagents: ClineAsk.USE_SUBAGENTS,
}
@@ -56,6 +57,7 @@ function convertProtoEnumToClineAsk(ask: ClineAsk): AppClineAsk | undefined {
[ClineAsk.NEW_TASK]: "new_task",
[ClineAsk.CONDENSE]: "condense",
[ClineAsk.SUMMARIZE_TASK]: "summarize_task",
[ClineAsk.REPORT_BUG]: "report_bug",
[ClineAsk.USE_SUBAGENTS]: "use_subagents",
}
+11
View File
@@ -2,6 +2,7 @@ export interface SlashCommand {
name: string
description?: string
section?: "default" | "custom" | "mcp"
cliCompatible?: boolean
}
export const BASE_SLASH_COMMANDS: SlashCommand[] = [
@@ -9,21 +10,31 @@ export const BASE_SLASH_COMMANDS: SlashCommand[] = [
name: "newtask",
description: "Create a new task with context from the current task",
section: "default",
cliCompatible: true,
},
{
name: "deep-planning",
description: "Create a comprehensive implementation plan before coding",
section: "default",
cliCompatible: true,
},
{
name: "smol",
description: "Condenses your current context window",
section: "default",
cliCompatible: true,
},
{
name: "newrule",
description: "Create a new Cline rule based on your conversation",
section: "default",
cliCompatible: true,
},
{
name: "reportbug",
description: "Create a Github issue with Cline",
section: "default",
cliCompatible: true,
},
]
+1
View File
@@ -27,6 +27,7 @@ export enum ClineDefaultTool {
WEB_SEARCH = "web_search",
CONDENSE = "condense",
SUMMARIZE_TASK = "summarize_task",
REPORT_BUG = "report_bug",
NEW_RULE = "new_rule",
APPLY_PATCH = "apply_patch",
USE_SKILL = "use_skill",
+1 -1
View File
@@ -1,3 +1,3 @@
export function isClineProvider(provider: string | undefined) {
export function isClineManagedProvider(provider: string | undefined) {
return provider === "cline" || provider === "cline-pass"
}
@@ -1,67 +0,0 @@
import { existsSync } from "node:fs"
import { readFile } from "node:fs/promises"
import { createRequire } from "node:module"
import { join } from "node:path"
import { describe, expect, it } from "bun:test"
import { $ } from "bun"
/**
* Integration test for CLINE-2584: the plugin sandbox bootstrap
* (`plugin-sandbox-bootstrap.js`) must be shipped with the VS Code extension.
*
* The bootstrap runs in an isolated child process spawned by
* `SubprocessSandbox` it cannot be inlined into `extension.js` because the
* sandbox spawns it via `node <bootstrapFile>`. The CLI build copies this
* file (`apps/cli/bun.mts`); the extension build (`esbuild.mjs`) must do the
* same.
*
* The bootstrap also has external runtime dependencies that must be resolvable
* from its on-disk location via Node's standard module resolution:
* - jiti (TypeScript transpilation of .ts plugins)
* - @cline/shared, @cline/sdk (host-provided SDK packages that plugins import)
*
* This test runs the real `bun esbuild.mjs` build and checks the real
* `dist/` output, exercising the same build pipeline CI uses.
*/
const projectRoot = join(import.meta.dir, "..", "..")
const distDir = join(projectRoot, "dist")
const bootstrapPath = join(distDir, "extensions", "plugin-sandbox-bootstrap.js")
describe("plugin-sandbox bootstrap build artifact (CLINE-2584)", () => {
it("esbuild.mjs emits plugin-sandbox-bootstrap.js into dist/", async () => {
const result = await $`bun esbuild.mjs`.cwd(projectRoot).quiet()
expect(result.exitCode).toBe(0)
expect(existsSync(join(distDir, "extension.js"))).toBe(true)
expect(existsSync(bootstrapPath)).toBe(true)
}, 60_000)
it("the bootstrap is a real executable script with IPC handling", async () => {
expect(existsSync(bootstrapPath)).toBe(true)
const content = await readFile(bootstrapPath, "utf8")
expect(content.length).toBeGreaterThan(1000)
expect(content).toMatch(/process\.on\(.process\.message|process\.send|type:\s*["']response["']/)
}, 60_000)
it("the bootstrap's runtime dependencies resolve from dist/", () => {
expect(existsSync(bootstrapPath)).toBe(true)
// The bootstrap is spawned as a standalone Node child process. It
// imports jiti (for TypeScript transpilation) and @cline/shared as
// external modules, and plugins import @cline/sdk. Node resolves
// these by walking up from the bootstrap's directory. All must be
// direct dependencies of the extension so they appear in
// node_modules and are resolvable.
const requireFromBootstrap = createRequire(bootstrapPath)
expect(() => requireFromBootstrap.resolve("jiti")).not.toThrow()
expect(() => requireFromBootstrap.resolve("@cline/shared")).not.toThrow()
// @cline/sdk is a host-provided SDK specifier that plugins import.
// The bootstrap's findHostPackageRoot walks up from dist/extensions/
// looking for node_modules/@cline/sdk/package.json.
expect(
existsSync(join(projectRoot, "node_modules", "@cline", "sdk", "package.json")),
).toBe(true)
}, 60_000)
})
+285
View File
@@ -0,0 +1,285 @@
import { afterEach, beforeEach, describe, it } from "mocha"
import "should"
import * as sinon from "sinon"
import { Controller } from "../core/controller"
import { getAvailableSlashCommands } from "../core/controller/slash/getAvailableSlashCommands"
import { EmptyRequest } from "../shared/proto/cline/common"
import { BASE_SLASH_COMMANDS } from "../shared/slashCommands"
/**
* Unit tests for getAvailableSlashCommands RPC endpoint
* Tests the slash command discovery and filtering functionality
*/
describe("getAvailableSlashCommands", () => {
let mockController: Partial<Controller>
let mockStateManager: {
getWorkspaceStateKey: sinon.SinonStub
getGlobalSettingsKey: sinon.SinonStub
getGlobalStateKey: sinon.SinonStub
getRemoteConfigSettings: sinon.SinonStub
}
beforeEach(() => {
mockStateManager = {
getWorkspaceStateKey: sinon.stub(),
getGlobalSettingsKey: sinon.stub(),
getGlobalStateKey: sinon.stub(),
getRemoteConfigSettings: sinon.stub(),
}
// Default stubs return empty/null values
mockStateManager.getWorkspaceStateKey.returns(null)
mockStateManager.getGlobalSettingsKey.returns(null)
mockStateManager.getGlobalStateKey.returns(null)
mockStateManager.getRemoteConfigSettings.returns(null)
mockController = {
stateManager: mockStateManager as any,
}
})
afterEach(() => {
sinon.restore()
})
describe("Base Slash Commands", () => {
it("should return all base slash commands", async () => {
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
// Should have at least all base commands
response.commands.length.should.be.greaterThanOrEqual(BASE_SLASH_COMMANDS.length)
// Verify each base command is present
for (const baseCmd of BASE_SLASH_COMMANDS) {
const found = response.commands.find((cmd) => cmd.name === baseCmd.name)
found!.should.not.be.undefined()
found!.description.should.equal(baseCmd.description)
found!.section.should.equal("default")
found!.cliCompatible.should.equal(baseCmd.cliCompatible ?? false)
}
})
it("should not include the deprecated subagent slash command", async () => {
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const deprecatedCommand = response.commands.find((cmd) => cmd.name === "subagent")
;(deprecatedCommand === undefined).should.be.true()
})
it("should mark base commands with section 'default'", async () => {
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const baseCommandNames = BASE_SLASH_COMMANDS.map((cmd) => cmd.name)
for (const cmd of response.commands) {
if (baseCommandNames.includes(cmd.name)) {
cmd.section.should.equal("default")
}
}
})
})
describe("Local Workflow Toggles", () => {
it("should include enabled local workflows", async () => {
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({
"/path/to/my-workflow.md": true,
"/path/to/another-workflow.md": true,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const myWorkflow = response.commands.find((cmd) => cmd.name === "my-workflow.md")
myWorkflow!.should.not.be.undefined()
myWorkflow!.section.should.equal("custom")
myWorkflow!.cliCompatible.should.equal(true)
const anotherWorkflow = response.commands.find((cmd) => cmd.name === "another-workflow.md")
anotherWorkflow!.should.not.be.undefined()
})
it("should exclude disabled local workflows", async () => {
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({
"/path/to/enabled-workflow.md": true,
"/path/to/disabled-workflow.md": false,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const enabled = response.commands.find((cmd) => cmd.name === "enabled-workflow.md")
enabled!.should.not.be.undefined()
const disabled = response.commands.find((cmd) => cmd.name === "disabled-workflow.md")
;(disabled === undefined).should.be.true()
})
it("should extract filename from full path", async () => {
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({
"/Users/test/project/.clinerules/workflows/deep-analysis.md": true,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "deep-analysis.md")
workflow!.should.not.be.undefined()
})
it("should handle Windows-style paths", async () => {
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({
"C:\\Users\\test\\project\\.clinerules\\workflows\\windows-workflow.md": true,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "windows-workflow.md")
workflow!.should.not.be.undefined()
})
})
describe("Global Workflow Toggles", () => {
it("should include enabled global workflows", async () => {
mockStateManager.getGlobalSettingsKey.withArgs("globalWorkflowToggles").returns({
"/global/path/global-workflow.md": true,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "global-workflow.md")
workflow!.should.not.be.undefined()
workflow!.section.should.equal("custom")
})
it("should exclude disabled global workflows", async () => {
mockStateManager.getGlobalSettingsKey.withArgs("globalWorkflowToggles").returns({
"/global/path/disabled-global.md": false,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "disabled-global.md")
;(workflow === undefined).should.be.true()
})
})
describe("Workflow Deduplication", () => {
it("should prefer local workflows over global workflows with same name", async () => {
// Same filename in both local and global
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({
"/local/path/shared-workflow.md": true,
})
mockStateManager.getGlobalSettingsKey.withArgs("globalWorkflowToggles").returns({
"/global/path/shared-workflow.md": true,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
// Should only appear once
const matches = response.commands.filter((cmd) => cmd.name === "shared-workflow.md")
matches.length.should.equal(1)
})
it("should include global workflow if local with same name is disabled", async () => {
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({
"/local/path/shared-workflow.md": false, // disabled locally
})
mockStateManager.getGlobalSettingsKey.withArgs("globalWorkflowToggles").returns({
"/global/path/shared-workflow.md": true, // enabled globally
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
// Global should appear since local is disabled
const workflow = response.commands.find((cmd) => cmd.name === "shared-workflow.md")
workflow!.should.not.be.undefined()
})
})
describe("Remote Workflows", () => {
it("should include alwaysEnabled remote workflows", async () => {
mockStateManager.getRemoteConfigSettings.returns({
remoteGlobalWorkflows: [{ name: "always-on-workflow", alwaysEnabled: true }],
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "always-on-workflow")
workflow!.should.not.be.undefined()
workflow!.section.should.equal("custom")
})
it("should include remote workflows enabled by toggle", async () => {
mockStateManager.getRemoteConfigSettings.returns({
remoteGlobalWorkflows: [{ name: "toggle-workflow", alwaysEnabled: false }],
})
mockStateManager.getGlobalStateKey.withArgs("remoteWorkflowToggles").returns({
"toggle-workflow": true, // not explicitly disabled
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "toggle-workflow")
workflow!.should.not.be.undefined()
})
it("should exclude remote workflows explicitly disabled by toggle", async () => {
mockStateManager.getRemoteConfigSettings.returns({
remoteGlobalWorkflows: [{ name: "disabled-remote", alwaysEnabled: false }],
})
mockStateManager.getGlobalStateKey.withArgs("remoteWorkflowToggles").returns({
"disabled-remote": false,
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "disabled-remote")
;(workflow === undefined).should.be.true()
})
it("should include remote workflows by default if not explicitly disabled", async () => {
mockStateManager.getRemoteConfigSettings.returns({
remoteGlobalWorkflows: [{ name: "default-enabled", alwaysEnabled: false }],
})
// No toggle entry for this workflow
mockStateManager.getGlobalStateKey.withArgs("remoteWorkflowToggles").returns({})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
const workflow = response.commands.find((cmd) => cmd.name === "default-enabled")
workflow!.should.not.be.undefined()
})
})
describe("Edge Cases", () => {
it("should handle null/undefined state values gracefully", async () => {
mockStateManager.getWorkspaceStateKey.returns(null)
mockStateManager.getGlobalSettingsKey.returns(undefined)
mockStateManager.getGlobalStateKey.returns(null)
mockStateManager.getRemoteConfigSettings.returns(null)
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
// Should still return base commands
response.commands.length.should.be.greaterThanOrEqual(BASE_SLASH_COMMANDS.length)
})
it("should handle empty workflow toggle objects", async () => {
mockStateManager.getWorkspaceStateKey.withArgs("workflowToggles").returns({})
mockStateManager.getGlobalSettingsKey.withArgs("globalWorkflowToggles").returns({})
mockStateManager.getGlobalStateKey.withArgs("remoteWorkflowToggles").returns({})
mockStateManager.getRemoteConfigSettings.returns({
remoteGlobalWorkflows: [],
})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
// Should only have base commands
response.commands.length.should.equal(BASE_SLASH_COMMANDS.length)
})
it("should handle remote config with no remoteGlobalWorkflows property", async () => {
mockStateManager.getRemoteConfigSettings.returns({})
const response = await getAvailableSlashCommands(mockController as Controller, EmptyRequest.create())
// Should not throw, just return base commands
response.commands.length.should.be.greaterThanOrEqual(BASE_SLASH_COMMANDS.length)
})
})
})
@@ -780,6 +780,15 @@ export const CondenseConversation = quickStory(
"Would you like me to condense the conversation to improve performance?",
"Shows utility action to condense conversation for better performance.",
)
export const ReportBug = quickStory(
"Report Bug",
"report_bug",
JSON.stringify({
steps_to_reproduce: "1. Open Cline\n2. Start a new task\n3. Observe the error",
what_happened: "Cline crashes unexpectedly",
}),
"Shows utility action to report bugs to the GitHub repository.",
)
export const ResumeCompletedTask = quickStory(
"Resume Completed Task type",
"resume_completed_task",
@@ -55,6 +55,7 @@ import { MarkdownRow } from "./MarkdownRow"
import NewTaskPreview from "./NewTaskPreview"
import PlanCompletionOutputRow from "./PlanCompletionOutputRow"
import QuoteButton from "./QuoteButton"
import ReportBugPreview from "./ReportBugPreview"
import { RequestStartRow } from "./RequestStartRow"
import SearchResultsDisplay from "./SearchResultsDisplay"
import SubagentStatusRow from "./SubagentStatusRow"
@@ -1158,6 +1159,16 @@ export const ChatRowContent = memo(
<NewTaskPreview context={message.text || ""} />
</div>
)
case "report_bug":
return (
<div>
<div className={HEADER_CLASSNAMES}>
<FilePlus2Icon className="size-2" />
<span className="text-foreground font-bold">Cline wants to create a Github issue:</span>
</div>
<ReportBugPreview data={message.text || ""} />
</div>
)
case "plan_mode_respond": {
let response: string | undefined
let options: string[] | undefined
@@ -224,7 +224,6 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
remoteConfigSettings,
navigateToSettingsModelPicker,
mcpServers,
pluginSlashCommands,
} = useExtensionState()
const [isTextAreaFocused, setIsTextAreaFocused] = useState(false)
const [isDraggingOver, setIsDraggingOver] = useState(false)
@@ -490,7 +489,6 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
remoteWorkflowToggles,
remoteConfigSettings?.remoteGlobalWorkflows,
mcpServers,
pluginSlashCommands,
)
if (allCommands.length === 0) {
@@ -516,7 +514,6 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
remoteWorkflowToggles,
remoteConfigSettings?.remoteGlobalWorkflows,
mcpServers,
pluginSlashCommands,
)
if (commands.length > 0) {
handleSlashCommandsSelect(commands[selectedSlashCommandsIndex])
@@ -676,7 +673,6 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
slashCommandsQuery,
handleSlashCommandsSelect,
sendingDisabled,
pluginSlashCommands,
],
)
@@ -988,8 +984,6 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
globalWorkflowToggles,
remoteWorkflowToggles,
remoteConfigSettings?.remoteGlobalWorkflows,
mcpServers,
pluginSlashCommands,
)
if (isValidCommand) {
@@ -1003,14 +997,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
highlightLayerRef.current.innerHTML = processedText
highlightLayerRef.current.scrollTop = textAreaRef.current.scrollTop
highlightLayerRef.current.scrollLeft = textAreaRef.current.scrollLeft
}, [
localWorkflowToggles,
globalWorkflowToggles,
remoteWorkflowToggles,
remoteConfigSettings,
mcpServers,
pluginSlashCommands,
])
}, [localWorkflowToggles, globalWorkflowToggles, remoteWorkflowToggles, remoteConfigSettings])
useLayoutEffect(() => {
updateHighlights()
@@ -1131,6 +1118,12 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
switch (selectedProvider) {
case "cline":
return `${selectedProvider}:${selectedModelId}`
case "cline-pass":
// Free models selected on ClinePass go through Cline usage billing,
// so label them the same way as the cline provider
return selectedModelId.startsWith("cline-pass/")
? `${selectedProvider}:${selectedModelId.replace(/^cline-pass\//, "")}`
: `cline:${selectedModelId}`
case "openai":
return `openai-compat:${selectedModelId}`
case "vscode-lm":
@@ -1413,7 +1406,6 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
mcpServers={mcpServers}
onMouseDown={handleMenuMouseDown}
onSelect={handleSlashCommandsSelect}
pluginSlashCommands={pluginSlashCommands}
query={slashCommandsQuery}
remoteWorkflows={remoteConfigSettings?.remoteGlobalWorkflows}
remoteWorkflowToggles={remoteWorkflowToggles}
@@ -1656,6 +1648,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
"pt-0.5 pb-px px-2 z-10 text-xs w-1/2 text-center bg-transparent",
mode === m.toLowerCase() ? "text-white" : "text-input-foreground",
)}
key={m}
onMouseLeave={() => setShownTooltipMode(null)}
onMouseOver={() => setShownTooltipMode(m.toLowerCase() === "plan" ? "plan" : "act")}
role="switch">
@@ -0,0 +1,72 @@
import type { ApiConfiguration } from "@shared/api"
import { UpdateApiConfigurationRequest } from "@shared/proto/cline/models"
import { convertApiConfigurationToProto } from "@shared/proto-conversions/models/api-configuration-conversion"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { useState } from "react"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { ModelsServiceClient } from "@/services/grpc-client"
interface ClinePassLimitErrorProps {
message: string
}
const CLINE_PROVIDER_ID = "cline"
const getProviderSwitchConfig = (apiConfiguration: ApiConfiguration): ApiConfiguration => {
return {
...apiConfiguration,
planModeApiProvider: CLINE_PROVIDER_ID,
actModeApiProvider: CLINE_PROVIDER_ID,
}
}
const ClinePassLimitError = ({ message }: ClinePassLimitErrorProps) => {
const { apiConfiguration } = useExtensionState()
const [isSwitching, setIsSwitching] = useState(false)
const [didSwitch, setDidSwitch] = useState(false)
const [error, setError] = useState<string | undefined>()
const handleSwitchToUsageBasedBilling = async () => {
setIsSwitching(true)
setError(undefined)
try {
const protoConfig = convertApiConfigurationToProto(getProviderSwitchConfig(apiConfiguration ?? {}))
await ModelsServiceClient.updateApiConfigurationProto(
UpdateApiConfigurationRequest.create({
apiConfiguration: protoConfig,
}),
)
setDidSwitch(true)
} catch (error) {
console.error("Failed to switch to Cline usage-based billing:", error)
setError("Failed to switch provider. Select Cline Usage-Billing in API Configuration settings.")
} finally {
setIsSwitching(false)
}
}
return (
<div
className="p-2 border-none rounded-md mb-2 bg-(--vscode-textBlockQuote-background)"
data-testid="cline-pass-limit-error">
<div className="text-error mb-2">ClinePass limit reached</div>
<div className="text-(--vscode-descriptionForeground) text-xs wrap-anywhere">{message}</div>
<div className="text-(--vscode-descriptionForeground) text-xs mt-2">
Would you like to switch to Usage-Based billing and retry with the Cline provider?
</div>
<VSCodeButton
appearance="primary"
className="w-full mt-3"
disabled={isSwitching || didSwitch}
onClick={handleSwitchToUsageBasedBilling}>
{isSwitching ? "Switching..." : didSwitch ? "Switched to Usage-Based billing" : "Switch to Usage-Based billing"}
</VSCodeButton>
{didSwitch && (
<div className="text-(--vscode-descriptionForeground) text-xs mt-2">Retry the request after switching.</div>
)}
{error && <div className="text-error text-xs mt-2">{error}</div>}
</div>
)
}
export default ClinePassLimitError
@@ -4,6 +4,13 @@ import { describe, expect, it, vi } from "vitest"
import ErrorRow from "./ErrorRow"
const mockSetUserOrganization = vi.hoisted(() => vi.fn())
const mockUpdateApiConfigurationProto = vi.hoisted(() => vi.fn())
const mockApiConfiguration = vi.hoisted(() => ({
planModeApiProvider: "cline-pass",
actModeApiProvider: "cline-pass",
planModeClinePassModelId: "cline-pass/test-plan-model",
actModeClinePassModelId: "cline-pass/test-act-model",
}))
// Mock the auth context
vi.mock("@/context/ClineAuthContext", () => ({
@@ -16,6 +23,12 @@ vi.mock("@/context/ClineAuthContext", () => ({
handleSignOut: vi.fn(),
}))
vi.mock("@/context/ExtensionStateContext", () => ({
useExtensionState: () => ({
apiConfiguration: mockApiConfiguration,
}),
}))
// Mock CreditLimitError component
vi.mock("@/components/chat/CreditLimitError", () => ({
default: ({ message }: { message: string }) => <div data-testid="credit-limit-error">{message}</div>,
@@ -30,6 +43,9 @@ vi.mock("@/services/grpc-client", () => ({
AccountServiceClient: {
setUserOrganization: mockSetUserOrganization,
},
ModelsServiceClient: {
updateApiConfigurationProto: mockUpdateApiConfigurationProto,
},
}))
// Mock ClineError
@@ -43,6 +59,7 @@ vi.mock("../../../../src/services/error/ClineError", () => ({
Auth: "auth",
Entitlement: "entitlement",
OrgClinePassRestriction: "orgClinePassRestriction",
ClinePassLimit: "clinePassLimit",
QuotaExceeded: "quotaExceeded",
},
}))
@@ -58,6 +75,7 @@ describe("ErrorRow", () => {
beforeEach(() => {
vi.clearAllMocks()
mockSetUserOrganization.mockResolvedValue({})
mockUpdateApiConfigurationProto.mockResolvedValue({})
})
it("renders basic error message", () => {
@@ -258,6 +276,36 @@ describe("ErrorRow", () => {
expect(screen.queryByText(formattedMessage)).not.toBeInTheDocument()
})
it("renders ClinePass limit error and switches to Cline usage-based billing", async () => {
const limitMessage = "You have reached your weekly Clinepass limit. The limit resets in 7d, please try again later."
const mockClineError = {
message: limitMessage,
isErrorType: vi.fn((type) => type === "clinePassLimit"),
providerId: "cline-pass",
_error: {
message: limitMessage,
},
}
const { ClineError } = await import("../../../../src/services/error/ClineError")
vi.mocked(ClineError.parse).mockReturnValue(mockClineError as any)
render(<ErrorRow apiRequestFailedMessage={limitMessage} errorType="error" message={mockMessage} />)
expect(screen.getByTestId("cline-pass-limit-error")).toBeInTheDocument()
expect(screen.getByText(limitMessage)).toBeInTheDocument()
fireEvent.click(screen.getByText("Switch to Usage-Based billing"))
await waitFor(() => expect(mockUpdateApiConfigurationProto).toHaveBeenCalledTimes(1))
const request = mockUpdateApiConfigurationProto.mock.calls[0][0]
expect(request.apiConfiguration.planModeApiProvider).toBe("cline")
expect(request.apiConfiguration.actModeApiProvider).toBe("cline")
expect(request.apiConfiguration.planModeClineModelId).toBeUndefined()
expect(request.apiConfiguration.actModeClineModelId).toBeUndefined()
expect(screen.getByText("Switched to Usage-Based billing")).toBeInTheDocument()
})
it("renders friendly logged-out message and sign in button when user is not signed in", async () => {
const mockClineError = {
message: "Authentication failed",
@@ -324,7 +372,7 @@ describe("ErrorRow", () => {
render(<ErrorRow apiRequestFailedMessage="Some API error" errorType="error" message={mockMessage} />)
// When ClineError.parse returns null, we display the raw error message for non-Cline providers
// Since clineError is undefined, isClineProvider is false, so we show the raw apiRequestFailedMessage
// Since clineError is undefined, isClineUsageBillingProvider is false, so we show the raw apiRequestFailedMessage
expect(screen.getByText("Some API error")).toBeInTheDocument()
})
@@ -1,6 +1,7 @@
import type { ClineMessage } from "@shared/ExtensionMessage"
import { memo } from "react"
import { ClineAuthStatus } from "@/components/account/ClineAuthStatus"
import ClinePassLimitError from "@/components/chat/ClinePassLimitError"
import CreditLimitError from "@/components/chat/CreditLimitError"
import EntitlementError from "@/components/chat/EntitlementError"
import OrgClinePassRestrictionError from "@/components/chat/OrgClinePassRestrictionError"
@@ -35,12 +36,15 @@ const ErrorRow = memo(({ message, errorType, apiRequestFailedMessage, apiReqStre
const errorMessage = clineError?._error?.message || clineError?.message || rawApiError
const requestId = clineError?._error?.request_id
const providerId = clineError?.providerId || clineError?._error?.providerId
const isClineProvider = providerId === "cline"
// Deliberately narrower than the shared isClineManagedProvider (which
// also matches cline-pass): only usage-billing errors get the credit
// and login prompts below.
const isClineUsageBillingProvider = providerId === "cline"
const errorCode = clineError?._error?.code
if (clineError?.isErrorType(ClineErrorType.Balance)) {
const errorDetails = clineError._error?.details
if (isClineProvider || errorDetails?.buy_credits_url) {
if (isClineUsageBillingProvider || errorDetails?.buy_credits_url) {
return (
<CreditLimitError
buyCreditsUrl={errorDetails?.buy_credits_url}
@@ -75,6 +79,11 @@ const ErrorRow = memo(({ message, errorType, apiRequestFailedMessage, apiReqStre
return <OrgClinePassRestrictionError />
}
if (clineError?.isErrorType(ClineErrorType.ClinePassLimit)) {
const detailMessage = clineError?._error?.details?.message || errorMessage
return <ClinePassLimitError message={detailMessage} />
}
if (clineError?.isErrorType(ClineErrorType.RateLimit)) {
return (
<p className="m-0 whitespace-pre-wrap text-error wrap-anywhere">
@@ -89,7 +98,7 @@ const ErrorRow = memo(({ message, errorType, apiRequestFailedMessage, apiReqStre
return <p className="m-0 whitespace-pre-wrap text-error wrap-anywhere">{detailMessage}</p>
}
if (clineError?.isErrorType(ClineErrorType.Auth) && isClineProvider) {
if (clineError?.isErrorType(ClineErrorType.Auth) && isClineUsageBillingProvider) {
return !clineUser ? (
// User is using Cline provider and is not logged in
<div className="flex flex-col gap-3">
@@ -37,6 +37,9 @@ const FEATURE_TIPS: FeatureTipItem[] = [
{
text: "You can drag and drop images into the chat to share screenshots with Cline.",
},
{
text: "Use /reportbug to quickly file a GitHub issue with diagnostic context included.",
},
{
text: 'You can disable these tips in Settings → Features → "Feature Tips".',
},
@@ -0,0 +1,84 @@
import React from "react"
import MarkdownBlock from "../common/MarkdownBlock"
interface ReportBugPreviewProps {
data: string
}
const ReportBugPreview: React.FC<ReportBugPreviewProps> = ({ data }) => {
// Parse the JSON data from the context string
const bugData = React.useMemo(() => {
try {
return JSON.parse(data || "{}")
} catch (e) {
console.error("Failed to parse bug report data", e)
return {}
}
}, [data])
return (
<div className="bg-badge-background/50 text-badge-foreground rounded-xs p-3">
<h2 className="font-bold mb-3">{bugData.title || "Bug Report"}</h2>
<div className="space-y-3 text-sm">
{bugData.what_happened && (
<div>
<div className="font-semibold">What Happened?</div>
<MarkdownBlock markdown={bugData.what_happened} />
</div>
)}
{bugData.steps_to_reproduce && (
<div>
<div className="font-semibold">Steps to Reproduce</div>
<MarkdownBlock markdown={bugData.steps_to_reproduce} />
</div>
)}
{bugData.api_request_output && (
<div>
<div className="font-semibold">Relevant API Request Output</div>
<MarkdownBlock markdown={bugData.api_request_output} />
</div>
)}
{bugData.provider_and_model && (
<div>
<div className="font-semibold">Provider/Model</div>
<MarkdownBlock markdown={bugData.provider_and_model} />
</div>
)}
{bugData.operating_system && (
<div>
<div className="font-semibold">Operating System</div>
<MarkdownBlock markdown={bugData.operating_system} />
</div>
)}
{bugData.system_info && (
<div>
<div className="font-semibold">System Info</div>
<MarkdownBlock markdown={bugData.system_info} />
</div>
)}
{bugData.cline_version && (
<div>
<div className="font-semibold">Cline Version</div>
<MarkdownBlock markdown={bugData.cline_version} />
</div>
)}
{bugData.additional_context && (
<div>
<div className="font-semibold">Additional Context</div>
<MarkdownBlock markdown={bugData.additional_context} />
</div>
)}
</div>
</div>
)
}
export default ReportBugPreview
@@ -16,7 +16,6 @@ interface SlashCommandMenuProps {
remoteWorkflowToggles?: Record<string, boolean>
remoteWorkflows?: any[]
mcpServers?: McpServer[]
pluginSlashCommands?: SlashCommand[]
}
const SlashCommandMenu: React.FC<SlashCommandMenuProps> = ({
@@ -30,7 +29,6 @@ const SlashCommandMenu: React.FC<SlashCommandMenuProps> = ({
remoteWorkflowToggles,
remoteWorkflows,
mcpServers = [],
pluginSlashCommands = [],
}) => {
const menuRef = useRef<HTMLDivElement>(null)
@@ -42,7 +40,6 @@ const SlashCommandMenu: React.FC<SlashCommandMenuProps> = ({
remoteWorkflowToggles,
remoteWorkflows,
mcpServers,
pluginSlashCommands,
)
const defaultCommands = filteredCommands.filter((cmd) => cmd.section === "default" || !cmd.section)
const workflowCommands = filteredCommands.filter((cmd) => cmd.section === "custom")
@@ -17,6 +17,7 @@ vi.mock("@/services/grpc-client", () => ({
},
SlashServiceClient: {
condense: (req: unknown) => condense(req),
reportBug: vi.fn().mockResolvedValue(undefined),
},
UiServiceClient: {
trackIntent: (req: unknown) => trackIntent(req),
@@ -179,7 +179,8 @@ export function useMessageHandlers(messages: ClineMessage[], chatState: ChatStat
case "mistake_limit_reached":
case "api_req_failed":
case "new_task":
case "condense": {
case "condense":
case "report_bug": {
// Most askResponse sends need a temporary webview-only user bubble because the
// extension will not echo the user's message until later. Active follow-up
// questions are the exception: they are backed by the SDK's pending ask_question
@@ -410,6 +411,11 @@ export function useMessageHandlers(messages: ClineMessage[], chatState: ChatStat
console.error(err),
)
break
case "report_bug":
await SlashServiceClient.reportBug(StringRequest.create({ value: lastMessage?.text })).catch((err) =>
console.error(err),
)
break
}
break
}
@@ -112,6 +112,7 @@ describe("getButtonConfig", () => {
{ ask: "resume_completed_task", expectedConfig: "resume_completed_task" },
{ ask: "new_task", expectedConfig: "new_task" },
{ ask: "condense", expectedConfig: "condense" },
{ ask: "report_bug", expectedConfig: "report_bug" },
]
stateConfigs.forEach(({ ask, expectedConfig }) => {
@@ -10,7 +10,7 @@ export type ButtonActionType =
| "proceed" // Send messageResponse or yesButtonClicked
| "new_task" // Start a new task
| "cancel" // Cancel streaming
| "utility" // Execute utility function (condense)
| "utility" // Execute utility function (condense, report_bug)
| "retry" // Retry the last action
/**
@@ -169,6 +169,15 @@ export const BUTTON_CONFIGS: Record<string, ButtonConfig> = {
primaryAction: "utility",
secondaryAction: undefined,
},
report_bug: {
sendingDisabled: false,
enableButtons: true,
primaryText: "Report GitHub issue",
secondaryText: undefined,
primaryAction: "utility",
secondaryAction: undefined,
},
// Streaming/partial states - disable interaction during streaming
partial: {
sendingDisabled: true,
@@ -278,6 +287,8 @@ export function getButtonConfig(message: ClineMessage | undefined, _mode: Mode =
// Utility
case "condense":
return BUTTON_CONFIGS.condense
case "report_bug":
return BUTTON_CONFIGS.report_bug
default:
return BUTTON_CONFIGS.tool_approve
@@ -1,5 +1,7 @@
import { buildModelInfoNameMap, type ModelInfo, openAiModelInfoSafeDefaults, resolveClinePassModelInfo } from "@shared/api"
import { StringRequest } from "@shared/proto/cline/common"
import type { OnboardingModel, OnboardingModelGroup, OpenRouterModelInfo } from "@shared/proto/index.cline"
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { AlertCircleIcon, CircleCheckIcon, CircleIcon, ListIcon, LoaderCircleIcon, ZapIcon } from "lucide-react"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import ClineLogoWhite from "@/assets/ClineLogoWhite"
@@ -13,7 +15,7 @@ import { useHasFeatureFlag } from "@/hooks/useFeatureFlag"
import { useProviderConfig } from "@/hooks/useProviderConfig"
import { useProviderModels } from "@/hooks/useProviderModels"
import { cn } from "@/lib/utils"
import { AccountServiceClient, StateServiceClient } from "@/services/grpc-client"
import { AccountServiceClient, StateServiceClient, UiServiceClient } from "@/services/grpc-client"
import ApiConfigurationSection from "../settings/sections/ApiConfigurationSection"
import { useApiConfigurationHandlers } from "../settings/utils/useApiConfigurationHandlers"
import WelcomeView from "../welcome/WelcomeView"
@@ -272,7 +274,25 @@ const UserTypeSelectionStep = ({ userType, onSelectUserType, userTypeSelections
</ItemMedia>
<ItemContent className="w-full">
<ItemTitle>{option.title}</ItemTitle>
<ItemDescription>{option.description}</ItemDescription>
<ItemDescription>
{option.description}
{option.learnMoreUrl && (
<>
{" "}
<VSCodeLink
className="inline"
style={{ fontSize: "inherit" }}
onClick={(e) => {
e.stopPropagation()
UiServiceClient.openUrl(
StringRequest.create({ value: option.learnMoreUrl }),
).catch((err) => console.error("Failed to open learn more link:", err))
}}>
Learn more
</VSCodeLink>
</>
)}
</ItemDescription>
</ItemContent>
</Item>
)
@@ -356,7 +376,7 @@ const OnboardingViewContent = ({ onboardingModels }: { onboardingModels: Onboard
// Gate on models too, so a fallback/empty response can't route flagged users into the dead-end empty step.
const showClinePass = isClinePassEnabled && models.clinePass.length > 0
const userTypeSelections = useMemo(() => getUserTypeSelections(showClinePass), [showClinePass])
// ClinePass model IDs (e.g. "cline-pass/glm-5.1") aren't keyed in openRouterModels,
// ClinePass model IDs (e.g. "cline-pass/glm-5.2") aren't keyed in openRouterModels,
// so resolve their info via the slug-based lookup used by ClinePassProvider.
const openRouterModelsByName = useMemo(() => buildModelInfoNameMap(openRouterModels), [openRouterModels])
const onboardingModelById = useMemo(() => {
@@ -27,7 +27,7 @@ describe("getClineUIOnboardingGroups", () => {
it("buckets ClinePass models into the clinePass group", () => {
const result = getClineUIOnboardingGroups(
groupOf([
model("cline-pass/glm-5.1", CLINEPASS_GROUP),
model("cline-pass/glm-5.2", CLINEPASS_GROUP),
model("free-model", "free"),
model("anthropic/claude", "frontier"),
model("z-ai/glm", "open source"),
@@ -36,7 +36,7 @@ describe("getClineUIOnboardingGroups", () => {
expect(result.clinePass).toHaveLength(1)
expect(result.clinePass[0].group).toBe(CLINEPASS_GROUP)
expect(result.clinePass[0].models.map((m) => m.id)).toEqual(["cline-pass/glm-5.1"])
expect(result.clinePass[0].models.map((m) => m.id)).toEqual(["cline-pass/glm-5.2"])
expect(result.free[0].models.map((m) => m.id)).toEqual(["free-model"])
expect(result.power.flatMap((g) => g.models.map((m) => m.id))).toEqual(["anthropic/claude", "z-ai/glm"])
})
@@ -58,22 +58,22 @@ describe("getRecommendedModelsData", () => {
const result = getRecommendedModelsData({
recommended: [],
free: [],
clinePass: [{ id: "cline-pass/glm-5.1", name: "GLM 5.1", description: "", tags: [] }],
clinePass: [{ id: "cline-pass/glm-5.2", name: "GLM 5.1", description: "", tags: [] }],
})
expect(result?.clinePass.map((model) => model.id)).toEqual(["cline-pass/glm-5.1"])
expect(result?.clinePass.map((model) => model.id)).toEqual(["cline-pass/glm-5.2"])
})
it("keeps classic recommended/free responses and ClinePass responses", () => {
const result = getRecommendedModelsData({
recommended: [{ id: "anthropic/claude", name: "Claude", description: "", tags: [] }],
free: [{ id: "free-model", name: "Free", description: "", tags: [] }],
clinePass: [{ id: "cline-pass/glm-5.1", name: "GLM 5.1", description: "", tags: [] }],
clinePass: [{ id: "cline-pass/glm-5.2", name: "GLM 5.1", description: "", tags: [] }],
})
expect(result?.recommended.map((model) => model.id)).toEqual(["anthropic/claude"])
expect(result?.free.map((model) => model.id)).toEqual(["free-model"])
expect(result?.clinePass.map((model) => model.id)).toEqual(["cline-pass/glm-5.1"])
expect(result?.clinePass.map((model) => model.id)).toEqual(["cline-pass/glm-5.2"])
})
it("returns undefined when every recommended bucket is empty", () => {
@@ -9,6 +9,7 @@ type UserTypeSelection = {
title: string
description: string
type: NEW_USER_TYPE
learnMoreUrl?: string
}
export const STEP_CONFIG = {
@@ -56,9 +57,10 @@ export const STEP_CONFIG = {
} as const
const CLINE_PASS_USER_TYPE_SELECTION: UserTypeSelection = {
title: "ClinePass (Recommended)",
description: "One subscription, curated models, no API keys",
title: "ClinePass",
description: "Low cost subscription plan for best open weights model.",
type: NEW_USER_TYPE.CLINE_PASS,
learnMoreUrl: "https://docs.cline.bot/getting-started/clinepass",
}
const BASE_USER_TYPE_SELECTIONS: UserTypeSelection[] = [
@@ -86,7 +86,7 @@ export function useOnboardingModels(): UseOnboardingModelsResult {
return { ...openRouterModels, ...(clineModels ?? {}) }
}, [openRouterModels, clineModels])
// ClinePass model IDs omit the upstream lab (e.g. "cline-pass/glm-5.1"), so look up
// ClinePass model IDs omit the upstream lab (e.g. "cline-pass/glm-5.2"), so look up
// capabilities via the model slug against the OpenRouter catalog, falling back to
// conservative ClinePass defaults. Mirrors ClinePassProvider's resolution.
const openRouterModelsByName = useMemo(() => buildModelInfoNameMap(openRouterModels), [openRouterModels])
@@ -598,8 +598,7 @@ const ClineModelPicker: React.FC<ClineModelPickerProps> = ({ isPopup, currentMod
marginTop: 0,
color: "var(--vscode-descriptionForeground)",
}}>
The extension automatically fetches the latest Cline model list. If you're unsure which model to choose,
compare available models by context window, pricing, and capabilities.
The extension automatically fetches the latest Cline model list.
</p>
)}
</div>
@@ -1,13 +1,20 @@
import type { ModelInfo } from "@shared/api"
import { openAiModelInfoSafeDefaults } from "@shared/api"
import { CLINE_RECOMMENDED_MODELS_FALLBACK } from "@shared/cline/recommended-models"
import { EmptyRequest } from "@shared/proto/cline/common"
import { type ClineRecommendedModel, ClineRecommendedModelsResponse } from "@shared/proto/cline/models"
import { Mode } from "@shared/storage/types"
import { useEffect, useMemo, useState } from "react"
import styled from "styled-components"
import { buildClinePassSubscriptionPageUrl } from "@/components/onboarding/clinePassSubscribe"
import { useClineAuth } from "@/context/ClineAuthContext"
import { useProviderConfig } from "@/hooks/useProviderConfig"
import { useProviderModelSelection } from "@/hooks/useProviderModelSelection"
import { useProviderModels } from "@/hooks/useProviderModels"
import { ModelsServiceClient } from "@/services/grpc-client"
import { ClineAccountInfoCard } from "../ClineAccountInfoCard"
import { ModelInfoView } from "../common/ModelInfoView"
import FeaturedModelCard from "../FeaturedModelCard"
import ReasoningEffortSelector from "../ReasoningEffortSelector"
import { type ModelPickerSelection, ModelPickerWithManualEntry } from "./ModelPickerWithManualEntry"
@@ -18,6 +25,15 @@ interface ClinePassProviderProps {
}
const CLINE_PASS_PROVIDER_ID = "cline-pass"
const CLINE_PASS_MODEL_ID_PREFIX = "cline-pass/"
const FREE_TAB_DESCRIPTION = "Try with limited usage, separate from ClinePass quota."
interface FeaturedTabEntry {
id: string
displayName: string
description: string
label: string
}
function clinePassFallbackModelInfo(modelId: string): ModelInfo {
return {
@@ -30,11 +46,42 @@ function clinePassFallbackModelInfo(modelId: string): ModelInfo {
}
}
function toSubscribedEntry(model: Pick<ClineRecommendedModel, "id" | "description">): FeaturedTabEntry | null {
if (!model.id) {
return null
}
// The whole list is included with the plan, so no per-card label chip
return {
id: model.id,
displayName: model.id.replace(CLINE_PASS_MODEL_ID_PREFIX, ""),
description: model.description || "",
label: "",
}
}
function toFreeEntry(model: Pick<ClineRecommendedModel, "id" | "name" | "description" | "tags">): FeaturedTabEntry | null {
if (!model.id) {
return null
}
const firstTag = model.tags?.[0]
return {
id: model.id,
// The FREE chip already says it, so drop OpenRouter's :free marker
displayName: (model.name || model.id).replace(/:free$/i, ""),
description: model.description || "",
label: typeof firstTag === "string" && firstTag.length > 0 ? firstTag.toUpperCase() : "FREE",
}
}
/**
* ClinePass is a first-class SDK provider whose credentials are backed by the
* user's Cline OAuth account. Keep the UX close to the Cline provider (account
* card + model selection), but resolve and persist selections through the SDK
* provider catalog under providerId="cline-pass".
*
* The featured section splits the catalog into Subscribed (the plan's models)
* and Free (Cline free models, selectable here because both providers hit the
* same Cline API free models simply ride usage billing at $0).
*/
export const ClinePassProvider = ({ showModelOptions, isPopup, currentMode }: ClinePassProviderProps) => {
const { models, defaultModelId, isLoading, isStale, error } = useProviderModels(CLINE_PASS_PROVIDER_ID)
@@ -47,11 +94,85 @@ export const ClinePassProvider = ({ showModelOptions, isPopup, currentMode }: Cl
customModelInfo: clinePassFallbackModelInfo,
})
const { clineUser } = useClineAuth()
const [subscribedEntries, setSubscribedEntries] = useState<FeaturedTabEntry[]>([])
const [freeEntries, setFreeEntries] = useState<FeaturedTabEntry[]>([])
const [activeTab, setActiveTab] = useState<"subscribed" | "free">("subscribed")
useEffect(() => {
let cancelled = false
const fetchRecommendedModels = async () => {
try {
const response = await ModelsServiceClient.makeUnaryRequest(
"refreshClineRecommendedModelsRpc",
EmptyRequest.create({}),
EmptyRequest.toJSON,
ClineRecommendedModelsResponse.fromJSON,
)
if (cancelled) {
return
}
setSubscribedEntries(
(response.clinePass ?? [])
.map(toSubscribedEntry)
.filter((entry): entry is FeaturedTabEntry => entry !== null),
)
setFreeEntries(
(response.free ?? []).map(toFreeEntry).filter((entry): entry is FeaturedTabEntry => entry !== null),
)
} catch (err) {
console.error("Failed to refresh ClinePass recommended models:", err)
}
}
void fetchRecommendedModels()
return () => {
cancelled = true
}
}, [])
// Fall back to the provider catalog (subscribed) and the bundled free list
// until the endpoint responds
const subscribedCards = useMemo(() => {
if (subscribedEntries.length > 0) {
return subscribedEntries
}
return Object.keys(models ?? {})
.filter((id) => id.startsWith(CLINE_PASS_MODEL_ID_PREFIX))
.map((id) => toSubscribedEntry({ id, description: models[id]?.description ?? "" }))
.filter((entry): entry is FeaturedTabEntry => entry !== null)
}, [subscribedEntries, models])
const freeCards = useMemo(() => {
if (freeEntries.length > 0) {
return freeEntries
}
return CLINE_RECOMMENDED_MODELS_FALLBACK.free
.map(toFreeEntry)
.filter((entry): entry is FeaturedTabEntry => entry !== null)
}, [freeEntries])
// Land on the tab containing the configured model
useEffect(() => {
if (freeCards.some((entry) => entry.id === selectedModel.modelId)) {
setActiveTab("free")
} else if (subscribedCards.some((entry) => entry.id === selectedModel.modelId)) {
setActiveTab("subscribed")
}
}, [selectedModel.modelId, freeCards, subscribedCards])
const handleModelSelect = (selection: ModelPickerSelection) => {
void commitModelSelection(selection).catch((err) => console.error("Failed to commit ClinePass model selection:", err))
}
const handleFeaturedModelSelect = (modelId: string) => {
handleModelSelect({
providerId: CLINE_PASS_PROVIDER_ID,
modelId,
modelInfo: models?.[modelId] ?? clinePassFallbackModelInfo(modelId),
})
}
const activeCards = activeTab === "free" ? freeCards : subscribedCards
return (
<div>
<div style={{ marginBottom: 14, marginTop: 4 }}>
@@ -60,6 +181,35 @@ export const ClinePassProvider = ({ showModelOptions, isPopup, currentMode }: Cl
{showModelOptions && (
<>
{/* Tabs */}
<TabsContainer style={{ marginTop: 4 }}>
<Tab active={activeTab === "subscribed"} onClick={() => setActiveTab("subscribed")}>
Subscribed
</Tab>
{freeCards.length > 0 && (
<Tab active={activeTab === "free"} onClick={() => setActiveTab("free")}>
Free
</Tab>
)}
</TabsContainer>
{/* Tab description */}
{activeTab === "free" && <TabDescription>{FREE_TAB_DESCRIPTION}</TabDescription>}
{/* Model Cards */}
<div style={{ marginBottom: "6px" }}>
{activeCards.map((entry) => (
<FeaturedModelCard
description={entry.description}
isSelected={selectedModel.modelId === entry.id}
key={entry.id}
label={entry.label}
modelId={entry.displayName}
onClick={() => handleFeaturedModelSelect(entry.id)}
/>
))}
</div>
<ModelPickerWithManualEntry
allowsCustomIds={false}
error={error}
@@ -95,3 +245,30 @@ export const ClinePassProvider = ({ showModelOptions, isPopup, currentMode }: Cl
</div>
)
}
const TabsContainer = styled.div`
display: flex;
gap: 0;
margin-bottom: 12px;
border-bottom: 1px solid var(--vscode-panel-border);
`
const Tab = styled.div<{ active: boolean }>`
padding: 8px 16px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
color: ${({ active }) => (active ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")};
border-bottom: 2px solid ${({ active }) => (active ? "var(--vscode-textLink-foreground)" : "transparent")};
transition: all 0.15s ease;
&:hover {
color: var(--vscode-foreground);
}
`
const TabDescription = styled.p`
font-size: 11px;
margin: -6px 0 6px 0;
color: var(--vscode-descriptionForeground);
`
@@ -216,6 +216,13 @@ export async function syncModeConfigurations(
updates.actModeClineModelInfo = sourceFields.clineModelInfo
break
case "cline-pass":
updates.planModeClinePassModelId = sourceFields.clinePassModelId
updates.actModeClinePassModelId = sourceFields.clinePassModelId
updates.planModeClinePassModelInfo = sourceFields.clinePassModelInfo
updates.actModeClinePassModelInfo = sourceFields.clinePassModelInfo
break
case "requesty":
updates.planModeRequestyModelId = sourceFields.requestyModelId
updates.actModeRequestyModelId = sourceFields.requestyModelId
@@ -289,7 +289,6 @@ export const ExtensionStateContextProvider: React.FC<{
localAgentsRulesToggles: {},
localWorkflowToggles: {},
globalWorkflowToggles: {},
pluginSlashCommands: [],
shellIntegrationTimeout: 4000,
terminalReuseEnabled: true,
vscodeTerminalExecutionMode: "vscodeTerminal",
@@ -907,7 +906,6 @@ export const ExtensionStateContextProvider: React.FC<{
localAgentsRulesToggles: state.localAgentsRulesToggles || {},
localWorkflowToggles: state.localWorkflowToggles || {},
globalWorkflowToggles: state.globalWorkflowToggles || {},
pluginSlashCommands: state.pluginSlashCommands || [],
remoteRulesToggles: state.remoteRulesToggles || {},
remoteWorkflowToggles: state.remoteWorkflowToggles || {},
enableCheckpointsSetting: state.enableCheckpointsSetting,
@@ -181,7 +181,6 @@ export function getMatchingSlashCommands(
remoteWorkflowToggles?: Record<string, boolean>,
remoteWorkflows?: any[],
mcpServers: McpServer[] = [],
pluginSlashCommands: SlashCommand[] = [],
): SlashCommand[] {
const workflowCommands = getWorkflowCommands(
localWorkflowToggles,
@@ -190,7 +189,7 @@ export function getMatchingSlashCommands(
remoteWorkflows,
)
const mcpPromptCommands = getMcpPromptCommands(mcpServers)
const allCommands = [...DEFAULT_SLASH_COMMANDS, ...workflowCommands, ...mcpPromptCommands, ...pluginSlashCommands]
const allCommands = [...DEFAULT_SLASH_COMMANDS, ...workflowCommands, ...mcpPromptCommands]
if (!query) {
return allCommands
@@ -234,7 +233,6 @@ export function validateSlashCommand(
remoteWorkflowToggles?: Record<string, boolean>,
remoteWorkflows?: any[],
mcpServers: McpServer[] = [],
pluginSlashCommands: SlashCommand[] = [],
): "full" | "partial" | null {
if (!command) {
return null
@@ -247,7 +245,7 @@ export function validateSlashCommand(
remoteWorkflows,
)
const mcpPromptCommands = getMcpPromptCommands(mcpServers)
const allCommands = [...DEFAULT_SLASH_COMMANDS, ...workflowCommands, ...mcpPromptCommands, ...pluginSlashCommands]
const allCommands = [...DEFAULT_SLASH_COMMANDS, ...workflowCommands, ...mcpPromptCommands]
// case insensitive matching
const exactMatch = allCommands.some((cmd) => cmd.name.toLowerCase() === command.toLowerCase())
+3 -3
View File
@@ -47,9 +47,6 @@ console.log("Building webview for", platform)
export default defineConfig({
base: "./",
optimizeDeps: {
force: true, // Forces re-optimization
},
plugins: [react(), tailwindcss(), writePortToFile()],
test: {
environment: "jsdom",
@@ -112,6 +109,9 @@ export default defineConfig({
},
server: {
port: 25463,
fs: {
allow: [resolve(__dirname, "../src/shared")],
},
hmr: {
host: "localhost",
protocol: "ws",
+164 -182
View File
@@ -19,7 +19,7 @@
},
"apps/cli": {
"name": "@cline/cli",
"version": "3.0.37",
"version": "3.0.38",
"bin": {
"cline": "src/index.ts",
},
@@ -161,7 +161,7 @@
},
"apps/examples/desktop-app": {
"name": "@cline/code",
"version": "0.0.0",
"version": "0.0.1",
"dependencies": {
"@base-ui/react": "^1.2.0",
"@cline/core": "workspace:*",
@@ -616,7 +616,7 @@
},
"sdk/packages/agents": {
"name": "@cline/agents",
"version": "0.0.58",
"version": "0.0.59",
"dependencies": {
"@cline/llms": "workspace:*",
"@cline/shared": "workspace:*",
@@ -625,7 +625,7 @@
},
"sdk/packages/core": {
"name": "@cline/core",
"version": "0.0.58",
"version": "0.0.59",
"dependencies": {
"@cline/agents": "workspace:*",
"@cline/llms": "workspace:*",
@@ -663,7 +663,7 @@
},
"sdk/packages/llms": {
"name": "@cline/llms",
"version": "0.0.58",
"version": "0.0.59",
"dependencies": {
"@ai-sdk/amazon-bedrock": "^4.0.89",
"@ai-sdk/anthropic": "^3.0.68",
@@ -697,14 +697,14 @@
},
"sdk/packages/sdk": {
"name": "@cline/sdk",
"version": "0.0.58",
"version": "0.0.59",
"dependencies": {
"@cline/core": "workspace:*",
},
},
"sdk/packages/shared": {
"name": "@cline/shared",
"version": "0.0.58",
"version": "0.0.59",
"dependencies": {
"aws4fetch": "^1.0.20",
"jsonrepair": "^3.13.2",
@@ -741,27 +741,27 @@
"@agentclientprotocol/sdk": ["@agentclientprotocol/sdk@0.16.1", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-1ad+Sc/0sCtZGHthxxvgEUo5Wsbw16I+aF+YwdiLnPwkZG8KAGUEAPK6LM6Pf69lCyJPt1Aomk1d+8oE3C4ZEw=="],
"@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@4.0.125", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.90", "@ai-sdk/openai": "3.0.78", "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-7C+ud1t6biknsr+fSOSOeFJXYrPAjOouSUPu2ZJ94pXywI2W7Y3E3Rn0s2/NYViknRgY0UBcLY9GR1KKwhf1Yg=="],
"@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@4.0.128", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.92", "@ai-sdk/openai": "3.0.80", "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-T6mvUEYjTCkRAYByOwCwHT12J8r2U9fxJqfEf6k04OceGFjERCfmDdc2wmEaZ4VLo62KpUKJJf6gdf9Bcrx1gw=="],
"@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.90", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-7K51KyEyyQPcvBdrxB+TPmHzmuXPhyDNwTZuqTcsYp2GbB0E2SzoM1qEJ4qLb1H2Q8xx5SkkOhATmDxC4oVo9A=="],
"@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.92", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-dFrf4xhx2yM686KHFm76Nn7nBekjkjiw1btqOyR26/kXz58QMguhNsjyvMqPktD8AW/wwTAq0fDRVyDvF2gH1w=="],
"@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.140", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-4VyQTHHqfZ0qI1fCcurJgYgzVDgLfV4svzBMOHGGxCu4srFkAn4ZmwFj2M0J00kNt7QLsjOtZ6PhueupeIJSjA=="],
"@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.142", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Y1iwdxdebYXpoK5y/4CrcCfJGeFwEJWlEx+pMWIg/ZVWGi9KA+JXM7YBkhxcshpq/jAXx8YyQeFMyZr0TGfXZQ=="],
"@ai-sdk/google": ["@ai-sdk/google@3.0.86", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-NZoFXTdK2/C7VuuGhAatoQ/wSiIvxVzw4Xr0AvcD3cotS5+iP/y0eN1J12pvFSZv+nAHa2Xl7xvFHDadzeU90g=="],
"@ai-sdk/google": ["@ai-sdk/google@3.0.88", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CN3PHCz5pa2sBowwZG4sNqE+7YfHWZT6+5KU12YMWuBssZ03s143Jr2jThkN5Fgemy8Kyg+ub2XbpHGhtIZ2yQ=="],
"@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@4.0.153", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.90", "@ai-sdk/google": "3.0.86", "@ai-sdk/openai-compatible": "2.0.54", "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZPPjMRkTmdRzDSjxlZFJXskuAtyTYffnPVQjbWDTNqiUTGOHQaxxRuqibepJqQ19pnDe72Yj1r+fL2kNkhml+g=="],
"@ai-sdk/google-vertex": ["@ai-sdk/google-vertex@4.0.155", "", { "dependencies": { "@ai-sdk/anthropic": "3.0.92", "@ai-sdk/google": "3.0.88", "@ai-sdk/openai-compatible": "2.0.56", "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35", "google-auth-library": "^10.5.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-DMH5rhnN2AcwDmLWcRqUwF/Mj5SlgaAK5uy9ke7SNZ/BCNUcnI7MBVr1urteBdro1P3BAfiNSXuTfjIlOhwl/Q=="],
"@ai-sdk/mistral": ["@ai-sdk/mistral@3.0.43", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-FtFcf0eXEm1v8JiDYe4fyQoRz9JmK5/LLH8nawFIttkxc309TsuPNFfwpSgj2Fm5osrBFL49FGPEL9phJVav7A=="],
"@ai-sdk/mistral": ["@ai-sdk/mistral@3.0.45", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-IyOPiBqPkd6RPqTvhDN6/JcoF7VVP2499FY4acnMz08Y7a1c1ZplsL6lPRTOmcFEwto1491ePilD9H0GtY1QEg=="],
"@ai-sdk/openai": ["@ai-sdk/openai@3.0.78", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-XlRHyAe1zvetAO1lXVQSNy8acsdd+kznTfmedXBCe7Pvu7lEGGePL8iUg/jH2qLqnlrIpYovuCd3jC2hSTOTsA=="],
"@ai-sdk/openai": ["@ai-sdk/openai@3.0.80", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-u3EfYbBG4YS/U2eOGH0yv8lPRwDj25X3sTluUKMYEwOLTZzWYv0IPtrpO7tPEra0QU4oq5Gpg49/FGFSrzE4vA=="],
"@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.54", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-OyXt0zK8y2/ZIyWlbxTv2r1M7AK227S+Gl4BYOEF42q0wz1n5m4fwR8L4Fy/MQ4Ho6xje47MPsFcRdIqIyP6Rw=="],
"@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.56", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-cQrN6OUn/jvsY3OdsU6Wn+ss7vp1iwIcakZKSlSRMnYqShBfyT7Qht+eqmgxs7w9ttrw6FAG6o11AiBs+iEsTA=="],
"@ai-sdk/provider": ["@ai-sdk/provider@3.0.12", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-sj9DWTJ2Ze0WR9qsiOPqoqzNx3OxL6iMxHImbhvoe9qOspekbzxNDMiJ4TIGfYHYh9w4OmBjz3prvqhzTi96+Q=="],
"@ai-sdk/provider": ["@ai-sdk/provider@3.0.13", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-ZPtVYt5QIJzOta1kdUiDuCx4HhFkvNPv/rvmZ2b1iXwybYjJsCnNYR4PAw4kW7rgVfDARvHXcU64efWuqNp6bw=="],
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.33", "", { "dependencies": { "@ai-sdk/provider": "3.0.12", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-nJ0bAfegMAIJtrzMJtbzer1cS3nb7c7DsyU1S4nrPm7ZU0Mn6SBBZv5IGZZGTbpWTJwqKTSPeZJTXalbAxt1BA=="],
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.35", "", { "dependencies": { "@ai-sdk/provider": "3.0.13", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bjYld/2KGPLt78kpqbya+fD4LYS7BqVQJyUjE3qAHrYB0FR2Q90BaWEVIBZaguTWXf/A8L6uG1zO1v9TxVlGWg=="],
"@ai-sdk/react": ["@ai-sdk/react@3.0.218", "", { "dependencies": { "@ai-sdk/provider-utils": "4.0.33", "ai": "6.0.216", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" } }, "sha512-gFtotqv2JmJeUIjmMigdIwwUbABXjJb786anZ26AcaLVSC/pKqhhtzYsT0uef5MuEcLquTzBAFtu6SY3Ov2I5Q=="],
"@ai-sdk/react": ["@ai-sdk/react@3.0.220", "", { "dependencies": { "@ai-sdk/provider-utils": "4.0.35", "ai": "6.0.218", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" } }, "sha512-mUqM13WXUT2jNhoU0Kf7YxAtIS+atCUtzZ1LNkhF1q42oYs4g2gWFtq4gNCejACvFMu1KusGRQU2S7ONXtVLZw=="],
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
@@ -769,71 +769,61 @@
"@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
"@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.196", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.196", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.196", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.196", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.196", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.196", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.196", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.196", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.196" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-yqsp1/04T2/tJ54jz+7YLsTZOPeQ/myUCrv17/IVZ9dbl+izIMP9ULuLpPCH5pj5msXxR80es+hpVgHoFuNm0A=="],
"@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.198", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.198", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.198", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.198", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.198", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.198", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.198", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.198", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.198" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-xt469sSCyclTPtzpLAg0Aschy665GiRMgZKabSmESbGUA5/H56HcILVOiFxclXswkeMUk2fQxfHJUY9UZfiTnA=="],
"@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.196", "", { "os": "darwin", "cpu": "arm64" }, "sha512-k1MKRDhSiNKpkTwhtU8QKGzfuRfr3YXS6oqsTuldMROX56L5iMXjzC7AYU1/KmPTeMl3SCQBQeDu0i8ciA0hQA=="],
"@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.198", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ZmiAybQKIKcP1qEAE/vfXvfxtKxG9CnJn98QTXC5Zxiwuy7Mllx2ALXh9dfmsf0V87CGEodlZQmMgUJotNIsUw=="],
"@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.196", "", { "os": "darwin", "cpu": "x64" }, "sha512-bBwx/7yKZMQ9NSUt4bg8P+zp6pgd/O/DTkzdqsRIivBvARmwo1QY/2qGrLO8RH0T8CG2lTjFNfDfOlJWbAkvAg=="],
"@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.198", "", { "os": "darwin", "cpu": "x64" }, "sha512-XwH5vgN46WSwg8aC1OagNofnJpV/G1ciEu118GEKer8ZhVkq/dvK/DqShxMkb6r1jV7u5IJ7zPXu9uKliyNJAw=="],
"@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.196", "", { "os": "linux", "cpu": "arm64" }, "sha512-fR5fy+pSQSpKZK0zTtAl3LZEGQTuwVK7svutH1bZUS5RGT2HdUWc71oltSZgW4upGaslj+gyusHGJHA5eAc+dw=="],
"@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.198", "", { "os": "linux", "cpu": "arm64" }, "sha512-qmz8dxEtDIlKntU5qYe0R4aWTxTue5S7zIQknatLX7aJ6HN/nq1aCNXWn5smTH2FViBkUPPR+sCIsNwSk6AT6Q=="],
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.196", "", { "os": "linux", "cpu": "arm64" }, "sha512-BhLxfx4j6mC3Uzmve1IbhFS1uvNlwATeo6uWyYDOMW4n3XKjiSgjD8bTfkamijrxCMvJo5swLju2y14ayDsokA=="],
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.198", "", { "os": "linux", "cpu": "arm64" }, "sha512-Q7lKVNjIrUQ2B/AR77OvRf0zeOdEjonFVaR9FYrrwtzGeEqum69WSht5nM7Y7el3wjbNi0/eV0QTUM0DlsTEfw=="],
"@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.196", "", { "os": "linux", "cpu": "x64" }, "sha512-9spZON7/tn0q9J+jICrdfHi7o7Fmjs9pIohCCxL+Yv7HbBXWVtEYJbYipBGLTl8ICG3mgPeEVMNsvOuh/jDTuA=="],
"@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.198", "", { "os": "linux", "cpu": "x64" }, "sha512-Zqxyz2AT1UM5WlOOoLJhLssZDgZo8rBK5ku6daveK12zp+UTJGZhGsjFghz1/ASxH08KqOTbUePNTORnPhHAEQ=="],
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.196", "", { "os": "linux", "cpu": "x64" }, "sha512-EOiNbxCXQLYzV7SQhMWkUC1ScWyTw/Qp+JyV2sEmIbzl/e7KMOxNE9J20k+lpPs6CXdxVzuMwH7yAGuDu5y+IQ=="],
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.198", "", { "os": "linux", "cpu": "x64" }, "sha512-h1SrWVIMjLInYNPlf+TxXuKTOdoiOfJLBSoQG97315Z2Nh0IpBfqWExlqYTtPCgKE7q2iga31U283QfHpIDlSQ=="],
"@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.196", "", { "os": "win32", "cpu": "arm64" }, "sha512-0xXkAWlDof/qFi3k5KJZ5WYbgp1X8hZHjyasOWTZWAmldoYaENI0vkL+PVMarvoAFYRRqcWoS81FSgm0QgH2sA=="],
"@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.198", "", { "os": "win32", "cpu": "arm64" }, "sha512-mjIHf1HFiRuXefewWTaNZFlTZlCaEt/xsRjc1nSTCEEpFolZayVhrDKz+O2QFVcDtPl8x8GeYSL0kiikg1DZjQ=="],
"@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.196", "", { "os": "win32", "cpu": "x64" }, "sha512-FxWLA3aOYgDf2J0o6Ov1/wgg9X6RkrgnX4ifUWO1i3+6mbc4efNLHkDZLxCHEnQgW8yBidX+iro19f9k64vV8A=="],
"@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.198", "", { "os": "win32", "cpu": "x64" }, "sha512-y3HLuCCz1kDwUrhd6OnqO+d5BUpTFSzNUsPT9kf3r1vk9HYKF+eMC9eIlcOhiW2kX491kxEvuEOfqgIkGx15cg=="],
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.37.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-tHjX2YbkUBwEgg0JZU3EFSSAQPoK4qQR/NFYa8Vtzd5UAyXzZksCw2In69Rml4R/TyHPBfRYaLK35XiOe33pjw=="],
"@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="],
"@aws-crypto/sha256-browser": ["@aws-crypto/sha256-browser@5.2.0", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw=="],
"@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.1078.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/credential-provider-node": "^3.972.61", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-BYy0X/+GMXlitKShxkdTsCexWwDrn8usY2Y2Z06M5MSi4aRT3Ce5ilyA6OubQUqOWfsmDMYrm8oBNaTIcQFyrg=="],
"@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="],
"@aws-sdk/core": ["@aws-sdk/core@3.974.26", "", { "dependencies": { "@aws-sdk/types": "^3.973.15", "@aws-sdk/xml-builder": "^3.972.33", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/core": "^3.29.0", "@smithy/signature-v4": "^5.6.1", "@smithy/types": "^4.15.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-wRj7Pthvjk3anees97pUWlxlTa0DUjeGrEQU5fKDZVdWZV0ekaprbof0df2uaE9g8u67t035v2j+ne2AW2UMkA=="],
"@aws-crypto/supports-web-crypto": ["@aws-crypto/supports-web-crypto@5.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg=="],
"@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.51", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-nXzAwRz0NOiHlG/HHea7oJ2ew2m21XZUU6h2cZMCrlNQqcWjMHCkun4D6E7CWqOxiFG0MeN8Gg5Iakrjv/UXrQ=="],
"@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="],
"@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.52", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-sxuaHZGHqOgKB8OdL3doXa1NJjqmO60FPfyTnYVKGjX9taRsIEGS9pd+2yALmo06hijZ8L94uSK0kfXZsRmVyA=="],
"@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.1076.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.24", "@aws-sdk/credential-provider-node": "^3.972.59", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/fetch-http-handler": "^5.6.0", "@smithy/node-http-handler": "^4.9.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-hSkEljVcPBXPSsB/GLeVZaNaIzrMLPAj//jg41rNObfMGa7qRvWHXtbDt7UVxXjAFlVw84wCFWNBMBSql5HynQ=="],
"@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.54", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-e6yz52nq3SpR1oPLcvfsDM7H7k2gIYk/NSn/rwsFqzGXEwr3g0mRMlPbLaKCPCGNZJMU/gZg6/64B3eSam+gBw=="],
"@aws-sdk/core": ["@aws-sdk/core@3.974.24", "", { "dependencies": { "@aws-sdk/types": "^3.973.14", "@aws-sdk/xml-builder": "^3.972.32", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/core": "^3.27.0", "@smithy/signature-v4": "^5.5.3", "@smithy/types": "^4.15.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-vWB/qJl21vxGKBkBN8fKPTVXgm14v/bUQWTtR5oikrfAZbIN2bxuSiCY5rRAMR4gs3vtR2Vw0aTfVDU4tdfIPg=="],
"@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.59", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/credential-provider-env": "^3.972.52", "@aws-sdk/credential-provider-http": "^3.972.54", "@aws-sdk/credential-provider-login": "^3.972.58", "@aws-sdk/credential-provider-process": "^3.972.52", "@aws-sdk/credential-provider-sso": "^3.972.58", "@aws-sdk/credential-provider-web-identity": "^3.972.58", "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/credential-provider-imds": "^4.4.5", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-9Um/UpruN76AdpiLnvwChVkJJwJ9Vx9ykk/2AeLxxSCM/YYRD8Kkq2towUk9fZQLV7dd9ATlsi87U7hKs0z/iQ=="],
"@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.49", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-PU8EJj5wMvTqp5oeBVCPK1vqraQ9ZlUVYTM5Bbvq1pBTY3WGr2wgvnGCRalFQpS7BFUQflpjumHcaQBmkOhfBA=="],
"@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.58", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-H3q96qF8/DJsPsXMVtMRqSWOc85K5O4zos32untdw+vE5vw0f3a6qJo1YqbND4BsEIKd4iZmzzVUq9kV4LjbHg=="],
"@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.50", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-l8bWzhPFTi9tDcvtURxeMlfsboul5/0sEN3SwwXxdpYudVB9+EuQcxo2pwlTzXwDo4Gm2VLGyiZ8zti3nfdOLw=="],
"@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.61", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.52", "@aws-sdk/credential-provider-http": "^3.972.54", "@aws-sdk/credential-provider-ini": "^3.972.59", "@aws-sdk/credential-provider-process": "^3.972.52", "@aws-sdk/credential-provider-sso": "^3.972.58", "@aws-sdk/credential-provider-web-identity": "^3.972.58", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/credential-provider-imds": "^4.4.5", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-2U2KHMRCt1dlZoLU3KZR5g5EL4b0h2HHw96SkaUBK7qvEXPZj5rGRO/3ZTeJmh37dIYQuCnA2273rZOQvmsiHw=="],
"@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.52", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/fetch-http-handler": "^5.6.0", "@smithy/node-http-handler": "^4.9.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-FjAlnsIvemWzO3JTM3ObuuxpqCyrqkXOewlYY2+NiR1MYO1JuFYSIJ8SJN5Q2KD1jkL5lIuab8awjb/AxsvjiQ=="],
"@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.52", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-Aff9Ebs42lz+Ep1wkS+Nlwh5S0eahakpyskPsuKGjiBJ6ExOjNtxbfKJTKovQtQNgJ7oG1BH6esJwGrbs7qgSA=="],
"@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.57", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/credential-provider-env": "^3.972.50", "@aws-sdk/credential-provider-http": "^3.972.52", "@aws-sdk/credential-provider-login": "^3.972.56", "@aws-sdk/credential-provider-process": "^3.972.50", "@aws-sdk/credential-provider-sso": "^3.972.56", "@aws-sdk/credential-provider-web-identity": "^3.972.56", "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/credential-provider-imds": "^4.4.3", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-8qwNhQ0sK/1KaOpVEFC7TFxrWP3fxzJV1K049MzjouiMIbvTDvIGDEUtj5ND5aTmlHVK/YZxjoYnLCeV/GZU0w=="],
"@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.58", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/token-providers": "3.1078.0", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-syloC58mXOacUqM2toPNfwd7X3jT+tWj0F/cN7qdW1FQyI0q41J0tPf6DIZ56BF0x82iS9j3ALP45MoBz79YuQ=="],
"@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.56", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-S36dCrDaafakFMlaCVGAF4advbQKoJuMcyMtNWVBpUz65uqhbIAsUfvAyp+djA+jkzaEfgZGd+AELjIGzTqyhw=="],
"@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.58", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-pTBImKzcGK+pcMKjL0fAJbnYzzYd1c0UDc7BSIOGNQhF9Nuk66vWlIXfYTYyzNSs+w8Q/vfbbNDDU8zdrouwLg=="],
"@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.59", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.50", "@aws-sdk/credential-provider-http": "^3.972.52", "@aws-sdk/credential-provider-ini": "^3.972.57", "@aws-sdk/credential-provider-process": "^3.972.50", "@aws-sdk/credential-provider-sso": "^3.972.56", "@aws-sdk/credential-provider-web-identity": "^3.972.56", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/credential-provider-imds": "^4.4.3", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-LkczBXaEsdManijlEZwbKfEoo1C98Yri3LHF8gQI7CYWv+uFkmpS3OZH3BSew8g1A2ppKsScdPUSlhI6NV7a9g=="],
"@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1078.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.1078.0", "@aws-sdk/core": "^3.974.26", "@aws-sdk/credential-provider-cognito-identity": "^3.972.51", "@aws-sdk/credential-provider-env": "^3.972.52", "@aws-sdk/credential-provider-http": "^3.972.54", "@aws-sdk/credential-provider-ini": "^3.972.59", "@aws-sdk/credential-provider-login": "^3.972.58", "@aws-sdk/credential-provider-node": "^3.972.61", "@aws-sdk/credential-provider-process": "^3.972.52", "@aws-sdk/credential-provider-sso": "^3.972.58", "@aws-sdk/credential-provider-web-identity": "^3.972.58", "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/credential-provider-imds": "^4.4.5", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-V9Tr3MrNWUfTGgTMIr+WJaMC/VDbXY57BzrGDuyDZn7+vgZjAEG6nI5nMdfnTGdvV9wq1n0zZPYW2RDfcsWNCw=="],
"@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.50", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-ARBEVkOQzmowTU0a35smGVyldJ9FN/f57XIGrPatrul4mYN+vvOKxoc1njDOX3nugVze+0sHzQZWJ8kPARAtUA=="],
"@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.26", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/signature-v4-multi-region": "^3.996.38", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/fetch-http-handler": "^5.6.2", "@smithy/node-http-handler": "^4.9.2", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-Lwe3F6K7bs+jEubp1LbrvzeMBYb5fMazJ1IxV9TtKWPF8CSh67Fmwyq9fLz3NL/k55Dfpuph5Dimw76JFgr+SA=="],
"@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.56", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/token-providers": "3.1076.0", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-LvbWiFcLI/D5RPaT68TrpLLHyv7x5X+dm59wJ5dFizyGPZggBC7OdgJTlP0X1bVjiSSAgE1u1oxxcBps0GCEnA=="],
"@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.38", "", { "dependencies": { "@aws-sdk/types": "^3.973.15", "@smithy/signature-v4": "^5.6.1", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-C379Sk+MiFZCfWZphKlMyLHKxV22OjoGM5KJjj5IJNJcOCWL4IGIpnEGzv1FQiRwhYXfq55SJMfxlqPE08JJ9g=="],
"@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.56", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-OV3JxmqMphVGMLWupYD2UhZxX07ATk1NwyYk7RgCnAEh0y3owHmtEnkWZ3ciCZ6liiFEwS8dYQpJGmKsR6ml4Q=="],
"@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1078.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.26", "@aws-sdk/nested-clients": "^3.997.26", "@aws-sdk/types": "^3.973.15", "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-/uyXLBGu3Lw1GbBA2X66hcOMnKtMcqAIF+3/eHfxBQmUeXF2sdqozDPrTfEr/TnSd0D6deZar+eVyhEqqWu29w=="],
"@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1076.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.1076.0", "@aws-sdk/core": "^3.974.24", "@aws-sdk/credential-provider-cognito-identity": "^3.972.49", "@aws-sdk/credential-provider-env": "^3.972.50", "@aws-sdk/credential-provider-http": "^3.972.52", "@aws-sdk/credential-provider-ini": "^3.972.57", "@aws-sdk/credential-provider-login": "^3.972.56", "@aws-sdk/credential-provider-node": "^3.972.59", "@aws-sdk/credential-provider-process": "^3.972.50", "@aws-sdk/credential-provider-sso": "^3.972.56", "@aws-sdk/credential-provider-web-identity": "^3.972.56", "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/credential-provider-imds": "^4.4.3", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-1jmzAXZdQzZKT/edDehSuxBfFo9M90nyLMGV65joOaZusa/p3YEPtPdHhTQ1CWoYq9kBBsMcfMElSbKjAfYTJw=="],
"@aws-sdk/types": ["@aws-sdk/types@3.973.15", "", { "dependencies": { "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-IULn8uBV/SMtmOIANsm4WHXIOtVPBWfOWs3WGL0j/sI+KhaYehvOw0ET+9urnn8MBpiijuU/0JOpuwKOE451PQ=="],
"@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.24", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.974.24", "@aws-sdk/signature-v4-multi-region": "^3.996.36", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/fetch-http-handler": "^5.6.0", "@smithy/node-http-handler": "^4.9.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-+wFVfVofxeiXdRhUjRwYISB2mVfBCdiCq1wThkRipTeOc10Kyr+LS9QJTjgZuhWsna7jyLMPndrCnzLGWWvZXg=="],
"@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.36", "", { "dependencies": { "@aws-sdk/types": "^3.973.14", "@smithy/signature-v4": "^5.5.3", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-VSOWIPkI+g3a7NkxIBCO24HnsR0BZXJAi3wrKaGIZwVKyrMtNRdHxPrQI/igazgla5J9FhDzmg4RgnOSr6UQBw=="],
"@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1076.0", "", { "dependencies": { "@aws-sdk/core": "^3.974.24", "@aws-sdk/nested-clients": "^3.997.24", "@aws-sdk/types": "^3.973.14", "@smithy/core": "^3.27.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-4rTHETRKe2JWAsFUMo5ENmlzc3i9FD4KqBVXgoaF8DLTADjGid8SA+1LR2nJWjefoafvKAHcQH9F2iKa8uHc6Q=="],
"@aws-sdk/types": ["@aws-sdk/types@3.973.14", "", { "dependencies": { "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-vH4pEu9YBEwr67yT+GVcmKX0GzfIrIYUn+MF5vXg9OspouVnAekuyVyawFvZHEK7WlcwVDwNrqI3ZBDUAiyu9A=="],
"@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.965.8", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g=="],
"@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.32", "", { "dependencies": { "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-2loKuOMRFDg1nwdni5AtJ9S5juVbRNPNsPC7tWTfkHyycPwACMhxepspUHi8GhvfNlL2cQo3sPMod1uib+KZ0w=="],
"@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.33", "", { "dependencies": { "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-ezbwz9WpuLctm6o7P2t2naDhVVPI5jFGrVefVybhcKGjU57VIyT46pQVO0RI2RYkUdhdj2Z9uSIlAzGZE9NW9A=="],
"@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.4", "", {}, "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ=="],
@@ -857,11 +847,11 @@
"@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
"@azure/msal-browser": ["@azure/msal-browser@5.15.0", "", { "dependencies": { "@azure/msal-common": "16.10.0" } }, "sha512-2NYT6v+eeQn8kmNddr9LnbXSvXbVELpmFMmfFvtRxD7I/5+5GlkMlncApeuRFj+mY6C9syOwQip1a0Y+TIbyiA=="],
"@azure/msal-browser": ["@azure/msal-browser@5.16.0", "", { "dependencies": { "@azure/msal-common": "16.11.0" } }, "sha512-Wc75FGnQgYpsm5jsOqn1H8AXsh8vXruA6vwip1nhjrJxwby7juxKAIVLr7csepmHiwdZGr6EwI5BlSc3PizEtQ=="],
"@azure/msal-common": ["@azure/msal-common@16.10.0", "", {}, "sha512-iYtjpanlv6963Jprs0MvzIap07V+QhultjQctfbEDQCflsDAEeO3R7XnVA5gk30fhoBFLdgJT7VqO0TGsEsN9w=="],
"@azure/msal-common": ["@azure/msal-common@16.11.0", "", {}, "sha512-UikJOtMwkFpZNzTH6Dqk8UTUPbow15zH3e0UjGYZy69lYENW/S05gMLhbxI2eonz66uALhIljvhsSMEb6+O30g=="],
"@azure/msal-node": ["@azure/msal-node@5.3.0", "", { "dependencies": { "@azure/msal-common": "16.10.0", "jsonwebtoken": "^9.0.0" } }, "sha512-fXtJX811pX8y8QlrQqBSH6+plvWyKZDI0IxkheAcyAw9OtcpXyFivmTC7eGUqutLWaDlKXuQ3yOESD4zAmkjHg=="],
"@azure/msal-node": ["@azure/msal-node@5.3.1", "", { "dependencies": { "@azure/msal-common": "16.11.0", "jsonwebtoken": "^9.0.0" } }, "sha512-sqqv3L1UOI4KDXonNtbxPYUgbSWVXqxvmmb6BUw9n4P/UXgG+cVur3dLWQN4Cz7qQ+UJROCCxMXlksm7gIq0Sw=="],
"@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="],
@@ -965,19 +955,19 @@
"@bufbuild/protobuf": ["@bufbuild/protobuf@2.12.1", "", {}, "sha512-BvAMfS6LrgZiryOAZ4pBYucu4wG/Ei/9o9DZ9akbREnMLbPJiom2i8b9C8IsKErQoiKqVhrerzt3kOT/RrzLHg=="],
"@chat-adapter/discord": ["@chat-adapter/discord@4.31.0", "", { "dependencies": { "@chat-adapter/shared": "4.31.0", "chat": "4.31.0", "discord-api-types": "^0.37.119", "discord-interactions": "^4.4.0", "discord.js": "^14.25.1" } }, "sha512-1dVw1+6ZBwdVh5ynLK9D+SyHdPWIBbiPmKRC+WhzDSddR8eySswcBiDUKaDMUaOmvJavPvibJLwWbohUSBiJww=="],
"@chat-adapter/discord": ["@chat-adapter/discord@4.32.0", "", { "dependencies": { "@chat-adapter/shared": "4.32.0", "chat": "4.32.0", "discord-api-types": "^0.37.119", "discord-interactions": "^4.4.0", "discord.js": "^14.25.1" } }, "sha512-npJGIv0jjhhupKdLSF6Di+64mJXFkwEDfx/DOlDn41x66KnJjx2QcqvkuPBpx557kSwWXLgwIq5KWx/rQ+tEPg=="],
"@chat-adapter/gchat": ["@chat-adapter/gchat@4.31.0", "", { "dependencies": { "@chat-adapter/shared": "4.31.0", "@googleapis/chat": "^44.6.0", "@googleapis/workspaceevents": "^9.1.0", "chat": "4.31.0" } }, "sha512-4g7k7rJjTJJmtkuAoU3uGp87zNlebhzP+IJcxd9YrfK83/kApB/El5PGtn2P2SF/x5fl+EkOR9r/hWmH1U7Iyg=="],
"@chat-adapter/gchat": ["@chat-adapter/gchat@4.32.0", "", { "dependencies": { "@chat-adapter/shared": "4.32.0", "@googleapis/chat": "^44.6.0", "@googleapis/workspaceevents": "^9.1.0", "chat": "4.32.0" } }, "sha512-QQRRpTmsIt1seYeZONalIurzpxJqHC1g8GEG+TJaCD5OamL65c4GTQJhRdA7FBgOZHEkvwT/TiKNwp4twK0cCA=="],
"@chat-adapter/linear": ["@chat-adapter/linear@4.31.0", "", { "dependencies": { "@chat-adapter/shared": "4.31.0", "@linear/sdk": "^76.0.0", "chat": "4.31.0" } }, "sha512-myEDw3LoSDaVCjLQ4nDNWK3XFTVa+asO3/78qRxEv76kl1izcYi0g0BhZvozdJgswkKeZC2AaLzvN8GEerKZPw=="],
"@chat-adapter/linear": ["@chat-adapter/linear@4.32.0", "", { "dependencies": { "@chat-adapter/shared": "4.32.0", "@linear/sdk": "^76.0.0", "chat": "4.32.0" } }, "sha512-ibOpeURIjpjxF2OyJ3hTYnVbT2oSKRbOUFhb+KJaw+YBUUHTXwcPCeUGhW+dLVBKOFiBZU3hO12eYbpXueQobA=="],
"@chat-adapter/shared": ["@chat-adapter/shared@4.31.0", "", { "dependencies": { "chat": "4.31.0" } }, "sha512-vT/0S/LKSU5QTz5xJNWdiGp1jl55x0o8Z9I2VqlHfwjOKxVR87z++bQjXlE99w6BAxZjSYhWErlveyKo4LiDGg=="],
"@chat-adapter/shared": ["@chat-adapter/shared@4.32.0", "", { "dependencies": { "chat": "4.32.0" } }, "sha512-ANXYe2dbSmr9A+yUAnV8TfFht4GM6f3zR5LnAYtQdNnRI9CJfXIUXuhRaVBe5RD8IEgGXyGi4BKj5qdjBtUumA=="],
"@chat-adapter/slack": ["@chat-adapter/slack@4.31.0", "", { "dependencies": { "@chat-adapter/shared": "4.31.0", "@slack/socket-mode": "^2.0.5", "@slack/web-api": "^7.14.0", "chat": "4.31.0" } }, "sha512-b+nUizoTQac0gNEaZ+F4XAYcFtynXufpGUYMkeSwfiD9najoQEKXpvZya8PgqX1Ddn3SPddeJ/ip+RS2oQuBLA=="],
"@chat-adapter/slack": ["@chat-adapter/slack@4.32.0", "", { "dependencies": { "@chat-adapter/shared": "4.32.0", "@slack/socket-mode": "^2.0.5", "@slack/web-api": "^7.14.0", "chat": "4.32.0" } }, "sha512-QZ7KYV8K1w5O91JzMuz5qTCpUaWfEgcxr/UFrBKSp30ZdaHbLH7BqOXHYLoFVwFnoEwKpInCgCgpEl36IU9ffQ=="],
"@chat-adapter/telegram": ["@chat-adapter/telegram@4.31.0", "", { "dependencies": { "@chat-adapter/shared": "4.31.0", "chat": "4.31.0" } }, "sha512-kwhPKkhhRzt82XTunCD1cROkJOo+c1cpOEzSXT3RX6BIcVwqikh6k7qTSPG6gmBPiouMbNnvzgnQYFgA7FZJPw=="],
"@chat-adapter/telegram": ["@chat-adapter/telegram@4.32.0", "", { "dependencies": { "@chat-adapter/shared": "4.32.0", "chat": "4.32.0" } }, "sha512-3QzXYJsT3vJMAP0KDrhSyppJ5bKo243ruytgCPyjqJ2J705J6Wy+KLD41b24hp6swYhpNGH1s5xOHpvPbNg/0g=="],
"@chat-adapter/whatsapp": ["@chat-adapter/whatsapp@4.31.0", "", { "dependencies": { "@chat-adapter/shared": "4.31.0", "chat": "4.31.0" } }, "sha512-aDLs2N1rVtci6CZ4dc2bSglBU1+QytPnMmKIVxy6W9fN/vPvv7tKbiCDNY6g5HIiixqU7QizHQ0Zbd4LOImJ0w=="],
"@chat-adapter/whatsapp": ["@chat-adapter/whatsapp@4.32.0", "", { "dependencies": { "@chat-adapter/shared": "4.32.0", "chat": "4.32.0" } }, "sha512-n3MbH4aSYpAk4mFKjuAvva4yJH94n1WA+47xNOHu7TLgoIPt1i96DOsERXCpiKqGlC/Nc+1/04DgYGzSTj6WWQ=="],
"@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="],
@@ -1661,7 +1651,7 @@
"@openai/codex-win32-x64": ["@openai/codex@0.130.0-win32-x64", "", { "os": "win32", "cpu": "x64" }, "sha512-FzMznm7fr5/nbjZgOujZ9Y9AbdGm7ji1FOoWiY3U+srqauvZaTgn6o6aCheSL7kuymu7nTLOO/cAyWV6NuesqQ=="],
"@opencode-ai/sdk": ["@opencode-ai/sdk@1.17.11", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-UdSwnNM4/cD5rHnI8O7VaHuiwYnsEOglpRPVeeYE2S5Nm1K34ijCyZGDvBecb0ShdBQgn49XvyQWJH6cREsIPw=="],
"@opencode-ai/sdk": ["@opencode-ai/sdk@1.17.13", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-VItOGjMzRQx3zypwmeFLNhCiIx32kxS7FqzIJvVZLfyNGCifs3rfGC9qzNKWcxQo4SjNvAw++v4gWWU6Inv+JQ=="],
"@opentelemetry/api": ["@opentelemetry/api@1.9.1", "", {}, "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q=="],
@@ -1739,7 +1729,7 @@
"@opentui/react": ["@opentui/react@0.1.102", "", { "dependencies": { "@opentui/core": "0.1.102", "react-reconciler": "^0.32.0" }, "peerDependencies": { "react": ">=19.0.0", "react-devtools-core": "^7.0.1", "ws": "^8.18.0" } }, "sha512-c7EiK30xlvaHc6WBOLAH7TJ8xC4QbiD5ZA6tb4zZ74XM4SH5Tb+uBee8b4TztTLseq+hGtW85qrIUJM3OrdtNw=="],
"@oxc-project/types": ["@oxc-project/types@0.137.0", "", {}, "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA=="],
"@oxc-project/types": ["@oxc-project/types@0.138.0", "", {}, "sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA=="],
"@paper-design/shaders": ["@paper-design/shaders@0.0.46", "", {}, "sha512-ErPQwLguvv7qI8E+bdwSaNQF27Q8MnZmtD8rGp+K473AYee+cXWv2OqBkKnuMl/n1JmL8vBxSSTflOfO6DB4aQ=="],
@@ -1751,7 +1741,7 @@
"@playwright/test": ["@playwright/test@1.61.1", "", { "dependencies": { "playwright": "1.61.1" }, "bin": { "playwright": "cli.js" } }, "sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig=="],
"@posthog/core": ["@posthog/core@1.38.1", "", { "dependencies": { "@posthog/types": "^1.392.0" } }, "sha512-tsJTugsKzx47eRMjNfG272/GFf0FF0LeI+gyJ/anibpbYAzdNuX5kr6enpmJrhdgLESqzJGH8QF0+I9075Xr1Q=="],
"@posthog/core": ["@posthog/core@1.39.3", "", { "dependencies": { "@posthog/types": "^1.392.0" } }, "sha512-oR+B8Q5O61N+W2+HVOBG9dbxAT/+OVxX+XvpNj6KYgptN2EB14JiKQ9Rm7DNpErNTLV7WApZEK/URkZgldOxfg=="],
"@posthog/types": ["@posthog/types@1.392.0", "", {}, "sha512-nctNujXL3FC1v99FktaTMSugSD9ZOZekEpahUSafkU2TSvW+XGKNkQZbokuJtiWvPBK208dwMJva8UfBkChqpw=="],
@@ -1781,13 +1771,13 @@
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
"@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.10", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TraSwZUqTcVbiDV2/RXzAXC7aeVVXchq0daPFZE7zAxYFaMzjOUggLOfQH9KFLgRizuwVKZO/crveV1eeO3/ZQ=="],
"@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.11", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-HQDOFTKwSnmUij6l54wYJJtxTAnxI71+YJLOrjm2ladFB8HAV5Jt7hwaZPhWTGBkYoW4+ZAOfNZrLDh/qvxSYA=="],
"@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA=="],
"@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
"@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.10", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-j2VTDz1vgCsmuG0k5lBfOcM8n5JPFqZBcMryasFjHYMhwxYL5SRUV5lMSUpRdNtw3D/Sv8pzJtrlAgkssYSsQQ=="],
"@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Kdil9BB1rIFC/khmf4hC35bn8701AJcizTU7G7cUbEbk5XqqbjDuHW60uUfKqO5WojjZcbAW51Q7P0hRmMLw8A=="],
"@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5nZrJTF7gH+e0nZS7/QxFz6tJV4VimhQb1avEgtsJxvvIp5JilL+c58HICsKzPxghdwaDt48hEfPM1au4zGy+w=="],
@@ -1817,7 +1807,7 @@
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
"@radix-ui/react-form": ["@radix-ui/react-form@0.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-label": "2.1.10", "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1NfuvctVtX4sU3Mmq/IdrR8UunxiCMiVg3A5UENKhFzxUBeOyaQQ+lmaQaV7Tc8cqvBKsJL3/KGBsixK0D8WFg=="],
"@radix-ui/react-form": ["@radix-ui/react-form@0.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-label": "2.1.11", "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0mTMJHv1gQAuEQoq5VDpTD3MRgmfUFdXAVFhpqR7wBeUr+tyRsof0wv/4XdPHLwQrefhoH2FiGHCggrCJhalIw=="],
"@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="],
@@ -1831,9 +1821,9 @@
"@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="],
"@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.10", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-GHkcJ+WVj91At+OvUVTD4R3W0/wxw9t/sG5xFUBYXaCbtWiooZX5Md376QjJqgH4VsVyXrbVNHO2O4NYcmjfVg=="],
"@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.11", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Rsgab65u73E5kPVh8OS6PgPwJgPyf08GFfJDGAbMdF4DL7CgDhFOaDnXuk/DiMEVF6kgQwl0oJmFklvipmiOLg=="],
"@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.5", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fVuA82u0b/fClpbEJv8yp1nU9eSvoSEOERsU/hhf3FXGPIvkmE7oEaHEu8poowoXO39/Va7zq2E0TUcYr1dBRg=="],
"@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pQ3xGp/uemomASPH97Eb3shfXX8QlG11bBJyEvRBV+vwtO4HvQlS06Yj9f31Ao7XepvF98SFrRgVDQ7jv+2xjQ=="],
"@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="],
@@ -1871,7 +1861,7 @@
"@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="],
"@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-separator": "1.1.10", "@radix-ui/react-toggle-group": "1.1.13" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Za1l4f6fzTkGgz/iynAMN8iaqiKff2wm2/QwiLmHPtDQreWEBrvSimgQFIekxMUdRPhILM7xdIXxuS/o/DGZag=="],
"@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-separator": "1.1.11", "@radix-ui/react-toggle-group": "1.1.14" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-L/EkWVqlnj3lL2toHh4C7PwH2jxfa7OCq6lGfXSCii99ve2S4Ux5rc9HnOa7LN9exHa/Nl9kmCAmP9BuDPy5UA=="],
"@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="],
@@ -1881,7 +1871,7 @@
"@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.3", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA=="],
"@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.2", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw=="],
"@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.3", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-3wEkMiPHXha/2VadZ68rYBcmYnPINVGl4Y3gtcM7fKRjANk0OscK+cdqBgUWdozb7YJxsh0vefM7vgAMHXOjqg=="],
"@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="],
@@ -2075,39 +2065,39 @@
"@react-types/tooltip": ["@react-types/tooltip@3.5.2", "", { "dependencies": { "@react-types/overlays": "^3.9.4", "@react-types/shared": "^3.33.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-FvSuZ2WP08NEWefrpCdBYpEEZh/5TvqvGjq0wqGzWg2OPwpc14HjD8aE7I3MOuylXkD4MSlMjl7J4DlvlcCs3Q=="],
"@rive-app/react-webgl2": ["@rive-app/react-webgl2@4.29.3", "", { "dependencies": { "@rive-app/webgl2": "2.38.3" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0" } }, "sha512-NotopuJ2FEM/th6t3kTN9aZB35xKeyqW68UXBy2ybPirysbLqn2yrGTP7IXoouG0MmRiGqFm+Ufbhk7LrkTc7g=="],
"@rive-app/react-webgl2": ["@rive-app/react-webgl2@4.29.4", "", { "dependencies": { "@rive-app/webgl2": "2.38.4" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0" } }, "sha512-eYGfsgwHnl1br8HbqoL34HbnH0TODEZuxmHYFhe32OTOwaOYI6ACifao/1dIFW/yUg+Jtt9CIIM8Scg+x+0cCQ=="],
"@rive-app/webgl2": ["@rive-app/webgl2@2.38.3", "", {}, "sha512-/bbhfV8fel3yPuOWBnqRlNjVa0j4B0Rm4t5VAQqIvNRHJrz9jzQ/gJx93X6IpQovgD57Gb+Jnwp6WPHFgX3eGA=="],
"@rive-app/webgl2": ["@rive-app/webgl2@2.38.4", "", {}, "sha512-/DitPRRNRHWgg6jB28dsH8vZyNHU2dorcOARCVkeEVGwSp/fthng+wwdtqUj/EnarnWKRVI3kr0lFjWorq85PQ=="],
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.3", "", { "os": "android", "cpu": "arm64" }, "sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g=="],
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.4", "", { "os": "android", "cpu": "arm64" }, "sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw=="],
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw=="],
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ=="],
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw=="],
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg=="],
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw=="],
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ=="],
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.3", "", { "os": "linux", "cpu": "arm" }, "sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg=="],
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.4", "", { "os": "linux", "cpu": "arm" }, "sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA=="],
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA=="],
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w=="],
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w=="],
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng=="],
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw=="],
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg=="],
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA=="],
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ=="],
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.3", "", { "os": "linux", "cpu": "x64" }, "sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg=="],
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw=="],
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.3", "", { "os": "linux", "cpu": "x64" }, "sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g=="],
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ=="],
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.3", "", { "os": "none", "cpu": "arm64" }, "sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ=="],
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.4", "", { "os": "none", "cpu": "arm64" }, "sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA=="],
"@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.3", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg=="],
"@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.4", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg=="],
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g=="],
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA=="],
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.3", "", { "os": "win32", "cpu": "x64" }, "sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA=="],
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.4", "", { "os": "win32", "cpu": "x64" }, "sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ=="],
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="],
@@ -2185,7 +2175,7 @@
"@sap/xsenv": ["@sap/xsenv@6.2.1", "", { "dependencies": { "debug": "4.4.3", "node-cache": "^5.1.2", "verror": "1.10.1" } }, "sha512-R1p7VdD3N3jvdkL8av4vLqF+cTQihTz9mCqqF+oa9rVZvgLaCb4ODyZ1dln5/fBgg1OSuch0ESxu3AqZrXVknw=="],
"@sap/xssec": ["@sap/xssec@4.13.0", "", { "dependencies": { "debug": "^4.4.3", "jwt-decode": "^4" } }, "sha512-8e+bU+OyAIpAGXQanOopZa5YEK+yHKw84dhhihcCotF40MSNFbVHjQ4xM5hf4QndlqDGfXIuvXmoOMuDATa/gA=="],
"@sap/xssec": ["@sap/xssec@4.13.1", "", { "dependencies": { "debug": "^4.4.3", "jwt-decode": "^4" } }, "sha512-sZwTvxO7Vh5qjrSXHgb0fTJEPz14kYPzScn4GI5kZYGb97fZ4X5IE90mlafjZeJFfQkBCCIzVWfrbweCpBbPyQ=="],
"@sapphire/async-queue": ["@sapphire/async-queue@1.5.5", "", {}, "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg=="],
@@ -2255,27 +2245,23 @@
"@slack/types": ["@slack/types@2.21.1", "", {}, "sha512-I8vmSjNYWsaxuWPx6dz4yeh0h7vRBWbgAMK14LEmblbZ404BtrPbXs6jDPx4cYgGf8msDGF4A9opLZBu21FViQ=="],
"@slack/web-api": ["@slack/web-api@7.17.0", "", { "dependencies": { "@slack/logger": "^4.0.1", "@slack/types": "^2.21.0", "@types/node": ">=18", "@types/retry": "0.12.0", "axios": "^1.16.0", "eventemitter3": "^5.0.1", "form-data": "^4.0.4", "is-electron": "2.2.2", "is-stream": "^2", "p-queue": "^6", "p-retry": "^4", "retry": "^0.13.1" } }, "sha512-jejr34a8B4L5AS713wOAx1LAqNkW16HVMDEa6sYBvFDc/llUBl8hXaiI4BwF+Al+Sug19Vn2O7iokTVIhVvZ1Q=="],
"@slack/web-api": ["@slack/web-api@7.18.0", "", { "dependencies": { "@slack/logger": "^4.0.1", "@slack/types": "^2.21.0", "@types/node": ">=18", "@types/retry": "0.12.0", "axios": "^1.16.0", "eventemitter3": "^5.0.1", "form-data": "^4.0.4", "is-electron": "2.2.2", "is-stream": "^2", "p-queue": "^6", "p-retry": "^4", "retry": "^0.13.1" } }, "sha512-EWBsKUhOFFp87beQg/ToSC+asWB7BrGHuh7uPC1ZI9vr41GjS+3WmmyWIMqs+mF6U+mh4d6HhtFlv67TrJFsvw=="],
"@smithy/core": ["@smithy/core@3.28.0", "", { "dependencies": { "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-N/LoLG8pZ1zv5cIWpdF6vmSjtZtXKK9G0OqT5yYCOZU+CzPq1+nYA95VoKJBGWRScs7YbMugZ7lZx8Fj1vdHoA=="],
"@smithy/core": ["@smithy/core@3.29.0", "", { "dependencies": { "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-sEvpvkBVoMxjoek35XyJFn2ZD3EJ1RpiZrT47WaZodxzAIWS44zkdvbqGE/ZlugtjiQp62cffYZ9ldyRkjAGnA=="],
"@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.4.4", "", { "dependencies": { "@smithy/core": "^3.28.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-jT0WrDaM88L5na9FX1xRNywCS3B1n75wPY5Ksasjo0PHUtuI7d8FclksN1BbOSYTiaiKxUDqU23nUymH/V+AaQ=="],
"@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.4.5", "", { "dependencies": { "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-LnjUTNG0GgQlKIq7IioeOrPaEmC5xOd1WtAz24TLSiYQnWX2uHr53GrFuQhkrJBktPYCMga/NbUOW7hFbSA2Cg=="],
"@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.4.4", "", { "dependencies": { "@smithy/core": "^3.28.0", "tslib": "^2.6.2" } }, "sha512-DStvMemWlcZRXkP9XdCsinolM6yZd4fL2NiQItC8n/I+JC6utkLr0Dc+wLjLqjPyAJR1zXt7inSflea217yGlw=="],
"@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.4.5", "", { "dependencies": { "@smithy/core": "^3.29.0", "tslib": "^2.6.2" } }, "sha512-rasV+96Obv6tEhWPKWaehEhR+MEd2/lE/rdOYcmSMh6tJiQdoZg4v21p37Y1A7DMZOFgFDUX/3eNl/J3+MJDdA=="],
"@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.6.1", "", { "dependencies": { "@smithy/core": "^3.28.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-fW6l9rWoyk1iyzfuZaERnZLNjB6WIojgGm6Bo9Hpfpy3RUpltjLikNlxTsS/YtxVobcfbCGBuAncREYqT4hvqQ=="],
"@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.6.2", "", { "dependencies": { "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-q96PSDOAGw+X+nuELd7Cjebps0SYr+YlPbviEX9sLVw+VM4M7VV8hn1nL1mGS6urDu33eQ5A7WhlphaDO6kUyQ=="],
"@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
"@smithy/node-http-handler": ["@smithy/node-http-handler@4.9.2", "", { "dependencies": { "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-s0yAIRj6TVfHgl+QzVyqal1KMGZ9B5512IrxKc6+dOpw8fUmFL3CvuAhjv0J+aNjUPfVZ2IhqPEDvkB5Ncx9oA=="],
"@smithy/node-http-handler": ["@smithy/node-http-handler@4.9.1", "", { "dependencies": { "@smithy/core": "^3.28.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-m/f15di58P6NtLQ7eVEb5N19NdJWn+4c7zfkFHMT/i3JH7U8UtknpPoy8o2tm2R3OdliYvsvQhZHIfACQDqT+Q=="],
"@smithy/signature-v4": ["@smithy/signature-v4@5.6.1", "", { "dependencies": { "@smithy/core": "^3.29.0", "@smithy/types": "^4.15.1", "tslib": "^2.6.2" } }, "sha512-SqvuP75p/DmgWWI7jv4kf/UW+V4LFmlUn19s604SgAcRuJRB1vDnWwzZMYCLUcmKxko9wDn6iLgGEIpTNgZbIQ=="],
"@smithy/signature-v4": ["@smithy/signature-v4@5.6.0", "", { "dependencies": { "@smithy/core": "^3.28.0", "@smithy/types": "^4.15.0", "tslib": "^2.6.2" } }, "sha512-IkPHQdbyoebSwBCuMTzJ/2oIhKVqiZZAZxQYSlpDZqq/WhJUpmdgbHvP7ItddxsPzcDUJeI0V4PNMSNtlZ0aqA=="],
"@smithy/types": ["@smithy/types@4.15.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-x3L0XSACF6UYzKpa9biqiRMgvH5+wnFFew9Tm/grFYqgaupPwx/+ojDPpPJM8dZON3S9tjz5U+PQYsCBd1Mw5Q=="],
"@smithy/types": ["@smithy/types@4.15.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Z5TAOxygoFvybJV3igo5SloFflSokHx2hu1eFA+DxDTcn+FtKxUSui+rbTRG1pAafMA888Z3MVvCWUuvCrTXjg=="],
"@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="],
"@smithy/util-utf8": ["@smithy/util-utf8@4.4.4", "", { "dependencies": { "@smithy/core": "^3.28.0", "tslib": "^2.6.2" } }, "sha512-kvxCWygmILHgwuIQKxocTHblTsF1eWLF/rBN5qjY7QmHfIglcqJoe/p9mo7uOR/dA+h3eVZVLZcmscxp+WtDCA=="],
"@smithy/util-utf8": ["@smithy/util-utf8@4.4.5", "", { "dependencies": { "@smithy/core": "^3.29.0", "tslib": "^2.6.2" } }, "sha512-ZS7Y5X8mU9qRSsqwOeGKw86WWtPsRxa396kX2HyhYwADRqFHJ0cb3p2uFk6QnFF3BluUUBHTZJpPA9QuEl0tlg=="],
"@so-ric/colorspace": ["@so-ric/colorspace@1.1.6", "", { "dependencies": { "color": "^5.0.2", "text-hex": "1.0.x" } }, "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw=="],
@@ -2737,7 +2723,7 @@
"agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="],
"ai": ["ai@6.0.216", "", { "dependencies": { "@ai-sdk/gateway": "3.0.140", "@ai-sdk/provider": "3.0.12", "@ai-sdk/provider-utils": "4.0.33", "@opentelemetry/api": "^1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-K6/H1H6b+IJuz79Nc44A/tEPzAH+dUCmQhHtP2In943OxvLekosVYBwUUsr1oQjc/JvN8WRpL1mLuefUBHxs/w=="],
"ai": ["ai@6.0.218", "", { "dependencies": { "@ai-sdk/gateway": "3.0.142", "@ai-sdk/provider": "3.0.13", "@ai-sdk/provider-utils": "4.0.35", "@opentelemetry/api": "^1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-HsyCUNaaYgX/b/kGOoYfKkqfT1HvpUKKDb8YkN1FKeCNZjKdqXLGY+cKBpYGIRAvsPuOHskxLxZ46cK1dTBWQQ=="],
"ai-sdk-provider-claude-code": ["ai-sdk-provider-claude-code@3.5.0", "", { "dependencies": { "@ai-sdk/provider": "^3.0.0", "@ai-sdk/provider-utils": "^4.0.1", "@anthropic-ai/claude-agent-sdk": "^0.3.170" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-7SZrTGkuR4G4zeNrjnJgDzYkrKZqzq7GUQJcFBKCxFH5dJpS9lbs+g9BCt7bwT1gDm4SAUmOQ0T5rKqcC2HkVQ=="],
@@ -2915,7 +2901,7 @@
"camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="],
"caniuse-lite": ["caniuse-lite@1.0.30001799", "", {}, "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw=="],
"caniuse-lite": ["caniuse-lite@1.0.30001800", "", {}, "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA=="],
"case-anything": ["case-anything@2.1.13", "", {}, "sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng=="],
@@ -2939,7 +2925,7 @@
"chardet": ["chardet@2.2.0", "", {}, "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA=="],
"chat": ["chat@4.31.0", "", { "dependencies": { "@workflow/serde": "4.1.0-beta.2", "mdast-util-to-string": "^4.0.0", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "remend": "^1.2.1", "unified": "^11.0.5" }, "peerDependencies": { "ai": "^6.0.182", "zod": "^3.0.0 || ^4.0.0" }, "optionalPeers": ["ai", "zod"] }, "sha512-F6oJq9JUraLFkITS96/NKgwZwBfZX8aOwOj5qMs5NNwnOGHrSXZ5+osK+EA4HjzfyUEDfFTNiOSmyzgtFLpuWg=="],
"chat": ["chat@4.32.0", "", { "dependencies": { "@workflow/serde": "4.1.0-beta.2", "mdast-util-to-string": "^4.0.0", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "remend": "^1.2.1", "unified": "^11.0.5" }, "peerDependencies": { "ai": "^6.0.182", "zod": "^3.0.0 || ^4.0.0" }, "optionalPeers": ["ai", "zod"] }, "sha512-0NlJcCLycTy8kytRsZEnW4Gzomm+SNh1Yg7y9GVYB5fTjyhOxCcnzqrythgXNn2dvv7VeihDIISpNU0WZdOKKg=="],
"check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="],
@@ -3257,7 +3243,7 @@
"eight-colors": ["eight-colors@1.3.3", "", {}, "sha512-4B54S2Qi4pJjeHmCbDIsveQZWQ/TSSQng4ixYJ9/SYHHpeS5nYK0pzcHvWzWUfRsvJQjwoIENhAwqg59thQceg=="],
"electron-to-chromium": ["electron-to-chromium@1.5.381", "", {}, "sha512-n9Wa6yB+vDsGuA8AKbl/0z7HbvWqt5jxIdvr1IUicd0ryPrk7/xzwqLv8D9AbbvZ6avVNtXYLTfmgFHkwkyelg=="],
"electron-to-chromium": ["electron-to-chromium@1.5.384", "", {}, "sha512-g6KAKY1vkYsADvSPWvdJsuYT0ixdcu6lUtD9P/wJKGBEDlZVXh2AX42j1mPqqaQPDluWjara9ziQ7xqAeXCt5A=="],
"embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="],
@@ -3293,7 +3279,7 @@
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-module-lexer": ["es-module-lexer@2.2.0", "", {}, "sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ=="],
"es-module-lexer": ["es-module-lexer@2.3.0", "", {}, "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw=="],
"es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="],
@@ -3463,7 +3449,7 @@
"fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
"framer-motion": ["framer-motion@12.42.0", "", { "dependencies": { "motion-dom": "^12.42.0", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-wp7EJnfWaaEScVygKv3e20udoRz+LbtxScsuTkakAxfXmt+ReC6WyPW2nINRAGvd+hG9odwcjBLyOTPjH5pBRA=="],
"framer-motion": ["framer-motion@12.42.2", "", { "dependencies": { "motion-dom": "^12.42.2", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw=="],
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
@@ -3967,7 +3953,7 @@
"mammoth": ["mammoth@1.12.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.6", "argparse": "~1.0.3", "base64-js": "^1.5.1", "bluebird": "~3.4.0", "dingbat-to-unicode": "^1.0.1", "jszip": "^3.7.1", "lop": "^0.4.2", "path-is-absolute": "^1.0.0", "underscore": "^1.13.1", "xmlbuilder": "^10.0.0" }, "bin": { "mammoth": "bin/mammoth" } }, "sha512-cwnK1RIcRdDMi2HRx2EXGYlxqIEh0Oo3bLhorgnsVJi2UkbX1+jKxuBNR9PC5+JaX7EkmJxFPmo6mjLpqShI2w=="],
"markdown-it": ["markdown-it@14.2.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", "linkify-it": "^5.0.1", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ=="],
"markdown-it": ["markdown-it@14.3.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.5.0", "linkify-it": "^5.0.2", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw=="],
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
@@ -4129,9 +4115,9 @@
"module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="],
"motion": ["motion@12.42.0", "", { "dependencies": { "framer-motion": "^12.42.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Qhwvu9sVl5/URSq5CNzwMCpSKK8Uhnrwb6VO977kZyj/wOCS7mWebJUnBoHx5cZU1Zv8a9BD5CSICWKAlrLJgA=="],
"motion": ["motion@12.42.2", "", { "dependencies": { "framer-motion": "^12.42.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q=="],
"motion-dom": ["motion-dom@12.42.0", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-M63h4n8R+quJdNhBwuLlgxM+OLYa9+I/T2pzDRboB9fLXRdbou+Gw7Zury+SkpaCyACP1JHSjHgZ1EgTkBr30w=="],
"motion-dom": ["motion-dom@12.42.2", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA=="],
"motion-utils": ["motion-utils@12.39.0", "", {}, "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ=="],
@@ -4159,7 +4145,7 @@
"nice-grpc-common": ["nice-grpc-common@2.0.3", "", { "dependencies": { "ts-error": "^1.0.6" } }, "sha512-MEhnD3JMah0mgyivpb9hpRDbOBuXBxI/TVO+OK1h6rC97WM42HsPMR+zzRNQ0C5BqYJTw1nyWiQRD0DucO+pjQ=="],
"node-abi": ["node-abi@3.92.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ=="],
"node-abi": ["node-abi@3.93.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-Cu6yUpX5Iavugm8BeX7c0wgU9CvOqfd1yM6A1d2q2ZMjym7GjpASv2GdRcTq3Fx+Sb5OgBkEEpw4VnAbY6Y5RA=="],
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
@@ -4265,7 +4251,7 @@
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
"package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
"package-manager-detector": ["package-manager-detector@1.7.0", "", {}, "sha512-xg1eHpwYL/D/HEdWw2goFZP6vV0FH7W+PZ5rFkGjdIDLtxq7EkzBUeT3m+lndYCt8wKbmofUu1MUdMCXkCk9ZQ=="],
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
@@ -4357,9 +4343,9 @@
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
"posthog-js": ["posthog-js@1.396.2", "", { "dependencies": { "@posthog/core": "^1.38.1", "@posthog/types": "^1.392.0", "core-js": "^3.38.1", "dompurify": "^3.3.2", "fflate": "^0.4.8", "preact": "^10.29.2", "query-selector-shadow-dom": "^1.0.1", "web-vitals": "^5.3.0" } }, "sha512-WFdS0JL+r/M7A9XQwIGbw1Xn6W7/V5TEmv1wgrq7GFcPxZ0I3TktNGtGQNmzARbI8nKedAHFkY9UPDDg+NTSQg=="],
"posthog-js": ["posthog-js@1.396.4", "", { "dependencies": { "@posthog/core": "^1.39.3", "@posthog/types": "^1.392.0", "core-js": "^3.38.1", "dompurify": "^3.3.2", "fflate": "^0.4.8", "preact": "^10.29.2", "query-selector-shadow-dom": "^1.0.1", "web-vitals": "^5.3.0" } }, "sha512-PycBmwKQD1T7YFYrGRb8rjQET/UVnexgUy8gVe6UBEhwHXEIhZF4na5VakJbn4zu1wg4tzjt8r7PA4VLu6bDjg=="],
"posthog-node": ["posthog-node@5.38.8", "", { "dependencies": { "@posthog/core": "^1.38.1" }, "peerDependencies": { "rxjs": "^7.0.0" }, "optionalPeers": ["rxjs"] }, "sha512-AWsp9Tigf4iZepabPErAt/2sLTGwJ7w6631JP+3ifDqWzaBPyzcukD7cTPeoNDKGwJreQ69Ju4l53n9g2+X6nQ=="],
"posthog-node": ["posthog-node@5.39.2", "", { "dependencies": { "@posthog/core": "^1.39.3" }, "peerDependencies": { "rxjs": "^7.0.0" }, "optionalPeers": ["rxjs"] }, "sha512-5piMedjlQ2x+UKLvHWTC5ls5/T1dDZKE1Pu5AKkYh9EkbZOjvu0cac6lWFB7mgbGkKQ0I1bhbjDx1QAYRJ7Unw=="],
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
@@ -4419,7 +4405,7 @@
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
"radix-ui": ["radix-ui@1.6.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-accessible-icon": "1.1.10", "@radix-ui/react-accordion": "1.2.14", "@radix-ui/react-alert-dialog": "1.1.17", "@radix-ui/react-arrow": "1.1.10", "@radix-ui/react-aspect-ratio": "1.1.10", "@radix-ui/react-avatar": "1.2.0", "@radix-ui/react-checkbox": "1.3.5", "@radix-ui/react-collapsible": "1.1.14", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-context-menu": "2.3.1", "@radix-ui/react-dialog": "1.1.17", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-dropdown-menu": "2.1.18", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-form": "0.1.10", "@radix-ui/react-hover-card": "1.1.17", "@radix-ui/react-label": "2.1.10", "@radix-ui/react-menu": "2.1.18", "@radix-ui/react-menubar": "1.1.18", "@radix-ui/react-navigation-menu": "1.2.16", "@radix-ui/react-one-time-password-field": "0.1.10", "@radix-ui/react-password-toggle-field": "0.1.5", "@radix-ui/react-popover": "1.1.17", "@radix-ui/react-popper": "1.3.1", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-progress": "1.1.10", "@radix-ui/react-radio-group": "1.4.1", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-scroll-area": "1.2.12", "@radix-ui/react-select": "2.3.1", "@radix-ui/react-separator": "1.1.10", "@radix-ui/react-slider": "1.4.1", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-switch": "1.3.1", "@radix-ui/react-tabs": "1.1.15", "@radix-ui/react-toast": "1.2.17", "@radix-ui/react-toggle": "1.1.12", "@radix-ui/react-toggle-group": "1.1.13", "@radix-ui/react-toolbar": "1.1.13", "@radix-ui/react-tooltip": "1.2.10", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-escape-keydown": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-EUEC70O03EgxWMP5aoqfBZ6iLC5bczFagGy7zhSYRt8o5DP7IWNiP3ywetse3L9b8843ExB0OGWZvgbYVJuNeg=="],
"radix-ui": ["radix-ui@1.6.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-accessible-icon": "1.1.11", "@radix-ui/react-accordion": "1.2.15", "@radix-ui/react-alert-dialog": "1.1.18", "@radix-ui/react-arrow": "1.1.11", "@radix-ui/react-aspect-ratio": "1.1.11", "@radix-ui/react-avatar": "1.2.1", "@radix-ui/react-checkbox": "1.3.6", "@radix-ui/react-collapsible": "1.1.15", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-context-menu": "2.3.2", "@radix-ui/react-dialog": "1.1.18", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-dropdown-menu": "2.1.19", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-form": "0.1.11", "@radix-ui/react-hover-card": "1.1.18", "@radix-ui/react-label": "2.1.11", "@radix-ui/react-menu": "2.1.19", "@radix-ui/react-menubar": "1.1.19", "@radix-ui/react-navigation-menu": "1.2.17", "@radix-ui/react-one-time-password-field": "0.1.11", "@radix-ui/react-password-toggle-field": "0.1.6", "@radix-ui/react-popover": "1.1.18", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-progress": "1.1.11", "@radix-ui/react-radio-group": "1.4.2", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-scroll-area": "1.2.13", "@radix-ui/react-select": "2.3.2", "@radix-ui/react-separator": "1.1.11", "@radix-ui/react-slider": "1.4.2", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-switch": "1.3.2", "@radix-ui/react-tabs": "1.1.16", "@radix-ui/react-toast": "1.2.18", "@radix-ui/react-toggle": "1.1.13", "@radix-ui/react-toggle-group": "1.1.14", "@radix-ui/react-toolbar": "1.1.14", "@radix-ui/react-tooltip": "1.2.11", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-escape-keydown": "1.1.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-QXDXJtB6sK83mLASONYUZCauatcWb+knFviFpN1EhtdbbmlsRmzCLrbZSKztnNiem2KOHIBbiDbauVB7SORXMw=="],
"range-parser": ["range-parser@1.3.0", "", {}, "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw=="],
@@ -4573,7 +4559,7 @@
"robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="],
"rolldown": ["rolldown@1.1.3", "", { "dependencies": { "@oxc-project/types": "=0.137.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.3", "@rolldown/binding-darwin-arm64": "1.1.3", "@rolldown/binding-darwin-x64": "1.1.3", "@rolldown/binding-freebsd-x64": "1.1.3", "@rolldown/binding-linux-arm-gnueabihf": "1.1.3", "@rolldown/binding-linux-arm64-gnu": "1.1.3", "@rolldown/binding-linux-arm64-musl": "1.1.3", "@rolldown/binding-linux-ppc64-gnu": "1.1.3", "@rolldown/binding-linux-s390x-gnu": "1.1.3", "@rolldown/binding-linux-x64-gnu": "1.1.3", "@rolldown/binding-linux-x64-musl": "1.1.3", "@rolldown/binding-openharmony-arm64": "1.1.3", "@rolldown/binding-wasm32-wasi": "1.1.3", "@rolldown/binding-win32-arm64-msvc": "1.1.3", "@rolldown/binding-win32-x64-msvc": "1.1.3" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g=="],
"rolldown": ["rolldown@1.1.4", "", { "dependencies": { "@oxc-project/types": "=0.138.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.4", "@rolldown/binding-darwin-arm64": "1.1.4", "@rolldown/binding-darwin-x64": "1.1.4", "@rolldown/binding-freebsd-x64": "1.1.4", "@rolldown/binding-linux-arm-gnueabihf": "1.1.4", "@rolldown/binding-linux-arm64-gnu": "1.1.4", "@rolldown/binding-linux-arm64-musl": "1.1.4", "@rolldown/binding-linux-ppc64-gnu": "1.1.4", "@rolldown/binding-linux-s390x-gnu": "1.1.4", "@rolldown/binding-linux-x64-gnu": "1.1.4", "@rolldown/binding-linux-x64-musl": "1.1.4", "@rolldown/binding-openharmony-arm64": "1.1.4", "@rolldown/binding-wasm32-wasi": "1.1.4", "@rolldown/binding-win32-arm64-msvc": "1.1.4", "@rolldown/binding-win32-x64-msvc": "1.1.4" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA=="],
"rollup": ["rollup@4.62.2", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.62.2", "@rollup/rollup-android-arm64": "4.62.2", "@rollup/rollup-darwin-arm64": "4.62.2", "@rollup/rollup-darwin-x64": "4.62.2", "@rollup/rollup-freebsd-arm64": "4.62.2", "@rollup/rollup-freebsd-x64": "4.62.2", "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", "@rollup/rollup-linux-arm-musleabihf": "4.62.2", "@rollup/rollup-linux-arm64-gnu": "4.62.2", "@rollup/rollup-linux-arm64-musl": "4.62.2", "@rollup/rollup-linux-loong64-gnu": "4.62.2", "@rollup/rollup-linux-loong64-musl": "4.62.2", "@rollup/rollup-linux-ppc64-gnu": "4.62.2", "@rollup/rollup-linux-ppc64-musl": "4.62.2", "@rollup/rollup-linux-riscv64-gnu": "4.62.2", "@rollup/rollup-linux-riscv64-musl": "4.62.2", "@rollup/rollup-linux-s390x-gnu": "4.62.2", "@rollup/rollup-linux-x64-gnu": "4.62.2", "@rollup/rollup-linux-x64-musl": "4.62.2", "@rollup/rollup-openbsd-x64": "4.62.2", "@rollup/rollup-openharmony-arm64": "4.62.2", "@rollup/rollup-win32-arm64-msvc": "4.62.2", "@rollup/rollup-win32-ia32-msvc": "4.62.2", "@rollup/rollup-win32-x64-gnu": "4.62.2", "@rollup/rollup-win32-x64-msvc": "4.62.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA=="],
@@ -4615,7 +4601,7 @@
"serialize-error": ["serialize-error@11.0.3", "", { "dependencies": { "type-fest": "^2.12.2" } }, "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g=="],
"serialize-javascript": ["serialize-javascript@7.0.6", "", {}, "sha512-ATTK5Q4gFVg0YDp1my2vqygyvhcklD/UV5GIlYHooGTn/NogJqIzpetkD6E5kmuVULqz/S9inUL25XcAgDRJQg=="],
"serialize-javascript": ["serialize-javascript@7.0.7", "", {}, "sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g=="],
"serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="],
@@ -5027,7 +5013,7 @@
"victory-vendor": ["victory-vendor@36.9.2", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ=="],
"vite": ["vite@8.1.0", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "~1.1.2", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q=="],
"vite": ["vite@8.1.2", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.16", "rolldown": "~1.1.3", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-6YYPbRXTxx6bRXmOn7XdnQAy5DQNHhDgtjhDHI13oe4pY93kkcdGJWxpGwOm++/Wh0QpQhDrpIoVMrmrsI5AGQ=="],
"vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="],
@@ -5149,10 +5135,6 @@
"@asamuzakjp/css-color/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
"@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
"@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
@@ -5429,7 +5411,7 @@
"@opentui/core/marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="],
"@radix-ui/react-accessible-icon/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.6", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jCE0WljWifTI4niIMCll06kGpsJTAPiZVU9H4WR1N6qW7At9ystHbN7dDB+we2xH535roFHj7qKS+RGj0FMDWQ=="],
"@radix-ui/react-accessible-icon/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1wNZBggTDK3GRuuQ6nP4k2yi7a6l7I5qbMPbZcRsrGsGVead/f/d5FhEzUvqFs0bcrDLx7n1zKQ3JvLR6whaaw=="],
"@radix-ui/react-accordion/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
@@ -5439,7 +5421,7 @@
"@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"@radix-ui/react-avatar/@radix-ui/react-context": ["@radix-ui/react-context@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw=="],
@@ -5487,9 +5469,9 @@
"@radix-ui/react-form/@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="],
"@radix-ui/react-form/@radix-ui/react-label": ["@radix-ui/react-label@2.1.10", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ib0zvq2ZsAqKm5tRnqGJn3vOxSgIts5ToxsXT0q1S/GfLD1Zj7UOEnkw8u2w6sRmn47djpQWuSU1DCL1R29/yw=="],
"@radix-ui/react-form/@radix-ui/react-label": ["@radix-ui/react-label@2.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3PKvDDxOn62k0oV1n4QtNtD2vpu+zYjXR7ojLBPaO6SPvhy53yg0vAmgNeBQeJW5rV3dffoRG+HYfLBZuzw0CQ=="],
"@radix-ui/react-form/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"@radix-ui/react-form/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"@radix-ui/react-hover-card/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
@@ -5515,7 +5497,7 @@
"@radix-ui/react-one-time-password-field/@radix-ui/primitive": ["@radix-ui/primitive@1.1.4", "", {}, "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IVVz4EvBcKjrzKgof714qDnz/SzQAkLA2Emh5edlHbgcE6fNd3Un6CJLlaYcnm8N4JmAtzQgse4dOKxcD2yc9g=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-djW9+zeg137KQdlPtmE8xnaD+K2rcXXMWFrSg0hsmYZ6HRbdTA7tDHFgpaW9+huWVEu0RCabL+985T4TA0BE7g=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="],
@@ -5523,9 +5505,9 @@
"@radix-ui/react-one-time-password-field/@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9gkwneI0guf8JDmrFxPjJF6Ozzgioyw+/lonYNCwefS9ZHA05er0BVHiXr+LbWGHxUfczvMY6G1oiZZi1VzjRw=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8Qcnx9447tx/aCBgw6Jenfqg4Skq+vqab9mCBmuGNipIS5YXvL275wbKEu7+ICYHIlAPgCduUMJH1XOYewKF6Q=="],
"@radix-ui/react-one-time-password-field/@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A=="],
@@ -5537,7 +5519,7 @@
"@radix-ui/react-password-toggle-field/@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="],
"@radix-ui/react-password-toggle-field/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"@radix-ui/react-password-toggle-field/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"@radix-ui/react-password-toggle-field/@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A=="],
@@ -5615,13 +5597,13 @@
"@radix-ui/react-toolbar/@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="],
"@radix-ui/react-toolbar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"@radix-ui/react-toolbar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"@radix-ui/react-toolbar/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9gkwneI0guf8JDmrFxPjJF6Ozzgioyw+/lonYNCwefS9ZHA05er0BVHiXr+LbWGHxUfczvMY6G1oiZZi1VzjRw=="],
"@radix-ui/react-toolbar/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8Qcnx9447tx/aCBgw6Jenfqg4Skq+vqab9mCBmuGNipIS5YXvL275wbKEu7+ICYHIlAPgCduUMJH1XOYewKF6Q=="],
"@radix-ui/react-toolbar/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.10", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Y6K6jLQCVfCnTL2MEtGxDLffkhNfEfHsEg3Wa8JU+IWdn3EWbLXd3OuOfQRN7p/W/cUce1WyTk3QeuAoDBzN9g=="],
"@radix-ui/react-toolbar/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jRhe86+8PF7VZ1u14eOWVOuh2BuAhALg/FT1VcMC4OHedMTRUazDnDlKTt+yxo5cRNKHMfmvZ4sSQtWDeMV4CQ=="],
"@radix-ui/react-toolbar/@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-toggle": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Xb9PLtlvU66F36LiKba6dFswu6V2mDkgidO4fNSbQHQwmZ9ObxMIO17MN/LJ4aWJecVuSVLAHPZjyeMzJrgeiA=="],
"@radix-ui/react-toolbar/@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-toggle": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TK1vusNKb8IRhF23FTbRgUNZ9zfs5rGIyI7LfR3h26p9LrQ060i0uW9QWeD8baZMddaaP0DBGlIa6pbZG+mitg=="],
"@radix-ui/react-tooltip/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
@@ -5955,7 +5937,7 @@
"mammoth/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"markdown-it/linkify-it": ["linkify-it@5.0.1", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg=="],
"markdown-it/linkify-it": ["linkify-it@5.0.2", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q=="],
"markdown-it/uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="],
@@ -6025,85 +6007,85 @@
"radix-ui/@radix-ui/primitive": ["@radix-ui/primitive@1.1.4", "", {}, "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ=="],
"radix-ui/@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collapsible": "1.1.14", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-iE8YB9nmTBH8zd73ofBISZ8JCzgMoMkATJr7qDwa6u5F1+7mTM81V6fa71jgZ65rpjVpecDf1vSnwIFP9Ly1zw=="],
"radix-ui/@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collapsible": "1.1.15", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-24Zz/0SYx8F2bSVThBnQrdJs2VbKelyuJordcFRRdA0fRAhrq/wSegGCqaQz34VQoiWqSMGYCYXEhynLSlyQlg=="],
"radix-ui/@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dialog": "1.1.17", "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-563ygGeyWPrxyVCNp7OV4rE2aIXhFPknpFyo4wbDlcyMMPZ6ySh+zC5WTvY0ZFLgPTg/QB6tA8PyDQyJ2b4cPg=="],
"radix-ui/@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dialog": "1.1.18", "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-6c2cXpNlAgHDhKguK24XcWHHayMpK+lk7/WwBXBco+ZJ4Dv7xP++GBM280KgTD/HCRu3jSdfe8WQiZssonYaIA=="],
"radix-ui/@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.10", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kbI7NrqhDeuytYrq7JjAsoXczvL8wgj2tc1MyaYWm+50bMKHCHQtVWCryslx4cCpmCTTkBcwQckE4CmmGV2haQ=="],
"radix-ui/@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IUAhIVpBUvP5NNICjlaB1OFmtRLGqQqTF3ZOSGPoq3XeLXRFtHiWTRxSVEULgOd9GQR2c7tsYqDnhUennapZnw=="],
"radix-ui/@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.2.0", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-am/CwltXtmtdtP+5FbYblYDnMa/zuKcMJP1i3/SJMDXXfj2mG+BTqLH2wucqeyyiQMursUtg/5cK+Nh2pCaSOA=="],
"radix-ui/@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.2.1", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+8PWoLLZv3AVb5m0pvoiOca/bQGzc9vPVb+982HB2x3Un0DpYEPM3zLMl4oqRpBsocJuNqLkiv/HXTnTrlwr4g=="],
"radix-ui/@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.5", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pREzrmNnVwGvYaBoM64huTRK7B3lrTRuwj8A9nwhPiEtMb+yudiWh6zWAqEtP0Dzd5+iBa1Ki7V1pCxV8ExMdA=="],
"radix-ui/@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-eUEUoGMDpfkgHWSE97ZZaUJtzR1M7EKnNIpD1Q16+8JR9NWghcaqMulx9PuCQ720w0UclfYn6FEbCdd5Hx087g=="],
"radix-ui/@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9bT+FvifX1FK2Mj6UEsTdyu0cN3JaA3KdfhaBao+ONrYFy/pyOy3TU1TNw7iOk1o+0hOEq67RojlUUmoFGwxyA=="],
"radix-ui/@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8A1zibu5skAQ+UVbaeNH5hVMibiFCRJzgMuM14LTWGttnTZKQL9jwYnhAbHRuxrtCqPXa4JvvnVUq1pTNgyZYw=="],
"radix-ui/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IVVz4EvBcKjrzKgof714qDnz/SzQAkLA2Emh5edlHbgcE6fNd3Un6CJLlaYcnm8N4JmAtzQgse4dOKxcD2yc9g=="],
"radix-ui/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-djW9+zeg137KQdlPtmE8xnaD+K2rcXXMWFrSg0hsmYZ6HRbdTA7tDHFgpaW9+huWVEu0RCabL+985T4TA0BE7g=="],
"radix-ui/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="],
"radix-ui/@radix-ui/react-context": ["@radix-ui/react-context@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg=="],
"radix-ui/@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.3.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-menu": "2.1.18", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XbrxS68W5dyiE4fAb96yvJwSVU5x66B20A99sD5Mk3xSWK/LqeOnx6TZnim1KieMjXS/CTFq8reOAjWxas2G8Q=="],
"radix-ui/@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.3.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-menu": "2.1.19", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qzsA/ZPhF6yMxBOTIk1nlCkoy2mswSbwYL+ErBa2iP0s4WWrlxmczArYqMcpVfEjmM7KJj/ADPXky0yZfbSxtQ=="],
"radix-ui/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TDTYmpdq8dI2+Xgvgj9AJ8Ghqq+Eph/TRVEdaFQPDItIY+6QSkU7MJMeevw1568Yw/2Ijz8BTphPSP2XejKphw=="],
"radix-ui/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-apa28mldjMgORmE6g/w3sCcA0Y9UAVeeDVoozN4i7kOw12mLl9RBchfzK3Nn6qxOWjrZhK1Lfy7f07kyzxtnBw=="],
"radix-ui/@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="],
"radix-ui/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-escape-keydown": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-2v+zNAWWe0ySxgC0D0yeXMPQ23xZVgXZTerTz+JKlmdRj6gfTqmCcR29jb6d290DezXPGgruHWDX/vYUebtErg=="],
"radix-ui/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-effect-event": "0.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4lUhWTWAjbDIqFrAPWJ3WqBOpO5YchVZ88X3nh6H9Lu5AFi5nCUeTPj3D8FSDmabmFeRe9ME0BDA4MwKTha5GQ=="],
"radix-ui/@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.18", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-PZGV82gFk0WltDRI//SsG28ZIjlo9ANTmoNYg0jLNzXXiDsAy5PkOOYQaVD1pPxY6t7gxffb1QMD6qaUvsBZdw=="],
"radix-ui/@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.19", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-HZccBkbK0LOi8nYKIp5jll/zIRW0cCOmG6WWyqsSpmXCU+ZlcBbTqIwlBvPCu886C5RVu6c/kHV7xSP8IgYNHw=="],
"radix-ui/@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q=="],
"radix-ui/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fas/lXQqhVvqwAb64s5RFeHiHYElZ6SUQbZaNd6EkfhP/Al7wTIQ9WIR4QVX475tlu5yFCEdDcJH6/UwsZjMWw=="],
"radix-ui/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Mn88Vg2whaRocGJNOH+DKFqYm6ySFPQaiwHNxZPyjn99B52KAEJWWY9NP83+nWdk2HM3rdov+STu9AG471Rt9w=="],
"radix-ui/@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-popper": "1.3.1", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-GjZQIEANVkuuWeztlKz6QEHe31ZX2iDfHzcTMCQVZXC0JyQrgfKWSC+LOOEw6aVV64zyjzobIzSA4AU4eKWrHA=="],
"radix-ui/@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-rt+Fx4HoCeEwFL2IdoV2QaPltqDLlzxN77i9nwB3Y70scFlfAHh1QCdE2TXKuFJtA1TNygb0oivnFBZifgtZOw=="],
"radix-ui/@radix-ui/react-label": ["@radix-ui/react-label@2.1.10", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ib0zvq2ZsAqKm5tRnqGJn3vOxSgIts5ToxsXT0q1S/GfLD1Zj7UOEnkw8u2w6sRmn47djpQWuSU1DCL1R29/yw=="],
"radix-ui/@radix-ui/react-label": ["@radix-ui/react-label@2.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3PKvDDxOn62k0oV1n4QtNtD2vpu+zYjXR7ojLBPaO6SPvhy53yg0vAmgNeBQeJW5rV3dffoRG+HYfLBZuzw0CQ=="],
"radix-ui/@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.1", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lj8Rxjtn6zJq1oSbE/uDtAwCbB9BnxgHD+8MwJMuTh6u1dPamYhW9iuELr/Z8d0D/UysFblYYHeBPwi7T4k0YQ=="],
"radix-ui/@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Mht9BVd1AIsNFVQr4KG3bIK7XQn5IXF0TL/2ObsrzOdc1loaly/+kBDL5roSCYn8j8XZkvpOD0WYLz2FQtH1Eg=="],
"radix-ui/@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.18", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-hX7EGx/oFq6DPY27GQuP/2wP48GHf5LG6r06VgNJlG+znmDS8OfopZcRcGly3L4lsB9FqpmLx6JQSE9P3BUpyw=="],
"radix-ui/@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.19", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Glt6mebxcgQvLeVkH3HiqV5bgQubE+31ELxLs7q0GlYI5k0XYkOkeuPrhXoylxK8eufvIt9CJjzY1TfFMXK3qw=="],
"radix-ui/@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nJ0SkrSQgudyYhMiYeHA1ayLVuduEJCFLan1RZZN7c9kqzzCFLaU9kuy81uNtqzweM9YaQPgWzxi9MwQ9jZ04g=="],
"radix-ui/@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fYeYQvbeNn5AQk2RBbpO7koLm2YbS00UYxC/IL2sgLlninEH5UNIv+X3E0KJ1Vy4WIo+dhN9w8GNqSHhbHWCIg=="],
"radix-ui/@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.1", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/YSAOdJ7YJvdn7bn5sdSx2egW+SKY+u7O5RyAVs94Ymrg2fg5QTSFPMRkzvhGyFuE4/qsmPBdrwYoZMZh/4f+g=="],
"radix-ui/@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qdXDes+eHlnMUGlBAAAe5EG7oOQvqsXuq4mq585diMudg80iB+jHbsSeG3+Q4eWNsogNyhqU2p/3i+Y0iEepqg=="],
"radix-ui/@radix-ui/react-popper": ["@radix-ui/react-popper@1.3.1", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-rect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bhnq/0DEPTi2lsOD3J5rTL65qUKHbKbhqHsmN9TMiclSXpipi651ooUKPPp6G5lF/WiHBdn1s0Wuqsn+myVAvw=="],
"radix-ui/@radix-ui/react-popper": ["@radix-ui/react-popper@1.3.2", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-rect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3QXNeMkdshed1MR3LNoiCirBywRFPkD8ETJa/HlPuLwSajaQixf2ro+isoDNJlGABg9ug41XuZpINZJIle4XWg=="],
"radix-ui/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.12", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m309havGzsjLHHaIX50G5PlvRs3xkgPCsGk/5PTvYm8D5q33yG0J7w/712PTOhid7NTaFETtnSXjngHQavvhVw=="],
"radix-ui/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.13", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA=="],
"radix-ui/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.6", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ=="],
"radix-ui/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"radix-ui/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"radix-ui/@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.10", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JYzEg60lk79PwKM27WZyKd7PW8O4OM5jOaFfRPfOyeXmMw7tLJh5kSj+CEjVTehszuwml/AdCzPGMXBTGf4BBw=="],
"radix-ui/@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.11", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-KqiGJcFaZDc+BvveAgU3ZhACg2MvSUDrCBx4lRR/ZVRNal0bvt8lBpvnSkep9heeOuF8Qfw3fszLDX4OpQ2NVw=="],
"radix-ui/@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.4.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/SSxZdKEo2Eo29FFRKd06EfFDYp8HryKg0WYg7QLXaydPzl52YfSvCH2a3QDBRdtcuwACroJT8UVjQVgOJ7P9A=="],
"radix-ui/@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.4.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-W8Uo9riHnlzLLWy+r2mVHUyuEWqD/+be4PZzbEvaGoFSBDHkm+GYWjtcE6u3AmPKNyfanWpnVfpZ2GqPCdzzsw=="],
"radix-ui/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9gkwneI0guf8JDmrFxPjJF6Ozzgioyw+/lonYNCwefS9ZHA05er0BVHiXr+LbWGHxUfczvMY6G1oiZZi1VzjRw=="],
"radix-ui/@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8Qcnx9447tx/aCBgw6Jenfqg4Skq+vqab9mCBmuGNipIS5YXvL275wbKEu7+ICYHIlAPgCduUMJH1XOYewKF6Q=="],
"radix-ui/@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.12", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-xuafVzQiTCLsyEjakowTdG3OgTXsmO7IdCiO77otIa+z44xoLNs9Do5eg7POFumIOCjtG6djfm6RKUKpUa/csA=="],
"radix-ui/@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.13", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7tncSubo2G0UY1e8rk+72qe3XRzrGnOLtZQ1PL1KoBfRUNX0NrJT5akb+0kfwSCc3gVR4wdHqyhAQBDpDNOwDw=="],
"radix-ui/@radix-ui/react-select": ["@radix-ui/react-select@2.3.1", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.1", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.6", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-w6eDvY78LE9ZUiNnXCA1QVK8RYN7k9galFv09kjVydJqBAgHd7Y9A6h0UJ/6DCZNGZMZrB2ohcSW1Bo9d8+wWA=="],
"radix-ui/@radix-ui/react-select": ["@radix-ui/react-select@2.3.2", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-brXD6C/V0fVK0DDbscLVw6LsXrjQ+ay8jdOBaN+tLb4vsHsAMm6Gt6eT77wHX1Eq8GPtD5rJ+RxFtfDozsb4+Q=="],
"radix-ui/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.10", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Y6K6jLQCVfCnTL2MEtGxDLffkhNfEfHsEg3Wa8JU+IWdn3EWbLXd3OuOfQRN7p/W/cUce1WyTk3QeuAoDBzN9g=="],
"radix-ui/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jRhe86+8PF7VZ1u14eOWVOuh2BuAhALg/FT1VcMC4OHedMTRUazDnDlKTt+yxo5cRNKHMfmvZ4sSQtWDeMV4CQ=="],
"radix-ui/@radix-ui/react-slider": ["@radix-ui/react-slider@1.4.1", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-r91WSpQucNGFKAIxT8FT0H0zyjd5tJlqObLp7LOMV4z49KoDCwjy01w3vDOU4e1wxhF9IgjYco7SB6byOW7Buw=="],
"radix-ui/@radix-ui/react-slider": ["@radix-ui/react-slider@1.4.2", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qt5C1ppJz66aUDrH1VccjPrq7aFchK0wBrn6xsxlCHNUyE57dRRQ7lp1QFpF7OscMexZF8MCGBTVBlENHPkNiA=="],
"radix-ui/@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA=="],
"radix-ui/@radix-ui/react-switch": ["@radix-ui/react-switch@1.3.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-55bQtCnOB0BohomSHi6qvQXpJEEqUGDm6hRrM0Bph5OXwhSegqkd8IqgBAQkM1IlgUlWZIxpxRcpOEfRIgimyw=="],
"radix-ui/@radix-ui/react-switch": ["@radix-ui/react-switch@1.3.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tgRBI3DdNwAJYE4BBZyZcz/HRRCvAsPkRvG1wvKc+41tBGMxPn/a87T/wikXAvyDypNQ9kaZwHbeZe+veHCGpA=="],
"radix-ui/@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kxc9gI6/HfcU4nfMMVS3AmQK414kbU1IE6UCJmMmxjhO3cRPXOyYnmvyKD+ODt7q56nRq9l7Wovi6uaGwKgMlg=="],
"radix-ui/@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-v3Ab2l7z6U7tRB4xA0IyKdq0OsqaO1o9ZjsIEoKKnSZ/l96mZz8aCTX0NCXw+YVHJXr8Km4d+Mn6/Q8YjXa+gw=="],
"radix-ui/@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-uL4kyyWy000pPL43fGGCV5qT6ZchCWEQZOSlkYiPwPt8Hy1iW38RjeptIvz1/SZesrW6Vn58Ct3sV7tfEfiAbw=="],
"radix-ui/@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YNEnTHV47hPep+U0QvVM02OJNka9uygREc+k4Nh5VSZBg4MmE+myI442x3hCGfRpX7N2WSSYSJKws4gE+Z8lgg=="],
"radix-ui/@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-AsAVsYNZIlRBsci7BhE+QyQeKd1h6TffJYt+lF0QQkd5OpQ3klfIByPsCb4G0h/Fq6PJwh1FYNluzBFYzhk4+w=="],
"radix-ui/@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bI2ILJrzwgmAsH05TsJ9pVrzqQwAip7OM2/krqAdYn0R16bl86UPWbe5VPHsALat0EnqpV01cGtkleaUKPNdNg=="],
"radix-ui/@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-toggle": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Xb9PLtlvU66F36LiKba6dFswu6V2mDkgidO4fNSbQHQwmZ9ObxMIO17MN/LJ4aWJecVuSVLAHPZjyeMzJrgeiA=="],
"radix-ui/@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-toggle": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TK1vusNKb8IRhF23FTbRgUNZ9zfs5rGIyI7LfR3h26p9LrQ060i0uW9QWeD8baZMddaaP0DBGlIa6pbZG+mitg=="],
"radix-ui/@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.1", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-visually-hidden": "1.2.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-NlNe8D0dWEpVfXFli90IO6X07Josx/b1iu98tDnx9Xv0HT4wLIL+m2VOheMHhK7qbp2HoTBqALEFzGyZs/levw=="],
"radix-ui/@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8XZ6Py3y3W2nEzAUGCN5cfVKaUi+CVApcz1d6lrNVVf2hvYEixMRkq8k9ggPKnQUpRRuOV5avt8uvxViH2jLwA=="],
"radix-ui/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw=="],
@@ -6111,7 +6093,7 @@
"radix-ui/@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w=="],
"radix-ui/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.6", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jCE0WljWifTI4niIMCll06kGpsJTAPiZVU9H4WR1N6qW7At9ystHbN7dDB+we2xH535roFHj7qKS+RGj0FMDWQ=="],
"radix-ui/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1wNZBggTDK3GRuuQ6nP4k2yi7a6l7I5qbMPbZcRsrGsGVead/f/d5FhEzUvqFs0bcrDLx7n1zKQ3JvLR6whaaw=="],
"raw-body/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
@@ -6215,7 +6197,7 @@
"unzipper/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"vaul/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TDTYmpdq8dI2+Xgvgj9AJ8Ghqq+Eph/TRVEdaFQPDItIY+6QSkU7MJMeevw1568Yw/2Ijz8BTphPSP2XejKphw=="],
"vaul/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-apa28mldjMgORmE6g/w3sCcA0Y9UAVeeDVoozN4i7kOw12mLl9RBchfzK3Nn6qxOWjrZhK1Lfy7f07kyzxtnBw=="],
"verror/core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
@@ -6423,7 +6405,7 @@
"@opentelemetry/sdk-node/@opentelemetry/sdk-trace-node/@opentelemetry/propagator-jaeger": ["@opentelemetry/propagator-jaeger@1.29.0", "", { "dependencies": { "@opentelemetry/core": "1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-EXIEYmFgybnFMijVgqx1mq/diWwSQcd0JWVksytAVQEnAiaDvP45WuncEVQkFIAC0gVxa2+Xr8wL5pF5jCVKbg=="],
"@radix-ui/react-accessible-icon/@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"@radix-ui/react-accessible-icon/@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"@radix-ui/react-accordion/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
@@ -6549,7 +6531,7 @@
"@radix-ui/react-toolbar/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA=="],
"@radix-ui/react-toolbar/@radix-ui/react-roving-focus/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IVVz4EvBcKjrzKgof714qDnz/SzQAkLA2Emh5edlHbgcE6fNd3Un6CJLlaYcnm8N4JmAtzQgse4dOKxcD2yc9g=="],
"@radix-ui/react-toolbar/@radix-ui/react-roving-focus/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-djW9+zeg137KQdlPtmE8xnaD+K2rcXXMWFrSg0hsmYZ6HRbdTA7tDHFgpaW9+huWVEu0RCabL+985T4TA0BE7g=="],
"@radix-ui/react-toolbar/@radix-ui/react-roving-focus/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="],
@@ -6557,7 +6539,7 @@
"@radix-ui/react-toolbar/@radix-ui/react-roving-focus/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw=="],
"@radix-ui/react-toolbar/@radix-ui/react-toggle-group/@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-AsAVsYNZIlRBsci7BhE+QyQeKd1h6TffJYt+lF0QQkd5OpQ3klfIByPsCb4G0h/Fq6PJwh1FYNluzBFYzhk4+w=="],
"@radix-ui/react-toolbar/@radix-ui/react-toggle-group/@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bI2ILJrzwgmAsH05TsJ9pVrzqQwAip7OM2/krqAdYn0R16bl86UPWbe5VPHsALat0EnqpV01cGtkleaUKPNdNg=="],
"@radix-ui/react-tooltip/@radix-ui/react-use-controllable-state/@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
@@ -6999,19 +6981,19 @@
"vaul/@radix-ui/react-dialog/@radix-ui/react-context": ["@radix-ui/react-context@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-escape-keydown": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-2v+zNAWWe0ySxgC0D0yeXMPQ23xZVgXZTerTz+JKlmdRj6gfTqmCcR29jb6d290DezXPGgruHWDX/vYUebtErg=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-effect-event": "0.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4lUhWTWAjbDIqFrAPWJ3WqBOpO5YchVZ88X3nh6H9Lu5AFi5nCUeTPj3D8FSDmabmFeRe9ME0BDA4MwKTha5GQ=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fas/lXQqhVvqwAb64s5RFeHiHYElZ6SUQbZaNd6EkfhP/Al7wTIQ9WIR4QVX475tlu5yFCEdDcJH6/UwsZjMWw=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Mn88Vg2whaRocGJNOH+DKFqYm6ySFPQaiwHNxZPyjn99B52KAEJWWY9NP83+nWdk2HM3rdov+STu9AG471Rt9w=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.12", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m309havGzsjLHHaIX50G5PlvRs3xkgPCsGk/5PTvYm8D5q33yG0J7w/712PTOhid7NTaFETtnSXjngHQavvhVw=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.13", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.6", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
"vaul/@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA=="],
+19
View File
@@ -19,6 +19,8 @@ Type `/` in the chat input to see available slash commands:
| `/newtask` | Start fresh task with distilled context from current conversation |
| `/smol` | Compress conversation history while preserving essential context |
| `/newrule` | Create a rule file to teach Cline your preferences |
| `/deep-planning` | Investigate codebase, plan thoroughly, then create implementation task |
| `/reportbug` | Report a bug with diagnostic info |
### /newtask
@@ -38,6 +40,23 @@ Use `/smol` when you're deep into a debugging session or brainstorming and need
Use `/newrule` when you find yourself repeating the same instructions across tasks. For more about rules, see [Cline Rules](/customization/cline-rules).
### /deep-planning
Transform Cline into a meticulous architect who investigates your codebase, asks clarifying questions, and creates a comprehensive implementation plan before writing any code. Deep planning follows a four-step process:
1. **Silent Investigation** - Cline explores your codebase structure and patterns
2. **Discussion** - Targeted questions about requirements and approach
3. **Plan Creation** - Generates `implementation_plan.md` with detailed specifications
4. **Task Creation** - Creates a new task with trackable implementation steps
Use `/deep-planning` for features touching multiple parts of your codebase, architectural changes, or complex integrations.
### /reportbug
`/reportbug` collects diagnostic information and helps you report issues with Cline. It gathers relevant context like your configuration, recent errors, and system details to make bug reports more useful for the development team.
Use `/reportbug` when you encounter unexpected behavior, crashes, or bugs you want to report.
## Skills via Slash Commands
In addition to built-in commands, you can trigger enabled skills directly from chat using slash commands.
@@ -33,7 +33,7 @@ Cline connects to AI models through a **provider**. You have three common paths:
</Step>
<Step title="Select Model">
Choose your desired Claude model from the **Model** dropdown.
Choose your desired model from the **Model** dropdown.
</Step>
</Steps>
+27
View File
@@ -0,0 +1,27 @@
---
title: "Atomic Chat"
description: "Use local models through Atomic Chat's OpenAI-compatible API."
---
[Atomic Chat](https://atomic.chat) is a local AI provider.
## Setup in Cline
1. Install and launch Atomic Chat.
2. Download or load a model in the app.
3. In Cline Settings, choose **Atomic Chat** as the provider.
4. Keep the default base URL `http://127.0.0.1:1337/v1` unless you changed Atomic Chat's server port.
5. Pick a model from the dropdown (models are fetched from `GET /v1/models`).
## API key
Atomic Chat typically does not require an API key for local use. Leave the field empty unless your setup requires one.
## Tool calling
Atomic Chat supports tool calls for agent workflows when the loaded model supports them. Enable **Use Compact Prompt** for smaller local context windows.
## Related links
- [Atomic Chat website](https://atomic.chat)
- [Atomic Chat GitHub](https://github.com/AtomicBot-ai/Atomic-Chat)
+26 -2
View File
@@ -1,14 +1,14 @@
---
title: "Local models"
sidebarTitle: "Local models"
description: "Run Cline with local models using Ollama or LM Studio."
description: "Run Cline with local models using Ollama, LM Studio or Atomic Chat."
---
Run Cline with local inference on your machine.
## Quick Start
1. Install a local runtime (**Ollama** or **LM Studio**)
1. Install a local runtime (**Ollama**, **LM Studio** or **Atomic Chat**)
2. Start the local server
3. In Cline Settings, select the matching provider
4. Select a local model
@@ -81,6 +81,30 @@ Run Cline with local inference on your machine.
- Ensure a model is loaded
- If connection fails, verify `http://localhost:1234`
</Tab>
<Tab title="Atomic Chat">
### 1) Install
- Download from [atomic.chat](https://atomic.chat) (macOS Apple Silicon)
- Or build from [AtomicBot-ai/Atomic-Chat](https://github.com/AtomicBot-ai/Atomic-Chat)
### 2) Load a model
- Open Atomic Chat and download or load a local model from the catalog
### 3) Start the local API
- Atomic Chat exposes an OpenAI-compatible server at `http://127.0.0.1:1337/v1` by default
- List loaded models: `curl http://127.0.0.1:1337/v1/models`
### 4) Configure Cline
1. Open Cline Settings
2. Select provider: **Atomic Chat**
3. Base URL: `http://127.0.0.1:1337/v1` (default)
4. Select your model from the dropdown
### 5) Troubleshooting
- Make sure Atomic Chat is running before sending prompts
- If connection fails, verify `http://127.0.0.1:1337/v1/models`
- If the model list is empty, load a model in Atomic Chat first
</Tab>
</Tabs>
## Recommended Cline Settings for Local Inference
+1 -1
View File
@@ -258,5 +258,5 @@ These same patterns work for any project, from simple scripts to full applicatio
## Need Help?
- **Start a fresh conversation**: Type `/new` in the chat input to begin a new task
- **Report issues**: Open an issue at [github.com/cline/cline/issues](https://github.com/cline/cline/issues)
- **Report issues**: Use `/reportbug` to help us improve
- **Get support**: Join our [Discord community](https://discord.gg/cline)
+13
View File
@@ -1,5 +1,18 @@
# Cline SDK Changelog
## 0.0.59
- You can now select Cline free models on the ClinePass provider
- The SDK now recognizes ClinePass rate-limit responses and surfaces them as a typed `ClinePassLimitError` (with `isClinePassLimitMessage` / `extractClinePassLimitMessage` helpers)
- Removed references to the retired ClinePass GLM 5.1 model
- Fixed OpenAI Codex model metadata under the GPT Subscription provider
- The detached hub daemon process now emits telemetry
- SDK/CLI telemetry identity attributes now include `user_id`
- Cline provider requests now send versioned Cline client-identity headers
- Fixed context compaction so canonical session history is preserved
- `str_replace` edits now report accurate diffs
- Fixed a performance issue where listing sessions could hang the extension host
## 0.0.58
- `read_files` now tolerates malformed input from weaker models: line-range entries (`start_line`/`end_line`) sent as separate array items are coalesced back onto the preceding file path instead of being rejected
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@cline/agents",
"version": "0.0.58",
"version": "0.0.59",
"repository": {
"type": "git",
"url": "https://github.com/cline/cline",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@cline/core",
"description": "Cline Core SDK for Node Runtime",
"version": "0.0.58",
"version": "0.0.59",
"repository": {
"type": "git",
"url": "https://github.com/cline/cline",
+55
View File
@@ -364,6 +364,61 @@ describe("ClineCore", () => {
);
});
it("normalizes config extension context into local runtime before delegating to the host", async () => {
const host = {
runtimeAddress: undefined,
startSession: vi.fn(async (_input: StartSessionInput) =>
createStartResult("session-extension-context"),
),
runTurn: vi.fn(),
getAccumulatedUsage: vi.fn(),
abort: vi.fn(),
stopSession: vi.fn(),
dispose: vi.fn(),
getSession: vi.fn(async () => undefined),
listSessions: vi.fn(),
deleteSession: vi.fn(),
readSessionMessages: vi.fn(),
subscribe: vi.fn(() => () => {}),
updateSessionModel: vi.fn(),
};
createRuntimeHostMock.mockResolvedValue(host);
const onTeamRestored = vi.fn();
const clientContext = {
name: "VSCode Extension",
version: "3.27.0",
platform: "Visual Studio Code",
platformVersion: "1.102.3",
isMultiRoot: true,
};
const core = await ClineCore.create();
await core.start({
...createStartInput(),
config: {
...createStartInput().config,
extensionContext: {
client: clientContext,
},
},
localRuntime: {
onTeamRestored,
},
});
const startInput = vi.mocked(host.startSession).mock.calls.at(-1)?.[0] as
| StartSessionInput
| undefined;
expect(startInput).toBeDefined();
if (!startInput) throw new Error("Expected host.startSession to be called");
expect(startInput.config).not.toHaveProperty("extensionContext");
expect(startInput.localRuntime?.extensionContext?.client).toEqual(
clientContext,
);
expect(startInput.localRuntime?.onTeamRestored).toBe(onTeamRestored);
});
it("prefers the per-session telemetry service over the ClineCore one", async () => {
const host = {
runtimeAddress: undefined,
-16
View File
@@ -1,4 +1,3 @@
import net from "node:net";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { ClineOAuthCredentials } from "./cline";
import { getValidClineCredentials, loginClineOAuth } from "./cline";
@@ -7,21 +6,6 @@ const PROVIDER_OPTIONS = {
apiBaseUrl: "https://auth.example.com",
};
const ORIGINAL_FETCH = globalThis.fetch;
const socketBindingSupported = await (async () => {
try {
const srv = net.createServer();
await new Promise<void>((resolve, reject) => {
srv.listen(0, "127.0.0.1", () => resolve());
srv.once("error", reject);
});
await new Promise<void>((resolve, reject) =>
srv.close((err) => (err ? reject(err) : resolve())),
);
return true;
} catch {
return false;
}
})();
function createCredentials(
overrides: Partial<ClineOAuthCredentials> = {},
@@ -129,9 +129,7 @@ describe("createEditorExecutor", () => {
expect(result).toBe(
`Edited ${filePath}\n\`\`\`diff\n-2: b\n-3: c\n-4: d\n+2: B\n\`\`\``,
);
await expect(fs.readFile(filePath, "utf-8")).resolves.toBe(
"a\nB\ne\nf",
);
await expect(fs.readFile(filePath, "utf-8")).resolves.toBe("a\nB\ne\nf");
});
});
@@ -144,9 +142,7 @@ describe("createEditorExecutor", () => {
context,
);
expect(result).toBe(
`Edited ${filePath}\n\`\`\`diff\n+2: new\n\`\`\``,
);
expect(result).toBe(`Edited ${filePath}\n\`\`\`diff\n+2: new\n\`\`\``);
});
});
@@ -38,6 +38,23 @@ const {
})),
}));
const {
mockDaemonTelemetryService,
mockDaemonTelemetryDispose,
mockCreateHubDaemonTelemetry,
} = vi.hoisted(() => {
const telemetry = { capture: vi.fn() };
const dispose = vi.fn(async () => undefined);
return {
mockDaemonTelemetryService: telemetry,
mockDaemonTelemetryDispose: dispose,
mockCreateHubDaemonTelemetry: vi.fn(() => ({
telemetry,
dispose,
})),
};
});
vi.mock("@cline/shared", () => ({
initVcr: mockInitVcr,
resolveClineBuildEnv: () => "production",
@@ -61,6 +78,10 @@ vi.mock("../server", () => ({
startHubWebSocketServer: mockStartHubWebSocketServer,
}));
vi.mock("./telemetry", () => ({
createHubDaemonTelemetry: mockCreateHubDaemonTelemetry,
}));
const originalArgv = [...process.argv];
const originalCwd = process.cwd();
@@ -78,6 +99,8 @@ describe("hub daemon entry", () => {
mockResolveProductionHubOwnerContext.mockClear();
mockResolveSharedHubOwnerContext.mockClear();
mockStartHubWebSocketServer.mockClear();
mockCreateHubDaemonTelemetry.mockClear();
mockDaemonTelemetryDispose.mockClear();
for (const dir of tempDirs.splice(0)) {
rmSync(dir, { recursive: true, force: true });
}
@@ -111,9 +134,33 @@ describe("hub daemon entry", () => {
port: 30000,
pathname: "/hub",
owner: expect.objectContaining({ ownerId: "production" }),
telemetry: mockDaemonTelemetryService,
cronOptions: { workspaceRoot: cwd },
}),
);
expect(mockCreateLocalHubScheduleRuntimeHandlers).toHaveBeenCalledOnce();
expect(mockCreateLocalHubScheduleRuntimeHandlers).toHaveBeenCalledWith({
telemetry: mockDaemonTelemetryService,
});
});
it("disposes telemetry and exits when server startup fails", async () => {
const cwd = mkdtempSync(join(tmpdir(), "cline-hub-entry-test-"));
tempDirs.push(cwd);
process.argv = ["node", "entry.js", "--cwd", cwd];
vi.spyOn(process, "on").mockImplementation(() => process);
vi.spyOn(process.stderr, "write").mockImplementation(() => true);
const exitSpy = vi
.spyOn(process, "exit")
.mockImplementation(() => undefined as never);
mockStartHubWebSocketServer.mockRejectedValueOnce(
new Error("port already in use"),
);
await import("./entry");
await vi.waitFor(() => {
expect(exitSpy).toHaveBeenCalledWith(1);
});
expect(mockDaemonTelemetryDispose).toHaveBeenCalled();
});
});
+32 -12
View File
@@ -7,6 +7,7 @@ import {
resolveSharedHubOwnerContext,
} from "../discovery/workspace";
import { startHubWebSocketServer } from "../server";
import { createHubDaemonTelemetry } from "./telemetry";
initVcr(process.env.CLINE_VCR);
@@ -61,20 +62,34 @@ async function main(): Promise<void> {
pathname: options.pathname,
});
const server = await startHubWebSocketServer({
host: endpoint.host,
port: endpoint.port,
pathname: endpoint.pathname,
owner:
resolveClineBuildEnv() === "production"
? resolveProductionHubOwnerContext()
: resolveSharedHubOwnerContext(),
runtimeHandlers: createLocalHubScheduleRuntimeHandlers(),
cronOptions: { workspaceRoot: options.cwd },
});
const daemonTelemetry = createHubDaemonTelemetry();
let server: Awaited<ReturnType<typeof startHubWebSocketServer>>;
try {
server = await startHubWebSocketServer({
host: endpoint.host,
port: endpoint.port,
pathname: endpoint.pathname,
owner:
resolveClineBuildEnv() === "production"
? resolveProductionHubOwnerContext()
: resolveSharedHubOwnerContext(),
telemetry: daemonTelemetry.telemetry,
runtimeHandlers: createLocalHubScheduleRuntimeHandlers({
telemetry: daemonTelemetry.telemetry,
}),
cronOptions: { workspaceRoot: options.cwd },
});
} catch (error) {
// Flush before the top-level catch exits so failed daemon starts are
// still visible in telemetry instead of dying silently.
await daemonTelemetry.dispose().catch(() => undefined);
throw error;
}
const shutdown = async (): Promise<void> => {
await server.close();
await daemonTelemetry.dispose().catch(() => undefined);
process.exit(0);
};
@@ -99,7 +114,12 @@ async function main(): Promise<void> {
);
})
.finally(() => {
process.exit(1);
void daemonTelemetry
.dispose()
.catch(() => undefined)
.finally(() => {
process.exit(1);
});
});
};
@@ -0,0 +1,140 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const {
mockIdentifyAccount,
mockGetProviderSettings,
mockFlush,
mockDispose,
mockTelemetryService,
mockCreateConfiguredTelemetryHandle,
providerSettingsManagerConstructions,
} = vi.hoisted(() => {
const telemetry = { capture: vi.fn() };
const mockFlush = vi.fn(async () => undefined);
const mockDispose = vi.fn(async () => undefined);
return {
mockIdentifyAccount: vi.fn(),
mockGetProviderSettings: vi.fn(),
mockFlush,
mockDispose,
mockTelemetryService: telemetry,
mockCreateConfiguredTelemetryHandle: vi.fn(() => ({
telemetry,
flush: mockFlush,
dispose: mockDispose,
})),
providerSettingsManagerConstructions: { count: 0 },
};
});
vi.mock("../../services/telemetry/OpenTelemetryProvider", () => ({
createConfiguredTelemetryHandle: mockCreateConfiguredTelemetryHandle,
}));
vi.mock("../../services/telemetry/core-events", () => ({
identifyAccount: mockIdentifyAccount,
}));
vi.mock("../../services/storage/provider-settings-manager", () => ({
ProviderSettingsManager: class {
constructor() {
providerSettingsManagerConstructions.count += 1;
}
getProviderSettings = mockGetProviderSettings;
},
}));
import { createHubDaemonTelemetry } from "./telemetry";
describe("createHubDaemonTelemetry", () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
mockIdentifyAccount.mockClear();
mockGetProviderSettings.mockClear();
mockFlush.mockClear();
mockFlush.mockImplementation(async () => undefined);
mockDispose.mockClear();
mockCreateConfiguredTelemetryHandle.mockClear();
providerSettingsManagerConstructions.count = 0;
});
it("identifies the cached cline account at startup", () => {
mockGetProviderSettings.mockReturnValue({
auth: { accountId: " usr-123 " },
});
const daemonTelemetry = createHubDaemonTelemetry();
expect(daemonTelemetry.telemetry).toBe(mockTelemetryService);
expect(mockCreateConfiguredTelemetryHandle).toHaveBeenCalledWith(
expect.objectContaining({
metadata: expect.objectContaining({
cline_type: "hub",
platform: "cline-hub-daemon",
}),
}),
);
expect(mockIdentifyAccount).toHaveBeenCalledExactlyOnceWith(
mockTelemetryService,
{ id: "usr-123", provider: "cline" },
);
});
it("stays anonymous when no cached account exists, then identifies once the user logs in", () => {
mockGetProviderSettings.mockReturnValue(undefined);
createHubDaemonTelemetry();
expect(mockIdentifyAccount).not.toHaveBeenCalled();
mockGetProviderSettings.mockReturnValue({
auth: { accountId: "usr-456" },
});
vi.advanceTimersByTime(5 * 60 * 1000);
expect(mockIdentifyAccount).toHaveBeenCalledExactlyOnceWith(
mockTelemetryService,
{ id: "usr-456", provider: "cline" },
);
});
it("does not re-identify an unchanged account and reuses one settings manager", () => {
mockGetProviderSettings.mockReturnValue({
auth: { accountId: "usr-123" },
});
createHubDaemonTelemetry();
vi.advanceTimersByTime(30 * 60 * 1000);
expect(mockIdentifyAccount).toHaveBeenCalledTimes(1);
expect(providerSettingsManagerConstructions.count).toBe(1);
});
it("survives provider settings read failures", () => {
mockGetProviderSettings.mockImplementation(() => {
throw new Error("corrupt settings");
});
expect(() => createHubDaemonTelemetry()).not.toThrow();
expect(mockIdentifyAccount).not.toHaveBeenCalled();
});
it("flushes and disposes the handle and stops the refresh timer on dispose", async () => {
mockGetProviderSettings.mockReturnValue(undefined);
const daemonTelemetry = createHubDaemonTelemetry();
await daemonTelemetry.dispose();
expect(mockFlush).toHaveBeenCalledTimes(1);
expect(mockDispose).toHaveBeenCalledTimes(1);
mockGetProviderSettings.mockReturnValue({
auth: { accountId: "usr-789" },
});
vi.advanceTimersByTime(30 * 60 * 1000);
expect(mockIdentifyAccount).not.toHaveBeenCalled();
});
it("does not let a hung exporter block dispose past the deadline", async () => {
mockGetProviderSettings.mockReturnValue(undefined);
mockFlush.mockImplementation(() => new Promise<undefined>(() => undefined));
const daemonTelemetry = createHubDaemonTelemetry();
const disposed = daemonTelemetry.dispose();
await vi.advanceTimersByTimeAsync(5_000);
await expect(disposed).resolves.toBeUndefined();
});
});

Some files were not shown because too many files have changed in this diff Show More