diff --git a/.gitignore b/.gitignore index be419356a..cb88e678c 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ goals/**/ACTIVE_GOAL_STATE.md goals/**/ACTIVE_GOAL_STATE.md.lock /runtime/ logs/ + +# superpowers +docs/superpowers/ diff --git a/docs/integrations/deepseek-harness-connector.md b/docs/integrations/deepseek-harness-connector.md index 9057d0c31..456c663e1 100644 --- a/docs/integrations/deepseek-harness-connector.md +++ b/docs/integrations/deepseek-harness-connector.md @@ -3,6 +3,14 @@ Status: public-safe v0 connector for using DeepSeek Harness (`dsh`) as a bounded agent execution host behind LoopX. +This document covers the external `deepseek-harness` agent type (`dsh` input +alias): LoopX launches one isolated, validated Turn through the Python SDK +adapter. For same-process continuation in the current visible DSH Session, +use the separate +[DeepSeek Harness native plugin](deepseek-harness-native-plugin.md) with the +canonical `deepseek-harness-native` agent type (`dsh-native` input alias). +Neither surface is a migration alias for the other. + DeepSeek Harness is an open-source agent harness by DeepSeek AI. LoopX does not replace dsh's model loop, tools, sandbox, or session log. Instead, the connector lets LoopX govern one dsh-backed work segment at a time through the existing @@ -128,6 +136,7 @@ final message, and complete LoopX validation/writeback/quota spend. ## Related Contracts +- [DeepSeek Harness native plugin](deepseek-harness-native-plugin.md) - [Runtime connector catalog](runtime-connector-catalog.md) - [LoopX Turn v0](../reference/protocols/loopx-turn-v0.md) - [Host integration surface v0](../reference/protocols/host-integration-surface-v0.md) diff --git a/docs/integrations/deepseek-harness-native-plugin.md b/docs/integrations/deepseek-harness-native-plugin.md new file mode 100644 index 000000000..bc4b30db8 --- /dev/null +++ b/docs/integrations/deepseek-harness-native-plugin.md @@ -0,0 +1,293 @@ +# DeepSeek Harness Native LoopX Plugin + +Status: public-safe v1 integration for running a LoopX-governed continuation +inside the current visible DeepSeek Harness Session. + +The native provider is an optional DSH bundle in +`packages/dsh-loopx-plugin/`. Its canonical LoopX agent type is +`deepseek-harness-native`; `dsh-native` is only an input alias. It is separate +from the existing `deepseek-harness` / `dsh` external adapter and is not a +migration or replacement for that connector. + +## Choose the correct surface + +| Need | Agent type | Execution shape | Entry point | +| --- | --- | --- | --- | +| Continue inside the current visible DSH Agent and Session | `deepseek-harness-native` (`dsh-native` alias) | Same-process command, tools, follow-up, and Host sidecar | `/loopx ` after installing `dsh-loopx-plugin` | +| Run one isolated, independently validated DSH-backed LoopX Turn | `deepseek-harness` (`dsh` alias) | External Python SDK adapter and headless runtime | `loopx turn run-once` with `scripts/dsh_turn_host_adapter.py` | + +Both surfaces keep LoopX authoritative for Goal, Todo, gate, quota, evidence, +scheduler, and terminal state. They differ only in Host integration and +execution lifecycle. + +## Install and verify + +Prerequisites are DSH `0.1.0-rc.7`, Node.js `^22.19.0 || >=24`, and a local +`loopx` executable: + +```bash +dsh --version +command -v loopx +loopx --version +``` + +Build and add the local bundle to the supported `web` profile: + +```bash +cd packages/dsh-loopx-plugin +corepack pnpm install --frozen-lockfile --ignore-scripts +pnpm typecheck +pnpm test +pnpm build +dsh plugin --profile web add "$PWD" +``` + +The canonical artifact path is a prebuilt tarball: + +```bash +pnpm pack --pack-destination +dsh plugin --profile web add /dsh-loopx-plugin-0.1.0.tgz +``` + +Profile readback is boot-free and must show four Host rows plus durable JSON +storage-domain routing: + +```bash +dsh --profile web --dump-config +``` + +Expected rows are `loopx-service`, `loopx-command`, `loopx-tools`, and +`loopx-driver`. The `storage-domain` row must resolve `backend: json`. The +service declares `storageDomain` as a required injection and therefore stays +pending when that backend is absent; no memory-only fallback exists. + +## Local LoopX executable + +The plugin uses Node `execFile` with argv arrays. It never evaluates packet +command strings and does not invoke Python directly. Resolution is explicit +`loopxBin` config, then `LOOPX_BIN`, then the locally installed `loopx` on +`PATH`. The normal setup is therefore simply: + +```bash +command -v loopx +dsh --profile web +``` + +Use `LOOPX_BIN=/path/to/loopx dsh --profile web` when the binary is not on the +Host `PATH`. Optional config can pin `project`, `runtimeRoot`, timeouts and +byte caps, or a minimal child-only environment. The defaults are read timeout +15 seconds, write timeout 30 seconds, stdout 1 MiB, and stderr 256 KiB. + +## Same-Session lifecycle + +Send any task-bearing request through the visible DSH command surface: + +```text +/loopx implement the bounded change +/loopx attach Goal goal-123 and continue it here +/loopx status +``` + +Every non-empty suffix except exact `/loopx version` uses the same semantic +entry, including words such as `start`, `attach`, `status`, `pause`, `resume`, +and `detach`. The plugin queues one plugin-owned follow-up in the same Session, +preserving the original suffix as quoted user text plus compact routing +guidance. The current main DSH model handles one ordinary turn and may compose +the registered `loopx_*` typed tools. The command does not mutate LoopX before +that turn, run a classifier, create another Agent, or invoke a second model. + +If the Session is unbound, attachment requires both an explicit Goal id and +explicit binding intent; otherwise the model starts a new Goal from the +original request. If the Session is already bound, the current Goal remains +selected. Switching requires a different exact Goal id plus explicit switching +intent; detaching the current binding requires explicit detach intent but no +Goal id. The model never guesses or fuzzy-matches a Goal id. If it cannot +choose a safe operation, it asks for clarification without changing state. + +The routing text is prompt guidance rather than a machine-enforced hard +allowlist. Other DSH tools may remain visible; LoopX mutations are still bounded +by the registered typed schemas and authoritative service readback. Ordinary +language without `/loopx` retains DSH's normal model/tool-selection behavior. + +When the semantic turn selects `loopx_goal_start`, LoopX returns the exact +thread/Goal/agent identity and the structured `loopx_goal_start_command_v0` +planning contract. The tool projects it to +`dsh_loopx_planning_checkpoint_v0` and returns it directly to the model. The +model writes the bounded plan only through `loopx_todo_add`; then +`loopx_goal_activate` performs a suppressed-sink refresh and authoritative +reread, fetches the heartbeat task body into memory, and arms the driver. The +plugin keeps no parallel Todo receipt ledger; LoopX remains authoritative for +the Todo and refreshed task state. + +If that initiating turn becomes idle before activation, the live driver may +re-present the exact process-local checkpoint for one planning-only recovery +round. The opportunity is consumed only when the follow-up passes pre-step +admission; yielding a queued copy to human input does not consume it. Planning +recovery does not call `quota should-run`, fetch a delivery task body, or spend +delivery quota. If the admitted recovery still does not activate the Goal, the +driver remains quiet until the user explicitly continues. + +A stable DSH Session with no prior binding defaults to a distinct public-safe +LoopX peer identity, so both `/loopx ` and semantic start can enter the +planning checkpoint without choosing an existing lane. Verified same-Session +bindings are reused; takeover of an existing peer remains explicit, while a +host without a stable Session id fails closed. + +For a fresh project, the plugin validates the structured +`loopx_start_goal_connect_v0` packet, constructs a locally owned and allowlisted +`loopx bootstrap` argv, validates `loopx_bootstrap_result_v0`, and rereads the +authoritative guided projection. It never executes packet command text, accepts +model-supplied argv, or edits a registry directly. Unknown versions and +malformed legacy connection states fail closed with actionable upgrade or +repair guidance. + +Fresh-agent registration runs the same source-to-global sync as a read-only +preflight before changing the source registry. A +`LOOPX_REGISTRY_INTEGRITY` result is therefore a deterministic pre-write +failure; run `loopx sync-global --goal-id --dry-run` and repair the +reported registry contract before retrying. A `LOOPX_WRITE_UNCERTAIN` result +instead means the source write may exist while global sync or exact readback is +unverified. Do not generate another peer: reconcile the source/global agent +sets before binding the Session. + +Existing Goals require an explicit lane decision: + +```text +/loopx attach +/loopx attach --new-peer +``` + +Natural-language attach requests use `loopx_goal_attach` with an exact Goal +selection. If start or attach targets a different Goal from the one historically +bound to this Session, the first call returns `switch_required` without +mutation. Only after explicit user confirmation may the model repeat the same +typed operation with its `switchConfirmation` token. The token is short-lived, +operation-bound, process-memory-only, and revalidated against the exact current +Goal and agent inside the per-Session queue. + +The model-facing surface contains exactly eleven tools: + +- `loopx_goal_start` +- `loopx_goal_attach` +- `loopx_goal_activate` +- `loopx_status` +- `loopx_goal_detach` +- `loopx_driver_pause` +- `loopx_driver_resume` +- `loopx_todo_add` +- `loopx_todo_claim` +- `loopx_todo_update` +- `loopx_todo_complete` + +All derive the current Session identity. Alternate Session ids, registry +paths, task bodies, arbitrary argv, and unsupported fields are rejected and +the active driver fails closed. + +After activation, each idle boundary calls `loopx quota should-run` with +runtime profile `generic_cli`, scheduler detail, and one unique turn identity. +A certain retryable failure gets at most one retry with that same identity. +Generation, message, pre-step, and lifecycle fences reject stale planning and +delivery follow-ups before model admission. + +## Observe, pause, resume, and detach + +```text +/loopx +/loopx version +/loopx status +/loopx pause +/loopx resume +/loopx detach +``` + +Empty `/loopx` retains the local status/help response. Exact `/loopx version` +returns only the installed `dsh-loopx-plugin` package version; it does not +invoke the LoopX CLI or inspect Goal, Todo, or Host binding state. `version` +with additional text and the other examples above enter the semantic path. +Their corresponding typed operations keep Host state separate from live LoopX +authority. Pause changes only driver state. Resume revalidates LoopX identity +and refetches task text before arming a fresh generation. Detach removes the +current Session binding and performs authoritative unbind readback; it does +not alter the Goal or Todo lifecycle. + +An uncertain detach stops a requested switch before the new Goal is started or +attached. If exact detach succeeds but the new operation fails, the Session is +reported honestly as unbound; the plugin does not claim to have restored the +old binding. + +Ordinary human messages temporarily preempt automatic continuation rather than +persistently pausing it. A queued automatic follow-up is removed so the human +turn runs first; already admitted work is allowed to settle. Once the human +turn is idle, the driver rereads the exact binding and, when still armed, asks +fresh quota before continuing. Direct command runs, explicit pause/detach or +switch, stale or uncertain readback, and Session/Agent disposal remain strong +fail-closed boundaries. + +Process-local authority never crosses DSH restart, Session resume or fork, or +plugin reload. A cold restore cannot reconstruct a planning body, so a binding +still in planning must be completed explicitly through natural language and +typed tools, or planned again. `/loopx resume` applies only to an activated +binding left paused by the lifecycle; it rereads exact LoopX authority before +arming a fresh generation. + +## Remove and rollback + +```bash +dsh plugin --profile web remove dsh-loopx-plugin +dsh --profile web --dump-config +``` + +Removal takes away the command, tools, service, and driver rows. It does not +delete LoopX state or purge the DSH storage-domain sidecar. v1 has no implicit +purge command. On reinstall, a stored armed binding cold-restores paused and +requires exact lifecycle readback plus explicit resume. + +Existing control words remain usable through the semantic `/loopx` entry, and +the prior five tools remain compatible. Typed start, attach, detach, driver +pause/resume, and Todo add are additive. Older consumers +may ignore the additive Python fields, but this +plugin fails closed when a required guided-connect, planning, refresh-state, or +bootstrap-result schema is unavailable. Roll back by removing the plugin or +installing the preceding package version; neither action migrates or rewrites +LoopX Goal/Todo authority. + +## Authority and privacy + +`ctx.loopx` and `ctx.goals` are fully isolated. DSH retains only Host binding +identity, locators, lifecycle phase/generation, scheduler bookkeeping, and a +bounded reason. Goal text, task bodies, and normal conversation content are not +copied into that sidecar or published as LoopX evidence; they still follow DSH +Session persistence. Raw command output, environment values, credentials, and +local logs are not projected into model output. + +Installing the provider grants only typed LoopX operations against derived +authoritative locators; it grants no arbitrary filesystem path, argv, shell, +network, credential, production, or cross-Session authority. Multi-Host +processes sharing one storage root, cross-machine scheduling, and hostile +local callers are outside the v1 threat model. + +## Hermetic acceptance + +Maintainers validate both a built package directory and its tarball against a +temporary `DSH_HOME`: + +```bash +node smoke/dsh-profile-smoke.mjs \ + --package-path . \ + --tarball /dsh-loopx-plugin-0.1.0.tgz +``` + +The smoke performs real DSH plugin add/dump/remove operations, uses a mock +LoopX executable, and checks all eleven registered tools, the versioned fresh +connect/bootstrap exchange, single-follow-up semantic command entry, typed Todo +writeback plus one-shot planning recovery and activation, quota continuation, +human-input yield with fresh continuation, sidecar privacy, and tarball +contents. It does not start a model, access the network, require credentials, +or touch the user's existing DSH Profile. + +## Related contracts + +- [External DeepSeek Harness connector](deepseek-harness-connector.md) +- [Runtime connector catalog](runtime-connector-catalog.md) +- [Host integration surface v0](../reference/protocols/host-integration-surface-v0.md) +- [LoopX Turn v0](../reference/protocols/loopx-turn-v0.md) diff --git a/docs/integrations/runtime-connector-catalog.md b/docs/integrations/runtime-connector-catalog.md index 1334119f1..6f58e6999 100644 --- a/docs/integrations/runtime-connector-catalog.md +++ b/docs/integrations/runtime-connector-catalog.md @@ -14,37 +14,38 @@ about the work. ## Connector Fields -| Field | Meaning | -| --- | --- | -| `id` | Stable connector id used by docs, status projections, and smokes. | -| `surface` | User-visible host surface or runtime family. | -| `execution_mode` | How the host loop runs: visible TUI, app heartbeat, local scheduler, webhook, or bridge. | -| `wake_triggers` | What starts one LoopX-controlled turn. | -| `state_writeback` | The LoopX write path after validated work. | -| `liveness_signal` | Minimal signal that the host loop is alive without copying raw logs. | -| `stop_reset_policy` | How scheduler hints, final checks, or host stop rules apply. | -| `budget_meter` | How the connector maps work to quota or no-spend monitor policy. | -| `human_visibility` | What the user can see without reading private state. | -| `boundary` | What the connector must not copy, infer, or mutate. | -| `smoke_expectation` | Focused public check that protects the connector contract. | +| Field | Meaning | +| ------------------- | ---------------------------------------------------------------------------------------- | +| `id` | Stable connector id used by docs, status projections, and smokes. | +| `surface` | User-visible host surface or runtime family. | +| `execution_mode` | How the host loop runs: visible TUI, app heartbeat, local scheduler, webhook, or bridge. | +| `wake_triggers` | What starts one LoopX-controlled turn. | +| `state_writeback` | The LoopX write path after validated work. | +| `liveness_signal` | Minimal signal that the host loop is alive without copying raw logs. | +| `stop_reset_policy` | How scheduler hints, final checks, or host stop rules apply. | +| `budget_meter` | How the connector maps work to quota or no-spend monitor policy. | +| `human_visibility` | What the user can see without reading private state. | +| `boundary` | What the connector must not copy, infer, or mutate. | +| `smoke_expectation` | Focused public check that protects the connector contract. | ## Initial Catalog -| id | surface | execution_mode | wake_triggers | state_writeback | liveness_signal | stop_reset_policy | budget_meter | human_visibility | boundary | smoke_expectation | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| `codex_app_heartbeat` | Codex App automation | Scheduled headless app thread | Codex App heartbeat RRULE; `scheduler_hint.reset_policy.reset_token` | `todo` lifecycle, `refresh-state`, then `quota spend-slot` after validation | Heartbeat run plus quota event | Apply `scheduler_hint.codex_app` reset/backoff; cadence-only changes do not spend | Per-goal/per-agent quota slot after validated writeback | Visible thread, heartbeat XML, concrete user todo when required | Generated heartbeat prompt; scoped `--agent-id`; no project-specific prompt branches | Prompt smoke covers scheduler hint, reset token, identity, and no-spend cadence change. | -| `codex_app_ssh_goal` | Codex App connected to a remote workspace over SSH | Visible interactive Goal loop | Host `/goal` continuation; no automation-tool dependency | Same CLI todo/refresh/spend path, with `--source visible-goal` after validation | Visible Goal state plus compact LoopX status | Complete only on terminal no-follow-up; after three unchanged blocked turns, native `update_goal(status=blocked)` stops host continuation while LoopX remains active; user `/goal resume` reactivates it | Quota slot after validated writeback; no spend for gates, waits, final checks, or host blocking | User sees the active Codex task and its concrete gate or next action | Generated body stays within the `/goal` 4000-character limit and never invents `LOOPX_TURN` or calls `automation_update` | Agent-onboard smoke proves exact host selection, typed scheduler context, body budget, bounded quiet stop, and absence of heartbeat-only instructions. | -| `codex_cli_tui` | Codex CLI TUI | Visible interactive terminal loop | User bootstrap, `/goal`, or visible continuation | Same CLI todo/refresh/spend path | TUI transcript plus compact LoopX status | Uses the same native `update_goal(status=blocked)` and `/goal resume` contract after the typed unchanged limit | Quota slot after validated writeback; no spend for blocked/final-check transitions | User sees the active TUI turn | Do not silently switch to hidden headless execution or copy raw transcripts | TUI prompt/bootstrap smoke covers scoped identity and native blocked/resume semantics. | -| `claude_code_loop` | Claude Code loop | Visible local agent loop | Slash command, local loop tick, or host loop continuation | Same CLI todo/refresh/spend path | Loop status plus compact transcript pointer | Final quota/replan check before stop when unchanged limit is configured | Quota slot after validated writeback; no spend for stop/final check | User sees local loop status and response | No private material, credentials, production action, or hidden approval bypass | Loop smoke covers scoped identity, unchanged final check, and stop-without-spend. | -| `opencode_goal_loop` | OpenCode goal mode | Visible OpenCode goal plugin loop gated by LoopX | `/loopx ` with the opt-in OpenCode goal bridge installed | Same CLI todo/refresh/spend path through the bridge | Bridge status plus compact LoopX status | Final quota/replan check before loop stop when unchanged limit is configured | Quota slot after validated writeback; no spend for stop/final check | User sees the OpenCode goal turn and bridge status | Bridge install stays opt-in; do not copy raw transcripts, credentials, or local session paths | OpenCode bridge tests and host-mode selector smoke cover scoped identity and catalog parity. | -| `opencode2_goal_worker` | OpenCode 2 goal mode | Persistent out-of-process worker driving a visible OpenCode 2 session over its HTTP API | `loopx opencode2-goal-worker --goal-id --directory ` | Same CLI todo/refresh/spend path through the worker | Worker state file, host poll receipt, and compact LoopX status | Unchanged-poll limit stops the loop with a visible synthetic notice; probe failures retry with bounded backoff | Quota slot after validated writeback; no spend for waits, notices, or final checks | User sees the OpenCode 2 session turns, continuation prompts, and stop/pause notices | Worker state stays under `$XDG_STATE_HOME/loopx/opencode2`; do not copy raw transcripts, credentials, or local session paths | Worker contract tests cover the turn loop, visible stops, lease fencing, and user-message continuation. | -| `pi_goal_loop` | Pi goal mode | Visible Pi goal extension loop gated by LoopX | `/loopx ` with the opt-in Pi goal extension installed | Same CLI todo/refresh/spend path through the extension | Extension status plus compact LoopX status | Final quota/replan check before loop stop when unchanged limit is configured | Quota slot after validated writeback; no spend for stop/final check | User sees the Pi goal turn and extension status | Extension install stays opt-in; bindings stay under the project `.loopx/` tree; do not copy raw transcripts, credentials, or local session paths | Pi extension source-contract tests and host-mode selector smoke cover scoped identity and catalog parity. | -| `shell_worker` | Shell, cron, launchd, or service timer | Headless local command | Cron/service/manual shell wakeup | CLI writeback commands from the project checkout | Exit code, run id, and compact status | Obey local `scheduler_hint` backoff/reset; fail closed on missing goal or agent id | Quota slot for delivery; monitor-only polls stay no-spend | Logs or status command, not raw state files | Do not bake local paths, secrets, or project policy into reusable scripts | Command examples use global registry, `--agent-id`, and no-spend monitor behavior. | -| `http_webhook` | HTTP webhook or local daemon | Request-driven bridge | Loopback callback, webhook, or host event | Adapter validates, then emits LoopX todo/gate/evidence events | Request log plus compact status export | Webhooks do not self-poll; scheduler hints are advisory unless a scheduler owns the retry | Quota spend only after accepted writeback | Dashboard/status feed | Loopback by default; write endpoints require explicit dry-run/preview and CLI-equivalent fallback | Loopback smoke rejects remote status/write authority and proves preview-gated writes. | -| `worker_bridge` | Worker bridge | External executor, task container, or remote worker bridge | Worker event, bridge message, or runner sidecar | Bridge emits compact public-safe state, todo, or evidence | Worker heartbeat/status and compact counter trace | Host-specific stop/reset maps back to scheduler hints and outcome policy | Quota event for accepted work; bridge evidence grants no task-score authority | Dashboard/frontstage projection and compact evidence timeline | Strip raw logs, local paths, private traces, task text, and credentials | Worker bridge install/status smoke proves source mount, counter trace, and private-boundary stripping. | -| `computer_use_runtime` | Browser, desktop, or app automation runtime (a provider/runtime execution surface, not a LoopX product capability or a `value-connectors` connector) | Visible or replayable UI execution surface | Bounded action request from an owning capability, host replay event, or user takeover handoff | Compact typed receipt (facts only) handed back to the owning capability's domain-local reducer, which proposes the LoopX gate/evidence writeback for Kernel validation | Host-owned replay/screenshot pointer plus compact receipt fields | Stop at unknown modal, privacy ambiguity, or final external-write action; scheduler hints still come from LoopX quota | Quota spend only after the owning capability's reducer proposal is accepted by the Kernel; readiness/profile checks stay no-spend | Review card with intended action, forbidden effect classes, evidence handle, and takeover path | Do not copy credentials, cookies, raw screenshots, private UI bodies, or perform sends/purchases/production mutations without exact gate; a provider must never author the Kernel writeback itself | Synthetic runtime-profile/action-request/receipt smokes prove gate-before-write, raw-evidence stripping, and rejection of provider-authored writeback fields. | -| `deepseek_harness_loop` | DeepSeek Harness | Isolated headless bounded execution through LoopX Turn | `loopx turn run-once` with `loopx.dsh_goal_mode` (compat: `scripts/dsh_turn_host_adapter.py`) | Same CLI todo/refresh/spend path after validated dsh result | Compact Turn receipt plus local dsh session pointer | Outer controller obeys scheduler hints; preview/failed validation stays no-spend | Quota slot only after validated writeback | Operator sees typed result, validator receipt, and next preview command | Do not copy dsh JSONL sessions, raw transcripts, credentials, local paths, or model tool logs | Adapter smoke, fake-dsh e2e, and real-dsh e2e prove typed result shaping, real dsh runtime startup, writeback, and replay idempotence. | -| `loopx_turn` | LoopX Turn host adapter | Isolated headless bounded execution | `loopx host-mode-plan` selects the mode, then `loopx turn plan` previews one typed decision | `loopx turn run-once --execute` writes back only after independent validation | Compact Turn receipt and scheduler execution context | Outer controller obeys scheduler hints; cadence-only/preview work stays no-spend | Quota slot only after validated writeback | Operator sees selected host, execution mode, validator requirement, and next preview command | Do not publish opaque session handles, raw transcripts, local paths, credentials, or host-local logs | Host-mode-plan smoke proves host-mode selection, scoped identity, Turn mapping, and visible/headless/hybrid handoff readiness. | +| id | surface | execution_mode | wake_triggers | state_writeback | liveness_signal | stop_reset_policy | budget_meter | human_visibility | boundary | smoke_expectation | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `codex_app_heartbeat` | Codex App automation | Scheduled headless app thread | Codex App heartbeat RRULE; `scheduler_hint.reset_policy.reset_token` | `todo` lifecycle, `refresh-state`, then `quota spend-slot` after validation | Heartbeat run plus quota event | Apply `scheduler_hint.codex_app` reset/backoff; cadence-only changes do not spend | Per-goal/per-agent quota slot after validated writeback | Visible thread, heartbeat XML, concrete user todo when required | Generated heartbeat prompt; scoped `--agent-id`; no project-specific prompt branches | Prompt smoke covers scheduler hint, reset token, identity, and no-spend cadence change. | +| `codex_app_ssh_goal` | Codex App connected to a remote workspace over SSH | Visible interactive Goal loop | Host `/goal` continuation; no automation-tool dependency | Same CLI todo/refresh/spend path, with `--source visible-goal` after validation | Visible Goal state plus compact LoopX status | Complete only on terminal no-follow-up; after three unchanged blocked turns, native `update_goal(status=blocked)` stops host continuation while LoopX remains active; user `/goal resume` reactivates it | Quota slot after validated writeback; no spend for gates, waits, final checks, or host blocking | User sees the active Codex task and its concrete gate or next action | Generated body stays within the `/goal` 4000-character limit and never invents `LOOPX_TURN` or calls `automation_update` | Agent-onboard smoke proves exact host selection, typed scheduler context, body budget, bounded quiet stop, and absence of heartbeat-only instructions. | +| `codex_cli_tui` | Codex CLI TUI | Visible interactive terminal loop | User bootstrap, `/goal`, or visible continuation | Same CLI todo/refresh/spend path | TUI transcript plus compact LoopX status | Uses the same native `update_goal(status=blocked)` and `/goal resume` contract after the typed unchanged limit | Quota slot after validated writeback; no spend for blocked/final-check transitions | User sees the active TUI turn | Do not silently switch to hidden headless execution or copy raw transcripts | TUI prompt/bootstrap smoke covers scoped identity and native blocked/resume semantics. | +| `claude_code_loop` | Claude Code loop | Visible local agent loop | Slash command, local loop tick, or host loop continuation | Same CLI todo/refresh/spend path | Loop status plus compact transcript pointer | Final quota/replan check before stop when unchanged limit is configured | Quota slot after validated writeback; no spend for stop/final check | User sees local loop status and response | No private material, credentials, production action, or hidden approval bypass | Loop smoke covers scoped identity, unchanged final check, and stop-without-spend. | +| `opencode_goal_loop` | OpenCode goal mode | Visible OpenCode goal plugin loop gated by LoopX | `/loopx ` with the opt-in OpenCode goal bridge installed | Same CLI todo/refresh/spend path through the bridge | Bridge status plus compact LoopX status | Final quota/replan check before loop stop when unchanged limit is configured | Quota slot after validated writeback; no spend for stop/final check | User sees the OpenCode goal turn and bridge status | Bridge install stays opt-in; do not copy raw transcripts, credentials, or local session paths | OpenCode bridge tests and host-mode selector smoke cover scoped identity and catalog parity. | +| `opencode2_goal_worker` | OpenCode 2 goal mode | Persistent out-of-process worker driving a visible OpenCode 2 session over its HTTP API | `loopx opencode2-goal-worker --goal-id --directory ` | Same CLI todo/refresh/spend path through the worker | Worker state file, host poll receipt, and compact LoopX status | Unchanged-poll limit stops the loop with a visible synthetic notice; probe failures retry with bounded backoff | Quota slot after validated writeback; no spend for waits, notices, or final checks | User sees the OpenCode 2 session turns, continuation prompts, and stop/pause notices | Worker state stays under `$XDG_STATE_HOME/loopx/opencode2`; do not copy raw transcripts, credentials, or local session paths | Worker contract tests cover the turn loop, visible stops, lease fencing, and user-message continuation. | +| `pi_goal_loop` | Pi goal mode | Visible Pi goal extension loop gated by LoopX | `/loopx ` with the opt-in Pi goal extension installed | Same CLI todo/refresh/spend path through the extension | Extension status plus compact LoopX status | Final quota/replan check before loop stop when unchanged limit is configured | Quota slot after validated writeback; no spend for stop/final check | User sees the Pi goal turn and extension status | Extension install stays opt-in; bindings stay under the project `.loopx/` tree; do not copy raw transcripts, credentials, or local session paths | Pi extension source-contract tests and host-mode selector smoke cover scoped identity and catalog parity. | +| `shell_worker` | Shell, cron, launchd, or service timer | Headless local command | Cron/service/manual shell wakeup | CLI writeback commands from the project checkout | Exit code, run id, and compact status | Obey local `scheduler_hint` backoff/reset; fail closed on missing goal or agent id | Quota slot for delivery; monitor-only polls stay no-spend | Logs or status command, not raw state files | Do not bake local paths, secrets, or project policy into reusable scripts | Command examples use global registry, `--agent-id`, and no-spend monitor behavior. | +| `http_webhook` | HTTP webhook or local daemon | Request-driven bridge | Loopback callback, webhook, or host event | Adapter validates, then emits LoopX todo/gate/evidence events | Request log plus compact status export | Webhooks do not self-poll; scheduler hints are advisory unless a scheduler owns the retry | Quota spend only after accepted writeback | Dashboard/status feed | Loopback by default; write endpoints require explicit dry-run/preview and CLI-equivalent fallback | Loopback smoke rejects remote status/write authority and proves preview-gated writes. | +| `worker_bridge` | Worker bridge | External executor, task container, or remote worker bridge | Worker event, bridge message, or runner sidecar | Bridge emits compact public-safe state, todo, or evidence | Worker heartbeat/status and compact counter trace | Host-specific stop/reset maps back to scheduler hints and outcome policy | Quota event for accepted work; bridge evidence grants no task-score authority | Dashboard/frontstage projection and compact evidence timeline | Strip raw logs, local paths, private traces, task text, and credentials | Worker bridge install/status smoke proves source mount, counter trace, and private-boundary stripping. | +| `computer_use_runtime` | Browser, desktop, or app automation runtime (a provider/runtime execution surface, not a LoopX product capability or a `value-connectors` connector) | Visible or replayable UI execution surface | Bounded action request from an owning capability, host replay event, or user takeover handoff | Compact typed receipt (facts only) handed back to the owning capability's domain-local reducer, which proposes the LoopX gate/evidence writeback for Kernel validation | Host-owned replay/screenshot pointer plus compact receipt fields | Stop at unknown modal, privacy ambiguity, or final external-write action; scheduler hints still come from LoopX quota | Quota spend only after the owning capability's reducer proposal is accepted by the Kernel; readiness/profile checks stay no-spend | Review card with intended action, forbidden effect classes, evidence handle, and takeover path | Do not copy credentials, cookies, raw screenshots, private UI bodies, or perform sends/purchases/production mutations without exact gate; a provider must never author the Kernel writeback itself | Synthetic runtime-profile/action-request/receipt smokes prove gate-before-write, raw-evidence stripping, and rejection of provider-authored writeback fields. | +| `deepseek_harness_loop` | DeepSeek Harness | Isolated headless bounded execution through LoopX Turn | `loopx turn run-once` with `scripts/dsh_turn_host_adapter.py` | Same CLI todo/refresh/spend path after validated dsh result | Compact Turn receipt plus local dsh session pointer | Outer controller obeys scheduler hints; preview/failed validation stays no-spend | Quota slot only after validated writeback | Operator sees typed result, validator receipt, and next preview command | Do not copy dsh JSONL sessions, raw transcripts, credentials, local paths, or model tool logs | Adapter smoke, fake-dsh e2e, and real-dsh e2e prove typed result shaping, real dsh runtime startup, writeback, and replay idempotence. | +| `deepseek_harness_native_loop` | DeepSeek Harness native LoopX plugin | Visible same-process continuation in the current DSH Session | `/loopx `, explicit attach/resume, DSH idle transition, or a LoopX scheduler timer | Five bounded tools call LoopX CLI contracts for exact current-Session Goal/Todo mutations; DSH stores only Host binding sidecar state | `/loopx status` separates live LoopX authority from Host phase/generation and bounded scheduler state | One generation-fenced evaluation/timer/follow-up; foreign input pauses locally; quiet at the unchanged limit; stop only on LoopX-validated terminal closure | `quota should-run --runtime-profile generic_cli` per idle turn; one same-turn retry only for certain retryable failures | User sees the planning checkpoint, same-Agent follow-up, status, selection gate, and pause/resume/detach results | `ctx.loopx` is isolated from `ctx.goals`; no alternate Session/registry/argv, raw task body persistence, transcript/log copy, credentials, or added file/shell/network authority | Package unit/race suite and temporary web-profile path/tarball smoke prove activation, status, idle continuation, preemption, storage boundary, install readback, and removal. | +| `loopx_turn` | LoopX Turn host adapter | Isolated headless bounded execution | `loopx host-mode-plan` selects the mode, then `loopx turn plan` previews one typed decision | `loopx turn run-once --execute` writes back only after independent validation | Compact Turn receipt and scheduler execution context | Outer controller obeys scheduler hints; cadence-only/preview work stays no-spend | Quota slot only after validated writeback | Operator sees selected host, execution mode, validator requirement, and next preview command | Do not publish opaque session handles, raw transcripts, local paths, credentials, or host-local logs | Host-mode-plan smoke proves host-mode selection, scoped identity, Turn mapping, and visible/headless/hybrid handoff readiness. | ### Reusable shell_worker reference @@ -74,8 +75,8 @@ The entries below are discovery notes, not availability claims. Cataloging an extension does not add a LoopX feature, advertise an available capability, or grant credentials, network access, private reads, or external-write authority. -| id | upstream surface | status | possible LoopX binding | boundary before integration | promotion evidence | -| --- | --- | --- | --- | --- | --- | +| id | upstream surface | status | possible LoopX binding | boundary before integration | promotion evidence | +| --------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `official_xmcp` | X Developer Platform [XMCP](https://github.com/xdevplatform/xmcp) and [official MCP documentation](https://docs.x.com/tools/mcp) | `catalogued_not_integrated`; no LoopX install check or live qualification | Optional MCP provider for the existing `content-ops` / `social_browser_x` outcome path; not a new capability and not a replacement control plane | Host owns OAuth material and X API cost/rate limits. Start with an explicit read-only tool allowlist. Posting, replies, likes, follows, DMs, account changes, paid queries, and private expansion require exact LoopX gates. Do not project raw posts, timelines, DMs, tokens, or MCP payloads into public state. | Provider-neutral operation map; credential-free install/readiness check; metadata-only public-read packet; exact write/private/cost gate plan; compact receipt; focused contract smoke. Live X E2E is a later owner-authorized qualification, not required for catalog status. | XMCP is an official local MCP server that derives more than 200 tools from the diff --git a/loopx/agent_onboarding.py b/loopx/agent_onboarding.py index 03256abb5..51dffe80a 100644 --- a/loopx/agent_onboarding.py +++ b/loopx/agent_onboarding.py @@ -257,6 +257,7 @@ def _bootstrap_pack_command( "pi": "pi", "gemini-cli": "gemini-cli", "cursor-agent": "cursor-agent", + "deepseek-harness-native": "deepseek-harness-native", "deepseek-harness": "deepseek-harness", "ark-managed-agent": "ark-managed-agent", "manual": "shell", @@ -319,6 +320,13 @@ def _start_instruction(agent_type: str) -> str: "`scripts/dsh_turn_host_adapter.py` launcher still works) as the " "generic-cli host adapter; every tick starts from `quota should-run`." ) + if agent_type == "deepseek-harness-native": + return ( + "Install `packages/dsh-loopx-plugin` in the DSH Profile, then run " + "`/loopx ` in the current DSH Session; after Todo writeback call " + "`loopx_goal_activate`, and let the plugin gate follow-ups through " + "`quota should-run`." + ) if agent_type == "ark-managed-agent": return ( "Use `$loopx ` as the ordinary task entry; after its todo " diff --git a/loopx/bootstrap_command_pack.py b/loopx/bootstrap_command_pack.py index 0e627b201..f6a070a10 100644 --- a/loopx/bootstrap_command_pack.py +++ b/loopx/bootstrap_command_pack.py @@ -21,6 +21,7 @@ from .host_loop_activation import ( agent_type_for_host_surface, build_host_loop_activation_packet, + normalize_host_surface, scheduler_command_binding_for_agent_type, ) from .project_alias import resolve_canonical_project_alias @@ -33,13 +34,21 @@ render_scheduler_execution_args, shell_arg, ) +from .paths import global_registry_path, resolve_runtime_root from .registry import registry_goals, resolve_state_file from .slash_commands import build_slash_command_catalog -from .thread_agent_binding import normalize_thread_id, resolve_thread_agent_binding +from .thread_agent_binding import ( + DSH_HOST_SURFACE, + HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + normalize_thread_id, + resolve_dsh_thread_agent_binding, + resolve_thread_agent_binding, +) SCHEMA_VERSION = "loopx_bootstrap_command_pack_v0" CANONICAL_SLASH_COMMAND = "/loopx" GUIDED_START_SCHEMA_VERSION = "loopx_start_goal_guided_v0" +START_GOAL_CONNECT_SCHEMA_VERSION = "loopx_start_goal_connect_v0" PACKET_SUMMARY_SCHEMA_VERSION = "loopx_start_goal_packet_summary_v0" PACKET_MEASUREMENT_SCHEMA_VERSION = "loopx_packet_duplication_measurement_v0" GUIDED_COMMAND_PACK_PROJECTION_SCHEMA_VERSION = ( @@ -60,6 +69,8 @@ "pi", "gemini-cli", "cursor-agent", + "dsh", + "deepseek-harness-native", "deepseek-harness", "ark-managed-agent", "shell", @@ -277,6 +288,14 @@ def _guided_command_pack_projection( "safety_contract": command_pack.get("safety_contract"), "detail_command": detail_command, } + for field in ( + "host_thread_binding", + "host_thread_binding_resolution", + "error_kind", + "error", + ): + if command_pack.get(field) is not None: + projection[field] = command_pack[field] projection["packet_summary"] = _build_packet_summary( projection, packet_kind="bootstrap_command_pack_projection", @@ -323,6 +342,8 @@ def build_start_goal_host_surface_selection_packet( "pi": "Pi LoopX goal extension", "gemini-cli": "Gemini CLI driving its own loop through the LoopX skill facade", "cursor-agent": "cursor-agent driving its own loop through the LoopX skill facade and MCP server", + "dsh": "DeepSeek Harness same-session LoopX plugin using global Host binding v1", + "deepseek-harness-native": "DeepSeek Harness same-session LoopX plugin", "deepseek-harness": "DeepSeek Harness automation loop through loopx.dsh_goal_mode (compat: scripts/dsh_turn_host_adapter.py)", "ark-managed-agent": "Ark Managed Agent with one-shot Goal submission", "shell": "manual shell or an explicitly configured external scheduler", @@ -650,6 +671,26 @@ def _goal_start_bootstrap_command( return "\n".join(lines) +def _goal_start_connect_contract( + *, + goal_id: str, + objective: str, + fine_grained: bool, +) -> dict[str, Any]: + """Return the allowlisted data contract for the conditional bootstrap.""" + + return { + "schema_version": START_GOAL_CONNECT_SCHEMA_VERSION, + "operation": "bootstrap_connect", + "goal_id": goal_id, + "objective": objective, + "adapter_kind": DEFAULT_HANDOFF_ADAPTER_KIND, + "adapter_status": DEFAULT_HANDOFF_ADAPTER_STATUS, + "onboarding_scan_enabled": False, + "fine_grained": fine_grained, + } + + def _selected_goal_capability_route( capability_route: str | None, ) -> dict[str, Any] | None: @@ -706,6 +747,7 @@ def build_loopx_bootstrap_command_pack( agent_id: str | None, cli_bin: str, host_surface: str, + runtime_root_override: str | None = None, goal_text: str | None = None, thread_id: str | None = None, new_peer: bool = False, @@ -714,6 +756,12 @@ def build_loopx_bootstrap_command_pack( fine_grained: bool = False, resolve_linked_worktree_alias: bool = True, ) -> dict[str, Any]: + dsh_global_binding = str(host_surface or "").strip().lower() == DSH_HOST_SURFACE + host_surface = ( + DSH_HOST_SURFACE + if dsh_global_binding + else normalize_host_surface(host_surface) + ) inspection = inspect_bootstrap_connection( project, goal_id=goal_id, @@ -730,9 +778,13 @@ def build_loopx_bootstrap_command_pack( cli_bin=cli_bin, goal_id="", ) - agent_type = agent_type_for_host_surface(host_surface) + agent_type = ( + "deepseek-harness-native" + if dsh_global_binding + else agent_type_for_host_surface(host_surface) + ) registry_path = Path(str(inspection["registry"])) - registry_payload, _registry_error = _read_registry(registry_path) + registry_payload, registry_error = _read_registry(registry_path) registry_goal = next( ( goal @@ -742,11 +794,78 @@ def build_loopx_bootstrap_command_pack( None, ) registered_agents = registered_agent_ids_for_goal(registry_goal) - thread_binding = resolve_thread_agent_binding( - registry_goal, - host_surface=host_surface, - thread_id=normalized_thread_id, - ) + dsh_binding_result: dict[str, Any] | None = None + if dsh_global_binding and normalized_thread_id: + if runtime_root_override: + runtime_root = Path(runtime_root_override).expanduser() + else: + declared_root = ( + registry_payload.get("common_runtime_root") + if registry_payload is not None + else None + ) + if registry_payload is None or ( + declared_root is not None and not isinstance(declared_root, str) + ): + dsh_binding_result = { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": False, + "changed": False, + "application": "no", + "error_kind": ( + "authority_corrupt" + if registry_error is not None + else "binding_home_unavailable" + ), + } + runtime_root = None + else: + runtime_root = resolve_runtime_root( + registry_payload, + None, + registry_path=registry_path, + ) + if runtime_root is not None: + dsh_binding_result = resolve_dsh_thread_agent_binding( + global_path=global_registry_path(runtime_root), + host_surface=DSH_HOST_SURFACE, + thread_id=normalized_thread_id, + ) + dsh_binding = ( + dsh_binding_result.get("binding") + if dsh_binding_result.get("ok") + and isinstance(dsh_binding_result.get("binding"), dict) + else None + ) + dsh_target = ( + dsh_binding.get("target") + if isinstance(dsh_binding, dict) + and isinstance(dsh_binding.get("target"), dict) + else {} + ) + dsh_bound_here = bool( + dsh_binding + and dsh_binding.get("state") == "bound" + and dsh_target.get("goal_id") == resolved_goal_id + ) + thread_binding = { + "status": ( + "bound" + if dsh_bound_here + else "missing" + if dsh_binding_result.get("error_kind") + in {"binding_not_found", "binding_home_uninitialized"} + or (dsh_binding and dsh_binding.get("state") == "unbound") + else "unavailable" + ), + "agent_id": dsh_target.get("agent_id") if dsh_bound_here else None, + } + else: + thread_binding = resolve_thread_agent_binding( + registry_goal, + host_surface=host_surface, + thread_id=normalized_thread_id, + ) has_registered_agents = bool(registered_agents) binding_missing = thread_binding.get("status") == "missing" thread_binding["selection_required"] = bool( @@ -761,7 +880,15 @@ def build_loopx_bootstrap_command_pack( fresh_agent_default = bool( explicit_goal_start - and (new_peer or not has_registered_agents) + and ( + new_peer + or not has_registered_agents + or ( + host_surface in {DSH_HOST_SURFACE, "deepseek-harness-native"} + and normalized_thread_id + and binding_missing + ) + ) ) bootstrap_preview_command = _bootstrap_command( @@ -792,6 +919,40 @@ def build_loopx_bootstrap_command_pack( thread_binding_projection = {"status": thread_binding.get("status")} if thread_binding.get("agent_id"): thread_binding_projection["agent_id"] = thread_binding["agent_id"] + dsh_authoritative_binding = ( + dsh_binding_result.get("binding") + if dsh_binding_result + and dsh_binding_result.get("ok") + and isinstance(dsh_binding_result.get("binding"), dict) + else None + ) + dsh_authoritative_target = ( + dsh_authoritative_binding.get("target") + if isinstance(dsh_authoritative_binding, dict) + and isinstance(dsh_authoritative_binding.get("target"), dict) + else {} + ) + dsh_expected_revision = ( + int(dsh_authoritative_binding["revision"]) + if isinstance(dsh_authoritative_binding, dict) + else 0 + if dsh_binding_result + and dsh_binding_result.get("error_kind") + in {"binding_not_found", "binding_home_uninitialized"} + else None + ) + dsh_bind_required = bool( + dsh_global_binding + and normalized_thread_id + and selected_agent_id + and dsh_expected_revision is not None + and ( + not dsh_authoritative_binding + or dsh_authoritative_binding.get("state") != "bound" + or dsh_authoritative_target.get("goal_id") != resolved_goal_id + or dsh_authoritative_target.get("agent_id") != selected_agent_id + ) + ) issue_fix_commands = build_issue_fix_goal_command_templates( cli_bin=cli_bin, goal_id=resolved_goal_id, @@ -965,11 +1126,21 @@ def build_loopx_bootstrap_command_pack( "goal_start_bind_thread": ( f"{shell_arg(cli_bin)} bind-agent-thread --goal-id {shell_arg(resolved_goal_id)} " f"--thread-id {shell_arg(normalized_thread_id)} --host-surface {shell_arg(host_surface)} " - f"--agent-id {shell_arg(str(selected_agent_id))} --execute" + f"--agent-id {shell_arg(str(selected_agent_id))}" + + ( + f" --expected-revision {dsh_expected_revision}" + if dsh_global_binding + else "" + ) + + " --execute" if ( normalized_thread_id and selected_agent_id - and thread_binding.get("status") == "missing" + and ( + dsh_bind_required + if dsh_global_binding + else thread_binding.get("status") == "missing" + ) ) else None ), @@ -1021,7 +1192,20 @@ def build_loopx_bootstrap_command_pack( } if normalized_thread_id: payload["thread_id"] = normalized_thread_id - payload["thread_agent_binding"] = thread_binding_projection + if dsh_global_binding: + if dsh_authoritative_binding is not None: + payload["host_thread_binding"] = dsh_authoritative_binding + elif dsh_binding_result is not None: + payload["host_thread_binding_resolution"] = dsh_binding_result + if dsh_binding_result.get("error_kind") not in { + "binding_not_found", + "binding_home_uninitialized", + }: + payload["ok"] = False + payload["error_kind"] = dsh_binding_result.get("error_kind") + payload["error"] = "DSH Host binding authority could not be resolved" + else: + payload["thread_agent_binding"] = thread_binding_projection if new_peer: payload["new_peer"] = True payload["message"] = render_loopx_bootstrap_command_pack_message(payload) @@ -1070,6 +1254,11 @@ def _build_multi_goal_start_selection_packet( normalized_goal_text = " ".join(goal_text.split()) normalized_thread_id = normalize_thread_id(thread_id) resolved_project = str(inspection["project"]) + agent_type = ( + "deepseek-harness-native" + if host_surface == DSH_HOST_SURFACE + else agent_type_for_host_surface(host_surface) + ) issue_fix_commands = build_issue_fix_goal_command_templates( cli_bin=cli_bin, goal_id="", @@ -1156,7 +1345,7 @@ def _build_multi_goal_start_selection_packet( "goal_id": None, "agent_id": None, "requested_agent_id": agent_id, - "agent_type": agent_type_for_host_surface(host_surface), + "agent_type": agent_type, "host_surface": host_surface, "project_connection": connection, "goal_selection_gate": goal_selection_gate, @@ -1174,7 +1363,7 @@ def _build_multi_goal_start_selection_packet( capability_route ), connected=True, - agent_type=agent_type_for_host_surface(host_surface), + agent_type=agent_type, issue_fix_commands=issue_fix_commands, fine_grained=fine_grained, ), @@ -1316,6 +1505,7 @@ def build_start_goal_guided_packet( cli_bin: str, host_surface: str, goal_text: str, + runtime_root_override: str | None = None, thread_id: str | None = None, new_peer: bool = False, available_capabilities: list[str] | None = None, @@ -1323,6 +1513,11 @@ def build_start_goal_guided_packet( fine_grained: bool = False, include_command_pack_detail: bool = False, ) -> dict[str, Any]: + host_surface = ( + DSH_HOST_SURFACE + if str(host_surface or "").strip().lower() == DSH_HOST_SURFACE + else normalize_host_surface(host_surface) + ) if goal_id is None: selection_packet = _build_multi_goal_start_selection_packet( project=project, @@ -1347,6 +1542,7 @@ def build_start_goal_guided_packet( new_peer=new_peer, cli_bin=cli_bin, host_surface=host_surface, + runtime_root_override=runtime_root_override, goal_text=goal_text, available_capabilities=available_capabilities, capability_route=capability_route, @@ -1423,12 +1619,28 @@ def rerun_start_goal(selected_agent_id: str) -> str: "purpose": "bind thread; verify readback before Todo writeback", "must_stop_on_failure": True, "result_contract": { - "schema_version": "loopx_thread_agent_binding_continuation_v0", - "required_result": { - "ok": True, - "global_sync": {"ok": True}, - "registration_readback": {"verified": True}, - }, + "schema_version": ( + HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION + if host_surface == DSH_HOST_SURFACE + else "loopx_thread_agent_binding_continuation_v0" + ), + "required_result": ( + { + "ok": True, + "application": "yes", + "binding": { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": DSH_HOST_SURFACE, + "state": "bound", + }, + } + if host_surface == DSH_HOST_SURFACE + else { + "ok": True, + "global_sync": {"ok": True}, + "registration_readback": {"verified": True}, + } + ), }, } ] @@ -1480,6 +1692,11 @@ def rerun_start_goal(selected_agent_id: str) -> str: "id": "connect_if_needed", "kind": "conditional_mutation", "command": commands.get("goal_start_connect_if_needed"), + "connect_contract": _goal_start_connect_contract( + goal_id=str(command_pack.get("goal_id") or ""), + objective=str(command_pack.get("goal_text") or goal_text), + fine_grained=fine_grained, + ), "purpose": "create or reuse project-local LoopX state only when no matching goal exists", }, *bind_thread_steps, @@ -1673,7 +1890,23 @@ def rerun_start_goal(selected_agent_id: str) -> str: } if command_pack.get("thread_id"): payload["thread_id"] = command_pack["thread_id"] - payload["thread_agent_binding"] = command_pack.get("thread_agent_binding") + if command_pack.get("host_surface") == DSH_HOST_SURFACE: + if command_pack.get("host_thread_binding") is not None: + payload["host_thread_binding"] = command_pack.get( + "host_thread_binding" + ) + if command_pack.get("host_thread_binding_resolution") is not None: + payload["host_thread_binding_resolution"] = command_pack.get( + "host_thread_binding_resolution" + ) + if command_pack.get("error_kind") is not None: + payload["error_kind"] = command_pack.get("error_kind") + payload["error"] = command_pack.get("error") + payload["ok"] = False + else: + payload["thread_agent_binding"] = command_pack.get( + "thread_agent_binding" + ) if command_pack.get("new_peer"): payload["new_peer"] = True payload["message"] = render_start_goal_guided_markdown(payload) diff --git a/loopx/cli_commands/bootstrap_connect.py b/loopx/cli_commands/bootstrap_connect.py index 1d854acf4..2443329b4 100644 --- a/loopx/cli_commands/bootstrap_connect.py +++ b/loopx/cli_commands/bootstrap_connect.py @@ -14,6 +14,23 @@ [dict[str, object], str, Callable[[dict[str, object]], str]], None, ] +BOOTSTRAP_RESULT_SCHEMA_VERSION = "loopx_bootstrap_result_v0" + + +def _version_bootstrap_result(payload: dict[str, object]) -> dict[str, object]: + result = {**payload, "schema_version": BOOTSTRAP_RESULT_SCHEMA_VERSION} + if result.get("ok") is not False: + return result + + error_kind = result.get("error_kind") + if not isinstance(error_kind, str) or not error_kind.strip(): + global_sync = result.get("global_sync") + if isinstance(global_sync, dict): + error_kind = global_sync.get("error_kind") + if not isinstance(error_kind, str) or not error_kind.strip(): + error_kind = "bootstrap_connect_failed" + result["error_kind"] = error_kind + return result def register_bootstrap_connect_command(subparsers: argparse._SubParsersAction) -> None: @@ -182,12 +199,21 @@ def handle_bootstrap_connect_command( ) -> int | None: if args.command not in {"bootstrap", "connect"}: return None + if args.fork_goal and args.goal_id and args.fork_goal != args.goal_id: + payload = _version_bootstrap_result( + { + "ok": False, + "registry": str(registry_path), + "error_kind": "invalid_bootstrap_request", + "error": "--fork-goal cannot be combined with a different --goal-id", + } + ) + print_payload(payload, args.format, render_bootstrap_markdown) + return 1 try: runtime_root = Path(args.runtime_root).expanduser() if args.runtime_root else None state_file = Path(args.state_file).expanduser() if args.state_file else None goal_doc = Path(args.goal_doc).expanduser() if args.goal_doc else None - if args.fork_goal and args.goal_id and args.fork_goal != args.goal_id: - raise ValueError("--fork-goal cannot be combined with a different --goal-id") goal_id = args.fork_goal or args.goal_id payload = bootstrap_project( project=Path(args.project), @@ -232,7 +258,9 @@ def handle_bootstrap_connect_command( payload = { "ok": False, "registry": str(registry_path), + "error_kind": "bootstrap_connect_failed", "error": str(exc), } + payload = _version_bootstrap_result(payload) print_payload(payload, args.format, render_bootstrap_markdown) return 0 if payload.get("ok") else 1 diff --git a/loopx/cli_commands/project_lifecycle.py b/loopx/cli_commands/project_lifecycle.py index 3596b1db1..e4cf9c070 100644 --- a/loopx/cli_commands/project_lifecycle.py +++ b/loopx/cli_commands/project_lifecycle.py @@ -75,6 +75,8 @@ "operator-gate", } +REFRESH_STATE_RESULT_SCHEMA_VERSION = "loopx_refresh_state_result_v0" + INLINE_VISION_FIELDS = { "vision_summary": "vision_summary", "vision_role_scope": "role_scope", @@ -618,6 +620,7 @@ def handle_project_lifecycle_command( progress_observation = _inline_progress_observation(args) except Exception as exc: payload = { + "schema_version": REFRESH_STATE_RESULT_SCHEMA_VERSION, "ok": False, "registry": str(registry_path), "runtime_root": args.runtime_root, @@ -674,6 +677,7 @@ def handle_project_lifecycle_command( "dry_run": bool(args.dry_run), "error": str(exc), } + payload["schema_version"] = REFRESH_STATE_RESULT_SCHEMA_VERSION projected_capabilities = runtime_capabilities_for_cli_projection( args.available_capabilities ) diff --git a/loopx/cli_commands/quota.py b/loopx/cli_commands/quota.py index 8db472b1b..dddc1bc0c 100644 --- a/loopx/cli_commands/quota.py +++ b/loopx/cli_commands/quota.py @@ -89,6 +89,8 @@ [dict[str, object], str, Callable[[dict[str, object]], str]], None, ] + +QUOTA_SHOULD_RUN_SCHEMA_VERSION = "loopx_quota_should_run_v0" RolloutEventAppender = Callable[..., dict[str, object]] QUOTA_EVENT_KINDS = { "should-run": "quota_should_run", @@ -936,6 +938,8 @@ def handle_quota_command( payload, include_decision_detail="decisions" in detail_sections, ) + if args.quota_command == "should-run": + payload["schema_version"] = QUOTA_SHOULD_RUN_SCHEMA_VERSION if args.quota_command == "should-run" and context is not None: attach_host_poll_receipt( context.status_payload, diff --git a/loopx/cli_commands/registry_admin.py b/loopx/cli_commands/registry_admin.py index c7022e2c6..cb76bd09e 100644 --- a/loopx/cli_commands/registry_admin.py +++ b/loopx/cli_commands/registry_admin.py @@ -32,8 +32,14 @@ render_state_migration_markdown, ) from ..thread_agent_binding import ( + DSH_HOST_SURFACE, + HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + DshBindingAuthorityError, + bind_dsh_thread_agent_in_global_registry, bind_thread_agent_in_registry, + resolve_dsh_thread_agent_binding, resolve_thread_agent_binding, + unbind_dsh_thread_agent_in_global_registry, unbind_thread_agent_in_registry, ) from ..upgrade import build_upgrade_plan @@ -51,12 +57,18 @@ None, ] +REGISTER_AGENT_SCHEMA_VERSION = "loopx_register_agent_v0" +THREAD_AGENT_BINDING_COMMAND_SCHEMA_VERSION = ( + "loopx_thread_agent_binding_command_v0" +) + REGISTRY_ADMIN_COMMANDS = { "configure-goal", "goal-lifecycle", "register-agent", "bind-agent-thread", "unbind-agent-thread", + "resolve-agent-thread", "archive-runtime", "retire-global-goal", "uninstall-project", @@ -70,6 +82,47 @@ def explicit_global_registry(runtime_root_arg: str | None) -> Path: return global_registry_path(runtime_root) +def dsh_binding_global_registry( + *, + registry_path: Path, + runtime_root_arg: str | None, +) -> Path: + """Select exactly one DSH binding home without scanning runtime roots.""" + + if runtime_root_arg: + return global_registry_path(Path(runtime_root_arg).expanduser()) + expanded_registry = registry_path.expanduser() + if expanded_registry.name == global_registry_path(Path(".")).name: + return expanded_registry.parent / expanded_registry.name + if not expanded_registry.exists(): + raise DshBindingAuthorityError("binding_home_unavailable") + try: + registry = load_registry(expanded_registry) + except OSError as exc: + raise DshBindingAuthorityError("binding_home_unavailable") from exc + except ValueError as exc: + raise DshBindingAuthorityError("authority_corrupt") from exc + declared_root = registry.get("common_runtime_root") + if declared_root is not None and not isinstance(declared_root, str): + raise DshBindingAuthorityError("binding_home_unavailable") + runtime_root = resolve_runtime_root( + registry, + None, + registry_path=expanded_registry, + ) + return global_registry_path(runtime_root) + + +def _dsh_binding_failure(error_kind: str) -> dict[str, object]: + return { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": False, + "changed": False, + "application": "no", + "error_kind": error_kind, + } + + def _registry_goal(path: Path, goal_id: str) -> dict[str, object]: payload = load_registry(path) goal = next((item for item in registry_goals(payload) if item.get("id") == goal_id), None) @@ -92,6 +145,44 @@ def _fresh_agent_collision_payload( existing_agents: list[str], requested_agents: list[str], collisions: list[str], +) -> dict[str, object]: + return _agent_registration_failure_payload( + execute=execute, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + registered_agents=existing_agents, + error_kind="agent_identity_already_registered", + error=( + "fresh agent registration requires an unused agent id; already " + f"registered: {', '.join(collisions)}" + ), + recommended_action=( + "choose a different public-safe agent id and rerun the preview; continue " + "only after the execute result reports ok=true, changed=true, and written=true" + ), + ) + + +def _agent_registration_failure_payload( + *, + execute: bool, + goal_id: str, + global_path: Path, + source_registry_path: Path, + existing_agents: list[str], + requested_agents: list[str], + error_kind: str, + error: str, + recommended_action: object, + registered_agents: list[str] | None = None, + changed: bool = False, + written: bool = False, + partial_write: bool = False, + global_sync: dict[str, object] | None = None, + registration_readback: dict[str, object] | None = None, ) -> dict[str, object]: return { "ok": False, @@ -102,18 +193,29 @@ def _fresh_agent_collision_payload( "source_registry": str(source_registry_path), "existing_agents": existing_agents, "requested_agents": requested_agents, - "registered_agents": existing_agents, - "changed": False, - "written": False, - "error_kind": "agent_identity_already_registered", - "error": ( - "fresh agent registration requires an unused agent id; already " - f"registered: {', '.join(collisions)}" - ), - "recommended_action": ( - "choose a different public-safe agent id and rerun the preview; continue " - "only after the execute result reports ok=true, changed=true, and written=true" + "registered_agents": ( + registered_agents if registered_agents is not None else existing_agents ), + "changed": changed, + "written": written, + "partial_write": partial_write, + "error_kind": error_kind, + "error": error, + "recommended_action": recommended_action, + "global_sync": global_sync + or { + "ok": False, + "enabled": execute, + "wrote": False, + "skipped": True, + "error_kind": error_kind, + }, + "registration_readback": registration_readback + or { + "schema_version": "loopx_agent_registration_readback_v0", + "performed": False, + "verified": False, + }, } @@ -184,37 +286,40 @@ def register_agent_via_source_registry( if execute: global_writability = probe_registry_write_path(global_path, create_parent=True) if not global_writability.get("ok"): - return { - "ok": False, - "dry_run": False, - "execute": True, - "goal_id": goal_id, - "global_registry": str(global_path), - "source_registry": str(source_registry_path), - "existing_agents": existing_agents, - "requested_agents": requested_agents, - "registered_agents": merged_agents, - "changed": merged_agents != existing_agents, - "written": False, - "host_loop_activation": loop_activation_for_goal( - registry_path=global_path, - runtime_root_arg=runtime_root_arg, - goal_id=goal_id, + result = _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + error_kind="global_registry_write_denied", + error=str( + global_writability.get("error") + or "global registry is not writable" ), - "global_registry_writability": global_writability, - "global_sync": { + recommended_action=global_writability.get("recommended_action"), + global_sync={ "ok": False, "enabled": True, + "phase": "preflight", "wrote": False, "write_denied": True, "error_kind": "global_registry_write_denied", "global_registry": str(global_path), "global_registry_writability": global_writability, - "recommended_action": global_writability.get("recommended_action"), + "recommended_action": global_writability.get( + "recommended_action" + ), }, - "error": str(global_writability.get("error") or "global registry is not writable"), - "recommended_action": global_writability.get("recommended_action"), - } + ) + result["host_loop_activation"] = loop_activation_for_goal( + registry_path=global_path, + runtime_root_arg=runtime_root_arg, + goal_id=goal_id, + ) + result["global_registry_writability"] = global_writability + return result sync_payload: dict[str, object] | None = None readback_payload: dict[str, object] = { "schema_version": "loopx_agent_registration_readback_v0", @@ -246,15 +351,108 @@ def register_agent_via_source_registry( for agent_id in requested_agents: if agent_id not in merged_agents: merged_agents.append(agent_id) - configure_payload = configure_goal( - registry_path=source_registry_path, - goal_id=goal_id, - registered_agents=merged_agents, - agent_model="peer_v1", - execute=True, - ) - if configure_payload.get("written"): - sync_payload = sync_project_registry_to_global( + try: + sync_preflight = sync_project_registry_to_global( + registry_path=source_registry_path, + runtime_root_override=str(global_path.parent), + goal_id=goal_id, + dry_run=True, + ) + except Exception as exc: + return _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + error_kind="agent_registration_sync_preflight_failed", + error=str(exc), + recommended_action=( + "run sync-global for this goal in dry-run mode and repair the " + "reported source/global registry integrity error before retrying" + ), + global_sync={ + "ok": False, + "enabled": True, + "phase": "preflight", + "wrote": False, + "error_kind": "agent_registration_sync_preflight_failed", + }, + ) + if not sync_preflight.get("ok"): + preflight_error_kind = str( + sync_preflight.get("error_kind") + or "agent_registration_sync_preflight_failed" + ) + return _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + error_kind=preflight_error_kind, + error=str( + sync_preflight.get("error") + or "source/global registry sync preflight failed" + ), + recommended_action=( + sync_preflight.get("recommended_action") + or "repair the source/global registry sync preflight before retrying" + ), + global_sync={ + **sync_preflight, + "ok": False, + "enabled": True, + "phase": "preflight", + "wrote": False, + "error_kind": preflight_error_kind, + }, + ) + try: + configure_payload = configure_goal( + registry_path=source_registry_path, + goal_id=goal_id, + registered_agents=merged_agents, + agent_model="peer_v1", + execute=True, + ) + except Exception as exc: + return _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + registered_agents=merged_agents, + error_kind="agent_registration_source_write_failed", + error=str(exc), + recommended_action=( + "read back the source and global registered-agent sets before retrying" + ), + partial_write=True, + ) + if require_new and ( + not configure_payload.get("changed") + or not configure_payload.get("written") + ): + return _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + error_kind="agent_registration_source_write_not_verified", + error="source registry did not confirm a fresh agent write", + recommended_action=( + "read back the source registered-agent set before retrying" + ), + ) + try: + sync_result = sync_project_registry_to_global( registry_path=source_registry_path, # Sync back to the same shared registry that supplied source_registry. # A project-local common_runtime_root must not redirect this write. @@ -262,12 +460,61 @@ def register_agent_via_source_registry( goal_id=goal_id, dry_run=False, ) + sync_payload = {**sync_result, "phase": "commit"} + except Exception as exc: + return _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + registered_agents=merged_agents, + changed=bool(configure_payload.get("changed")), + written=bool(configure_payload.get("written")), + partial_write=True, + error_kind="agent_registration_global_sync_failed", + error=str(exc), + recommended_action=( + "repair global sync, then verify the exact source/global agent " + "sets before binding a host thread" + ), + global_sync={ + "ok": False, + "enabled": True, + "phase": "commit", + "wrote": False, + "outcome_uncertain": True, + "error_kind": "agent_registration_global_sync_failed", + }, + ) + try: readback_payload = _agent_registration_readback( source_registry_path=source_registry_path, global_path=global_path, goal_id=goal_id, requested_agents=requested_agents, ) + except Exception as exc: + return _agent_registration_failure_payload( + execute=True, + goal_id=goal_id, + global_path=global_path, + source_registry_path=source_registry_path, + existing_agents=existing_agents, + requested_agents=requested_agents, + registered_agents=merged_agents, + changed=bool(configure_payload.get("changed")), + written=bool(configure_payload.get("written")), + partial_write=True, + error_kind="agent_registration_readback_failed", + error=str(exc), + recommended_action=( + "read back the exact source/global registered-agent sets before " + "binding a host thread" + ), + global_sync=sync_payload, + ) else: configure_payload = configure_goal( registry_path=source_registry_path, @@ -282,7 +529,29 @@ def register_agent_via_source_registry( if execute and configure_payload.get("written") else True ) - overall_ok = sync_ok and readback_ok + overall_ok = ( + sync_ok + and readback_ok + and ( + not execute + or not require_new + or bool(configure_payload.get("changed")) + ) + and ( + not execute + or not require_new + or bool(configure_payload.get("written")) + ) + ) + error_kind = None + if execute and not overall_ok: + error_kind = ( + str(sync_payload.get("error_kind")) + if isinstance(sync_payload, dict) and sync_payload.get("error_kind") + else "agent_registration_readback_failed" + if not readback_ok + else "agent_registration_write_not_verified" + ) result = { "ok": overall_ok, "dry_run": not execute, @@ -307,9 +576,12 @@ def register_agent_via_source_registry( else None ) ), - "global_sync": sync_payload or {"enabled": bool(execute), "wrote": False}, + "global_sync": sync_payload + or {"ok": not execute, "enabled": bool(execute), "wrote": False}, "registration_readback": readback_payload, } + if error_kind is not None: + result["error_kind"] = error_kind result["host_loop_activation"] = loop_activation_for_goal( registry_path=global_path, runtime_root_arg=runtime_root_arg, @@ -402,22 +674,43 @@ def register_registry_admin_commands(subparsers: argparse._SubParsersAction) -> "bind-agent-thread", help="Bind a stable host thread to one already registered LoopX agent.", ) - bind_thread_parser.add_argument("--goal-id", required=True, help="Goal id already present in the global registry.") + bind_thread_parser.add_argument("--goal-id", help="Goal id already present in the global registry.") bind_thread_parser.add_argument("--thread-id", required=True, help="Stable opaque host thread id.") bind_thread_parser.add_argument("--host-surface", required=True, help="Host surface such as codex-app.") - bind_thread_parser.add_argument("--agent-id", required=True, help="Already registered public-safe agent id.") + bind_thread_parser.add_argument("--agent-id", help="Already registered public-safe agent id.") + bind_thread_parser.add_argument( + "--expected-revision", + type=int, + help="Mandatory CAS revision for host-surface=dsh; zero selects an absent key.", + ) bind_thread_parser.add_argument("--execute", action="store_true", help="Write the binding; otherwise preview only.") unbind_thread_parser = subparsers.add_parser( "unbind-agent-thread", help="Remove one exact host-thread binding from its expected LoopX agent.", ) - unbind_thread_parser.add_argument("--goal-id", required=True, help="Goal id already present in the global registry.") + unbind_thread_parser.add_argument("--goal-id", help="Expected Goal id for non-DSH Goal-local bindings.") unbind_thread_parser.add_argument("--thread-id", required=True, help="Stable opaque host thread id.") unbind_thread_parser.add_argument("--host-surface", required=True, help="Host surface such as codex-app.") - unbind_thread_parser.add_argument("--agent-id", required=True, help="Expected registered public-safe agent id.") + unbind_thread_parser.add_argument("--agent-id", help="Expected registered public-safe agent id for non-DSH bindings.") + unbind_thread_parser.add_argument( + "--expected-revision", + type=int, + help="Mandatory CAS revision for host-surface=dsh.", + ) unbind_thread_parser.add_argument("--execute", action="store_true", help="Remove the binding; otherwise preview only.") + resolve_thread_parser = subparsers.add_parser( + "resolve-agent-thread", + help="Resolve one exact DSH Host-thread binding from the selected runtime root.", + ) + resolve_thread_parser.add_argument("--thread-id", required=True, help="Stable opaque DSH thread id.") + resolve_thread_parser.add_argument( + "--host-surface", + required=True, + help="The v1 global authority accepts exactly dsh.", + ) + archive_runtime_parser = subparsers.add_parser( "archive-runtime", help="Move an obsolete runtime goal directory into the archive area. Defaults to dry-run.", @@ -701,6 +994,11 @@ def handle_registry_admin_command( require_new=bool(args.require_new), ) except Exception as exc: + lock_error = lock_timeout_error_fields(exc) + error_kind = str( + lock_error.get("error_kind") + or "agent_registration_precondition_failed" + ) payload = { "ok": False, "dry_run": not bool(args.execute), @@ -708,14 +1006,99 @@ def handle_registry_admin_command( "goal_id": args.goal_id, "changed": False, "written": False, + "partial_write": False, + "error_kind": error_kind, "error": str(exc), - **lock_timeout_error_fields(exc), + "global_sync": { + "ok": False, + "enabled": bool(args.execute), + "phase": "preflight", + "wrote": False, + "skipped": True, + "error_kind": error_kind, + }, + "registration_readback": { + "schema_version": "loopx_agent_registration_readback_v0", + "performed": False, + "verified": False, + }, + **lock_error, } + payload["schema_version"] = REGISTER_AGENT_SCHEMA_VERSION + print_payload(payload, args.format, render_register_agent_markdown) + return 0 if payload.get("ok") else 1 + + if args.command == "resolve-agent-thread": + try: + if str(args.host_surface or "").strip().lower() != DSH_HOST_SURFACE: + raise DshBindingAuthorityError("invalid_target") + global_path = dsh_binding_global_registry( + registry_path=registry_path, + runtime_root_arg=args.runtime_root, + ) + payload = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface=args.host_surface, + thread_id=args.thread_id, + ) + except DshBindingAuthorityError as exc: + payload = _dsh_binding_failure(exc.error_kind) + except OSError: + payload = _dsh_binding_failure("binding_home_unavailable") + except ValueError: + payload = _dsh_binding_failure("authority_corrupt") print_payload(payload, args.format, render_register_agent_markdown) return 0 if payload.get("ok") else 1 if args.command in {"bind-agent-thread", "unbind-agent-thread"}: + if str(args.host_surface or "").strip().lower() == DSH_HOST_SURFACE: + try: + if args.expected_revision is None: + raise DshBindingAuthorityError("invalid_target") + global_path = dsh_binding_global_registry( + registry_path=registry_path, + runtime_root_arg=args.runtime_root, + ) + if args.command == "bind-agent-thread": + if not args.goal_id or not args.agent_id: + raise DshBindingAuthorityError("invalid_target") + payload = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface=args.host_surface, + thread_id=args.thread_id, + goal_id=args.goal_id, + agent_id=args.agent_id, + expected_revision=args.expected_revision, + execute=bool(args.execute), + ) + else: + if args.goal_id is not None or args.agent_id is not None: + raise DshBindingAuthorityError("invalid_target") + payload = unbind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface=args.host_surface, + thread_id=args.thread_id, + expected_revision=args.expected_revision, + execute=bool(args.execute), + ) + except DshBindingAuthorityError as exc: + payload = _dsh_binding_failure(exc.error_kind) + except OSError: + payload = _dsh_binding_failure("binding_home_unavailable") + except ValueError: + payload = _dsh_binding_failure("authority_corrupt") + print_payload(payload, args.format, render_register_agent_markdown) + return 0 if payload.get("ok") else 1 + try: + if not args.goal_id or not args.agent_id: + raise ValueError( + "non-DSH thread bindings require --goal-id and --agent-id" + ) + if args.expected_revision is not None: + raise ValueError( + "--expected-revision is only valid with --host-surface dsh" + ) global_path = explicit_global_registry(args.runtime_root) global_goal = _registry_goal(global_path, args.goal_id) source_registry = global_goal.get("source_registry") @@ -734,6 +1117,7 @@ def handle_registry_admin_command( except ValueError as exc: raise ValueError("source_registry is outside the goal repository") from exc source_path = source_path_resolved + payload: dict[str, object] | None = None if args.execute: writability = probe_registry_write_path(global_path, create_parent=True) if not writability.get("ok"): @@ -748,67 +1132,76 @@ def handle_registry_admin_command( "global_registry_writability": writability, "recommended_action": writability.get("recommended_action"), } - print_payload(payload, args.format, render_register_agent_markdown) - return 1 - binding_operation = ( - bind_thread_agent_in_registry - if args.command == "bind-agent-thread" - else unbind_thread_agent_in_registry - ) - payload = binding_operation( - registry_path=source_path, - goal_id=args.goal_id, - host_surface=args.host_surface, - thread_id=args.thread_id, - agent_id=args.agent_id, - execute=bool(args.execute), - ) - payload["global_registry"] = str(global_path) - payload["source_registry"] = str(source_path) - if args.execute and payload.get("ok"): - payload["global_sync"] = sync_project_registry_to_global( + if payload is None: + binding_operation = ( + bind_thread_agent_in_registry + if args.command == "bind-agent-thread" + else unbind_thread_agent_in_registry + ) + payload = binding_operation( registry_path=source_path, - runtime_root_override=str(global_path.parent), goal_id=args.goal_id, - dry_run=False, - ) - source_binding = resolve_thread_agent_binding( - _registry_goal(source_path, args.goal_id), host_surface=args.host_surface, thread_id=args.thread_id, + agent_id=args.agent_id, + execute=bool(args.execute), ) - global_binding = resolve_thread_agent_binding( - _registry_goal(global_path, args.goal_id), - host_surface=args.host_surface, - thread_id=args.thread_id, - ) - if args.command == "bind-agent-thread": - readback_verified = all( - binding.get("status") == "bound" - and binding.get("agent_id") == args.agent_id - for binding in (source_binding, global_binding) + payload["global_registry"] = str(global_path) + payload["source_registry"] = str(source_path) + if args.execute and payload.get("ok"): + payload["global_sync"] = sync_project_registry_to_global( + registry_path=source_path, + runtime_root_override=str(global_path.parent), + goal_id=args.goal_id, + dry_run=False, ) - else: - source_agents = _goal_registered_agents( - _registry_goal(source_path, args.goal_id) + source_binding = resolve_thread_agent_binding( + _registry_goal(source_path, args.goal_id), + host_surface=args.host_surface, + thread_id=args.thread_id, ) - global_agents = _goal_registered_agents( - _registry_goal(global_path, args.goal_id) + global_binding = resolve_thread_agent_binding( + _registry_goal(global_path, args.goal_id), + host_surface=args.host_surface, + thread_id=args.thread_id, ) - readback_verified = ( - all( - binding.get("status") == "missing" + if args.command == "bind-agent-thread": + readback_verified = all( + binding.get("status") == "bound" + and binding.get("agent_id") == args.agent_id for binding in (source_binding, global_binding) ) - and args.agent_id in source_agents - and args.agent_id in global_agents + else: + source_agents = _goal_registered_agents( + _registry_goal(source_path, args.goal_id) + ) + global_agents = _goal_registered_agents( + _registry_goal(global_path, args.goal_id) + ) + readback_verified = ( + all( + binding.get("status") == "missing" + for binding in (source_binding, global_binding) + ) + and args.agent_id in source_agents + and args.agent_id in global_agents + ) + payload["registration_readback"] = { + "verified": readback_verified + } + payload["ok"] = ( + bool(payload["global_sync"].get("ok")) + and readback_verified ) - payload["registration_readback"] = {"verified": readback_verified} - payload["ok"] = bool(payload["global_sync"].get("ok")) and readback_verified - if not payload["ok"]: - payload["error_kind"] = "thread_agent_binding_readback_failed" - else: - payload["global_sync"] = {"enabled": bool(args.execute), "wrote": False} + if not payload["ok"]: + payload["error_kind"] = ( + "thread_agent_binding_readback_failed" + ) + else: + payload["global_sync"] = { + "enabled": bool(args.execute), + "wrote": False, + } except Exception as exc: payload = { "ok": False, @@ -820,6 +1213,7 @@ def handle_registry_admin_command( "error": str(exc), **lock_timeout_error_fields(exc), } + payload["schema_version"] = THREAD_AGENT_BINDING_COMMAND_SCHEMA_VERSION print_payload(payload, args.format, render_register_agent_markdown) return 0 if payload.get("ok") else 1 diff --git a/loopx/cli_commands/start_goal.py b/loopx/cli_commands/start_goal.py index 7c894b9d7..cf40fd9d4 100644 --- a/loopx/cli_commands/start_goal.py +++ b/loopx/cli_commands/start_goal.py @@ -242,6 +242,7 @@ def handle_start_goal_command( cli_bin=args.cli_bin, host_surface=args.host_surface, goal_text=goal_text, + runtime_root_override=args.runtime_root, available_capabilities=args.available_capabilities, capability_route=capability_route, fine_grained=fine_grained, diff --git a/loopx/cli_commands/starter_bootstrap.py b/loopx/cli_commands/starter_bootstrap.py index a598c4448..c2c0b641c 100644 --- a/loopx/cli_commands/starter_bootstrap.py +++ b/loopx/cli_commands/starter_bootstrap.py @@ -102,6 +102,7 @@ def handle_loopx_bootstrap_command_pack_command( new_peer=bool(getattr(args, "new_peer", False)), cli_bin=args.cli_bin, host_surface=args.host_surface, + runtime_root_override=args.runtime_root, goal_text=args.goal_text, available_capabilities=args.available_capabilities, capability_route=args.capability_route, diff --git a/loopx/cli_commands/status.py b/loopx/cli_commands/status.py index cd18f75b8..dc9360c4d 100644 --- a/loopx/cli_commands/status.py +++ b/loopx/cli_commands/status.py @@ -35,6 +35,8 @@ ] FormatSelector = Callable[..., str] +STATUS_SCHEMA_VERSION = "loopx_status_v0" + def _scan_roots(args: argparse.Namespace) -> list[Path]: scan_roots = [Path(item).expanduser() for item in args.scan_path] @@ -256,6 +258,7 @@ def handle_status_command( ], }, } + payload["schema_version"] = STATUS_SCHEMA_VERSION print_payload(payload, output_format(args), render_status_markdown) return 0 if payload.get("ok") else 1 diff --git a/loopx/cli_commands/todo.py b/loopx/cli_commands/todo.py index 7c7bf0a8d..77367034f 100644 --- a/loopx/cli_commands/todo.py +++ b/loopx/cli_commands/todo.py @@ -59,6 +59,8 @@ ) from .todo_event import RolloutEventAppender, append_todo_rollout_event +TODO_COMMAND_SCHEMA_VERSION = "loopx_todo_command_v0" + PrintPayload = Callable[ [dict[str, object], str, Callable[[dict[str, object]], str]], None, @@ -951,6 +953,7 @@ def handle_todo_command( payload["ok"] = False payload["receipt_repair_required"] = True payload["error"] = settlement_result.failure.reason + payload["schema_version"] = TODO_COMMAND_SCHEMA_VERSION print_payload( payload, format_name or str(getattr(args, "format", None) or "markdown"), diff --git a/loopx/control_plane/goals/configure_goal_service.py b/loopx/control_plane/goals/configure_goal_service.py index 94a96cfa6..d0a24b8e5 100644 --- a/loopx/control_plane/goals/configure_goal_service.py +++ b/loopx/control_plane/goals/configure_goal_service.py @@ -6,7 +6,11 @@ from typing import Any from ...configure_goal import configure_goal +from ...file_lock import exclusive_file_lock from ...global_registry import ( + GlobalRegistryReduction, + assert_dsh_agent_membership_retained, + mutate_global_registry, sanitize_goal_for_global, sync_project_registry_to_global, ) @@ -225,6 +229,23 @@ def _sync_plan( } +def _dsh_membership_guard_reduction( + current: dict[str, Any], + *, + goal_id: str, + registered_agents: list[str], +) -> GlobalRegistryReduction: + assert_dsh_agent_membership_retained( + current, + goal_id=goal_id, + registered_agents=registered_agents, + ) + return GlobalRegistryReduction( + payload=current, + receipt={"ok": True}, + ) + + def configure_goal_with_global_sync( *, registry_path: Path, @@ -232,6 +253,37 @@ def configure_goal_with_global_sync( runtime_root_override: str | None, execute: bool, **configure_options: Any, +) -> dict[str, Any]: + """Serialize membership changes before the global DSH reference check.""" + + if not execute: + return _configure_goal_with_global_sync_under_source_lock( + registry_path=registry_path, + goal_id=goal_id, + runtime_root_override=runtime_root_override, + execute=False, + **configure_options, + ) + with exclusive_file_lock( + registry_path.expanduser(), + operation="configure_goal_global_sync", + ): + return _configure_goal_with_global_sync_under_source_lock( + registry_path=registry_path, + goal_id=goal_id, + runtime_root_override=runtime_root_override, + execute=True, + **configure_options, + ) + + +def _configure_goal_with_global_sync_under_source_lock( + *, + registry_path: Path, + goal_id: str, + runtime_root_override: str | None, + execute: bool, + **configure_options: Any, ) -> dict[str, Any]: """Configure one source goal and keep its authoritative shared read model current.""" @@ -296,6 +348,19 @@ def configure_goal_with_global_sync( ) return preview + before_agents = list(preview.get("before", {}).get("registered_agents") or []) + after_agents = list(preview.get("after", {}).get("registered_agents") or []) + if before_agents != after_agents: + mutate_global_registry( + target_registry, + "configure_goal_dsh_membership_guard", + lambda current: _dsh_membership_guard_reduction( + current, + goal_id=goal_id, + registered_agents=after_agents, + ), + ) + applied = configure_goal( registry_path=registry_path, goal_id=goal_id, diff --git a/loopx/control_plane/goals/start_contract.py b/loopx/control_plane/goals/start_contract.py index 4c6c4117d..e29b889c3 100644 --- a/loopx/control_plane/goals/start_contract.py +++ b/loopx/control_plane/goals/start_contract.py @@ -89,6 +89,8 @@ def build_goal_start_contract( "pi": "Pi `loopx_goal_activate`", "gemini-cli": "agent-driven Gemini CLI loop; every turn enters through quota should-run", "cursor-agent": "agent-driven cursor-agent loop; every turn enters through quota should-run", + "deepseek-harness-native": "same-session DSH LoopX plugin through loopx_goal_activate and quota should-run", + "deepseek-harness": "external DeepSeek Harness adapter through loopx turn run-once", "ark-managed-agent": "one-shot Goal", "manual": "external scheduler or manual quota/status loop", "other-agent": "custom host loop driver using the returned task body and quota guard", diff --git a/loopx/control_plane/heartbeat/builder.py b/loopx/control_plane/heartbeat/builder.py index 8c513e79c..c30d3c63c 100644 --- a/loopx/control_plane/heartbeat/builder.py +++ b/loopx/control_plane/heartbeat/builder.py @@ -67,6 +67,8 @@ render_refresh_state_command, ) +HEARTBEAT_PROMPT_SCHEMA_VERSION = "loopx_heartbeat_prompt_v0" + FINE_GRAINED_TURN_RULE = ( "Fine-grained planning contract: each Todo must be one small verifiable checkpoint; " "if broader, split before delivery. The turn budget is one coherent decision slice " @@ -345,6 +347,7 @@ def build_heartbeat_prompt( "shorten agent scopes or project-specific prompt rules" ) payload = { + "schema_version": HEARTBEAT_PROMPT_SCHEMA_VERSION, "ok": True, "goal_id": goal_id, "active_state": active_state_text, @@ -419,7 +422,9 @@ def build_heartbeat_prompt( "agent_role", "agent_scope_source", "agent_scopes", + "pr_review_pre_quota_command", "registered_agents", + "scheduler_execution_context", ): if not payload.get(key): payload.pop(key, None) @@ -469,6 +474,7 @@ def build_heartbeat_prompt_error_payload( thin_prompt_command = f"{cli_bin} heartbeat-prompt --thin --goal-id {goal_id}{active_state_arg}{agent_args}{capability_args}" normalized_registered_agents = normalize_registered_agents(registered_agents) payload = { + "schema_version": HEARTBEAT_PROMPT_SCHEMA_VERSION, "ok": False, "goal_id": goal_id, "error": error, diff --git a/loopx/global_registry.py b/loopx/global_registry.py index f2ced8d86..2b07b2eb9 100644 --- a/loopx/global_registry.py +++ b/loopx/global_registry.py @@ -8,6 +8,7 @@ from pathlib import Path from typing import Any, Callable +from .agent_registry import normalize_registered_agents from .authority import compact_authority_registry from .control_plane.projects.contract import validate_project_record_bindings from .control_plane.runtime.time import now_local_iso @@ -29,6 +30,103 @@ ROUTE_FIELDS = ("source_registry", "repo", "state_file") +def _goal_by_id( + goals: list[Any], + goal_id: str, +) -> dict[str, Any] | None: + matches = [ + item + for item in goals + if isinstance(item, dict) and str(item.get("id") or "") == goal_id + ] + if len(matches) > 1: + raise ValueError(f"global registry contains duplicate goal ids: {goal_id}") + return matches[0] if matches else None + + +def assert_dsh_binding_targets_retained( + payload: dict[str, Any], + *, + removed_goal_ids: set[str] | None = None, + replacement_goals: dict[str, dict[str, Any]] | None = None, +) -> None: + """Reject Goal route or membership removal while a DSH Host is bound.""" + + from .thread_agent_binding import live_dsh_binding_references + + removed_goal_ids = removed_goal_ids or set() + replacement_goals = replacement_goals or {} + current_goals = payload.get("goals") + current_goals = current_goals if isinstance(current_goals, list) else [] + conflicts: list[dict[str, Any]] = [] + for reference in live_dsh_binding_references(payload): + goal_id = str(reference["goal_id"]) + agent_id = str(reference["agent_id"]) + reason: str | None = None + if goal_id in removed_goal_ids: + reason = "goal_removal" + elif goal_id in replacement_goals: + current_goal = _goal_by_id(current_goals, goal_id) + replacement = replacement_goals[goal_id] + if current_goal is None or route_snapshot(current_goal) != route_snapshot( + replacement + ): + reason = "goal_route_replacement" + else: + coordination = replacement.get("coordination") + raw_agents = ( + coordination.get("registered_agents") + if isinstance(coordination, dict) + else None + ) + agents = normalize_registered_agents(raw_agents) + if ( + not isinstance(raw_agents, list) + or raw_agents != agents + or agent_id not in agents + ): + reason = "agent_membership_removal" + if reason: + conflicts.append({**reference, "reason": reason}) + if conflicts: + summary = ", ".join( + f"{item['goal_id']}/{item['agent_id']}@{item['thread_id']}" + for item in conflicts + ) + raise ValueError( + "DSH Host binding blocks Goal route or Agent membership removal; " + f"CAS-unbind or switch the Host first: {summary}" + ) + + +def assert_dsh_agent_membership_retained( + payload: dict[str, Any], + *, + goal_id: str, + registered_agents: list[str], +) -> None: + """Reject removal of a Goal-Agent lane referenced by a live DSH Host.""" + + from .thread_agent_binding import live_dsh_binding_references + + retained = set(registered_agents) + conflicts = [ + reference + for reference in live_dsh_binding_references(payload) + if reference["goal_id"] == goal_id + and reference["agent_id"] not in retained + ] + if conflicts: + summary = ", ".join( + f"{item['goal_id']}/{item['agent_id']}@{item['thread_id']}" + for item in conflicts + ) + raise ValueError( + "DSH Host binding blocks Agent membership removal; " + f"CAS-unbind or switch the Host first: {summary}" + ) + + def now_local() -> str: return now_local_iso() @@ -356,6 +454,15 @@ def _merge_global_registry_payload( existing_goals = existing.get("goals") if not isinstance(existing_goals, list): existing_goals = [] + incoming_by_id = { + str(goal.get("id")): goal + for goal in incoming + if str(goal.get("id") or "") + } + assert_dsh_binding_targets_retained( + existing, + replacement_goals=incoming_by_id, + ) merged_goals, actions, synced_ids, collisions = merge_goal_entries( existing_goals, incoming, @@ -493,6 +600,10 @@ def _retire_global_registry_reduction( ) retired = set(requested_ids) + assert_dsh_binding_targets_retained( + current, + removed_goal_ids=retired, + ) retained_goals = [ goal for goal in current_goals diff --git a/loopx/host_loop_activation.py b/loopx/host_loop_activation.py index 871b2838b..189234159 100644 --- a/loopx/host_loop_activation.py +++ b/loopx/host_loop_activation.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json from typing import Any from .agent_registry import normalize_registered_agents @@ -45,6 +46,7 @@ def scheduler_command_binding_for_agent_type( "gemini-cli": SchedulerRuntimeProfile.GENERIC_CLI_AGENT_LOOP, "cursor-agent": SchedulerRuntimeProfile.GENERIC_CLI_AGENT_LOOP, "deepseek-harness": SchedulerRuntimeProfile.GENERIC_CLI_AGENT_LOOP, + "deepseek-harness-native": SchedulerRuntimeProfile.GENERIC_CLI_AGENT_LOOP, }.get(canonical) if runtime_profile is not None: return {"runtime_profile": runtime_profile.value} @@ -70,6 +72,7 @@ def agent_type_uses_host_managed_skills(agent_type: str) -> bool: "gemini-cli", "cursor-agent", "deepseek-harness", + "deepseek-harness-native", "manual", "other-agent", ] @@ -244,6 +247,15 @@ def agent_type_uses_host_managed_skills(agent_type: str) -> bool: "dsh", ], }, + "deepseek-harness-native": { + "display_name": "DeepSeek Harness Native", + "host_loop": "same-session DSH LoopX plugin gated by LoopX quota", + "entry": "/loopx with packages/dsh-loopx-plugin installed", + "accepted_inputs": [ + "deepseek-harness-native", + "dsh-native", + ], + }, "manual": { "display_name": "Manual shell / external scheduler", "host_loop": "external scheduler or manual quota/status loop", @@ -321,6 +333,8 @@ def to_payload(self) -> dict[str, Any]: "cursor": "cursor-agent", "deepseek-harness": "deepseek-harness", "dsh": "deepseek-harness", + "deepseek-harness-native": "deepseek-harness-native", + "dsh-native": "deepseek-harness-native", "shell": "manual", "http": "other-agent", "worker-bridge": "other-agent", @@ -424,12 +438,33 @@ def normalize_agent_type(value: str | None) -> str: def agent_type_for_host_surface(value: str | None) -> str: - key = (value or "codex-app").strip().lower() + key = normalize_host_surface(value) if key in HOST_SURFACE_TO_AGENT_TYPE: return HOST_SURFACE_TO_AGENT_TYPE[key] return normalize_agent_type(key) +def normalize_host_surface(value: str | None) -> str: + """Canonicalize aliases that share one persisted Host thread identity. + + Both DSH integrations keep their existing execution behavior, but every + accepted spelling must collapse before thread lookup or write so one + Session cannot acquire duplicate lanes for the same Host surface. + """ + + surface = (value or "codex-app").strip().lower() + if surface in { + "deepseek-harness", + "deepseek_harness", + "deepseek harness", + "dsh", + }: + return "deepseek-harness" + if surface == "dsh-native": + return "deepseek-harness-native" + return surface + + def _heartbeat_commands( *, goal_id: str, @@ -452,6 +487,7 @@ def _heartbeat_commands( "gemini-cli": "Gemini CLI agent loop gated by LoopX", "cursor-agent": "Cursor Agent CLI loop gated by LoopX", "deepseek-harness": "DeepSeek Harness automation loop gated by LoopX", + "deepseek-harness-native": "DeepSeek Harness same-session LoopX plugin gated by LoopX", "manual": "External scheduler or manual shell LoopX poll", "other-agent": "Custom agent host loop gated by LoopX", } @@ -1137,6 +1173,71 @@ def _deepseek_harness_activation(commands: dict[str, str]) -> dict[str, Any]: } +def _deepseek_harness_native_activation( + *, + goal_id: str, + agent_id: str | None, +) -> dict[str, Any]: + activation_input = { + "schema_version": "loopx_deepseek_harness_native_activation_input_v0", + "tool": "loopx_goal_activate", + "arguments": { + "goalId": goal_id, + **({"agentId": agent_id} if agent_id else {}), + }, + } + return { + "host_surface": "deepseek_harness_native_session", + "entry_command_hint": "/loopx ", + "activation_method": "current_session_host_tool", + "activation_input": activation_input, + "activation_input_command": json.dumps( + activation_input, + sort_keys=True, + separators=(",", ":"), + ), + "setup": { + "owner": "DSH LoopX plugin", + "package_path": "packages/dsh-loopx-plugin", + "install_surface": "dsh_host_bundle", + }, + "host_mutation": { + "owner": "DSH LoopX plugin", + "host_loop_primitive": "agent.followup", + "host_tool": "loopx_goal_activate", + "current_session_only": True, + "cli_can_mutate_directly": False, + "tool_argument_mapping": { + "goalId": "activation_input.arguments.goalId", + "agentId": "activation_input.arguments.agentId when present", + }, + "forbidden_tool_arguments": [ + "sessionId", + "registryPath", + "taskBody", + "argv", + ], + "missing_host_tool_gate": ( + "Install and enable the independent packages/dsh-loopx-plugin " + "Host bundle before claiming same-session continuation." + ), + }, + "activation_steps": [ + "Install and enable packages/dsh-loopx-plugin in the current DSH Profile.", + "After planning, Todo writeback, and refresh, invoke loopx_goal_activate " + "with the returned JSON arguments in this same DSH Session.", + "Let the plugin read back LoopX identity and task state; do not pass a " + "registry locator, task body, Session id, or arbitrary command.", + "Allow the plugin driver to follow up only after quota should-run permits it.", + ], + "success_criteria": [ + "The current DSH Session is bound to the exact LoopX goal and agent lane.", + "The DSH LoopX plugin reports an armed binding after authoritative LoopX readback.", + "Every continuation is gated by the generic_cli quota contract and foreign input pauses it.", + ], + } + + def _manual_activation(commands: dict[str, str]) -> dict[str, Any]: return { "host_surface": "external_scheduler_or_manual_shell", @@ -1229,6 +1330,11 @@ def build_host_loop_activation_packet( surface = _cursor_agent_activation(commands, cli_bin) elif canonical == "deepseek-harness": surface = _deepseek_harness_activation(commands) + elif canonical == "deepseek-harness-native": + surface = _deepseek_harness_native_activation( + goal_id=goal_id, + agent_id=str(selected_agent_id) if selected_agent_id else None, + ) else: surface = _manual_activation(commands) if canonical == "other-agent": @@ -1245,15 +1351,27 @@ def build_host_loop_activation_packet( agent_id=candidate, available_capabilities=normalized_available_capabilities, ) + native_candidate_activation = ( + _deepseek_harness_native_activation( + goal_id=goal_id, + agent_id=candidate, + ) + if canonical == "deepseek-harness-native" + else None + ) choice: dict[str, Any] = { "agent_id": candidate, "activation_input_command": ( - candidate_commands["visible_goal_prompt_json"] - if canonical == "traex-cli" - else candidate_commands["heartbeat_prompt_json"] + native_candidate_activation["activation_input_command"] + if native_candidate_activation + else ( + candidate_commands["visible_goal_prompt_json"] + if canonical == "traex-cli" + else candidate_commands["heartbeat_prompt_json"] + ) ), } - if canonical != "traex-cli": + if canonical not in {"traex-cli", "deepseek-harness-native"}: choice.update( { "heartbeat_prompt_json": candidate_commands[ diff --git a/loopx/project_uninstall.py b/loopx/project_uninstall.py index 38060943e..b857a641f 100644 --- a/loopx/project_uninstall.py +++ b/loopx/project_uninstall.py @@ -7,7 +7,12 @@ from typing import Any from .control_plane.runtime.time import now_local_iso, utc_timestamp -from .global_registry import GlobalRegistryReduction, mutate_global_registry +from .file_lock import exclusive_file_lock +from .global_registry import ( + GlobalRegistryReduction, + assert_dsh_binding_targets_retained, + mutate_global_registry, +) from .history import load_registry from .paths import DEFAULT_RUNTIME_ROOT, global_registry_path, resolve_runtime_root from .registry import registry_goals @@ -182,6 +187,10 @@ def _remove_global_goals( source_registry: Path, target_goal_ids: set[str], ) -> tuple[dict[str, Any], list[str], list[str], int, int]: + assert_dsh_binding_targets_retained( + global_registry, + removed_goal_ids=target_goal_ids, + ) goals = global_registry.get("goals") before = len(registry_goals(global_registry)) if not isinstance(goals, list): @@ -247,6 +256,40 @@ def uninstall_project( archive_state: bool, remove_empty_registry: bool, execute: bool, +) -> dict[str, Any]: + """Run uninstall under the source lock before acquiring the global lock.""" + + if not execute: + return _uninstall_project_under_source_lock( + registry_path=registry_path, + runtime_root_override=runtime_root_override, + goal_ids=goal_ids, + archive_state=archive_state, + remove_empty_registry=remove_empty_registry, + execute=False, + ) + with exclusive_file_lock( + registry_path.expanduser(), + operation="project_uninstall_source_registry", + ): + return _uninstall_project_under_source_lock( + registry_path=registry_path, + runtime_root_override=runtime_root_override, + goal_ids=goal_ids, + archive_state=archive_state, + remove_empty_registry=remove_empty_registry, + execute=True, + ) + + +def _uninstall_project_under_source_lock( + *, + registry_path: Path, + runtime_root_override: str | None, + goal_ids: list[str] | None, + archive_state: bool, + remove_empty_registry: bool, + execute: bool, ) -> dict[str, Any]: registry_path = registry_path.expanduser() if not registry_path.exists(): diff --git a/loopx/slash_command_install.py b/loopx/slash_command_install.py index 739a818b8..3a68203d9 100644 --- a/loopx/slash_command_install.py +++ b/loopx/slash_command_install.py @@ -145,7 +145,7 @@ def _command_prompt_specs(*, cli_bin: str, include_legacy_aliases: bool) -> list "argument_hint": "[--fine-grained] [--capability-route issue-fix] [task text]", "instructions": [ "Visible command arguments: `$ARGUMENTS`.", - "Identify the exact current host surface (codex-app, codex-app-ssh, codex-ide-plugin, codex-cli-tui, opencode, opencode2, traex-cli, pi, gemini-cli, cursor-agent, deepseek-harness, or ark-managed-agent).", + "Identify the exact current host surface (codex-app, codex-app-ssh, codex-ide-plugin, codex-cli-tui, opencode, opencode2, traex-cli, pi, gemini-cli, cursor-agent, deepseek-harness-native, deepseek-harness, or ark-managed-agent).", _loopx_start_goal_arguments_instruction( cli_bin=cli_bin, host_surface=None, diff --git a/loopx/thread_agent_binding.py b/loopx/thread_agent_binding.py index 1c8d1c76d..44840120f 100644 --- a/loopx/thread_agent_binding.py +++ b/loopx/thread_agent_binding.py @@ -1,17 +1,52 @@ -"""Validated, project-local bindings between host threads and agent lanes.""" +"""Validated Host-thread bindings for Goal-scoped Agent lanes. + +Non-DSH Hosts keep the Goal-local v0 contract below. The DSH integration uses +the strict, revisioned global authority defined in the second half of this +module; the two stores are deliberately never mirrored into each other. +""" from __future__ import annotations +import re from pathlib import Path from typing import Any +from .agent_registry import normalize_registered_agents from .control_plane.todos.contract import normalize_todo_claimed_by from .file_lock import exclusive_file_lock from .history import load_registry +from .host_loop_activation import normalize_host_surface from .registry import atomic_write_json, find_registry_goal +from .runtime import validate_goal_id_path_segment THREAD_ID_MAX_LENGTH = 128 +GOAL_ID_MAX_LENGTH = 256 THREAD_BINDING_SCHEMA_VERSION = "loopx_thread_agent_binding_v0" +DSH_HOST_SURFACE = "dsh" +DSH_BINDING_COLLECTION_KEY = "dsh_host_thread_bindings" +DSH_BINDING_COLLECTION_SCHEMA_VERSION = "loopx_dsh_host_thread_bindings_v1" +HOST_THREAD_BINDING_SCHEMA_VERSION = "loopx_host_thread_binding_v1" +HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION = ( + "loopx_host_thread_binding_command_v1" +) +JAVASCRIPT_SAFE_INTEGER_MAX = 9_007_199_254_740_991 +DSH_THREAD_ID_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$") +DSH_GOAL_ID_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$") +DSH_AGENT_ID_PATTERN = re.compile(r"^[a-z0-9][a-z0-9._-]{0,127}$") + + +class DshBindingAuthorityError(ValueError): + """Typed, public-safe rejection from the DSH binding authority.""" + + def __init__( + self, + error_kind: str, + *, + binding: dict[str, Any] | None = None, + ) -> None: + super().__init__(error_kind) + self.error_kind = error_kind + self.binding = binding def normalize_thread_id(value: Any) -> str | None: @@ -34,9 +69,10 @@ def normalize_thread_id(value: Any) -> str | None: def _normalized_host_surface(value: Any) -> str: - surface = str(value or "").strip() - if not surface: + raw_surface = str(value or "").strip() + if not raw_surface: raise ValueError("host_surface is required for a thread binding") + surface = normalize_host_surface(raw_surface) if len(surface) > 64 or any(char.isspace() for char in surface): raise ValueError("host_surface must be a compact public-safe token") return surface @@ -406,3 +442,528 @@ def unbind_thread_agent_in_registry( ) result["registry"] = str(registry_path) return result + + +def _dsh_result( + *, + binding: dict[str, Any] | None = None, + error_kind: str | None = None, + changed: bool = False, + application: str = "no", +) -> dict[str, Any]: + result: dict[str, Any] = { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": error_kind is None, + "changed": changed if error_kind is None else False, + "application": application, + } + if error_kind is not None: + result["error_kind"] = error_kind + if binding is not None: + result["binding"] = binding + return result + + +def _dsh_exception_result( + exc: DshBindingAuthorityError | OSError | ValueError, + *, + execute: bool = False, +) -> dict[str, Any]: + if isinstance(exc, DshBindingAuthorityError): + return _dsh_result(error_kind=exc.error_kind, binding=exc.binding) + if isinstance(exc, OSError): + return _dsh_result( + error_kind="authority_unhealthy" if execute else "binding_home_unavailable", + application="unknown" if execute else "no", + ) + return _dsh_result(error_kind="authority_corrupt") + + +def _require_dsh_surface(value: Any) -> str: + if value != DSH_HOST_SURFACE: + raise DshBindingAuthorityError("invalid_target") + return DSH_HOST_SURFACE + + +def _required_thread_id(value: Any) -> str: + if not isinstance(value, str): + raise DshBindingAuthorityError("invalid_target") + try: + thread_id = normalize_thread_id(value) + except ValueError: + thread_id = None + if thread_id is None or not DSH_THREAD_ID_PATTERN.fullmatch(thread_id): + raise DshBindingAuthorityError("invalid_target") + return thread_id + + +def _normalized_goal_id(value: Any) -> str: + if not isinstance(value, str): + raise DshBindingAuthorityError("invalid_target") + try: + goal_id = validate_goal_id_path_segment(value) + except ValueError as exc: + raise DshBindingAuthorityError("invalid_target") from exc + if len(goal_id) > GOAL_ID_MAX_LENGTH or not DSH_GOAL_ID_PATTERN.fullmatch( + goal_id + ): + raise DshBindingAuthorityError("invalid_target") + return goal_id + + +def _normalized_agent_id(value: Any) -> str: + if not isinstance(value, str): + raise DshBindingAuthorityError("invalid_target") + agent_id = value + if not DSH_AGENT_ID_PATTERN.fullmatch(agent_id): + raise DshBindingAuthorityError("invalid_target") + return agent_id + + +def _revision(value: Any, *, minimum: int = 0) -> int: + if ( + isinstance(value, bool) + or not isinstance(value, int) + or value < minimum + or value > JAVASCRIPT_SAFE_INTEGER_MAX + ): + raise DshBindingAuthorityError("invalid_target") + return value + + +def _strict_target(value: Any) -> dict[str, str]: + if not isinstance(value, dict) or set(value) != {"goal_id", "agent_id"}: + raise DshBindingAuthorityError("authority_corrupt") + try: + goal_id = _normalized_goal_id(value.get("goal_id")) + agent_id = _normalized_agent_id(value.get("agent_id")) + except DshBindingAuthorityError as exc: + raise DshBindingAuthorityError("authority_corrupt") from exc + if value.get("goal_id") != goal_id or value.get("agent_id") != agent_id: + raise DshBindingAuthorityError("authority_corrupt") + return {"goal_id": goal_id, "agent_id": agent_id} + + +def _strict_dsh_binding_row( + value: Any, + *, + map_key: str, +) -> dict[str, Any]: + if not isinstance(value, dict): + raise DshBindingAuthorityError("authority_corrupt") + state = value.get("state") + expected_keys = { + "schema_version", + "host_surface", + "thread_id", + "revision", + "state", + } + if state == "bound": + expected_keys.add("target") + elif state != "unbound": + raise DshBindingAuthorityError("authority_corrupt") + if set(value) != expected_keys: + raise DshBindingAuthorityError("authority_corrupt") + if value.get("schema_version") != HOST_THREAD_BINDING_SCHEMA_VERSION: + raise DshBindingAuthorityError("authority_corrupt") + if value.get("host_surface") != DSH_HOST_SURFACE: + raise DshBindingAuthorityError("authority_corrupt") + try: + thread_id = _required_thread_id(value.get("thread_id")) + _revision(value.get("revision"), minimum=1) + if state == "bound": + _strict_target(value.get("target")) + except DshBindingAuthorityError as exc: + raise DshBindingAuthorityError("authority_corrupt") from exc + if thread_id != value.get("thread_id") or thread_id != map_key: + raise DshBindingAuthorityError("authority_corrupt") + return value + + +def strict_dsh_host_thread_bindings( + payload: dict[str, Any], +) -> dict[str, dict[str, Any]]: + """Parse the complete DSH collection or reject the whole authority.""" + + if DSH_BINDING_COLLECTION_KEY not in payload: + raise DshBindingAuthorityError("binding_home_uninitialized") + collection = payload.get(DSH_BINDING_COLLECTION_KEY) + if not isinstance(collection, dict) or set(collection) != { + "schema_version", + "records", + }: + raise DshBindingAuthorityError("authority_corrupt") + if collection.get("schema_version") != DSH_BINDING_COLLECTION_SCHEMA_VERSION: + raise DshBindingAuthorityError("authority_corrupt") + raw_records = collection.get("records") + if not isinstance(raw_records, dict): + raise DshBindingAuthorityError("authority_corrupt") + + records: dict[str, dict[str, Any]] = {} + for raw_key, raw_row in raw_records.items(): + if not isinstance(raw_key, str): + raise DshBindingAuthorityError("authority_corrupt") + try: + key = _required_thread_id(raw_key) + except DshBindingAuthorityError as exc: + raise DshBindingAuthorityError("authority_corrupt") from exc + if key != raw_key: + raise DshBindingAuthorityError("authority_corrupt") + records[key] = _strict_dsh_binding_row(raw_row, map_key=key) + return records + + +def _require_global_registry_payload(payload: Any) -> dict[str, Any]: + schema_version = ( + payload.get("schema_version") if isinstance(payload, dict) else None + ) + if ( + not isinstance(payload, dict) + or not isinstance(schema_version, str) + or not schema_version.strip() + or not isinstance(payload.get("goals"), list) + ): + raise DshBindingAuthorityError("authority_corrupt") + return payload + + +def _exact_goal(payload: dict[str, Any], goal_id: str) -> dict[str, Any]: + matches = [ + item + for item in payload.get("goals", []) + if isinstance(item, dict) and str(item.get("id") or "") == goal_id + ] + if len(matches) != 1: + raise DshBindingAuthorityError("authority_unhealthy") + return matches[0] + + +def _source_registry_path( + global_goal: dict[str, Any], + *, + global_path: Path, +) -> Path: + source = str(global_goal.get("source_registry") or "").strip() + repo = str(global_goal.get("repo") or "").strip() + if not source or not repo: + raise DshBindingAuthorityError("authority_unhealthy") + repo_path = Path(repo).expanduser() + if not repo_path.is_absolute(): + repo_path = global_path.parent / repo_path + source_path = Path(source).expanduser() + if not source_path.is_absolute(): + source_path = repo_path / source_path + try: + source_path = source_path.resolve() + repo_path = repo_path.resolve() + source_path.relative_to(repo_path) + except (OSError, ValueError) as exc: + raise DshBindingAuthorityError("authority_unhealthy") from exc + if source_path == global_path.expanduser().resolve(): + raise DshBindingAuthorityError("authority_unhealthy") + return source_path + + +def _goal_membership(goal: dict[str, Any]) -> list[str]: + coordination = goal.get("coordination") + if not isinstance(coordination, dict): + raise DshBindingAuthorityError("authority_unhealthy") + raw_agents = coordination.get("registered_agents") + agents = normalize_registered_agents(raw_agents) + if not isinstance(raw_agents, list) or raw_agents != agents: + raise DshBindingAuthorityError("authority_unhealthy") + return agents + + +def _source_membership(source_path: Path, goal_id: str) -> list[str]: + try: + payload = _require_global_registry_payload(load_registry(source_path)) + return _goal_membership(_exact_goal(payload, goal_id)) + except (OSError, ValueError) as exc: + raise DshBindingAuthorityError("authority_unhealthy") from exc + + +def _target_context( + payload: dict[str, Any], + *, + global_path: Path, + target: dict[str, str], +) -> None: + global_goal = _exact_goal(payload, target["goal_id"]) + source_path = _source_registry_path(global_goal, global_path=global_path) + source_agents = _source_membership(source_path, target["goal_id"]) + if ( + source_agents != _goal_membership(global_goal) + or target["agent_id"] not in source_agents + ): + raise DshBindingAuthorityError("authority_unhealthy") + + +def _read_global_registry(global_path: Path) -> dict[str, Any]: + if not global_path.exists(): + raise DshBindingAuthorityError("binding_home_unavailable") + try: + return _require_global_registry_payload(load_registry(global_path)) + except OSError as exc: + raise DshBindingAuthorityError("binding_home_unavailable") from exc + except ValueError as exc: + raise DshBindingAuthorityError("authority_corrupt") from exc + + +def resolve_dsh_thread_agent_binding( + *, + global_path: Path, + host_surface: str, + thread_id: str, +) -> dict[str, Any]: + """Resolve one exact DSH Host key and validate its Goal-Agent target.""" + + try: + _require_dsh_surface(host_surface) + normalized_thread_id = _required_thread_id(thread_id) + payload = _read_global_registry(global_path) + records = strict_dsh_host_thread_bindings(payload) + binding = records.get(normalized_thread_id) + if binding is None: + raise DshBindingAuthorityError("binding_not_found") + if binding["state"] == "bound": + try: + _target_context( + payload, + global_path=global_path, + target=binding["target"], + ) + except DshBindingAuthorityError as exc: + raise DshBindingAuthorityError( + "authority_unhealthy", + binding=binding, + ) from exc + return _dsh_result(binding=binding) + except (DshBindingAuthorityError, OSError, ValueError) as exc: + return _dsh_exception_result(exc) + + +def _binding_row( + thread_id: str, + revision: int, + target: dict[str, str] | None, +) -> dict[str, Any]: + row: dict[str, Any] = { + "schema_version": HOST_THREAD_BINDING_SCHEMA_VERSION, + "host_surface": DSH_HOST_SURFACE, + "thread_id": thread_id, + "revision": revision, + "state": "bound" if target is not None else "unbound", + } + if target is not None: + row["target"] = target + return row + + +def _write_dsh_records( + payload: dict[str, Any], + records: dict[str, dict[str, Any]], +) -> dict[str, Any]: + updated = dict(payload) + updated[DSH_BINDING_COLLECTION_KEY] = { + "schema_version": DSH_BINDING_COLLECTION_SCHEMA_VERSION, + "records": records, + } + return updated + + +def _binding_reduction( + payload: dict[str, Any], + *, + thread_id: str, + expected_revision: int, + target: dict[str, str] | None, +) -> tuple[dict[str, Any], dict[str, Any]]: + _require_global_registry_payload(payload) + try: + records = strict_dsh_host_thread_bindings(payload) + except DshBindingAuthorityError as exc: + if not ( + target is not None + and expected_revision == 0 + and exc.error_kind == "binding_home_uninitialized" + ): + raise + records = {} + current = records.get(thread_id) + if current is None and target is None: + raise DshBindingAuthorityError("binding_not_found") + current_revision = current["revision"] if current else 0 + if expected_revision != current_revision: + raise DshBindingAuthorityError("revision_conflict", binding=current) + matches = current is not None and ( + (target is None and current["state"] == "unbound") + or ( + target is not None + and current["state"] == "bound" + and current["target"] == target + ) + ) + if matches: + return payload, _dsh_result(binding=current) + if current_revision >= JAVASCRIPT_SAFE_INTEGER_MAX: + raise DshBindingAuthorityError("authority_exhausted", binding=current) + binding = _binding_row(thread_id, current_revision + 1, target) + return ( + _write_dsh_records(payload, {**records, thread_id: binding}), + _dsh_result(binding=binding, changed=True, application="yes"), + ) + + +def _run_global_binding_reduction( + *, + global_path: Path, + operation: str, + initial: dict[str, Any], + reducer: Any, + execute: bool, +) -> dict[str, Any]: + if not execute: + receipt = reducer(initial).receipt + receipt["application"] = "no" + return receipt + from .global_registry import mutate_global_registry + + mutation = mutate_global_registry(global_path, operation, reducer) + receipt = mutation["receipt"] + if receipt["changed"] and not mutation["wrote"]: + return _dsh_result(error_kind="authority_unhealthy", application="unknown") + return receipt + + +def bind_dsh_thread_agent_in_global_registry( + *, + global_path: Path, + host_surface: str, + thread_id: str, + goal_id: str, + agent_id: str, + expected_revision: int, + execute: bool, +) -> dict[str, Any]: + """CAS-bind or atomically switch one DSH Host key.""" + + try: + _require_dsh_surface(host_surface) + normalized_thread_id = _required_thread_id(thread_id) + normalized_target = { + "goal_id": _normalized_goal_id(goal_id), + "agent_id": _normalized_agent_id(agent_id), + } + normalized_revision = _revision(expected_revision) + initial = _read_global_registry(global_path) + global_goal = _exact_goal(initial, normalized_target["goal_id"]) + source_path = _source_registry_path(global_goal, global_path=global_path) + + from .global_registry import ( + GlobalRegistryReduction, + route_snapshot, + ) + + initial_route = route_snapshot(global_goal) + with exclusive_file_lock( + source_path, + agent_id=normalized_target["agent_id"], + operation="bind_dsh_agent_thread", + ): + source_agents = _source_membership( + source_path, + normalized_target["goal_id"], + ) + if normalized_target["agent_id"] not in source_agents: + raise DshBindingAuthorityError("invalid_target") + + def reduce(current: dict[str, Any]) -> GlobalRegistryReduction: + _require_global_registry_payload(current) + current_goal = _exact_goal(current, normalized_target["goal_id"]) + if route_snapshot(current_goal) != initial_route: + raise DshBindingAuthorityError("authority_unhealthy") + current_source = _source_registry_path( + current_goal, + global_path=global_path, + ) + if current_source != source_path: + raise DshBindingAuthorityError("authority_unhealthy") + if _goal_membership(current_goal) != source_agents: + raise DshBindingAuthorityError("authority_unhealthy") + updated, receipt = _binding_reduction( + current, + thread_id=normalized_thread_id, + expected_revision=normalized_revision, + target=normalized_target, + ) + return GlobalRegistryReduction(payload=updated, receipt=receipt) + + return _run_global_binding_reduction( + global_path=global_path, + operation="bind_dsh_agent_thread", + initial=initial, + reducer=reduce, + execute=execute, + ) + except (DshBindingAuthorityError, OSError, ValueError) as exc: + return _dsh_exception_result(exc, execute=execute) + + +def unbind_dsh_thread_agent_in_global_registry( + *, + global_path: Path, + host_surface: str, + thread_id: str, + expected_revision: int, + execute: bool, +) -> dict[str, Any]: + """CAS-unbind one exact DSH key, preserving a permanent tombstone.""" + + try: + _require_dsh_surface(host_surface) + normalized_thread_id = _required_thread_id(thread_id) + normalized_revision = _revision(expected_revision) + initial = _read_global_registry(global_path) + + from .global_registry import GlobalRegistryReduction + + def reduce(current: dict[str, Any]) -> GlobalRegistryReduction: + updated, receipt = _binding_reduction( + current, + thread_id=normalized_thread_id, + expected_revision=normalized_revision, + target=None, + ) + return GlobalRegistryReduction(payload=updated, receipt=receipt) + + return _run_global_binding_reduction( + global_path=global_path, + operation="unbind_dsh_agent_thread", + initial=initial, + reducer=reduce, + execute=execute, + ) + except (DshBindingAuthorityError, OSError, ValueError) as exc: + return _dsh_exception_result(exc, execute=execute) + + +def live_dsh_binding_references( + payload: dict[str, Any], +) -> list[dict[str, Any]]: + """Return bounded live references, rejecting a malformed collection.""" + + if DSH_BINDING_COLLECTION_KEY not in payload: + return [] + records = strict_dsh_host_thread_bindings(payload) + return [ + { + "thread_id": row["thread_id"], + "revision": row["revision"], + "goal_id": row["target"]["goal_id"], + "agent_id": row["target"]["agent_id"], + } + for row in records.values() + if row["state"] == "bound" + ] diff --git a/packages/dsh-loopx-plugin/.gitignore b/packages/dsh-loopx-plugin/.gitignore new file mode 100644 index 000000000..8e22ac3db --- /dev/null +++ b/packages/dsh-loopx-plugin/.gitignore @@ -0,0 +1,4 @@ +lib/ +build-temp/ +output/ +*.tgz diff --git a/packages/dsh-loopx-plugin/LICENSE b/packages/dsh-loopx-plugin/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/packages/dsh-loopx-plugin/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/dsh-loopx-plugin/NOTICE b/packages/dsh-loopx-plugin/NOTICE new file mode 100644 index 000000000..c14946715 --- /dev/null +++ b/packages/dsh-loopx-plugin/NOTICE @@ -0,0 +1,6 @@ +LoopX +Copyright 2026 LoopX contributors + +LoopX releases through v0.4.7 were distributed under the MIT License. +The historical MIT license text and copyright notice are retained in +LICENSE-MIT. diff --git a/packages/dsh-loopx-plugin/README.md b/packages/dsh-loopx-plugin/README.md new file mode 100644 index 000000000..ac0800eae --- /dev/null +++ b/packages/dsh-loopx-plugin/README.md @@ -0,0 +1,249 @@ +# LoopX for DeepSeek Harness + +`dsh-loopx-plugin` adds a same-session `/loopx` command, eleven bounded model +tools, and a quota-gated continuation driver to the DeepSeek Harness `web` +profile. LoopX remains the only authority for Goal, Todo, quota, status, +evidence, and terminal state; DSH persists only a Host binding sidecar. + +This package targets DSH `0.1.0-rc.7`, Node.js `^22.19.0 || >=24`, and a +locally installed `loopx` command. The plugin invokes that executable with +Node `execFile` and argv arrays. It does not invoke Python directly, start a +nested DSH process, or call `loopx turn run-once`. + +## Prerequisites + +Confirm both CLIs before installing the bundle: + +```bash +dsh --version +command -v loopx +loopx --version +``` + +The LoopX binary resolution order is: + +1. `loopxBin` in the `loopx-service` row config; +2. `LOOPX_BIN` in the DSH Host environment; +3. `loopx` on `PATH` (the normal default). + +## Install from a local checkout + +Build the package, then add its directory to the `web` profile: + +```bash +cd packages/dsh-loopx-plugin +corepack pnpm install --frozen-lockfile --ignore-scripts +pnpm build +dsh plugin --profile web add "$PWD" +``` + +For a reviewable prebuilt artifact: + +```bash +pnpm pack --pack-destination +dsh plugin --profile web add /dsh-loopx-plugin-0.1.0.tgz +``` + +Read back the composed profile before starting DSH: + +```bash +dsh --profile web --dump-config +``` + +The dump must contain `loopx-service`, `loopx-command`, `loopx-tools`, and +`loopx-driver`, in that order, plus the `web` profile's `storage-domain` row +with `backend: json`. If the storage-domain service is unavailable, the LoopX +service stays pending; it never falls back to process memory. + +To select an explicit executable without changing the profile, launch DSH +with `LOOPX_BIN=/path/to/loopx`. A profile-local override can instead replace +the bundle row in `$DSH_HOME/profiles/web/cordis.patch.yml`: + +```yaml +- insert: + - id: loopx-service + name: dsh-loopx-plugin/service + config: + loopxBin: /path/to/loopx +``` + +Optional service config also includes `project`, `runtimeRoot`, and an +explicit child-only `environment` mapping. Do not place credentials in that +mapping. Defaults are 15 seconds for reads, 30 seconds for writes, 1 MiB for +stdout, and 256 KiB for stderr. + +## Use + +Send any task-bearing request through the current visible DSH Session: + +```text +/loopx implement the requested change +/loopx attach Goal goal-123 and continue it here +/loopx status +``` + +Every non-empty suffix except exact `/loopx version` follows the same path, +including words such as `start`, `attach`, `status`, `pause`, `resume`, and +`detach`. The plugin queues one plugin-owned follow-up in the same Session. It +preserves the original suffix as quoted user text plus compact routing guidance, +then the current main DSH model handles one ordinary turn and may compose the +registered `loopx_*` typed tools. The command does not mutate LoopX before that +turn, run a keyword classifier, create another Agent, or invoke a second model. + +For an unbound Session, the model may attach only when the request contains an +explicit Goal id and explicit binding intent; otherwise it starts a new Goal +from the original request. For an already-bound Session, it keeps the current +Goal. Switching requires a different exact Goal id plus explicit switching +intent; detaching the current binding requires explicit detach intent but no +Goal id. It never guesses or fuzzy-matches a Goal id. When no safe operation +can be determined, it asks for clarification without changing state. + +The routing text is prompt guidance, not a machine-enforced hard allowlist. +Other DSH tools may remain visible; LoopX mutations remain bounded by the +registered typed schemas and authoritative service readback. Ordinary language +without `/loopx` continues through DSH's normal model/tool-selection path. + +Starting a new Goal is deliberately two-phase. After the semantic turn selects +`loopx_goal_start`, that tool returns the structured +`dsh_loopx_planning_checkpoint_v0` directly to the model. The model writes the +minimum sufficient public-safe plan through +`loopx_todo_add`, then calls `loopx_goal_activate`. Activation performs a +suppressed-sink refresh plus authoritative readback before arming the local +driver. The plugin keeps no parallel Todo receipt ledger; LoopX remains the +authority for the resulting Todo and refreshed task state. + +If the initiating turn stops while that exact binding is still planning, the +live driver may admit the cached checkpoint once more as a planning-only +recovery. Only model-step admission consumes that opportunity; removing a +queued recovery for a human message does not. This lane never calls delivery +quota, fetches a task body, or writes delivery spend. It either reaches the +same Todo-and-activation gate or becomes quiet until explicit continuation. + +When start runs in a stable DSH Session with no prior binding, LoopX defaults +to a distinct public-safe peer identity for that Session. A verified binding +is reused on later starts; taking over an existing peer remains an explicit +exact-identity action, and a host without a stable Session id still fails +closed. + +On a fresh project, the plugin accepts only the structured +`loopx_start_goal_connect_v0` contract, maps its allowlisted fields to a fixed +local `loopx bootstrap` argv, validates `loopx_bootstrap_result_v0`, and rereads +the guided state before binding. A producer-supplied command hint is never +executed. Unsupported or malformed producer schemas fail closed with upgrade +or repair guidance; the plugin never falls back to a shell command or direct +registry edit. + +Fresh-agent registration preflights the same source-to-global sync before it +changes the source registry. `LOOPX_REGISTRY_INTEGRITY` therefore means no +fresh identity was written; inspect the authoritative error with +`loopx sync-global --goal-id --dry-run`, repair that registry +contract, and retry. `LOOPX_WRITE_UNCERTAIN` means a source write may already +exist but global sync or exact readback was not verified. Do not create another +peer in that case: repair and reconcile the source/global agent sets first. + +Attach an existing Goal only with an explicit identity decision: + +```text +/loopx attach +/loopx attach --new-peer +``` + +The tool equivalent is `loopx_goal_attach` with the exact `goalId` and, when +needed, `agentId` or `newPeer`. If a start or attach request would replace a +historical binding, the first call returns `switch_required` and performs no +binding mutation. After the user explicitly confirms, the model repeats the +same typed operation with its short-lived `switchConfirmation` token. Tokens +are operation-bound, memory-only, and invalid after expiry, reload, disposal, +or target change. + +The model-facing surface contains exactly eleven bounded tools: + +- `loopx_goal_start` +- `loopx_goal_attach` +- `loopx_goal_activate` +- `loopx_status` +- `loopx_goal_detach` +- `loopx_driver_pause` +- `loopx_driver_resume` +- `loopx_todo_add` +- `loopx_todo_claim` +- `loopx_todo_update` +- `loopx_todo_complete` + +The only command-local cases are empty `/loopx` and exact `/loopx version`: + +```text +/loopx +/loopx version +``` + +Empty `/loopx` retains the local status/help response. Exact `/loopx version` +returns only the installed `dsh-loopx-plugin` package version and does not +invoke the LoopX CLI or read Session state. `version` with additional text, +plus `status`, `pause`, `resume`, and `detach`, enters the semantic path above. +The corresponding typed operations keep Host state separate from live LoopX +authority: pause and detach do not complete, pause, delete, or otherwise +rewrite the Goal or its Todos, while resume revalidates the exact binding and +refetches the task body before arming a new generation. + +After activation, each idle boundary asks LoopX quota whether the exact lane +should run. It reuses one turn identity for at most one certain, retryable +quota retry. Scheduler hints produce one per-Session timer and become quiet at +the unchanged limit. Only a LoopX-validated terminal closure stops without +another follow-up. Ordinary human input temporarily wins: queued automatic +work is removed, admitted work settles, and the driver rereads the binding and +fresh quota after the human turn. Explicit commands, detach/switch/pause, +uncertain or stale readback, and lifecycle disposal remain strong fail-closed +boundaries. + +## Remove + +```bash +dsh plugin --profile web remove dsh-loopx-plugin +dsh --profile web --dump-config +``` + +Removal deletes the bundle layer only. It does not delete LoopX state and v1 +does not implicitly purge the storage-domain sidecar. Reinstalling still +performs Session lifecycle checks and cold-restores any formerly armed row as +paused. DSH restart, Session resume or fork, and plugin reload never inherit +process-local planning or delivery authority. A restored planning binding has +no cached body: continue with natural language and typed tools, or start its +planning again. Use `/loopx resume` only for an activated binding that the +lifecycle left paused; it performs exact readback before re-arming. + +## Authority and privacy boundary + +- `ctx.loopx` is isolated from DSH `ctx.goals`; installing this bundle neither + reads nor mutates the DSH Goal service. +- LoopX is authoritative for Goal, Todo, quota, status, evidence, scheduler, + and terminal facts. DSH stores only Session identity, exact Goal/agent ids, + Host locators, driver generation, scheduler hint bookkeeping, and lifecycle + reason in its private sidecar. +- Goal text and task bodies are not copied into the Host sidecar or published + as LoopX evidence. Routed command/checkpoint content still follows normal DSH + Session persistence. Raw CLI stdout/stderr, environment values, credentials, + and tool logs are not projected into model output. +- Installing the bundle grants only the typed LoopX operations against derived + authoritative locators. It grants no arbitrary filesystem path, argv, shell, + network, credential, production, or cross-Session authority. + +## v1 limits + +The supported runbook is the DSH `web` profile on one protected local Host. +There is no Client-plane UI row, automatic sidecar purge, cross-machine +scheduler, shared multi-process storage-root coordination, or migration from +the external `deepseek-harness` / `dsh` LoopX Turn adapter. + +Existing control words remain usable through the semantic `/loopx` entry; +connected projects and the prior five tools remain compatible. Six typed +start/attach/detach/driver/Todo-add operations are additive. This +plugin requires the documented guided-connect, +planning, refresh-state, and bootstrap-result schema versions; use a compatible +local LoopX CLI or remove the plugin to roll back. Removing it does not +reinterpret or migrate authoritative LoopX state. + +See the canonical +[DeepSeek Harness native plugin integration guide](https://github.com/huangruiteng/loopx/blob/main/docs/integrations/deepseek-harness-native-plugin.md) +and the separate +[external DeepSeek Harness connector](https://github.com/huangruiteng/loopx/blob/main/docs/integrations/deepseek-harness-connector.md). diff --git a/packages/dsh-loopx-plugin/cordis.patch.yml b/packages/dsh-loopx-plugin/cordis.patch.yml new file mode 100644 index 000000000..499408f53 --- /dev/null +++ b/packages/dsh-loopx-plugin/cordis.patch.yml @@ -0,0 +1,14 @@ +# Host-plane only. LoopX owns durable authority; this package keeps only +# process-local coordination state. +- insert: + - id: loopx-service + name: dsh-loopx-plugin/service + + - id: loopx-command + name: dsh-loopx-plugin/command + + - id: loopx-tools + name: dsh-loopx-plugin/tools + + - id: loopx-driver + name: dsh-loopx-plugin/driver diff --git a/packages/dsh-loopx-plugin/install.sh b/packages/dsh-loopx-plugin/install.sh new file mode 100755 index 000000000..3db27b2b6 --- /dev/null +++ b/packages/dsh-loopx-plugin/install.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +PACKAGE_JSON="$SCRIPT_DIR/package.json" +OUTPUT_DIR="$SCRIPT_DIR/output" +PACKAGE_NAME="dsh-loopx-plugin" +PROFILE_NAME="web" + +usage() { + cat <<'EOF' +Usage: ./install.sh [--help] + +Build and install the current dsh-loopx-plugin package into the DSH web +profile. The package version is always read from package.json, and the packed +tarball is retained under output/. + +Environment: + LOOPX_BIN=/path/to/loopx Override the LoopX CLI used for the preflight. + DSH_BIN=/path/to/dsh Override the package-local DSH CLI. +EOF +} + +case "${1:-}" in + -h|--help) + if [[ "$#" -ne 1 ]]; then + echo 'install: --help does not accept additional arguments' >&2 + usage >&2 + exit 2 + fi + usage + exit 0 + ;; + '') + ;; + *) + echo "install: unsupported argument: $1" >&2 + usage >&2 + exit 2 + ;; +esac + +if [[ "$#" -gt 1 ]]; then + echo 'install: positional arguments are not supported' >&2 + usage >&2 + exit 2 +fi + +need() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "install: required command not found on PATH: $1" >&2 + if [[ "$1" == 'pnpm' ]]; then + echo 'install: install pnpm or enable its Corepack shim first' >&2 + fi + exit 2 + fi +} + +resolve_command() { + command -v "$1" 2>/dev/null +} + +need node +need pnpm + +PACKAGE_VERSION="$( + node -e ' + const fs = require("node:fs") + const manifest = JSON.parse(fs.readFileSync(process.argv[1], "utf8")) + if (manifest.name !== "dsh-loopx-plugin") { + throw new TypeError("package.json name must be dsh-loopx-plugin") + } + if (typeof manifest.version !== "string" || manifest.version.length === 0) { + throw new TypeError("package.json version must be a non-empty string") + } + process.stdout.write(manifest.version) + ' "$PACKAGE_JSON" +)" + +if [[ ! "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then + echo "install: package.json contains an invalid semantic version: $PACKAGE_VERSION" >&2 + exit 2 +fi + +requested_loopx="${LOOPX_BIN:-loopx}" +if ! loopx_bin="$(resolve_command "$requested_loopx")"; then + echo "install: LoopX CLI not found: $requested_loopx" >&2 + echo 'install: install LoopX first or set LOOPX_BIN=/path/to/loopx' >&2 + exit 2 +fi +if ! "$loopx_bin" --version >/dev/null 2>&1; then + echo "install: LoopX CLI preflight failed: $requested_loopx --version" >&2 + exit 2 +fi + +echo "install: preparing $PACKAGE_NAME@$PACKAGE_VERSION" +CI=true pnpm --dir "$SCRIPT_DIR" install --frozen-lockfile --ignore-scripts + +if [[ -n "${DSH_BIN:-}" ]]; then + if ! dsh_bin="$(resolve_command "$DSH_BIN")"; then + echo "install: explicit DSH_BIN is not executable: $DSH_BIN" >&2 + exit 2 + fi +else + dsh_bin="$SCRIPT_DIR/node_modules/.bin/dsh" + if [[ ! -x "$dsh_bin" ]]; then + echo "install: package-local DSH CLI is missing after pnpm install: $dsh_bin" >&2 + exit 2 + fi +fi +if ! "$dsh_bin" --version >/dev/null 2>&1; then + echo 'install: DSH CLI preflight failed' >&2 + exit 2 +fi + +mkdir -p "$OUTPUT_DIR" +tarball="$OUTPUT_DIR/$PACKAGE_NAME-$PACKAGE_VERSION.tgz" + +echo "install: packing $tarball" +pnpm --dir "$SCRIPT_DIR" pack --out "$tarball" +if [[ ! -s "$tarball" ]]; then + echo "install: pnpm did not create the expected tarball: $tarball" >&2 + exit 1 +fi + +echo "install: installing or updating $PACKAGE_NAME in DSH profile $PROFILE_NAME" +"$dsh_bin" plugin --profile "$PROFILE_NAME" add "$tarball" --ignore-scripts + +if ! profile_dump="$("$dsh_bin" --profile "$PROFILE_NAME" --dump-config)"; then + echo "install: DSH profile $PROFILE_NAME could not be read back" >&2 + exit 1 +fi + +if ! printf '%s' "$profile_dump" | node -e ' + const fs = require("node:fs") + const dump = fs.readFileSync(0, "utf8") + const rows = [ + ["loopx-service", "dsh-loopx-plugin/service"], + ["loopx-command", "dsh-loopx-plugin/command"], + ["loopx-tools", "dsh-loopx-plugin/tools"], + ["loopx-driver", "dsh-loopx-plugin/driver"], + ] + let previous = -1 + for (const [id, name] of rows) { + const position = dump.indexOf(`id: ${id}`) + if (position < 0) throw new Error(`missing bundle row ${id}`) + if (position <= previous) throw new Error(`unordered bundle row ${id}`) + if (!dump.includes(`name: ${name}`)) throw new Error(`missing bundle module ${name}`) + previous = position + } +'; then + echo 'install: DSH profile readback failed; the full profile was not printed or persisted' >&2 + exit 1 +fi + +echo "install: installed $PACKAGE_NAME@$PACKAGE_VERSION" +echo "install: verified $PROFILE_NAME rows loopx-service -> loopx-command -> loopx-tools -> loopx-driver" +echo "install: artifact retained at $tarball" diff --git a/packages/dsh-loopx-plugin/package.json b/packages/dsh-loopx-plugin/package.json new file mode 100644 index 000000000..dac6d714c --- /dev/null +++ b/packages/dsh-loopx-plugin/package.json @@ -0,0 +1,80 @@ +{ + "name": "dsh-loopx-plugin", + "version": "0.2.0", + "description": "Same-session LoopX host integration for DeepSeek Harness", + "private": true, + "type": "module", + "main": "./lib/index.js", + "types": "./lib/types/index.d.ts", + "exports": { + ".": { + "types": "./lib/types/index.d.ts", + "default": "./lib/index.js" + }, + "./service": { + "types": "./lib/types/service.d.ts", + "default": "./lib/service.js" + }, + "./command": { + "types": "./lib/types/command.d.ts", + "default": "./lib/command.js" + }, + "./tools": { + "types": "./lib/types/tools.d.ts", + "default": "./lib/tools.js" + }, + "./driver": { + "types": "./lib/types/driver.d.ts", + "default": "./lib/driver.js" + }, + "./cordis.patch.yml": "./cordis.patch.yml", + "./package.json": "./package.json" + }, + "files": [ + "lib/*.js", + "lib/types/**/*.d.ts", + "cordis.patch.yml", + "README.md", + "LICENSE", + "NOTICE" + ], + "engines": { + "node": "^22.19.0 || >=24.0.0" + }, + "scripts": { + "build": "node scripts/build.mjs", + "typecheck": "tsc -p tsconfig.json --noEmit", + "test": "vitest run", + "prepack": "pnpm build", + "smoke:profile": "node smoke/dsh-profile-smoke.mjs" + }, + "dsh": { + "bundle": { + "patch": "./cordis.patch.yml" + } + }, + "dependencies": { + "@deepseek-ai/schemastery": "3.18.1", + "zod": "^4.4.3" + }, + "peerDependencies": { + "@deepseek-ai/cordis": "^4.0.1", + "@deepseek-ai/dsh-agent": "0.1.0-rc.7", + "@deepseek-ai/dsh-commands": "0.1.0-rc.7", + "@deepseek-ai/dsh-session": "0.1.0-rc.7", + "@deepseek-ai/dsh-tools": "0.1.0-rc.7" + }, + "devDependencies": { + "@deepseek-ai/cordis": "4.0.1", + "@deepseek-ai/dsh": "0.1.0-rc.7", + "@deepseek-ai/dsh-agent": "0.1.0-rc.7", + "@deepseek-ai/dsh-commands": "0.1.0-rc.7", + "@deepseek-ai/dsh-session": "0.1.0-rc.7", + "@deepseek-ai/dsh-tools": "0.1.0-rc.7", + "@types/node": "^22.19.0", + "tsdown": "0.22.2", + "typescript": "^6.0.3", + "vitest": "^4.1.8" + }, + "license": "Apache-2.0" +} diff --git a/packages/dsh-loopx-plugin/pnpm-lock.yaml b/packages/dsh-loopx-plugin/pnpm-lock.yaml new file mode 100644 index 000000000..8cf6a84cf --- /dev/null +++ b/packages/dsh-loopx-plugin/pnpm-lock.yaml @@ -0,0 +1,9198 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@deepseek-ai/schemastery': + specifier: 3.18.1 + version: 3.18.1 + zod: + specifier: ^4.4.3 + version: 4.4.3 + devDependencies: + '@deepseek-ai/cordis': + specifier: 4.0.1 + version: 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh': + specifier: 0.1.0-rc.7 + version: 0.1.0-rc.7(1028bc4c4765246571adba5ae8d2d1c8) + '@deepseek-ai/dsh-agent': + specifier: 0.1.0-rc.7 + version: 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-commands': + specifier: 0.1.0-rc.7 + version: 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': + specifier: 0.1.0-rc.7 + version: 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-tools': + specifier: 0.1.0-rc.7 + version: 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@types/node': + specifier: ^22.19.0 + version: 22.20.1 + tsdown: + specifier: 0.22.2 + version: 0.22.2(typescript@6.0.3) + typescript: + specifier: ^6.0.3 + version: 6.0.3 + vitest: + specifier: ^4.1.8 + version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@22.20.1)(vite@8.2.1(@types/node@22.20.1)(yaml@2.9.0)) + +packages: + + '@anthropic-ai/sdk@0.91.1': + resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/client-bedrock-runtime@3.1048.0': + resolution: {integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.977.8': + resolution: {integrity: sha512-7+Kcrkvrk9lM/m7jRhHpT4jCdvzGHsuaSRbF8TdzzkY1mRzp/Ogwf9c7H29k4gGhey0BBWhCWr16+t0J61gwmg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.69': + resolution: {integrity: sha512-AreCFzcB4kH2HF9031Ot0jSJr3KXvRg6e8uDeub20JEVdZU3Bv0sTq1plc7VsT3KiqutlzH7l0j50UcCWHUioA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.71': + resolution: {integrity: sha512-A8ObcqVmDMnk4F9NozZ7JwmUu9Q4xyBJkmyq1C5U+wNM9ht9J7+EuuyabsLWXZnOoTqFaJuYBYTKf5CTipkEjA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.973.14': + resolution: {integrity: sha512-7c+Wti2LsERNWMfm7ySz3/6RPopFW3Nmn7s63Xpcq6R/tRuY5hpvkHA2xVgi5ukJbvok9l0IDtVEvqTtg+X7dw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.76': + resolution: {integrity: sha512-LVixwOnEJfrrfKHeZjBA8pIMTZjNDq8ak8VpcoWUuCJDrSnBNU8POJksULMgvN089P0MXtQYH2Zs627/MK1K0g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.80': + resolution: {integrity: sha512-bE2qh8ww4iClO1jHsBXdOE8FUgzDbdxbyorNjSCoPSkQd51k3jODItuPZfuwcLHZqDXsH+bI4AMHhqtuyR7mSg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.69': + resolution: {integrity: sha512-9kpTNdZTrcqXTfhxM7fgl9Z68ek3Fu5oe3Yf+A/pJGibEqpgZxz2tSY7SinmyCIU2PJ+ygY4FPoBBnLpocMtrQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.973.13': + resolution: {integrity: sha512-Oc81qauMPzUoTnAS2YKpNwY6sY/LUyQTEeaf6yP197WMxkEBQfcKLR1MFpD7+pNTubXnfkH6gwpji+Gc7iyD2Q==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.75': + resolution: {integrity: sha512-YPN6uoGDgjjjeVFZrcOeCJqmB6zpXoeeNgIjqe+DexJaWqdjVfCCe+VAZwli9Z2h8KhFW8oxkO39emQ1tyz/Mw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/eventstream-handler-node@3.972.33': + resolution: {integrity: sha512-1Dd5WyEE2Kb3HvY44u7Ob16ST2W6iutOqsQ8Y2hUmsL2mAH/STlGS1dS9h3IOE6L7Ld3AR2HzKJ6XeCMOw8Peg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-eventstream@3.972.28': + resolution: {integrity: sha512-Z1EDXnS01P7H5jVrUx+/dBqV0m7dta7bSxLclkOuDuS93pNNQm0IcT4YLUbuvWKPYNxbI8aTG0p5Br30GSKDgA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-websocket@3.972.51': + resolution: {integrity: sha512-jdgP3jR5Q96j1jjZ98GGwpGg1CBNFIO2YE+vXg8cg8PvNY4NvgQNYJsqDaRX2PYv5gSUX/+C0D58Fhspj9ELMQ==} + engines: {node: '>= 14.0.0'} + + '@aws-sdk/nested-clients@3.997.43': + resolution: {integrity: sha512-bit+VpqWNyi3wHxFoTsTliNXimCSL2r2OeDTm7ZrG+YsTZ2D7ofDJ6r/t9PVBn80i6/v0X2h9Tgw6QP2MAKfPw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.45': + resolution: {integrity: sha512-bBuyztukzXq6plzFGHAWiQt0QXo+HL8b8lX5cFTzkez/74PtS1c0qPFCIVuHkyoT+miH2qOjAcm1/yoro2ESPA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1048.0': + resolution: {integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1111.0': + resolution: {integrity: sha512-JfljgoVtl+s3Qy21n9a7Z48uCQaOXcN74KJ3TEQfPoB293GrXFSt6HSQJF1sTZ8c/5QedEvd3NjJQMO4u9qa5A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.974.4': + resolution: {integrity: sha512-dSFDNG00MEz0/xl5gxL62giLd1iYyJsTxZ1I1DOj6lC+bbgLB4TRsYClJg3b62dhXT1uATzsTNXPnC+33EJV3A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-locate-window@3.965.10': + resolution: {integrity: sha512-ycwH6Zd2GhuSqdXX9ihbCjeGTB6xOJs+O3+Jb8/zDG9978XU80qs75dfkPJRMNKe5MvBZPuNeFpd4JZKPoUF4g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/xml-builder@3.972.39': + resolution: {integrity: sha512-FTti8DS5MMWXNUWiRwXAJeYS+0GHHiMy0+7XOhcwk63ILHmfS2UFy2z/HNpZCSOJJ3P3dnWY6hfYNW3DF0nXUA==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.3.0': + resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==} + engines: {node: '>=18.0.0'} + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@8.0.0-rc.6': + resolution: {integrity: sha512-6mIzgVK8DgEzvIapoQwhXTMnnkuE4STQmVv9H03i/tZ2ml8oev3TRvZJgTenK2Bsq0YWNtzOrFdTyNzCMFtjJQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@8.0.0-rc.6': + resolution: {integrity: sha512-nVJ+1JcCgntv8d78rRo++o2wuODT0Irknx2BF8Np4Ft2CRgjLqIs4qzSZ8b66yGbBdMWGmZBO9WEZv1hhNiSpg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/parser@8.0.0-rc.6': + resolution: {integrity: sha512-rOS8IpdO7mQELkTPlCsTgPejO0bFuZdEDCGQJouYbYf9e1FLTym7Fei2pEjq8q7MWbX0ravcd7QQYKs1TxOuog==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@deepseek-ai/cordis-plugin-group@1.0.1': + resolution: {integrity: sha512-E1NThkFB3jn3TCqa6Oc++1zQHqLejF3W2wDwv2BlL3UEmgtBXL1K1j1koc+j676RuiOXtJkUJlPcOntRGKLWBQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + + '@deepseek-ai/cordis-plugin-hmr@1.0.16': + resolution: {integrity: sha512-S7VHfylDg1+Y5O6fdYYZu0KFRAj/snHywcFPnX3KmQYa/qv2Q8IXi4zAt9ABq0BJYqhNoqRlbpGMfIjabgXjKA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-timer': ^1.1.3 + + '@deepseek-ai/cordis-plugin-include@1.0.6': + resolution: {integrity: sha512-i1VXrZCbv6tk/iUgedCNjrxxArbWT3IvRZGB5sdqJ3ectnihivXXQbRZ8JJ73DSmAPvlMGmrbtjFAfm10yvXRg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + + '@deepseek-ai/cordis-plugin-loader@1.0.2': + resolution: {integrity: sha512-RIW9hoVyhYDWdCI9BsvtZccPde1ECLC4OAxupwowGTak78vwVTVdb3HezTSOK1Y1/Ax3Ru0LA1pYOB04CnTxIQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + node-addon-require-builtin: ^0.1.4 + peerDependenciesMeta: + node-addon-require-builtin: + optional: true + + '@deepseek-ai/cordis-plugin-timer@1.1.3': + resolution: {integrity: sha512-IOkey1VNmJwYa5U8bksyMOnM7mtirqjjbWLr3xA8QybLMK0sMooG3a6iJwtvd8P3MFwo3FQibEg+JPixp37MEw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + + '@deepseek-ai/cordis@4.0.1': + resolution: {integrity: sha512-YBdskTU2Po1kru3GgcUWUbkTsPMA9LkSQDAY8rBkFJeajdgcQad3QPJZE26JyK99Xb6HaASvoXg2DSUTeN/0Nw==} + hasBin: true + peerDependencies: + '@deepseek-ai/cordis-plugin-include': ^1.0.6 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + peerDependenciesMeta: + '@deepseek-ai/cordis-plugin-include': + optional: true + '@deepseek-ai/cordis-plugin-loader': + optional: true + + '@deepseek-ai/cosmokit@1.8.2': + resolution: {integrity: sha512-muBOKtSrUKU5m/xpq8ZXWL6hQ/jgd4PhU2PqH97bcxIiLEJfNwZOGQEx4t/aS/GgxRAR+ra9pMHPMtTHU4sqqA==} + + '@deepseek-ai/dsh-agent-default-model@0.1.0-rc.7': + resolution: {integrity: sha512-zHtD4FAqxzidyNiyx1bpvLHdOTTsKnmjlHRqDS1KegIMSTNFmmp1B2bHdAUXp/OH7fPDmv+1ZXzDoJhBNUY9jA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-agent-instructions@0.1.0-rc.7': + resolution: {integrity: sha512-laLz5ee7tKqVzrj15ztHuOnJLxDiGlqFOm6mEJUjJPWWD9Yzj1Iq+6WHZZ3Hw66vrNzYKqEN0TBofWF3DA7OzQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-agent-loop@0.1.0-rc.7': + resolution: {integrity: sha512-98jV+6XnkZ93g4C1BJ/hCcC8k4GVhH+oNrkhLFvc6aOQz6o+9kdV8IrgEVr0qRcAfHKlCMfiV4BIDz4eBBoziw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-agent-presets@0.1.0-rc.7': + resolution: {integrity: sha512-T/VcMV7lrXCFmRKrtoMTAz5DAdUmku6hz95wbikRvRc0WizIwQ3R04ke9KIeDiQcxK8xkE8cx+IYqEWa9C5gPg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-include': ^1.0.6 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-atomic-write': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-agent-tool-presentation@0.1.0-rc.7': + resolution: {integrity: sha512-RAtrfRyLZ/ob9lW5/fKeU7T4LYPTXYP7qCmu2i7ZBqwHseMdYHk0U1Ti8z2kr2NF4LIzHNUXIwaE9s7za5cwuA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-agent@0.1.0-rc.7': + resolution: {integrity: sha512-AqBQavJYgbCUUYBHP7OGCaw8WN5082NXYQOoOfNRO72bub3E+/nWkl8b4B7BAJdFfyLo9ce+Kgb1BCHSJU/JLg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-anonymous-user-id@0.1.0-rc.7': + resolution: {integrity: sha512-g39W2HSWum6ghJG3src3rLVR8mnCsc0xCBSRpef1Fxgsjjn1LS2KNstKThXQtn7lYQZM/DNE7uiaOmsLxayeJQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-api-gateway@0.1.0-rc.7': + resolution: {integrity: sha512-tcoOuHMSqYqCtMxLjWBHKN+glS56XaUo3ImphvDvUkB84FyU3btHNJbYeAt2oXoWbHfOedcIRWpfNN4tSmhPwQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-registry': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-api-remotes@0.1.0-rc.7': + resolution: {integrity: sha512-dsP69u0avHRcJTPzngudqCm73UaTxNvGi/557DNPi3cOSoIh1SyPzPgk8W8rQQEFTL07rkwt8KfdQoMU5ga1fg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-agent-presets': ^0.1.0-rc.7 + '@deepseek-ai/dsh-api-gateway': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-cordis-host-runner': ^0.1.0-rc.7 + '@deepseek-ai/dsh-credentials': ^0.1.0-rc.7 + '@deepseek-ai/dsh-goal': ^0.1.0-rc.7 + '@deepseek-ai/dsh-host-plugin-inventory': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-message-feedback': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-registry': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-app-boot@0.1.0-rc.7': + resolution: {integrity: sha512-3qgv994YzNGrlDcOyarL4vqNky3ttmYsUhDsMgGdefALK6gpL7ZCWF+9m0ehZjGY0Rb4VcBdieJYOY2EgpWb0w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-group': ^1.0.1 + '@deepseek-ai/cordis-plugin-hmr': ^1.0.16 + '@deepseek-ai/cordis-plugin-include': ^1.0.6 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-launch-environment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + peerDependenciesMeta: + '@deepseek-ai/cordis-plugin-hmr': + optional: true + + '@deepseek-ai/dsh-atomic-write@0.1.0-rc.7': + resolution: {integrity: sha512-LxRx6K8FJ8bXZHiNhH6Rvj+jh/ZIpolmsmi138XrvMUGvbOBWE6QLbdzcgTgwrYZm5GP2kqqLe/3gQlgtt2bXA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-attachment-local@0.1.0-rc.7': + resolution: {integrity: sha512-7i2Fuj811MFeqrUYnpEG3VBoShZEjQ7zNXdLOa1W5hZ4TWV+tUjX7pJoN88U1LOgEOWMc9uzSPqGA5/aKBYgdQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-attachment@0.1.0-rc.7': + resolution: {integrity: sha512-rsR/xVNOGIig8gXxhrKnkd6YD7aYliGtA/e7b4DlPawMpLhsItAh0HQ832n8LJn1aGZxKf68y9PRgzfljsveOQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-base@0.1.0-rc.7': + resolution: {integrity: sha512-lpAMUO3PdxZwLnCQOdOZ/fu7eI27Ckz3Ec9MB9QYL4u34yatndCliTrGaFBDoNHoWt3V4gojzszRFrEx+Vce/g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-bash-local@0.1.0-rc.7': + resolution: {integrity: sha512-fsw2Ex5ExyX4A62P1+fodbnUG4PXOSyHAM4YtaLg2kcPcElLwatYNPG3gEuulxwbpWDlx/OWvbjHThnJUuzaoA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-bash-sandbox@0.1.0-rc.7': + resolution: {integrity: sha512-xX+XhqPeRaOqMPDNk8dPboHza2pP13hTIMt+ztvd8WpD0t35idrNrcsXEYs+CtKiFWn6I05WB1BeAimWkLDOcg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-bash-local': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-brand@0.1.0-rc.7': + resolution: {integrity: sha512-P7+w0fN40yXXQkV360p6jQi63pcl68OOWebNGN5gf8w8sguvni2mA1cU8RLZzDkRNFSZD+BCw3D4uWYM+hhh7A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-connection@0.1.0-rc.7': + resolution: {integrity: sha512-JZWDKCbwKHOUcm7+JadKA3aJCSEB34XfPycCtPgdWfABIiHMaSpnmSVy/8Jed4hw6hxhnR6A3rnvW02Xr2yqwA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-host-webserver': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-hmr@0.1.0-rc.7': + resolution: {integrity: sha512-uJVHLMgmf19JI7UCqrC8jipf/5oaM539RPJ5sNv+BJCbt9Ik6VqaKbu4uiF+gz8i8EqbXV3D9criL1IiCS+pdg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-client-modules': ^0.1.0-rc.7 + '@deepseek-ai/dsh-host-webserver': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-locale@0.1.0-rc.7': + resolution: {integrity: sha512-1onX79wXJfAzdwIJPUI9jEVYeVQJfWwyQvyL/OmGrnkCs8srJHIXBdYtsUC7ILlR13y5nOY4j6bifBOAoGRn6w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-modules@0.1.0-rc.7': + resolution: {integrity: sha512-hczFl0TRH5sLt/dS0+TMCtQvfDoeLw/r88L6n3rXfY6Q1e4Yddg6RAv4kGsUoMoLYgWi7qPwD6HcUGgyKkDPHg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-runtime@0.1.0-rc.7': + resolution: {integrity: sha512-Ish2uFML2FibTpzo7QyVSt29jf/iG4j9BFQ41ychVMPRR3trJGM3h8CMuam3oKWlvB8OXVXFd6gO929w6PI0Ew==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-registry': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7': + resolution: {integrity: sha512-acGeXjGl2lMqCO+jY1z9/FKbIiskk7FZO266OSBOwHJQP6yBd5MBnrvtPJUB3glP6xsQK8neFLLtRwVgRJ+GqQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-agent-preset@0.1.0-rc.7': + resolution: {integrity: sha512-85GLGfg3iEISMhHxn9ZePkB/mtXIJdWkpvSHCm9bZizK8KiyRfA/OjDpKfk5kvG16xKNV0KQo65HOf0JdwtyXQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-web-react': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-attachment@0.1.0-rc.7': + resolution: {integrity: sha512-IRA778yZpOaoJEkODlfydd6yuASf7hF229s64IY5zaY+22K7D+X1cmDo8D13UylxQXFPAomTlHtQtQpCtghKXw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-commands@0.1.0-rc.7': + resolution: {integrity: sha512-gLuzEmgVhEIjVeLlmIAdKX/SEEFavnVOD0mQPlHIMqFAX/80yzYfRD7CMxXc0amOj7uBcw7qsSa4WzFvaWso3w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7': + resolution: {integrity: sha512-CyjFjP+oRJQ4ydX8WVrKUeloQnAJRA/fN6RRY6NAHldFC9pd1l8YogmTcR1JuCIlqzMnLRyYlGODQBYz8WOjmA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm-retry': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-stats': ^0.1.0-rc.7 + '@deepseek-ai/dsh-token-meter': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-cordis@0.1.0-rc.7': + resolution: {integrity: sha512-8OwbFdMHRIE7L2PvoIGwSOkhUYsznr9u773K3s64DMxp4oLLl3ZzHc2hfaOfQTTmyE7ItpDJm8Von42LsJBKaw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-sidebar': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-tool': ^0.1.0-rc.7 + '@deepseek-ai/dsh-cordis-client-runner': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-deliverables@0.1.0-rc.7': + resolution: {integrity: sha512-uVN7TXKrGQMACKToSTPxOIeDlebQgi2OMiKBaKrYcI7jBsCRief3CTLziZ6Kups2h2s72Eo6gu/0eueccwLYew==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-directory-picker-browse@0.1.0-rc.7': + resolution: {integrity: sha512-5lj27c68wWqroyIOXmFPGUDFQxICDYEcYAJSuV5ZbnHXyN2cBTTDTW4zJPwisY5GhKfiJXjhS0YZqLi54/Xn+Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-workspace': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-directory-picker-native@0.1.0-rc.7': + resolution: {integrity: sha512-SZ9NuuIDrBjHJsEcnqwhbiCZknjkyNd0ZBHDl453p2WHkfA8zwDMUJRdAMWd0sC95WH2Yu4rMzkAVYjZwCBjVw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-workspace': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-goal@0.1.0-rc.7': + resolution: {integrity: sha512-zZEAbaA6ZCMw2ZDGMWFm+nBXnBBRfI8StRtx33GoFcJHlMIP5mJfuSm2gcFHdO+3aeAmuTf5G++DdWwLRLZv9A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-goal': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-input-trigger@0.1.0-rc.7': + resolution: {integrity: sha512-Sfn4YlS6dKm/ojGRyZL5oq34+GSeyirzGkmqhtoX7hpjHAhBVmugz2jku2ijYEjjFtD6YKYdWwvQxHdRaHFZ+w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-jobs@0.1.0-rc.7': + resolution: {integrity: sha512-q8WvaB1gxj4OBPCLC/luDLQ7TRY2iwuhOZKrwG1MbXhSmfd14RiyKHG1p/5HIxwTJZfqnxuN69NzdAZY6cjU8g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-layout@0.1.0-rc.7': + resolution: {integrity: sha512-4z5xkH/O8GT6ve1IX15WTel236fJwSuRZusMKJ9qIxdslZZ1h+wMbtgX3tCqg7mTtMznRDspCpC1b1QSAt4nTg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-theme': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-message-feedback@0.1.0-rc.7': + resolution: {integrity: sha512-B8y2+tu1xorpHmwo8KWsLFZwa4P0uFCI32H1SwYyQjBjoTbSb+TOfPA3i6na988XMiF8NCcxynTFzHRv/77AJw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-message-feedback': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-model-selection@0.1.0-rc.7': + resolution: {integrity: sha512-Gr5goo9dEGCR/CqpeJgO1mGO1ZqoX4tpuAMuZoq3wmLwaeK8qOMMhHGTxGOI9NbBD1snvbUzOJP/LUoNrS61YQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + clsx: ^2.1.1 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-permission-presets@0.1.0-rc.7': + resolution: {integrity: sha512-OO/miNmPCJS/5GffqXeBnPvdx1HnHvi9AHb4Uoy9N+zucwo7ZQV40lQ+ODcAX9UaRW/6x3a8CxQ3G4q1t/ltKQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-schema-form': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-permission-presets': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-plan@0.1.0-rc.7': + resolution: {integrity: sha512-b6qqGcq5MxulD+XBxcD3ZewgJ17OUegeSA0Ov0afC4hvgyhWhZP3b+odH92ax7Ckaat8/Yx2j4NPpu81e30qLA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-plan-mode': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7': + resolution: {integrity: sha512-x3cnIAeOdDMd7no8JwP65q7J9Fj4xQWAZPPJY4MzgfQAAOcHJb0T0d5Uo4FXMiCcTeU/73n7BssS5PE7jjgiDg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-settings-general@0.1.0-rc.7': + resolution: {integrity: sha512-L5heQqyzZ/Kd+/hj8Ptd89OOss6FI8TjD3iwC47V3Xj/8ZgtnHwEA7vSqeoTe03uzRz8Zd8ec+bz/q47z8/I/Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-sidebar': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-web-react': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-settings-models@0.1.0-rc.7': + resolution: {integrity: sha512-q73sXPomdUGpucj6pgKuO3WrGzqCoqyZhbqOZQL7EIdJcl9N3P+tNhsNj+ls1UOcOpb36Ou2NzUdIeyHSNVmKg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-schema-form': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-web-react': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-settings-plugin-inventory@0.1.0-rc.7': + resolution: {integrity: sha512-Ei6q5/UdUC9SxrTcbn/XR1NCe4iZgovhmbKCKBKBHMCNxhE0umdUJL8M7uKZdlpItJQ2ggiK9L8RmztKDmv59A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-settings-plugins@0.1.0-rc.7': + resolution: {integrity: sha512-oOOgj9NTv1GE+QdKhBfkcWG2+WS9uJz5NYgIZzahbg6xCbu4a2vugcCKcyslQEKKOB35mGHH/orPcoj2N+DeHg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-web-react': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-settings@0.1.0-rc.7': + resolution: {integrity: sha512-I02BGKw3/yG25yf5omsMwmwJ2CnFyxTvbxqgRgSmTCUxATkLT87K8SxcemRZqXnFXQZhm6Il6bwVCpVfRfmNoA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-schema-form': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-sidebar@0.1.0-rc.7': + resolution: {integrity: sha512-YduvLROf3gniqYggfRfkvNDMtqvWlREmwxVtxullWTXhrgXmcPya7GCKJeru8ZuyrF3FU1XqOR8KJT+OzLSv7w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-skill@0.1.0-rc.7': + resolution: {integrity: sha512-jxqQhu4RkNjEf2zTm/h9qJZ+q/mHdSBVC05XqfsdNP1VRni9k9L/LcR2TWHfyuvM61drtdi5s+/ZW9pbxaQPiQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-tool': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7': + resolution: {integrity: sha512-5rPP/6IWZflhiegVHU56IOPGHtrhLgBV44mOFn2JNVwiwxxmKeIhEcnYD4M0eKkI+pRiJIO5WvkRYokIGgyFiA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-subagent@0.1.0-rc.7': + resolution: {integrity: sha512-geEZbS5N68tYJIPSToWIFPj0EjRiJBzryLvv3VL+INqt6urYCEm2uY7arNLUFJhHpjOJVi45ZM8qlh0qw5Sk7Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-input-trigger': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-token-meter': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7': + resolution: {integrity: sha512-T5YaUZEJv0XHL0VYuP4/Vg+tbQGgRq0+gqsbqryuU5nq59PPISDED81zpCSb1jkZ/xFNc5Weq68+54cUGndpQg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-host-webserver': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-tool@0.1.0-rc.7': + resolution: {integrity: sha512-smo+6QWddCdtLQb4AUVbaaxsu3h8ImQlMDTBYK4qeoxlVTQdKgrNdgtQe5YoB8bvuGLQd6obVVwwScPNaD73xw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-trajectory@0.1.0-rc.7': + resolution: {integrity: sha512-Iuksc3q9Rpwj+EQMoCv9BqfLBEclDiUGiGwUec2p2FhZjr1yEBK4ujlQK2N71EteyBjQ5yODE+/S+TzNkrou9w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + react: ^18.2.0 + react-dom: ^18.2.0 + + '@deepseek-ai/dsh-client-ui-user-questions@0.1.0-rc.7': + resolution: {integrity: sha512-HrFy3NpBx8J1Az+4WCljgXQvt/TTa6G3SKgtF0ZxdstB+BYoiMyBjO8aXAKQ94BM7zLcOVfUmL1bCb9t6tFmvg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-workflow-run@0.1.0-rc.7': + resolution: {integrity: sha512-XTKDLADe621GN+D2ysnOdVFvK1Et4nxvdrvsCxl7epsfrelsZD4l+/BleUQ+G/vQVZt3v03VkVVnE0SPGpt9Fg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tool-workflow': ^0.1.0-rc.7 + '@deepseek-ai/dsh-workflow': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-ui-workspace@0.1.0-rc.7': + resolution: {integrity: sha512-+8TmQprJ4y1J9AyM+/ABkndWsv6/lwA7by6HlRup4Ks2auQBhejFG7FjZPFACjkWLuJaIgDUN1aRQ5MNFCanfQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-client-web-react@0.1.0-rc.7': + resolution: {integrity: sha512-aw8s6RgMVJNNPTHB4TzVmKsuROp9yZDMKKXsMEEha8CESlHhCF1c+qxLsjAcilwY5CYCwin2T/3lot88k+ITiw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-client-web@0.1.0-rc.7': + resolution: {integrity: sha512-1pb5B7V8vhrgoCFsBwa8A+MsXkPvwPJ8fJ5ldMZ4Cd1RyFPgVev48LW/z2WF4tc6qkots2wnjZ2i6bMz8wvk2g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-cmdline@0.1.0-rc.7': + resolution: {integrity: sha512-jNY9OOSpcH3csXqCwj8MMinByo42aUVIEauTSK1tNIOn6h6q0Y7SPu1ObIo5i3k0Khh/OWIiBTS1SbBlxcJHjw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-code-runtime-worker-thread@0.1.0-rc.7': + resolution: {integrity: sha512-CEGOMie1k733yc6TCSZuAtgbcs5H2QPO9wZnDnkx/kqaj3W+cEZGz6zZvljYNMWspNpomDTqOqpcB4ZAOI/K3g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-code-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-code-runtime@0.1.0-rc.7': + resolution: {integrity: sha512-vzW82eU4so0qJQ/XS7BGBUSguJMAgEOW3GaJJW0g+W5ysBJg+UC/Jjo1Np8mPjSpjjl4eoyXpshJzrwjoxCpRg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-command-compact@0.1.0-rc.7': + resolution: {integrity: sha512-zDBNVlCAwnieffyctzqZ7hUGLJqyTjqvtCEvzSNckmd2owyuYNPDIeFu4NTo/xN8Z/TISiuGbgA0wnIBCIsNtQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-command-feedback@0.1.0-rc.7': + resolution: {integrity: sha512-DM/EGrz8vvgRJSxV4UAWtyJpxFi1v8gWkj/iT9q5iGex0zNdDO4Ml0/u/e73brmN3bsGyubsdUuIdkGsl8n/Ig==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-anonymous-user-id': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-telemetry': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-command-goal@0.1.0-rc.7': + resolution: {integrity: sha512-ezuYaKmblRkOaFLUpzrTK9DiTrbES2lBtmkzo/Fg4UteDHLBVEaBgoips0J15gXJm8mE6o3LHhsgmGCIdNepKQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-goal': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-commands@0.1.0-rc.7': + resolution: {integrity: sha512-SYrQpJZQ4fvfyfw3IJ5j0goUiOFZb1ZhcANgUp99HVlhhN/l1oEOAvEZL1efaSE7KIG6qp4JEn7iLtNdo8+mEA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-compaction-basic@0.1.0-rc.7': + resolution: {integrity: sha512-c4bkTsJMKeDDgN3F9GBvEJCnsaLyl3I+uXb42rBPhOzH85bG2x55fMO9lBhtpvE5h5JUOP/tBMtTAW2OCe10Mg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-compaction-tool-result-pruner': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-token-meter': ^0.1.0-rc.7 + peerDependenciesMeta: + '@deepseek-ai/dsh-compaction-tool-result-pruner': + optional: true + + '@deepseek-ai/dsh-compaction-tool-result-pruner@0.1.0-rc.7': + resolution: {integrity: sha512-W4SbSgHlAhCB6ZXjr1/BdRiTn1F1x5nZdCY+0AazHoJY9FDACN0hUd6Rlkc40n3x0BHxXN/sZFDHCtT/26Fw+Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-token-meter': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-compaction@0.1.0-rc.7': + resolution: {integrity: sha512-9SDsfhfOzriMw4AF/md6MDOjl+YOwtE9BKFwunCGzfyWZnOUljoKEZxjtU0w1sIESSAjJnTicqb2NBOAIV9YQQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-cordis-client-runner@0.1.0-rc.7': + resolution: {integrity: sha512-D8A93lu2T1/QfT9yRErxI3ptgTyGwJUIorzf5WQe4+3/buv1LUKCXJHabm0fknaDiQdUOge+MjdZDNV2SoYGvw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-api-remotes': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-connection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-modules': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-theme': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-cordis-host-runner@0.1.0-rc.7': + resolution: {integrity: sha512-A7R39cSNsLwjm+P54bUFBUd5+YbdyKkC5cLQqYt12STt0Z06az10Qt5rsL25rnWkxW7x7Ql0wVA83tOmO2oy0g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-credentials-local@0.1.0-rc.7': + resolution: {integrity: sha512-3HB4nHXzR3HreJE4MfVSX45Am1/JiKFSDOYmrnyX7kK3Hvb9qH1J2Mm4gCzNislCemhZ+wlYQgevrvyH1L1PvQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-atomic-write': ^0.1.0-rc.7 + '@deepseek-ai/dsh-credentials': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-launch-environment': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-credentials@0.1.0-rc.7': + resolution: {integrity: sha512-24oY36x90GN3QG2BASlryjzsO5eLA1U9vsvH1tPtBRJ1pBC6JqnW2v0SfDI/pcMT0ZbWo0uEATiik8rrv6xRpA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-fs-local@0.1.0-rc.7': + resolution: {integrity: sha512-gbiH8xBrBw/1iRM3MLwI9zlFqLRg+1d+hNs8Etdn240xjWPuFdv5Hjg+eu4V5I+lU3M/lZieahEUpwYRScGuVw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-fs-observation-policy@0.1.0-rc.7': + resolution: {integrity: sha512-UbLBBWzUfBHAaZ6xGY/pPlIemGKz2iPoiCfmMkFQeLXVlLzeMrsTY4mvdx5ywu63tKYHvPpHHGdXMRFHqrTBvw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-fs-sandbox@0.1.0-rc.7': + resolution: {integrity: sha512-QMv2QbqVAKkFAmIIPFmW8cvjk8U9T4ZEVsoPdbanw5Enrg3qEYZUmii9WBkAxNtQhG5MRUf5Tg8jDkZqPScYrQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-fs-local': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-fs@0.1.0-rc.7': + resolution: {integrity: sha512-l4jEcfjrV7hWTQo6sH0oXntg4pz1nVuDXRcprps6NhZ0/OOer/9SzUx7J9aLnLeX9XDtExXsFbxkXW5Js3ZFwg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-goal-round-driver@0.1.0-rc.7': + resolution: {integrity: sha512-PWIaza45vFqqrf8bYyw5tPgEXRqLliHqAn3uKEwui8b1hM6UHJtApq1jX83PO4gtJZs/yAnRK6LCbaS5VJBC9A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-goal': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-goal@0.1.0-rc.7': + resolution: {integrity: sha512-/pI2o0YcP21ReT+OQx7aA8SyUsnuEHxTQtMbu3DvN9ChvaFeptCTXGvHWocwVtzEEi48mdvAXF4Mx0Ptj1LJYA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-headless@0.1.0-rc.7': + resolution: {integrity: sha512-EKn/wrMKgqxPUPwLgoTGk3BY8vFcYSYBWfXxnc8ZOKiH2pmprKnzm89AcOkbERNBJzPySQEsDdSoWwWJ2Mut4w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-agent-default-model': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-home-paths@0.1.0-rc.7': + resolution: {integrity: sha512-9Bu0eAbPw/FfCNpiX9hvyP5wedMUUQBc2sVTtU+xtH27/iUPxXoamFtBt3ydBJUeuVhja/leuhJ/d3MRhXO9fQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-apiproxy@0.1.0-rc.7': + resolution: {integrity: sha512-oBCIJzzvVXijtxAPqSlQUlYTywEmkn3JEpMB2PM8W4UafnxNhqvDh8ikGE7/1y6KWoFUS4jHGwerUzyp3C6oWw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent-presets': ^0.1.0-rc.7 + '@deepseek-ai/dsh-cordis-host-runner': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-directory-picker-auto@0.1.0-rc.7': + resolution: {integrity: sha512-QFuI5xGvVQAtbgN5xEZddM9+s5/2GWem8Gvq5hQpi1faUPyY/GS34B3lpuui0khSyS2NTa5GUXtYhDN1qZTVjw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-client-ui-directory-picker-browse': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-directory-picker-native': ^0.1.0-rc.7 + '@deepseek-ai/dsh-host-directory-picker-browse': ^0.1.0-rc.7 + '@deepseek-ai/dsh-host-directory-picker-native': ^0.1.0-rc.7 + '@deepseek-ai/dsh-host-webserver': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-directory-picker-browse@0.1.0-rc.7': + resolution: {integrity: sha512-yVHhAPK61gurrgys+xKia3RCr2OlwFCSb/XGzSDuzkVtAmqtG03oWTvnMiNpRKUyGCRFdgN0TP3QDg46rRlQ/g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-directory-picker-native@0.1.0-rc.7': + resolution: {integrity: sha512-CMHnPXL0oqwCnwt4TVRBAUfM4GNwkcZ1yURLlUo11ISBYh11LbOCXri3LoDjXzdCaZ21CWEKl25sZHnHnQ2GWg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-directory-picker@0.1.0-rc.7': + resolution: {integrity: sha512-CamVZ4wOjGcgzOiRFQtG0J0hy4EY3nXJBRFs0S397+H7b9eJUTtaMdOxP5w7VhMQ0Aq2ND7gpadwIcFaqINsMw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-frontend-static@0.1.0-rc.7': + resolution: {integrity: sha512-qSKYgM2W5EV8mE5J3OEujTY4z7mRwPBCRK3hQrl8vm4IAuSf0vfv2qrS9rpgU2SUrpHlQCqsu44bp8OPX+XeUg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-host-webserver': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-plugin-inventory@0.1.0-rc.7': + resolution: {integrity: sha512-B8ITfMnBAdgkkuvoMrBdVgydhsCYGnP8XIGXIouOQyT9/eWbD3WqO76XG+u+e2G36ACXu2NaIxsRh3ijzyorwg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-host-webserver@0.1.0-rc.7': + resolution: {integrity: sha512-ip6HeN9YpWJXgWKAWsL3JUrI8j+MHEvbQ/m3U5ubP/Pc0AQ9x+6xZ/nYe+22112I12rihiwb85ykFwFfx0QbKQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-invariants@0.1.0-rc.7': + resolution: {integrity: sha512-PnO1F4aZGUmqZPyuPJpBUfQ4DZmjCGCNGr0yuN2iURTP/e6h0kGnTNTYgR2NqMvAtpP66WNiHhvH2LMqumk1+A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + + '@deepseek-ai/dsh-jobs-local@0.1.0-rc.7': + resolution: {integrity: sha512-DAC8i+sshAkXPI8IcrUp5O6cOOkLLsKsD7mAcorFFbQjcPVBLdeRmtko3E1J9Jmf79IjoAvKVE+J+y84km9yKA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-jobs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-jobs@0.1.0-rc.7': + resolution: {integrity: sha512-+omM89dEsaiAL1XtsSTMmRF46POp5g25Qs5KVj+Zfrk7whlXjLXwFiaukt/htdVdHIOM51qM+tCleqlHOU0Chw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-launch-environment@0.1.0-rc.7': + resolution: {integrity: sha512-ATVyi47hyAWFINOxi8TGurRF8rShW/WzqWKqjxEQU5gLZbWtAMgkpAc+hwlyo/lXytGaj5cMXyzeyjpD6URHFg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-llm-deepseek@0.1.0-rc.7': + resolution: {integrity: sha512-cWNbBF+LeFrexht5V8cFeo4Kb0KeFaQWtemPJeTHRcijafq4OuQvgJEPx1IyelzzX6vctLQGSlmvvCNesLvIcw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-anonymous-user-id': ^0.1.0-rc.7 + '@deepseek-ai/dsh-credentials': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-launch-environment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-llm-pi-ai@0.1.0-rc.7': + resolution: {integrity: sha512-8sZuvgylK9ZKQmZtUU4z3DVBcM4Q4SH4OWo4qeOahLOsteT9NdIwZFer6f0QwqH6DjXIqz2Gq+XtntYXznGZPw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-credentials': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-launch-environment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-llm-retry@0.1.0-rc.7': + resolution: {integrity: sha512-yyn5Yqth6vdScgmcYDF7L3a1jbfcu2y205HyTx9d84H+eU+h9m8k0Mc+1l8VCJbv9GILPCvoijP8wFTPDas7gQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-llm@0.1.0-rc.7': + resolution: {integrity: sha512-VaB9kQ8XOA+R5jtsWf92QMc1WpaatEAFUvQePGUYrzQ7Z86b9VhQQzmchh5VmknT4oRSSdn0re5tReCvfcYNXQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-mcp-client@0.1.0-rc.7': + resolution: {integrity: sha512-hjdki2TTXfyZMJuddOVXV0lEhZjdku2aoPagVKV4TOhqz3jDJE0mQds87mtDOI9J4pyRGWfYXky6HN9Bi/usgg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-message-feedback@0.1.0-rc.7': + resolution: {integrity: sha512-P/Inw7dQMZCC6I6NC6G0UF9SeOVlpQxOBg2+LoCdvyTt40itDow2wmlThqkQDIt4UMHLT4yRc0Gd6a4gmTNJ2w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-storage-domain': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-native-command@0.1.0-rc.7': + resolution: {integrity: sha512-c7NiAYPx5Ho2ZYOODRvt0yTZ9l00n7QvRh8paiyLaYBOuzo30KDo5wTJXGLxMkfzi6EQsWw1tljd8MnpGL2P4Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-output-retention@0.1.0-rc.7': + resolution: {integrity: sha512-bhmSfXIaLWLrYwC4ziMZ7GkNy5i9ltGBvlNZ5eB7NZoDAMh0Du7pKkMY+oqm2ajvx5O5qiFkHEhYoypRpEB56g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-permission-presets@0.1.0-rc.7': + resolution: {integrity: sha512-AC6cyrinc3fQ2/TKmm8V1r/32f3VekR/w6rS1+RWGefRm6PDGnNo4T96/U4EoMyWDq0VBCn1Oye+uqhWPtl/3g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-approval': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-persona@0.1.0-rc.7': + resolution: {integrity: sha512-1XhQNi3pIQ9TMUiquo+RRS4VpbXYhpFmZJ845kaVGToAexS2gJRVte8i/wKaDHDp/huAhJIsZemHlX0qADDsjw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-plan-mode@0.1.0-rc.7': + resolution: {integrity: sha512-VXUxBvmZ9PYinVbYsu7GmT8BZMXCfAbqExNMoR4RoZm+leOLzZOkWOKea9THoJwIik0lUbAO5lzrqaeVKa99Dw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-questions': ^0.1.0-rc.7 + peerDependenciesMeta: + '@deepseek-ai/dsh-commands': + optional: true + + '@deepseek-ai/dsh-pwsh-local@0.1.0-rc.7': + resolution: {integrity: sha512-AImknM43+7bIR9BzEatmbZMvhjgBgAt7MWqJzmTo1KnBNTY1j7r/RmOiQTBX4R+tpsLXMza5oW7svHSAYw/ypw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-pwsh-sandbox@0.1.0-rc.7': + resolution: {integrity: sha512-mXJcllRKoGnFhVs1mtUjjmqdfMymTRif5lrtxdhlkpegH6E9qKF7Wyq1Wnjkpsk6QW/iCicrRkXF2Bw623eDag==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-pwsh-local': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-repeat-tool-reminder@0.1.0-rc.7': + resolution: {integrity: sha512-AdG/wyhpWSJcLkRqs3j2VVgS6uH5xQf0mK7WZsdQ/RidB3OVYZiBg9Mto7Of25AtV5lP7ZN6TrqCqWgi60XwFA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-sandbox-local@0.1.0-rc.7': + resolution: {integrity: sha512-jahNeS/WnBinCisOB4O+zeS366v7gWt6Uzfso0/C5He/vZFEITW5jPfWrJkZLuuN5S55LshaDEnegsddEIp6kw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-sandbox-policy@0.1.0-rc.7': + resolution: {integrity: sha512-TnOy1SnnSNPVZyw9UFNwQ7eE2lGxQBU6kye7+aAwDbNvSnudCJDEnQJhjTvGewHWA6PYA0O60XERKcCQAnK+dw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-sandbox-windows-acl@0.1.0-rc.7': + resolution: {integrity: sha512-Br+Ocg+dr1PcCA71DxPJd7/7Cel+HLnRyglbkhSPx9mEYpXXgioVCkDHJh7J9OvjRw19UF56g2CvgVah6HwFww==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-sandbox@0.1.0-rc.7': + resolution: {integrity: sha512-he43z39/SC8cMzPDsoP7EEXiXKjav3VClj/U943pxycvRL78JGkNEQQjv21n5mnuto0ti/gFBquybSI4sBAFqA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-schedule@0.1.0-rc.7': + resolution: {integrity: sha512-vlvjvhE2B07XG3X+jUsfEDUjsiEGln8GFdy+ojWm27FKtA8JuoMdrMMUcCuVHnyr23jyk2Ft/qGA3JIJUOvIKQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-scope@0.1.0-rc.7': + resolution: {integrity: sha512-8gn+sANXhpv+9egbNwq49/uI3XhbmB33obo9yMyzyzruan3zFoxeH4UV54jTC2hjbu8gFNPsyNam9AAtRV8/Cg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-checkpoint-policy@0.1.0-rc.7': + resolution: {integrity: sha512-Gw8GDvEJsH815NQuKkWhPPmw61hqhcdVpaaTXbCTAq/+0YdgNzNxAGIzizufAmq099QsqVWX0zs7IWGpWzCfEw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-log-export@0.1.0-rc.7': + resolution: {integrity: sha512-yToQnjzMGl5KCq//k9bN4OUXxpyRRjh3hBtnf/9AVVSvvV5DGDLHryEm7erECLOnoWZnng5J5SDERcykrVbYlA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-client-locale': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-conversation': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-primitives': ^0.1.0-rc.7 + '@deepseek-ai/dsh-client-ui-slots': ^0.1.0-rc.7 + '@deepseek-ai/dsh-commands': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + react: ^18.2.0 + + '@deepseek-ai/dsh-session-persistence-jsonl@0.1.0-rc.7': + resolution: {integrity: sha512-amPgKP84E99YEiOroeoQNya3Rjm1VRWWU6y0ft02iVtFohTmWRMLESArkAAtFfap76bk34xEkvujp34nJl40Ow==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-persistence@0.1.0-rc.7': + resolution: {integrity: sha512-NFH1uIGQDgMFOijgAv8lLWRiY3eHFEZW2alwuHlu4C32P4+jdChh9fjPlzBar3ZZTq0ZW0qWCdbYZS02DNxsvA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-projection-cache@0.1.0-rc.7': + resolution: {integrity: sha512-qWf7p2Xgr0LnY4o466ei3L/81QbGFQcCbEi+4XX9rxLKgnU+RvlQzwmIilrgz9N2hK/RqwS1Nb03bFRisxVeaw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-storage-domain': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-projection@0.1.0-rc.7': + resolution: {integrity: sha512-BXehLYt6wYnV0PNNhv5GECePkH1w+1yuu/R63d2tdYdUQ7XVrd6tu5hMwfTH0P9AnBDxJir08FRu2WKO69JypA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-query-sqlite@0.1.0-rc.7': + resolution: {integrity: sha512-XuhVkX2V+tx/xO9/gCzPHGbovoApwaojwCjNFAuBUbHLMvMl1wMdxvxSgk/xLPKnll98daXRPoq5Csg6hrG8MA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-query': ^0.1.0-rc.7 + peerDependenciesMeta: + '@deepseek-ai/dsh-session-persistence': + optional: true + + '@deepseek-ai/dsh-session-query@0.1.0-rc.7': + resolution: {integrity: sha512-JKlEpByllYQU9JZLadrS3ClWCVZMcKRB4nc6iCWuNExyRi/Whwa5GicKFs+jXwGKe/rdSbTCom/jYLwkqipjuw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-title': ^0.1.0-rc.7 + peerDependenciesMeta: + '@deepseek-ai/dsh-session-persistence': + optional: true + + '@deepseek-ai/dsh-session-reference@0.1.0-rc.7': + resolution: {integrity: sha512-lyD9VbGrOSVkAV8mr6aIl22bdWIe61lC9/dtZ6CtS3DLnewvSkZ4CNlUDG/qS1SUIZfk7A2UixgXYBIB2771xw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-output-retention': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-query': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-stats@0.1.0-rc.7': + resolution: {integrity: sha512-ryf7HSYdmLbrTv4HQmeW/h0bHLiCNnSZYiY9RoBrzg2qh89MU8S+Q/a9CLVWA06TRXKt7tNbizF82dCj2/O0bQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-telemetry-otel@0.1.0-rc.7': + resolution: {integrity: sha512-k5zHavA2RoBtZ5igD+qpbdfyxKvesZa2w+YKLfMtUnZOj7HZM9qcxvfYo4xJ9spNLpN5OGY/sWZBB5itilZlCw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-anonymous-user-id': ^0.1.0-rc.7 + '@deepseek-ai/dsh-command-feedback': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-telemetry': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-telemetry@0.1.0-rc.7': + resolution: {integrity: sha512-6f5U7nt5Iqwh5RAFBqV2Ib7LJU2o89Et0r0eV7bskYws+PNM7ZRRW/Nw4a12ZcnuTp1eKPyVE8H6oJua6/7XLA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-title-first-prompt-llm@0.1.0-rc.7': + resolution: {integrity: sha512-tFocCpSglf69VC6a23R9OcomMBQdfQZm8MvAOGgENBzWz9htDLuyq6jukKzPdTtS3VdRDu4wzJtaWKAYBUCX4w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-title': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-title-llm': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-title-llm@0.1.0-rc.7': + resolution: {integrity: sha512-mpQo/1x4jaWNdQAXckOs68U59u+/WHJlb/BX1zAvr02eJPV3Wac2/7NP+/vTw5TElEyzIAU8k0f3PMgvozUk0g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-title': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session-title@0.1.0-rc.7': + resolution: {integrity: sha512-jhFiZa/C58zchuJkBodnkiPil7AEK8mHfB/hMOAW3N/7tUg5nbMLBERNqHdDMbIrvhTndrF4SN9qy+ltUf0cOQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-session@0.1.0-rc.7': + resolution: {integrity: sha512-02WVTkqIH+TyDL7dhMN3Hm+qcTEdhD0fVDC0aIAyND2fBdXj3CagEXXvpmt3mzwWfKwOTGL1RdxtC6pMA4Bl1A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-protocol': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-settings-file@0.1.0-rc.7': + resolution: {integrity: sha512-ODz9QWtCOjmwX7gxewPBfIHkA9twPiHDpcwgAW4sQUztgsJZKUtoe2T47loNH6QlHBPcSL5WMP4/QlnkRVKC0Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-atomic-write': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-settings@0.1.0-rc.7': + resolution: {integrity: sha512-cS1+StK2xIVykrskw+KrO+hKJxYaVVgY2Jex2we5zASTNLHYCj74WQluPlaFjFgnXoZ1RYz8HNXL5/Ho6h1Ynw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/schemastery': ^3.18.1 + + '@deepseek-ai/dsh-shell-env@0.1.0-rc.7': + resolution: {integrity: sha512-joSBNw/d54gq/VjkHLGSJ6y/Qr+594sObF4ApbJi2eEopx41L0Ky7kNW/W7cbrGIIN3KBGRDdiGv1s1paWzsMw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-shell@0.1.0-rc.7': + resolution: {integrity: sha512-in3ifbq80tn5cf1ICBBsRdwKjURB0g0dIRdCVUgl/GDqCdC/S0TjMLXw4nmFdCssYLm7JbG5a59BfJG0KFuz6Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-skill-badge@0.1.0-rc.7': + resolution: {integrity: sha512-01Ue3mvLYyBwNj+fAuTUZN4gJLuDySPDqAZhCtWoYagZudCuLB8kAdpYWztKA4TRVSyml+EfGo1LrWvQeTD1wQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-skill': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-skill-filesystem@0.1.0-rc.7': + resolution: {integrity: sha512-i95xycP3vkz4IZnIO4BTzGNB6waKl1M5AsW2x04C0FIqLa4BSILvVUVwqcbwpBZm7Cd/KF50Q050au3NvauGrw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-home-paths': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-skill': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-skill@0.1.0-rc.7': + resolution: {integrity: sha512-tDaqB1TOs27fSt6FZdjvPs4THXAFKoKOEgQG+iFUv63O5bm+glyLY3K1LTK8JeofB4lg3+4JIAeWRslnLJH57w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-spill-local@0.1.0-rc.7': + resolution: {integrity: sha512-jx198A2cc1gxsoKb2pRmXnDbIwIHAKg78ZjRMyiLRGpOFEZugVudILdDMp8u+lGpavP9xVAxBc1n75Z5NDRw7g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-spill': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-spill-policy@0.1.0-rc.7': + resolution: {integrity: sha512-fYypZXcXFkXybf8N0tz70+XCtxvnn9mDN8JiKnTp2ZNhXb/zvFbdf661Pp45lFWS6j0cHZsdZ5T8DfuQjfO94Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-output-retention': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-spill': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-spill@0.1.0-rc.7': + resolution: {integrity: sha512-EdX5AZElelHlCKlbflZipl4KRDiEHWLN/8smgnkzAhJgpXFq5dyp9jK58dO5v7cuODeq+/SfeDyUE5Mffdhh8Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-storage-domain@0.1.0-rc.7': + resolution: {integrity: sha512-UxXwoCB0q4+/F+zddvi8I4LknTIlGD/1ec57Ym52kWRb7a8qGgrcIYrOC3yPCozn8rkirAuhEAkyAhR6AO5QDw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-storage': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-storage-json@0.1.0-rc.7': + resolution: {integrity: sha512-xYvEY3+ttxJg4/UPzXuxgeKcLxKvDP4alvPpEfRwuMBcp//O6FtzEJSqV8zycJVYHU8V0wmUKRIn4V1ycXlFgA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-storage': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-storage@0.1.0-rc.7': + resolution: {integrity: sha512-M+6+SOjWWcfYoGASBMx+b1sHmWPFAHXF57rE/Mew9k5tHC5bEV8+owWwYOWQfv41eO1FfRMibZd0rH6mwPNApg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-subagent-fork-in-process@0.1.0-rc.7': + resolution: {integrity: sha512-PnT/poBisBmA9U+mLZeyQJfHS4Ps8kwN1ioZEmv36TwnROCrmwzog5FB33r9rXU/gKVX0dD/LkjxxTGmzC1xCA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent-in-process-driver': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-subagent-in-process-driver@0.1.0-rc.7': + resolution: {integrity: sha512-YleMt6xtXmW8LkHZ95MLPq1urIt1+sBUK908GCQ2EhV6nyfUwNog4XVDlVbzf3GXzc+3z/xiMW2GvVp3IQ5NIA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-subagent-spawn-in-process@0.1.0-rc.7': + resolution: {integrity: sha512-4C06MeBvsbgiUrWh+tge91wRLSOOJDU/Ub7b9Q6nTxQKEMJooJwCQRPfgaWtdXuNHrJGIJ87GKsgqV2iwfQ/jA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent-in-process-driver': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-subagent@0.1.0-rc.7': + resolution: {integrity: sha512-PEpA9XT6E4hg7N8m7GYQyDLwFUwoqWTz0Cm9SrdAoNcju4byG08qy4+muDZbG0a1tm3PR4rxNB5zKcobDhDocg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-agent-presets': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-jobs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection-cache': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-approval': ^0.1.0-rc.7 + peerDependenciesMeta: + '@deepseek-ai/dsh-agent-presets': + optional: true + '@deepseek-ai/dsh-jobs': + optional: true + '@deepseek-ai/dsh-sandbox': + optional: true + '@deepseek-ai/dsh-sandbox-policy': + optional: true + '@deepseek-ai/dsh-session-persistence': + optional: true + '@deepseek-ai/dsh-session-projection': + optional: true + '@deepseek-ai/dsh-session-projection-cache': + optional: true + '@deepseek-ai/dsh-user-approval': + optional: true + + '@deepseek-ai/dsh-subprocess-local@0.1.0-rc.7': + resolution: {integrity: sha512-Q1zl35fRNSASv2FOi6viwR29cn3vtOcyKfamcmRB789m6sb6CdlhIMettvcxxDDHwTSH/jjz3hqb0JAx2GT32g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-subprocess@0.1.0-rc.7': + resolution: {integrity: sha512-xiHD61S2trIZ0CzhSMgXxZJVyJ2c76DkX4eqP3Of4mBEnm6C7g7FChII6uL0z5v1bnOnTmpHzwPX8YCwqb7dbg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-system-prompt@0.1.0-rc.7': + resolution: {integrity: sha512-Rair2ZkzgoIIr+UstYVYeqeUgORNPIW1LNcsXz3Zjglx4FGjsmzs0UALdNYvSBpBvCLNmt4E6+XQIrBbS/s9jw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-terminal-bash@0.1.0-rc.7': + resolution: {integrity: sha512-2muS7xmy4olNEpGANp0ViK3/r4A4UlfQa5w24HJ2PrCy0J3qlk1vwHrpj30nAGK6sCaxbXmb8IjYUfNs7st7zw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + '@deepseek-ai/dsh-terminal': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-terminal@0.1.0-rc.7': + resolution: {integrity: sha512-B22qppmKWvw5Ez9eMKnppHiaMrikIcHmfmvyd296EspnhTBJAvXDnc9NggT0DUnSvm+2gh5ffohhMJel9A2pSA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-time-context@0.1.0-rc.7': + resolution: {integrity: sha512-rZhEYA/urMq8sReaMc5rb9A/p7X1MXwktoF5Y6SwGUWqJQsdvHzXppksOEqJpg4a1pNDBe2N9X5o+wMKPmukMQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-timeout@0.1.0-rc.7': + resolution: {integrity: sha512-Ufl9G7zP7Tky/zkXscavEiolEfAwutfbPeLb5sUU/tPQlDykhh1NwGrarNJ11fdR723zmA/3co4LgxtDtWCOEQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tmux-context@0.1.0-rc.7': + resolution: {integrity: sha512-DYoWGpJglqzWxCFDzynJ7ebt9m7Redlm2Iuon5U2tJ0rsyOSRIgKuwQMXI67FdN/MNVXvSQ2xybUqu+5V0krnA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-token-meter@0.1.0-rc.7': + resolution: {integrity: sha512-i2WOx26otsAt3sTFOoXjo2xsdvUyC5CAuNiJyRQoo6yn1smx+NX541clIOYdx1uneZFmV0T6bK46JpdXasxaAA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-compaction': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-ask-user@0.1.0-rc.7': + resolution: {integrity: sha512-ZqwrTw+w4GepNCVQ7NIq71s+Hlrqu3jAfYCdKuNbkUy461EjlRLGMcHspSHAt1uhdwL9QDTodB6RRhpg65Hozw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-questions': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-bash-persistent@0.1.0-rc.7': + resolution: {integrity: sha512-5tMC1TuWiGDerYd0UuUUzRdmv+uy/22lXbxmmrmUfR8aACeK6T76yXorvuvJSDYjhPpLoUovz9XU5LqGm3D2Wg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-terminal': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-bash@0.1.0-rc.7': + resolution: {integrity: sha512-nfc0SI3Xk36rgIOLmTBDSrSTN3Ufp9Wvefta/M82kbBCo6fesB4lst+VAw74039jzHUboXc2gwQ/j5rRcOpiuw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-jobs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell-env': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-approval': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-call-timeout-policy@0.1.0-rc.7': + resolution: {integrity: sha512-GKmrKxwfIhk51dEEzWjvPKTZ2SK/RNxKXROAaSsZ/HGcerv2kmBHRCEPlaphKBoWhFuw7KAhDnzI6foXLg4BWQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-cordis@0.1.0-rc.7': + resolution: {integrity: sha512-tzZ1A+HhfqkMyOWwPgkWezY34rrK/OHD6BBX9DZ4km5/545JZ37+jmViza4TwrUhVxbs+Szhrx6g6V3Hm+674A==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-cordis-host-runner': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-fs-search@0.1.0-rc.7': + resolution: {integrity: sha512-0Lo6bbpPcSMKZlWkBGx2KjwyLy5zYJKMH8fmwz8orwOKHjbfYQT51GV9cpdhLq6NYTwKeMUaxTZC4xPlZ03SAg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-output-retention': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-spill': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subprocess': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-timeout': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-fs@0.1.0-rc.7': + resolution: {integrity: sha512-/Uf2z6OZckk0Nz7XjVbzf/yUnvDeY58CkUjAqy2FxgGuNc0rvIR6VzRER5NZ+30bXeB8TPnjMuCVB+j/8zltrw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-attachment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-approval': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-goal@0.1.0-rc.7': + resolution: {integrity: sha512-bQTVYD7nAtddefQZvvoKsoRHehA/hAHIPbNRdY+L97HVwKnowg5rlcUn/v+MJFQ1NPaTrTAfVQiHXGKEeeI9tA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-goal': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-jobs@0.1.0-rc.7': + resolution: {integrity: sha512-n/YcmHVTBrN3soZqzMElsnzIQoClOS3U1n5oqpg+oPyesMehpp7DFjdqh7kCZGEmI8chtq4AhYsPUWTPo85G7g==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-jobs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-output-retention': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-pwsh@0.1.0-rc.7': + resolution: {integrity: sha512-J24DC4otd3gAVvJ2jPpCfxrrujB/5isEqScp53O2vSvFP7rKn/Rwo8ddr1v462JVWyUG5HtyKpR23cPmQrP0+w==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-jobs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell-env': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-approval': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-ralph@0.1.0-rc.7': + resolution: {integrity: sha512-1ZCj5w7GRcbs0zuDiDpZLJKc1zs/WSn1WX9VWTuXvWocV66Rq8GGMZLGDksBeltd+jv/dym7xro4+xFl87059Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-workflow': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-skill@0.1.0-rc.7': + resolution: {integrity: sha512-AnXLgiDXq8qB196qq4LnJ6rC5ukoPA4WZH+ILSFpLm59owkfwJLS9rGsfP+PGqiTN7NhoZtAwGmZoYCdSDi0kA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-skill': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-str-replace-editor@0.1.0-rc.7': + resolution: {integrity: sha512-p4GmCg5wC9uw9BaVK9W0hOnEnjGvhhRF234ClVnQMbHwzfgPbhc0eSYUNJQmouqxLAa4kVuiF0nVZvc3aftCeQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-fs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox': ^0.1.0-rc.7 + '@deepseek-ai/dsh-sandbox-policy': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-subagent-control@0.1.0-rc.7': + resolution: {integrity: sha512-VPWUrhTc+X9DcrM/WC+ikM7vCjW54KzRU9wfdhFbXD6hea3hBQ4AlhEdtFtRwmgv3HmjYIUgHkPA3h7pqTsB1Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-subagent-report@0.1.0-rc.7': + resolution: {integrity: sha512-bdDcRsiB9t4EILfA4gO+FWwXrj6SA12SP0nqymz5yOI5AJWR6pzuIOwRk7IdguHBzq8pDyfelw0YxN+EtkS+tA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-subagent@0.1.0-rc.7': + resolution: {integrity: sha512-QWs7SeItxpaJ3zY5Vh0scAv84QI+ZRyg9+dws15H88T+dp9dRr4gmR+fqEUdwd9JhPJF5VIORtKY/MqVtaiYQA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-jobs': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-todo@0.1.0-rc.7': + resolution: {integrity: sha512-Jm00eSYvNq8Qj5GmXdsC7EY3Q6TLSzBTiODNAu2bs5HxEqE5ssQ/fdcxuAXAfSFmh2Vq0ENLZckDg3q5Xvj6Qg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-projection': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-web@0.1.0-rc.7': + resolution: {integrity: sha512-FJyrD+LspCOIP05/v9hv6MJNkTbgDw8ZpmyAXk6sRopA3yOUju5SnN5HpSZ97ZAK65T6tHYbTMdJhy51D41wOw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-web': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tool-workflow@0.1.0-rc.7': + resolution: {integrity: sha512-EF9qbGiCK+SdFhckVcS8o4F0Rrib4VEbt5yCe0njj4UrHubjz5Ldmz68TqdrvFqw6mvQ11SUqAm1ookp5hp8gA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-workflow': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-tools@0.1.0-rc.7': + resolution: {integrity: sha512-7Kq3EEv354aNcxbS0NRfxxyJiZhCsvFV/03a3MdkYO/gG2eM9+E4xQum0N2FL5bw7JiGlgw8jdLMkcNGmavEaA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-code-runtime': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + '@deepseek-ai/dsh-user-approval': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-typert-loader@0.1.0-rc.7': + resolution: {integrity: sha512-0sU6QDo5/8/F7eIi9YGOqI4PTz34O6+NOUr3qRK6U3m6YWh4SVzn1Fc5LXqpnaZPNQpetuLnkvTvFylewBghJA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-typert-registry': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7': + resolution: {integrity: sha512-R7qdvaRRHbz5xijoVOxueeBB/VT0eDzuQNQN4iNEBUbI/L9xG9bZutktTQlgrIlBSn1sPH4pLqiCiM6ErQPTaQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-typert-registry@0.1.0-rc.7': + resolution: {integrity: sha512-7AQNJLNZTw7/5DzjbfBy4dRqr6VSwc74HBOSPpxm0zzzbmXOEqRCRzMps25IByoAeltRz1ZyY4fzN3tcYa+XwQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-user-approval@0.1.0-rc.7': + resolution: {integrity: sha512-kYMpU6eg1m1BcfSC4FLWUcNH/QAE8tcu0WRkQzqzoCw8bK/Nl3dqHtd2qSVzI/emIviTulM5I230e4wPi/kuVg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-scope': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-user-questions@0.1.0-rc.7': + resolution: {integrity: sha512-dfT6pj84lJdhrtbW2pV6hRftoKDkqx0aJevrhUhOy7Lv3CqTOheuLwwyT69Lww+n/q80Z+yp41qJq9loCkrOaw==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-web-app@0.1.0-rc.7': + resolution: {integrity: sha512-hcpVwEk5/SgZ63TRUmGaQsC1p2zBBSO8/KAr4xfM2XSwq/tbvpMLrkyt1zehBXcsx6ijB2s62bsr6AYOz9EczA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/cordis-plugin-loader': ^1.0.2 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-shell-env': ^0.1.0-rc.7 + '@deepseek-ai/dsh-system-prompt': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-web-frontend@0.1.0-rc.7': + resolution: {integrity: sha512-U9Neu6x2/0hrDwCeExEjGO9KkXiJEoJgp61QF/XQkaHyg4E7YSWZDG9NttlhepqFgqs6Dn/qcjrL5G0JGuWYeA==} + + '@deepseek-ai/dsh-web-search-deepseek@0.1.0-rc.7': + resolution: {integrity: sha512-NciK9Tm68RK5XOzl+Jcr4+eG6M5Svq1/23Mhjor9QVYPW1J+wnyxUt6RKLIrmjyiS6VOCOCcZVtyITFkkfVaSQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-credentials': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-launch-environment': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-settings': ^0.1.0-rc.7 + '@deepseek-ai/dsh-web': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-web@0.1.0-rc.7': + resolution: {integrity: sha512-v3Wx/Kn57RyLDqvEhmz0m0p4YluLGSabmMp7dRVJSemYUzT6ZB0JCtMhWkXh6O3kNHSBGpfxeY9Pk+8k80X11Q==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-workflow-worker-thread@0.1.0-rc.7': + resolution: {integrity: sha512-v0YIoPylB1SJW5gBV8gaqoE0PCAZLzEgIU5OqckBKiApHBd0jIo7EzCeTW9+9Tzd8gwwcBQYv7Yxr++rmH8WGQ==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-subagent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-tools': ^0.1.0-rc.7 + '@deepseek-ai/dsh-workflow': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-workflow@0.1.0-rc.7': + resolution: {integrity: sha512-PRGT0iF2KcOTxDC1DDIrNOe9bID3zZms902ScrxGAGj8AksRO97kj+3U2MOhRPfHkkNhSQMHCLt42DiclYhWtA==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-agent': ^0.1.0-rc.7 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-llm': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + + '@deepseek-ai/dsh-workspace@0.1.0-rc.7': + resolution: {integrity: sha512-0czW0bI+uFFOS8h8eJ9SGZSdv+StEsa/+E1WEjZQXVeIOxo520Pv47dq+Z3mTyBfV8gJB+UcY0AQ3F0FddYohg==} + peerDependencies: + '@deepseek-ai/cordis': ^4.0.1 + '@deepseek-ai/dsh-brand': ^0.1.0-rc.7 + '@deepseek-ai/dsh-invariants': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session': ^0.1.0-rc.7 + '@deepseek-ai/dsh-session-persistence': ^0.1.0-rc.7 + '@deepseek-ai/dsh-storage': ^0.1.0-rc.7 + '@deepseek-ai/dsh-storage-domain': ^0.1.0-rc.7 + + '@deepseek-ai/dsh@0.1.0-rc.7': + resolution: {integrity: sha512-ZceDCJ8FAywih+USW/OMk9jEhunlvJBGEz4kqrhau23hPzbciOazZrywH0nBRsaalSeAJ1JGBmjtw4OSjToStw==} + hasBin: true + + '@deepseek-ai/node-addon-landlock-run-linux-arm64@0.1.1': + resolution: {integrity: sha512-lYY2RbcPW4rGRM5hVJbrXlvLqyBxeJBjBqvt+QTHTU+GtfUVVjTODKa4e3CRwMQoCEpOjoARdQBHbN7HvE72WQ==} + engines: {node: '>=20'} + cpu: [arm64] + os: [linux] + + '@deepseek-ai/node-addon-landlock-run-linux-x64@0.1.1': + resolution: {integrity: sha512-OHAzPW2Coe/iYobAJAAA8CeVrBoKV4BnNHsgwvXwOfishxkUVSWSvdyxrZPiwYRXutpIGVrSo9zV3WOQy2euBA==} + engines: {node: '>=20'} + cpu: [x64] + os: [linux] + + '@deepseek-ai/node-addon-landlock-run@0.1.1': + resolution: {integrity: sha512-aHGhlQJEutfobKM/4K59SERbT7RmQdD2oMKzD8Bne/Ps7TeT8AweCN+dpdfuxQhMNbFcJMymrgPnID0WYQ30Tw==} + engines: {node: '>=20'} + + '@deepseek-ai/schemastery@3.18.1': + resolution: {integrity: sha512-Qn0FCSwCQnpnj6SB31I6i2sIKgKWnkbJM8O0EU91Gv2UsYVvtZTl6IA0sCwk2e2MZf5S8w5hpq9QkeVvK9qwxg==} + + '@earendil-works/pi-ai@0.82.1': + resolution: {integrity: sha512-3WFYRhEp3lQB3444EhPMBcM7zSaEUE3eJgHOR7s4081NLqbw/FsWilIKWXSua0Gv3sRr7m9xMidR3pPDE7jI/A==} + engines: {node: '>=22.19.0'} + hasBin: true + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@google/genai@1.52.0': + resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.2 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + + '@hono/node-server@2.1.0': + resolution: {integrity: sha512-XovyyCCnBzW+zKu+z/zq8hwNs4KOR5rEMAOxo2f40Q5xoOI37IMm6MIg2COOUtUApo0i6850MTBKH2u4QLGIqg==} + engines: {node: '>=20'} + peerDependencies: + hono: ^4 + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.3': + resolution: {integrity: sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.3': + resolution: {integrity: sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.3': + resolution: {integrity: sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.2': + resolution: {integrity: sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.2': + resolution: {integrity: sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.2': + resolution: {integrity: sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.2': + resolution: {integrity: sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.2': + resolution: {integrity: sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.2': + resolution: {integrity: sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.2': + resolution: {integrity: sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.2': + resolution: {integrity: sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + resolution: {integrity: sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + resolution: {integrity: sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.3': + resolution: {integrity: sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.3': + resolution: {integrity: sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.3': + resolution: {integrity: sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.3': + resolution: {integrity: sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.3': + resolution: {integrity: sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.3': + resolution: {integrity: sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.3': + resolution: {integrity: sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.3': + resolution: {integrity: sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.3': + resolution: {integrity: sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.3': + resolution: {integrity: sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.3': + resolution: {integrity: sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.3': + resolution: {integrity: sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.3': + resolution: {integrity: sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@joplin/turndown-plugin-gfm@1.0.67': + resolution: {integrity: sha512-FZfW5EZfidhzd1IaY1uxHnIZPTVOxAdleMZ4/1U6Nt5b7+Qj5JThDnaIomuJtetnUBzuRNbe9FWMuqD4B3dlWA==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@koromix/koffi-darwin-arm64@3.1.5': + resolution: {integrity: sha512-IpqITl2fJi3QN9bTtNnygWPdK7ScSjw3xtGu8e6feYGvimCysu+spgI5KyeslY2jTnqxGS9xr8pLAbLhGJ8edA==} + cpu: [arm64] + os: [darwin] + + '@koromix/koffi-darwin-x64@3.1.5': + resolution: {integrity: sha512-4Tia4BS5EV/+vN9eIrdToanVe+U/2VqTZCBgOzoUbPKjgky51eqM+3J4qdRUvmYJohcJNPob5/hsxeItUZrl1g==} + cpu: [x64] + os: [darwin] + + '@koromix/koffi-freebsd-arm64@3.1.5': + resolution: {integrity: sha512-bP94uzseFO79NG3flpU3WxfyvltD+jzC/kN8FDZLi8J0VUZNW1Wmu8yq87KEzjX1qT9KyX4Y+elVbGqHXHTv2Q==} + cpu: [arm64] + os: [freebsd] + + '@koromix/koffi-freebsd-ia32@3.1.5': + resolution: {integrity: sha512-raFXXAPHzvCQWhaoMUF+Cc2ZWgg2UBU0RVoowHZhaw9nQYPC1pERcPRH+JA+SNIN6g4d2GFW6uPFc+QbUhsagA==} + cpu: [ia32] + os: [freebsd] + + '@koromix/koffi-freebsd-x64@3.1.5': + resolution: {integrity: sha512-h6RyBZmPMBIDWTABkJIhzDdYwSnYAJvTacHpEjbT55Arkmw1H15Rl7CFtXuEuBrqh+uivoCrRgA6vszl9CsJ9g==} + cpu: [x64] + os: [freebsd] + + '@koromix/koffi-linux-arm64@3.1.5': + resolution: {integrity: sha512-u0vCmKPu4yQDhl/ri1J6U3vDnvYtYjoZaIWb+oMbRXhVZeiqdE53MGPb+q2A7Dj2n9IbYloAfEICQbL6l0pmiQ==} + cpu: [arm64] + os: [linux] + + '@koromix/koffi-linux-ia32@3.1.5': + resolution: {integrity: sha512-Xa5JbumWglwPVZgrJcLhqyC1wCWlfm7+C00p3FuOTNGp0qoYuf2/tOoAh0/q7+taVm30cMopu/6lRHwdmF6I/w==} + cpu: [ia32] + os: [linux] + + '@koromix/koffi-linux-loong64@3.1.5': + resolution: {integrity: sha512-F3i2CeTcqVBUQiSRUBSEzX1VgtXmLLiZb/ouZtXHkWpTLhJNd9TH7s3CizTofci0VRqlKdexGUYhK5vzPDAAHA==} + cpu: [loong64] + os: [linux] + + '@koromix/koffi-linux-riscv64@3.1.5': + resolution: {integrity: sha512-2TgQuzy+4PfDg+rw3kOmN6lywEWdzKT3eaLPbOp0b/9DaN7CLBJ/QIR5GhGsMNpeI30zU0YzFeYFxoVoJ/LqFw==} + cpu: [riscv64] + os: [linux] + + '@koromix/koffi-linux-x64@3.1.5': + resolution: {integrity: sha512-2yaIg/1V0m4CiAUMzG4CIlWmq1WJ+QBMlFfaGr9su+OH5fuIqC7V3BbMiB03IwIl1VofIZO5JA4Db4lID8tpbw==} + cpu: [x64] + os: [linux] + + '@koromix/koffi-openbsd-ia32@3.1.5': + resolution: {integrity: sha512-8/OXd+u9omMooykhvdJPEP7u6FFzzrrFo9gOmSHc9/DPt3XkVYOtSsE97PDk6zYaAzwIYHSKjHvIXsfFwFc7sg==} + cpu: [ia32] + os: [openbsd] + + '@koromix/koffi-openbsd-x64@3.1.5': + resolution: {integrity: sha512-SpeqldKkuDk2aTj5PVWumy7eq6Tr2GtBPAOI1NiDHhg8xe433KraxrA9V9UjEd+1+kSGJQGR04nQByN3MPA9PQ==} + cpu: [x64] + os: [openbsd] + + '@koromix/koffi-win32-arm64@3.1.5': + resolution: {integrity: sha512-uej3YAEKAhlfVPoIo5sOwtxhTLRVJ01LgtWrKGpnnAQU3C+Ilmaxdh+Oc2xc1G3NK30N5eCVJpyO9r3pjKC6Vw==} + cpu: [arm64] + os: [win32] + + '@koromix/koffi-win32-ia32@3.1.5': + resolution: {integrity: sha512-d42jv2f4PwtJGNJS19Xfn/BRtGsBNNVkw0O0K5tkIGI+yNq4MnPTSUsaGbDIkCLNsCgk/LFqAaE8BExyCdrujA==} + cpu: [ia32] + os: [win32] + + '@koromix/koffi-win32-x64@3.1.5': + resolution: {integrity: sha512-Pyo1WEHEP6Ek2NEn2pquwJzSPLOdY4vymoPSz0an1DgvFWSkOyBYYkGVoxL1ajfj5I1pPdXysYqixtVTzAtOfQ==} + cpu: [x64] + os: [win32] + + '@mistralai/mistralai@2.2.6': + resolution: {integrity: sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + + '@modelcontextprotocol/sdk@1.30.0': + resolution: {integrity: sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@napi-rs/wasm-runtime@1.2.3': + resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + + '@opentelemetry/api-logs@0.220.0': + resolution: {integrity: sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/core@2.10.0': + resolution: {integrity: sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@2.9.0': + resolution: {integrity: sha512-m2nckMT80NnmjTYSPjJQObBJ+8dgkoajEOUbznL8AHZ3T3yHRk2P7gI1PhEBc1+lOnrYE9UWrWHqJDsmqjmNbw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/exporter-logs-otlp-http@0.220.0': + resolution: {integrity: sha512-8186thl+pTw64iz/qEEen5oJZoZ/gO73XruChdaGlYdWOdBIQ42r+vHLf6a7vIDqTD4b8ZOoMlyxptanECaI9A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-exporter-base@0.220.0': + resolution: {integrity: sha512-CXYo8UD5Mn9YbgebO2EL4wejtA+gxLmLiu6HCk2KH2BR7XhFN6/6p1UlCb23DYCjeYkndevLHuejCCN1yx4+OQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-transformer@0.220.0': + resolution: {integrity: sha512-lXGrv7KXZ0gNH9SVNUaa6vv6phVYGvJxfXAlMbzbakiXru75f5MZl8Z7oqiMMQD77riVHJCFlQvbZs/VVN2/4A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/resources@2.10.0': + resolution: {integrity: sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/resources@2.9.0': + resolution: {integrity: sha512-jyA5MBLQ+Dkl3+JsZkUoUvL7yHvU64kLsvpXKarWm6347Sl1t1bXFTFykUePNpT5WH5pm9a2Qtt03iIYQhZ1Fg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-logs@0.220.0': + resolution: {integrity: sha512-WywcTkQtv2iNmt+6y5Kcd4rzvx9bLVsBa2Nwcmg01IUaBTkTow3W4d9KE5vNBpEDtb9tp21WcRBY/lANRrApYA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.4.0 <1.10.0' + + '@opentelemetry/sdk-metrics@2.9.0': + resolution: {integrity: sha512-Xx8RGS4H5XEBl01WuCreMIpiah9cCXMbSkeuIePPdD2cUpq/vUzYmj8E/MK1OsbOc93FuAD4jfn2WOacKwLn7Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-trace@2.9.0': + resolution: {integrity: sha512-sGA19HvtrrSKYsseHphluH6j3p6Xa3fqc7c7y8f/7mYWejc1lyDFcpSdD1kYa50HCLUeEo4zA5bW0pniaPszuw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.43.0': + resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} + engines: {node: '>=14'} + + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + + '@oxc-project/types@0.144.0': + resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.1': + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.2': + resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} + + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-android-arm64@1.2.4': + resolution: {integrity: sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-arm64@1.2.4': + resolution: {integrity: sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.4': + resolution: {integrity: sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-freebsd-x64@1.2.4': + resolution: {integrity: sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.4': + resolution: {integrity: sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-gnu@1.2.4': + resolution: {integrity: sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-arm64-musl@1.2.4': + resolution: {integrity: sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-ppc64-gnu@1.2.4': + resolution: {integrity: sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.4': + resolution: {integrity: sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.4': + resolution: {integrity: sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-x64-musl@1.2.4': + resolution: {integrity: sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-openharmony-arm64@1.2.4': + resolution: {integrity: sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.2.4': + resolution: {integrity: sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.4': + resolution: {integrity: sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@shikijs/core@4.4.3': + resolution: {integrity: sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.4.3': + resolution: {integrity: sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.4.3': + resolution: {integrity: sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==} + engines: {node: '>=20'} + + '@shikijs/langs@4.4.3': + resolution: {integrity: sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.4.3': + resolution: {integrity: sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==} + engines: {node: '>=20'} + + '@shikijs/themes@4.4.3': + resolution: {integrity: sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==} + engines: {node: '>=20'} + + '@shikijs/types@4.4.3': + resolution: {integrity: sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@smithy/core@3.33.2': + resolution: {integrity: sha512-CUGXpnPkVdjUCbix+83sWLW9VFgQOm44MDOx/ihITJMAnOZKvL8YYIc7DR9pP/tZ8CIRvMiON/TucvygqbHO3w==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.5.2': + resolution: {integrity: sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.7.2': + resolution: {integrity: sha512-nZyWTmSpJEXl6VtWVMBJve/7x12DZu6sIX1z1a+ZMaHlQQRs9Zpu6NbTe/gmxYXVRpkjxyDYpZ5gx2IM6f/Wkw==} + engines: {node: '>=18.0.0'} + + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/node-http-handler@4.11.2': + resolution: {integrity: sha512-avwAh9HM3h2lcfjvP3zYIZGf+XVgLQ91wOJ2qoFbNpW1UZeZb33aGlhTZvtkANHfcGhJroRY64525OjfgOg30g==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.7.3': + resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.7.2': + resolution: {integrity: sha512-P7Ki6px6OOrxVtx8K7nLmyx4SlXUW/uTKDdMG44UHefmPGSRMBKe2v+TM59WdLcpUIrBrnuCsIqiM2MbsZjmhw==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.17.2': + resolution: {integrity: sha512-FOKpVZob9MPTn2znRzGrnsMHv7BOsKVw3XiP/cOyYLDVZ9qKp4nifIiSCuUU/fIj5Vu0UOAxCFr+qRAtG0NUkA==} + engines: {node: '>=18.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tanstack/react-virtual@3.14.9': + resolution: {integrity: sha512-qZyr0FZDP8rDC4WBhsryIZmAd9bveJvFGUJJtskWaew6/0dTRS6wZxnR6VQ5bY2KwL3LjerrHqQLk3a0GKcPXQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/virtual-core@3.17.7': + resolution: {integrity: sha512-bp+v10y65sp2H7WpWfIMyxTNfl8ZVfxFTLRjPIFRryi6FV/J33z4IS53WO4pTk36KlvJ4iLiQz+oaydDC1xbcA==} + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/hast@3.0.5': + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@22.20.1': + resolution: {integrity: sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==} + + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.3': + resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==} + + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} + + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} + + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} + + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} + + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} + + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} + + '@vscode/ripgrep-darwin-arm64@1.18.0': + resolution: {integrity: sha512-r3ktHSvbFycQNF6sl7sNDPocpsI7J+mEzh1IaZFkY0spm3k2Z9t8hPAeOK7+p0l6p6/swkQC14XWX01low+94Q==} + cpu: [arm64] + os: [darwin] + + '@vscode/ripgrep-darwin-x64@1.18.0': + resolution: {integrity: sha512-25b4gWbL138dGuQU244ebCKKc0q05ULBMoFSz9oAEUHNeqK/lOJViDS7DRvbDazzAzSEdan391Znks/R5mkaTQ==} + cpu: [x64] + os: [darwin] + + '@vscode/ripgrep-linux-arm64@1.18.0': + resolution: {integrity: sha512-lQ/5zTG++U0E3IhVgS4EPTTn/U4okncaRMM5GOFfOYZywS4nuD31GhkHbNYlDk5CuDC68+hYJ0/eQeyCKJDA+g==} + cpu: [arm64] + os: [linux] + + '@vscode/ripgrep-linux-arm@1.18.0': + resolution: {integrity: sha512-GDAvufNDHu8zqLEmXstalQF0Wh6wQvdsBi/Vg3Yi3CK4a8XoFXqqXVEHEZ9xQz3t0NfoSEc9JbvK9DDS6FxyxQ==} + cpu: [arm] + os: [linux] + + '@vscode/ripgrep-linux-ia32@1.18.0': + resolution: {integrity: sha512-YWLkSUtFd4Jh5EepIhA9RJSfv3uMAVMo+2rBIGHPBnvgLrZciIs2cDKei1/p6Wc/aCzUoHyMAg2R6tw4ZCBKGg==} + cpu: [ia32] + os: [linux] + + '@vscode/ripgrep-linux-ppc64@1.18.0': + resolution: {integrity: sha512-quXVY8fwQ8O/lvU1yrSqSl3jlUzysRSb+AfUfCL/tRtphxsKlFvPAejryZ6vg4Bgvn8XL74xb4qMCDmWgYrT5w==} + cpu: [ppc64] + os: [linux] + + '@vscode/ripgrep-linux-riscv64@1.18.0': + resolution: {integrity: sha512-f5kBQBrWfQt8Q7OhSORuNDei5dkYagBj3y4jImSUXGMy8B/Ke7SltSRcUtjPv166FAFfHCAmWuZp3+cWnX2/Vw==} + cpu: [riscv64] + os: [linux] + + '@vscode/ripgrep-linux-s390x@1.18.0': + resolution: {integrity: sha512-rTOcJFGGcl2c07RUOWUo4U1ndnemKhY6A9hnMB18uk7jSgJc0d/QLBGWMWpumdtoJtpizn/wIv5mXIisJukusQ==} + cpu: [s390x] + os: [linux] + + '@vscode/ripgrep-linux-x64@1.18.0': + resolution: {integrity: sha512-mQ3bVrUpnD2vs7QT0vX90Lt0cnUq467uFtEktIdsJJmW296RoSULRGqWgzG1AKxyBpNDD6l4ZO4qKf6SgyC23Q==} + cpu: [x64] + os: [linux] + + '@vscode/ripgrep-win32-arm64@1.18.0': + resolution: {integrity: sha512-vfTIjq1OHnzUjxZcHVQAMbnggp8dpGf+0QKFOZHwWPqFwXxQC8eCWM+5NUdoJ6yrElCeMzoUTXoK/LdZaniB+Q==} + cpu: [arm64] + os: [win32] + + '@vscode/ripgrep-win32-ia32@1.18.0': + resolution: {integrity: sha512-//rfAE+BOw5AC2EMmepmiE36jUuevtQYNQqqlw1s3m9FlRxjxEut97RkRPHAu9BG4mSojatZx+kXZXNdyI9caQ==} + cpu: [ia32] + os: [win32] + + '@vscode/ripgrep-win32-x64@1.18.0': + resolution: {integrity: sha512-KNPvtElldqILHdnAetujPaowkNbpqJy3ssIGGN6F6Kve9Qi+nNLI2DN01O83JjCEVQbCzl8Ov3QZ9Eov3BR8Dg==} + cpu: [x64] + os: [win32] + + '@vscode/ripgrep@1.18.0': + resolution: {integrity: sha512-ns5lWe44tSfbTMbVUsyB+I1819PVSw4AdpgK0RNkzfWfwy6+3IUNSxwSrfTno1/oWaS/hERNz+XLWVyga2aJBQ==} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + anser@2.3.5: + resolution: {integrity: sha512-vcZjxvvVoxTeR5XBNJB38oTu/7eDCZlwdz32N1eNgpyPF7j/Z7Idf+CUwQOkKKpJ7RJyjxgLHCM7vdIK0iCNMQ==} + + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} + engines: {node: '>=14'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@3.0.0: + resolution: {integrity: sha512-8OG92q3R35qjC/4i6BLBMg8IB+fClWu/1PEwg2Z9Rn+BuNaiEgJzpzn+pxWOdHJWDCAwu2JP0wCDTozAM4QirQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + birpc@4.1.0: + resolution: {integrity: sha512-O8L9vALWGqdEe0cG4HJckauw3WeJETlJnDRPUYpgwB7wrU43b/5NGMdVjdVcRo+4ROgd3ih2wha1glDe4HRVgw==} + + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@15.0.0: + resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} + engines: {node: '>=22.12.0'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@9.0.0: + resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} + engines: {node: '>=0.3.1'} + + dts-resolver@3.0.0: + resolution: {integrity: sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==} + engines: {node: ^22.18.0 || >=24.0.0} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventsource-parser@3.1.1: + resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} + + express-rate-limit@8.6.2: + resolution: {integrity: sha512-YH4ru+eOJxQABscKFfRCy9R7x9QFGdezclVMwwgFFndzS2Xnm0uo6B0ABZsLhcpeptGv2qvuJVWlQr9gQZoC3A==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.5: + resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + fflate@0.8.3: + resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gaxios@7.3.1: + resolution: {integrity: sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==} + engines: {node: '>=18'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-tsconfig@5.0.0-beta.5: + resolution: {integrity: sha512-/6gFNr0N04nob252sTQxyFLi3eKFRqIg1I87YcqAMT1i6SQrSF6KujUEQrtrjMV0H/eejTCltLdDSTEMzHbnsQ==} + engines: {node: '>=20.20.0'} + + google-auth-library@10.9.1: + resolution: {integrity: sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==} + engines: {node: '>=18'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hono@4.13.2: + resolution: {integrity: sha512-JydRilDRkYBQMt9qR9U92mXxmbGqsqSn/IKOrh4e7/gEbn+0zSr8igTu0obwJoNGN4sez28DIql7FBHWydoJpA==} + engines: {node: '>=16.9.0'} + + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + + immer@10.2.0: + resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} + + import-without-cache@0.4.0: + resolution: {integrity: sha512-NkJQA7oZ4YHQhd2+H3BoRFKF3d/XNsiKpHZCQEMH9pDX27hQQLsTyOocyRgaIVtf8gHX3Nt3LPkR4e5EdtPAGQ==} + engines: {node: ^22.18.0 || >=24.0.0} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ip-address@10.5.0: + resolution: {integrity: sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jose@6.2.9: + resolution: {integrity: sha512-XrchZOFZUl/T3vTwRe8XK+cJrGtMF4th1ARnDfwbBXFKThGhlsxEE4Zu03AD/bjJSt/9jT/mxrOCkJWOg77aPA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + katex@0.16.47: + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} + hasBin: true + + koffi@3.1.5: + resolution: {integrity: sha512-XVwwrxg0Ca6IEUQF4YtGIU4XN0LSselFYpYvgfhh8wafCunhEEx5hPr7LZhp5QyeFA/LcRsKHTqncCdjWjWAlg==} + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-addon-native-custom-loader@0.1.5: + resolution: {integrity: sha512-rL0XXRytayIChYf1xaG9/1NzGBRTyFkQTIpn+MDz/hpr0PZw1a9PZIoH9HlYfagNawhXU+jfN650EvoSIvR7Vw==} + engines: {node: '>=20'} + + node-addon-require-builtin-darwin-arm64@0.1.5: + resolution: {integrity: sha512-MZ5RyGhuU7DTbwuNpOQW81/ep8n5Yd5YlZa6dWiEfJEh+01Dl4cCKGmMCWNgb0VtqAImRtAOtmZIPtwngiemKQ==} + engines: {node: '>=20'} + cpu: [arm64] + os: [darwin] + + node-addon-require-builtin-darwin-x64@0.1.5: + resolution: {integrity: sha512-wdCSPn49AdNZ2EXHQqswiXk1cROFe9zSRaAX8PwQLxmjdLt+xZF7vZP6VlqgXm+VAOHv98q8kp9m7mO9jY3OgQ==} + engines: {node: '>=20'} + cpu: [x64] + os: [darwin] + + node-addon-require-builtin-linux-arm64-gnu@0.1.5: + resolution: {integrity: sha512-hCqzKpQiknDDv6rUdZqrxCBXROg/uUruO0geUuZsdM9M/Lds45gSb4bDE958HlPaCvrDyR0wTHl3II8A7yQeew==} + engines: {node: '>=20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + node-addon-require-builtin-linux-x64-gnu@0.1.5: + resolution: {integrity: sha512-lgP+ruwWXbcXDslhp5uIc+dFgzITEGPZ4E50WdHGt/OzcoVhN6y5z72pRRvxy8DE661//QxqmCLe72rS3SVg+w==} + engines: {node: '>=20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + node-addon-require-builtin-win32-arm64-msvc@0.1.5: + resolution: {integrity: sha512-KEO2eWS4lvZg6JmPPz04OdI4Ojrc7YzOs++4r6VnvwsqYN2r6mjGSGpouQkk8J2eLXBzC7X/D9wYTbUuQS8u1Q==} + engines: {node: '>=20'} + cpu: [arm64] + os: [win32] + + node-addon-require-builtin-win32-ia32-msvc@0.1.5: + resolution: {integrity: sha512-iSC988EqZm5XbKWp/giW6K6EBRTrHt/YQbAkKsZLglt7PplmvvrZ7C3tUsyh1wVxUTYAaxFdE2xbqSdpw0rb6g==} + engines: {node: '>=20 <23'} + cpu: [ia32] + os: [win32] + + node-addon-require-builtin-win32-x64-msvc@0.1.5: + resolution: {integrity: sha512-pjuco/ESU3ChIp7WwacWfY2ENu2K5rGAgqjcXedoiFcTrjTf5Ln/miKSuNfE6IiuJ7tfMTJH6VH5hq+C1Y8JMQ==} + engines: {node: '>=20'} + cpu: [x64] + os: [win32] + + node-addon-require-builtin@0.1.5: + resolution: {integrity: sha512-isaquiStlp7qdFpaffy+2ssJPUR/kLPRE5gqfeWbb0Ahph9H7O3BOFwThqkVaTrxfpnjrQauxlOEgvzD+snhUg==} + engines: {node: '>=20'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-pty@1.2.0-beta.15: + resolution: {integrity: sha512-vORSzHXi4Ofl7HemVWpuudLqCPdaQb4LfpRCUpE5HPxhp4JYscl8zZwxh11p26v2wvW24WMwnMfLjhRLixrfxA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} + engines: {node: '>=12.20.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + + openai@6.26.0: + resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + partial-json@0.1.7: + resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + postcss@8.5.26: + resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + engines: {node: ^10 || ^12 || >=14} + + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + + protobufjs@7.6.5: + resolution: {integrity: sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + engines: {node: '>=0.6'} + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + rolldown-plugin-dts@0.25.2: + resolution: {integrity: sha512-nMhN/R+vmR8GM45ZW1FWMSjRTSDDn/6w4GTf8RNrEFCBdl8B1kySWrU1ixPtbwzXoRlcO+R/S88VgXuJQwfdDg==} + engines: {node: ^22.18.0 || >=24.0.0} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20260325.1' + rolldown: ^1.0.0 + typescript: ^5.0.0 || ^6.0.0 + vue-tsc: ~3.2.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rolldown@1.2.4: + resolution: {integrity: sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sharp@0.35.3: + resolution: {integrity: sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@4.4.3: + resolution: {integrity: sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==} + engines: {node: '>=20'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.3.0: + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.1: + resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} + engines: {node: '>=14.0.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + + tsdown@0.22.2: + resolution: {integrity: sha512-VX9gsyKXsTnBZjnIM4jsHl9aRv+GfgkE/k1hQslilaBfZMlaw3JuGR+6yhiU0QxWBtOCDnTjwOSoXzgB7Rr50g==} + engines: {node: ^22.18.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + '@tsdown/css': 0.22.2 + '@tsdown/exe': 0.22.2 + '@vitejs/devtools': '*' + publint: ^0.3.8 + tsx: '*' + typescript: ^5.0.0 || ^6.0.0 + unplugin-unused: ^0.5.0 + unrun: '*' + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@tsdown/css': + optional: true + '@tsdown/exe': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + tsx: + optional: true + typescript: + optional: true + unplugin-unused: + optional: true + unrun: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + turndown@7.2.4: + resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} + engines: {node: '>=18', npm: '>=9'} + + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + + typebox@1.1.38: + resolution: {integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@8.2.1: + resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.4.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 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + + zustand@4.4.7: + resolution: {integrity: sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@anthropic-ai/sdk@0.91.1(zod@4.4.3)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 4.4.3 + + '@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.974.4 + '@aws-sdk/util-locate-window': 3.965.10 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.974.4 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.974.4 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-bedrock-runtime@3.1048.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.977.8 + '@aws-sdk/credential-provider-node': 3.972.80 + '@aws-sdk/eventstream-handler-node': 3.972.33 + '@aws-sdk/middleware-eventstream': 3.972.28 + '@aws-sdk/middleware-websocket': 3.972.51 + '@aws-sdk/token-providers': 3.1048.0 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/fetch-http-handler': 5.7.2 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/core@3.977.8': + dependencies: + '@aws-sdk/types': 3.974.4 + '@aws-sdk/xml-builder': 3.972.39 + '@aws/lambda-invoke-store': 0.3.0 + '@smithy/core': 3.33.2 + '@smithy/signature-v4': 5.7.2 + '@smithy/types': 4.17.2 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.69': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.71': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/fetch-http-handler': 5.7.2 + '@smithy/node-http-handler': 4.11.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.973.14': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/credential-provider-env': 3.972.69 + '@aws-sdk/credential-provider-http': 3.972.71 + '@aws-sdk/credential-provider-login': 3.972.76 + '@aws-sdk/credential-provider-process': 3.972.69 + '@aws-sdk/credential-provider-sso': 3.973.13 + '@aws-sdk/credential-provider-web-identity': 3.972.75 + '@aws-sdk/nested-clients': 3.997.43 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/credential-provider-imds': 4.5.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-login@3.972.76': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/nested-clients': 3.997.43 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-node@3.972.80': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.69 + '@aws-sdk/credential-provider-http': 3.972.71 + '@aws-sdk/credential-provider-ini': 3.973.14 + '@aws-sdk/credential-provider-process': 3.972.69 + '@aws-sdk/credential-provider-sso': 3.973.13 + '@aws-sdk/credential-provider-web-identity': 3.972.75 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/credential-provider-imds': 4.5.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.972.69': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.973.13': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/nested-clients': 3.997.43 + '@aws-sdk/token-providers': 3.1111.0 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-web-identity@3.972.75': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/nested-clients': 3.997.43 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/eventstream-handler-node@3.972.33': + dependencies: + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-eventstream@3.972.28': + dependencies: + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-websocket@3.972.51': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/fetch-http-handler': 5.7.2 + '@smithy/signature-v4': 5.7.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.997.43': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/signature-v4-multi-region': 3.996.45 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/fetch-http-handler': 5.7.2 + '@smithy/node-http-handler': 4.11.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-multi-region@3.996.45': + dependencies: + '@aws-sdk/types': 3.974.4 + '@smithy/signature-v4': 5.7.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1048.0': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/nested-clients': 3.997.43 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1111.0': + dependencies: + '@aws-sdk/core': 3.977.8 + '@aws-sdk/nested-clients': 3.997.43 + '@aws-sdk/types': 3.974.4 + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/types@3.974.4': + dependencies: + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws-sdk/util-locate-window@3.965.10': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.39': + dependencies: + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.3.0': {} + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/generator@8.0.0-rc.6': + dependencies: + '@babel/parser': 8.0.0-rc.6 + '@babel/types': 8.0.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/helper-string-parser@8.0.0': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-identifier@8.0.0-rc.6': {} + + '@babel/helper-validator-identifier@8.0.4': {} + + '@babel/parser@8.0.0-rc.6': + dependencies: + '@babel/types': 8.0.4 + + '@babel/parser@8.0.4': + dependencies: + '@babel/types': 8.0.4 + + '@babel/runtime@7.29.7': {} + + '@babel/types@8.0.4': + dependencies: + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 + + '@deepseek-ai/cordis-plugin-group@1.0.1(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + + '@deepseek-ai/cordis-plugin-hmr@1.0.16(@deepseek-ai/cordis-plugin-timer@1.1.3(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/cordis@4.0.1)': + dependencies: + '@babel/code-frame': 7.29.7 + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-timer': 1.1.3(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cosmokit': 1.8.2 + '@deepseek-ai/schemastery': 3.18.1 + chokidar: 4.0.3 + picomatch: 4.0.5 + + '@deepseek-ai/cordis-plugin-include@1.0.6(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/cosmokit': 1.8.2 + js-yaml: 4.3.1 + + '@deepseek-ai/cordis-plugin-loader@1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cosmokit': 1.8.2 + optionalDependencies: + node-addon-require-builtin: 0.1.5 + + '@deepseek-ai/cordis-plugin-timer@1.1.3(@deepseek-ai/cordis@4.0.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cosmokit': 1.8.2 + + '@deepseek-ai/cordis@4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2)': + dependencies: + '@deepseek-ai/cosmokit': 1.8.2 + '@standard-schema/spec': 1.1.0 + optionalDependencies: + '@deepseek-ai/cordis-plugin-include': 1.0.6(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + + '@deepseek-ai/cosmokit@1.8.2': {} + + '@deepseek-ai/dsh-agent-default-model@0.1.0-rc.7(1eb7ceb2998733be9eba21a37a3dc291)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-agent-instructions@0.1.0-rc.7(93b00e8961a24ed58236184dea3d0e10)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-agent-loop@0.1.0-rc.7(c781feb845781bb9aab3d875c8c71a7b)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-agent-presets@0.1.0-rc.7(c0f9f44edab94cddae92cd4b4f319bab)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-include': 1.0.6(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-atomic-write': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + js-yaml: 4.3.1 + + '@deepseek-ai/dsh-agent-tool-presentation@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + + '@deepseek-ai/dsh-anonymous-user-id@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-api-gateway@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-registry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-typert-registry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + + '@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-agent-presets': 0.1.0-rc.7(c0f9f44edab94cddae92cd4b4f319bab) + '@deepseek-ai/dsh-api-gateway': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-registry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-cordis-host-runner': 0.1.0-rc.7(2a80d56ba6af58ca8075e00e0fa2157b) + '@deepseek-ai/dsh-credentials': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-host-plugin-inventory': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-message-feedback': 0.1.0-rc.7(1fcfefbbf5e365eda1a59fadd94056b9) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-typert-registry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + + '@deepseek-ai/dsh-app-boot@0.1.0-rc.7(aad8c687644ca696866ebd36b8ea50bc)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-group': 1.0.1(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-include': 1.0.6(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-launch-environment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + js-yaml: 4.3.1 + optionalDependencies: + '@deepseek-ai/cordis-plugin-hmr': 1.0.16(@deepseek-ai/cordis-plugin-timer@1.1.3(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-atomic-write@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-attachment-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@types/node@22.20.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + sharp: 0.35.3(@types/node@22.20.1) + transitivePeerDependencies: + - '@types/node' + + '@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-base@0.1.0-rc.7(4c88fd6b241c39b2a20aa507ebfa0e9c)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-hmr': 1.0.16(@deepseek-ai/cordis-plugin-timer@1.1.3(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-timer': 1.1.3(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-agent-default-model': 0.1.0-rc.7(1eb7ceb2998733be9eba21a37a3dc291) + '@deepseek-ai/dsh-agent-instructions': 0.1.0-rc.7(93b00e8961a24ed58236184dea3d0e10) + '@deepseek-ai/dsh-agent-loop': 0.1.0-rc.7(c781feb845781bb9aab3d875c8c71a7b) + '@deepseek-ai/dsh-api-gateway': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-registry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-attachment-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@types/node@22.20.1) + '@deepseek-ai/dsh-bash-sandbox': 0.1.0-rc.7(685f6ca975e6615c43b38d43329eb0bf) + '@deepseek-ai/dsh-command-compact': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-command-feedback': 0.1.0-rc.7(8240ebd5c5c18b0099c826ca9c37a21e) + '@deepseek-ai/dsh-command-goal': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-compaction-basic': 0.1.0-rc.7(f519e9ab3c16060968f3852a830521b6) + '@deepseek-ai/dsh-compaction-tool-result-pruner': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-token-meter@0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09)) + '@deepseek-ai/dsh-credentials-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-atomic-write@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-credentials@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-launch-environment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-fs-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-fs-observation-policy': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-fs-sandbox': 0.1.0-rc.7(e2c3f749b35e7992023fc11ff304b924) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-goal-round-driver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-jobs@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-llm-deepseek': 0.1.0-rc.7(1b165c0b687652478be7b7375cfce4e5) + '@deepseek-ai/dsh-llm-pi-ai': 0.1.0-rc.7(7012acaf3effe0bd7eda8406abb0be6d) + '@deepseek-ai/dsh-llm-retry': 0.1.0-rc.7(f6ee553b5544017c93f5bcbec0012ce3) + '@deepseek-ai/dsh-permission-presets': 0.1.0-rc.7(bd0acd1ff6121b02d9866ecbfc1d9b12) + '@deepseek-ai/dsh-plan-mode': 0.1.0-rc.7(3abfc5979880a1c8e6bc377abfd69758) + '@deepseek-ai/dsh-pwsh-sandbox': 0.1.0-rc.7(01b43dee0e175c8dd5e3a7e6517088bf) + '@deepseek-ai/dsh-repeat-tool-reminder': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-sandbox-local': 0.1.0-rc.7(dbd40ab583e375c407ea206b169b3049) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-checkpoint-policy': 0.1.0-rc.7(1a5c4e40a544406e1e82bb99610f66a3) + '@deepseek-ai/dsh-session-persistence-jsonl': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-query-sqlite': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session-query@0.1.0-rc.7(fa24861d08a9d735fc78888af6ddf326))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-telemetry-otel': 0.1.0-rc.7(2ea544043975e11edf40fad6b8322b79) + '@deepseek-ai/dsh-session-title': 0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2) + '@deepseek-ai/dsh-session-title-first-prompt-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session-title-llm@0.1.0-rc.7(6fcdcafdc6a942dddc20da358d69b413))(@deepseek-ai/dsh-session-title@0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-settings-file': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-atomic-write@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1)) + '@deepseek-ai/dsh-shell-env': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-skill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-skill-badge': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-skill@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + '@deepseek-ai/dsh-skill-filesystem': 0.1.0-rc.7(cea9f3527f4d5c630f6db1120eda1b51) + '@deepseek-ai/dsh-spill-local': 0.1.0-rc.7(fa23de144536b578bc3d547e7122cf66) + '@deepseek-ai/dsh-spill-policy': 0.1.0-rc.7(a25502e01591be81db4b639e945e283f) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-subagent-fork-in-process': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-subagent-in-process-driver@0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da)) + '@deepseek-ai/dsh-subagent-spawn-in-process': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-subagent-in-process-driver@0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da)) + '@deepseek-ai/dsh-subprocess-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-token-meter': 0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09) + '@deepseek-ai/dsh-tool-bash': 0.1.0-rc.7(e6524a4741ca5f7a041a012548fcf420) + '@deepseek-ai/dsh-tool-call-timeout-policy': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-tool-fs': 0.1.0-rc.7(e7d989b5e5a4423849aa5d8248287fa2) + '@deepseek-ai/dsh-tool-fs-search': 0.1.0-rc.7(b32686f6bdfad4e2bac19ddddae90f15) + '@deepseek-ai/dsh-tool-goal': 0.1.0-rc.7(180e0f3f329d9b10860ecf7e00313277) + '@deepseek-ai/dsh-tool-jobs': 0.1.0-rc.7(9946e50f0ee52458165c230dc9c7c6b5) + '@deepseek-ai/dsh-tool-pwsh': 0.1.0-rc.7(e6524a4741ca5f7a041a012548fcf420) + '@deepseek-ai/dsh-tool-ralph': 0.1.0-rc.7(bab3281304625d6d534bd32fe485cf79) + '@deepseek-ai/dsh-tool-skill': 0.1.0-rc.7(df0d23800fad5b2ada25025e060bda44) + '@deepseek-ai/dsh-tool-str-replace-editor': 0.1.0-rc.7(3bd2fa864f678fb2dc668eb7729286c2) + '@deepseek-ai/dsh-tool-subagent': 0.1.0-rc.7(1222888b06fba7e9c8bcaa54a558d14e) + '@deepseek-ai/dsh-tool-subagent-control': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-tool-subagent-report': 0.1.0-rc.7(640d921ae2b98078971463f9056a34f9) + '@deepseek-ai/dsh-tool-todo': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-projection@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-tool-web': 0.1.0-rc.7(a1e227eab3db3d5fdb80246cd440578f) + '@deepseek-ai/dsh-tool-workflow': 0.1.0-rc.7(568ef6a59b3c44062c8cbf5cb759c397) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-typert-loader': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-registry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-typert-registry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/dsh-user-questions': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + '@deepseek-ai/dsh-web': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + '@deepseek-ai/dsh-web-search-deepseek': 0.1.0-rc.7(682f945d61f3362c5b4bd1233bf7a050) + '@deepseek-ai/dsh-workflow-worker-thread': 0.1.0-rc.7(6ad95a742535dff29ed317a2fc297623) + transitivePeerDependencies: + - '@deepseek-ai/cordis-plugin-loader' + - '@deepseek-ai/dsh-agent-presets' + - '@deepseek-ai/dsh-anonymous-user-id' + - '@deepseek-ai/dsh-atomic-write' + - '@deepseek-ai/dsh-attachment' + - '@deepseek-ai/dsh-bash-local' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-client-connection' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-compaction' + - '@deepseek-ai/dsh-credentials' + - '@deepseek-ai/dsh-fs' + - '@deepseek-ai/dsh-home-paths' + - '@deepseek-ai/dsh-jobs' + - '@deepseek-ai/dsh-launch-environment' + - '@deepseek-ai/dsh-output-retention' + - '@deepseek-ai/dsh-pwsh-local' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-session-persistence' + - '@deepseek-ai/dsh-session-projection-cache' + - '@deepseek-ai/dsh-session-query' + - '@deepseek-ai/dsh-session-telemetry' + - '@deepseek-ai/dsh-session-title-llm' + - '@deepseek-ai/dsh-settings' + - '@deepseek-ai/dsh-shell' + - '@deepseek-ai/dsh-spill' + - '@deepseek-ai/dsh-subagent-in-process-driver' + - '@deepseek-ai/dsh-subprocess' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-typert-protocol' + - '@deepseek-ai/dsh-workflow' + - '@modelcontextprotocol/sdk' + - '@types/node' + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@deepseek-ai/dsh-bash-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-bash-sandbox@0.1.0-rc.7(685f6ca975e6615c43b38d43329eb0bf)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-bash-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + + '@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-client-connection@0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-host-apiproxy': 0.1.0-rc.7(20514f3a3e01200624daa2ce81cb702e) + '@deepseek-ai/dsh-host-webserver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + ws: 8.21.3 + transitivePeerDependencies: + - '@deepseek-ai/dsh-agent' + - '@deepseek-ai/dsh-agent-presets' + - '@deepseek-ai/dsh-api-gateway' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-cordis-host-runner' + - '@deepseek-ai/dsh-host-plugin-inventory' + - '@deepseek-ai/dsh-message-feedback' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-sandbox-policy' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-storage' + - '@deepseek-ai/dsh-storage-domain' + - '@deepseek-ai/dsh-system-prompt' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-typert-protocol' + - '@deepseek-ai/dsh-typert-registry' + - '@deepseek-ai/dsh-user-approval' + - bufferutil + - utf-8-validate + + '@deepseek-ai/dsh-client-hmr@0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-host-webserver@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-client-modules': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-webserver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/schemastery': 3.18.1 + react: 18.3.1 + transitivePeerDependencies: + - '@deepseek-ai/dsh-brand' + + '@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-host-apiproxy': 0.1.0-rc.7(20514f3a3e01200624daa2ce81cb702e) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-llm-retry': 0.1.0-rc.7(f6ee553b5544017c93f5bcbec0012ce3) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-title': 0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-typert-registry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + immer: 10.2.0 + react: 18.3.1 + zustand: 4.4.7(immer@10.2.0)(react@18.3.1) + transitivePeerDependencies: + - '@deepseek-ai/dsh-agent-presets' + - '@deepseek-ai/dsh-api-gateway' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-cordis-host-runner' + - '@deepseek-ai/dsh-host-plugin-inventory' + - '@deepseek-ai/dsh-host-webserver' + - '@deepseek-ai/dsh-message-feedback' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-sandbox-policy' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-storage' + - '@deepseek-ai/dsh-storage-domain' + - '@deepseek-ai/dsh-system-prompt' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-user-approval' + - '@types/react' + - bufferutil + - utf-8-validate + + '@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-client-ui-agent-preset@0.1.0-rc.7(af1f0dfda1b313f0e26ca09e9ae27396)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-web-react': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@deepseek-ai/dsh-brand' + - supports-color + + '@deepseek-ai/dsh-client-ui-commands@0.1.0-rc.7(26504d5ecc5244ba7b677378b7933298)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm-retry': 0.1.0-rc.7(f6ee553b5544017c93f5bcbec0012ce3) + '@deepseek-ai/dsh-session-stats': 0.1.0-rc.7(162e09a00c830c72cf271bc0dbd64697) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-token-meter': 0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-cordis@0.1.0-rc.7(bf687ae130e22673b950361a807ff16c)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-sidebar': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-tool': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-cordis-client-runner': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-deliverables@0.1.0-rc.7(7249ff3b991002071e4561a99f8ee1c2)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-directory-picker-browse@0.1.0-rc.7(0dfe4bda28d14a5dd77b4a591646a18c)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-workspace': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-directory-picker-native@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-workspace@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-workspace': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-goal@0.1.0-rc.7(c21ab1c36a0529cde1094ac4152e8cd0)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-input-trigger@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-jobs@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-layout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-theme': 0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + ? '@deepseek-ai/dsh-client-ui-message-feedback@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-message-feedback@0.1.0-rc.7(1fcfefbbf5e365eda1a59fadd94056b9))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(react@18.3.1)' + : dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-message-feedback': 0.1.0-rc.7(1fcfefbbf5e365eda1a59fadd94056b9) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-model-selection@0.1.0-rc.7(fa7dfd679b06b363d46ed7789b85ff86)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-commands': 0.1.0-rc.7(26504d5ecc5244ba7b677378b7933298) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-permission-presets@0.1.0-rc.7(2d26805daefd8bdf9333cc6c10b78030)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-schema-form': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-commands': 0.1.0-rc.7(26504d5ecc5244ba7b677378b7933298) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-permission-presets': 0.1.0-rc.7(bd0acd1ff6121b02d9866ecbfc1d9b12) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-plan@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-plan-mode@0.1.0-rc.7(3abfc5979880a1c8e6bc377abfd69758))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-plan-mode': 0.1.0-rc.7(3abfc5979880a1c8e6bc377abfd69758) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@shikijs/langs': 4.4.3 + '@types/mdast': 4.0.4 + anser: 2.3.5 + clsx: 2.1.1 + katex: 0.16.47 + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm: 3.1.0 + mdast-util-math: 3.0.0 + micromark-core-commonmark: 2.0.3 + micromark-extension-gfm: 3.0.0 + micromark-extension-math: 3.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-classify-character: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + shiki: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@deepseek-ai/dsh-client-ui-settings-general@0.1.0-rc.7(7752585f0696b00bd95e546fb67ff66a)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-sidebar': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-web-react': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/schemastery': 3.18.1 + clsx: 2.1.1 + react: 18.3.1 + transitivePeerDependencies: + - '@deepseek-ai/dsh-brand' + + '@deepseek-ai/dsh-client-ui-settings-models@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-web-react@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-schema-form': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-web-react': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-settings-plugin-inventory@0.1.0-rc.7(cb962c4a2902db0fad3b93b45cd71c01)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-settings-plugins@0.1.0-rc.7(003ac2d7911288fd946bd49107ea2822)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-web-react': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-schema-form': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-sidebar@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-skill@0.1.0-rc.7(152d1dcbb4454c394fd2bfff1b3ae10c)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-tool': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-client-ui-subagent@0.1.0-rc.7(94207603c9ef3302f528dc84d74863b2)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-token-meter': 0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-webserver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/schemastery': 3.18.1 + clsx: 2.1.1 + react: 18.3.1 + transitivePeerDependencies: + - '@deepseek-ai/dsh-brand' + + '@deepseek-ai/dsh-client-ui-tool@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-trajectory@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@tanstack/react-virtual': 3.14.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + diff: 9.0.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@deepseek-ai/dsh-client-ui-user-questions@0.1.0-rc.7(513da2308aa1aecd90c9e1b8fef56d3a)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + transitivePeerDependencies: + - '@deepseek-ai/dsh-agent' + - '@deepseek-ai/dsh-agent-presets' + - '@deepseek-ai/dsh-api-gateway' + - '@deepseek-ai/dsh-attachment' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-client-ui-attachment' + - '@deepseek-ai/dsh-client-ui-input-trigger' + - '@deepseek-ai/dsh-client-ui-settings' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-commands' + - '@deepseek-ai/dsh-compaction' + - '@deepseek-ai/dsh-cordis-host-runner' + - '@deepseek-ai/dsh-host-plugin-inventory' + - '@deepseek-ai/dsh-host-webserver' + - '@deepseek-ai/dsh-llm-retry' + - '@deepseek-ai/dsh-message-feedback' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-sandbox-policy' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-session-stats' + - '@deepseek-ai/dsh-storage' + - '@deepseek-ai/dsh-storage-domain' + - '@deepseek-ai/dsh-system-prompt' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-token-meter' + - '@deepseek-ai/dsh-tools' + - '@deepseek-ai/dsh-typert-protocol' + - '@deepseek-ai/dsh-typert-registry' + - '@deepseek-ai/dsh-user-approval' + - '@types/react' + - bufferutil + - supports-color + - utf-8-validate + + '@deepseek-ai/dsh-client-ui-workflow-run@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-tool-workflow@0.1.0-rc.7(568ef6a59b3c44062c8cbf5cb759c397))(@deepseek-ai/dsh-workflow@0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-tool-workflow': 0.1.0-rc.7(568ef6a59b3c44062c8cbf5cb759c397) + '@deepseek-ai/dsh-workflow': 0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd) + react: 18.3.1 + + '@deepseek-ai/dsh-client-ui-workspace@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + clsx: 2.1.1 + react: 18.3.1 + + '@deepseek-ai/dsh-client-web-react@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + use-sync-external-store: 1.2.0(react@18.3.1) + + '@deepseek-ai/dsh-client-web@0.1.0-rc.7(b1b4c4d8e767964f8435b704957716b7)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-client-modules': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-schema-form': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-theme': 0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e) + '@deepseek-ai/dsh-client-web-react': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@deepseek-ai/dsh-api-remotes' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-client-connection' + - '@deepseek-ai/dsh-client-locale' + - '@deepseek-ai/dsh-client-runtime' + - '@deepseek-ai/dsh-client-ui-settings' + - '@deepseek-ai/dsh-host-webserver' + - supports-color + + '@deepseek-ai/dsh-cmdline@0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-code-runtime-worker-thread@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-code-runtime@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-code-runtime': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-code-runtime@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-command-compact@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-command-feedback@0.1.0-rc.7(8240ebd5c5c18b0099c826ca9c37a21e)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-anonymous-user-id': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-telemetry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + + '@deepseek-ai/dsh-command-goal@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + zod: 4.4.3 + + '@deepseek-ai/dsh-compaction-basic@0.1.0-rc.7(f519e9ab3c16060968f3852a830521b6)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-token-meter': 0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09) + '@deepseek-ai/schemastery': 3.18.1 + optionalDependencies: + '@deepseek-ai/dsh-compaction-tool-result-pruner': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-token-meter@0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09)) + + '@deepseek-ai/dsh-compaction-tool-result-pruner@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-token-meter@0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-token-meter': 0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + '@deepseek-ai/dsh-cordis-client-runner@0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-modules': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-theme': 0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-cordis-host-runner@0.1.0-rc.7(2a80d56ba6af58ca8075e00e0fa2157b)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-credentials-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-atomic-write@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-credentials@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-launch-environment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-atomic-write': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-credentials': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-launch-environment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + chokidar: 4.0.3 + yaml: 2.9.0 + + '@deepseek-ai/dsh-credentials@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-fs-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + koffi: 3.1.5 + + '@deepseek-ai/dsh-fs-observation-policy@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-fs-sandbox@0.1.0-rc.7(e2c3f749b35e7992023fc11ff304b924)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-fs-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + + '@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + + '@deepseek-ai/dsh-goal-round-driver@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + '@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-headless@0.1.0-rc.7(85cf737328c42864c624534435ec3820)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-agent-default-model': 0.1.0-rc.7(1eb7ceb2998733be9eba21a37a3dc291) + '@deepseek-ai/dsh-cmdline': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-code-runtime-worker-thread': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-code-runtime@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/schemastery': 3.18.1 + commander: 15.0.0 + transitivePeerDependencies: + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-timeout' + + '@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-host-apiproxy@0.1.0-rc.7(20514f3a3e01200624daa2ce81cb702e)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-agent-default-model': 0.1.0-rc.7(1eb7ceb2998733be9eba21a37a3dc291) + '@deepseek-ai/dsh-agent-presets': 0.1.0-rc.7(c0f9f44edab94cddae92cd4b4f319bab) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-cordis-host-runner': 0.1.0-rc.7(2a80d56ba6af58ca8075e00e0fa2157b) + '@deepseek-ai/dsh-credentials': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-host-directory-picker': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-native-command': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-projection-cache': 0.1.0-rc.7(5ae699d01eec9f3ccaa1e8c13f88dd36) + '@deepseek-ai/dsh-session-query': 0.1.0-rc.7(fa24861d08a9d735fc78888af6ddf326) + '@deepseek-ai/dsh-session-title': 0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-skill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/dsh-user-questions': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + '@deepseek-ai/dsh-workspace': 0.1.0-rc.7(52d55750df813bb508c3c8815dfcc2bd) + '@deepseek-ai/schemastery': 3.18.1 + fflate: 0.8.3 + zod: 4.4.3 + transitivePeerDependencies: + - '@deepseek-ai/dsh-api-gateway' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-host-plugin-inventory' + - '@deepseek-ai/dsh-message-feedback' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-sandbox-policy' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-storage' + - '@deepseek-ai/dsh-storage-domain' + - '@deepseek-ai/dsh-system-prompt' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-typert-protocol' + - '@deepseek-ai/dsh-typert-registry' + + '@deepseek-ai/dsh-host-directory-picker-auto@0.1.0-rc.7(da3caeaacbe519905d0ce88b6e588026)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-client-ui-directory-picker-browse': 0.1.0-rc.7(0dfe4bda28d14a5dd77b4a591646a18c) + '@deepseek-ai/dsh-client-ui-directory-picker-native': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-workspace@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-host-directory-picker-browse': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-directory-picker-native': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-webserver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-host-directory-picker-browse@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-host-directory-picker': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-host-directory-picker-native@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-host-directory-picker': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-native-command': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + koffi: 3.1.5 + + '@deepseek-ai/dsh-host-directory-picker@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-host-frontend-static@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-host-webserver@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-host-webserver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-host-plugin-inventory@0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + zod: 4.4.3 + + '@deepseek-ai/dsh-host-webserver@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-jobs-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-jobs@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-jobs@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + '@deepseek-ai/dsh-launch-environment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-llm-deepseek@0.1.0-rc.7(1b165c0b687652478be7b7375cfce4e5)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-anonymous-user-id': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-credentials': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-launch-environment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + eventsource-parser: 3.1.1 + + '@deepseek-ai/dsh-llm-pi-ai@0.1.0-rc.7(7012acaf3effe0bd7eda8406abb0be6d)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-credentials': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-launch-environment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@deepseek-ai/dsh-llm-retry@0.1.0-rc.7(f6ee553b5544017c93f5bcbec0012ce3)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-mcp-client@0.1.0-rc.7(8a97403e980dbcaa31e3631c5bdae10e)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + '@modelcontextprotocol/sdk': 1.30.0(zod@4.4.3) + zod: 4.4.3 + transitivePeerDependencies: + - '@cfworker/json-schema' + - supports-color + + '@deepseek-ai/dsh-message-feedback@0.1.0-rc.7(1fcfefbbf5e365eda1a59fadd94056b9)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-storage-domain': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-native-command@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-output-retention@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-permission-presets@0.1.0-rc.7(bd0acd1ff6121b02d9866ecbfc1d9b12)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-persona@0.1.0-rc.7(cd103793887a77cfa11721505870efe9)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-plan-mode@0.1.0-rc.7(3abfc5979880a1c8e6bc377abfd69758)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-user-questions': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + zod: 4.4.3 + optionalDependencies: + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + + '@deepseek-ai/dsh-pwsh-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-pwsh-sandbox@0.1.0-rc.7(01b43dee0e175c8dd5e3a7e6517088bf)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-pwsh-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + + '@deepseek-ai/dsh-repeat-tool-reminder@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-sandbox-local@0.1.0-rc.7(dbd40ab583e375c407ea206b169b3049)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-windows-acl': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/node-addon-landlock-run': 0.1.1 + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-sandbox-policy@0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-sandbox-windows-acl@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + koffi: 3.1.5 + + '@deepseek-ai/dsh-sandbox@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + '@deepseek-ai/dsh-schedule@0.1.0-rc.7(2a787269d0a16d51cbe6213bebf2cad4)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + + '@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-session-checkpoint-policy@0.1.0-rc.7(1a5c4e40a544406e1e82bb99610f66a3)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + + '@deepseek-ai/dsh-session-log-export@0.1.0-rc.7(f26d44b13c483ceafe59cc97fd2e3a49)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-commands': 0.1.0-rc.7(26504d5ecc5244ba7b677378b7933298) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-primitives': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-slots': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-commands': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + react: 18.3.1 + + '@deepseek-ai/dsh-session-persistence-jsonl@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + koffi: 3.1.5 + + '@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + + '@deepseek-ai/dsh-session-projection-cache@0.1.0-rc.7(5ae699d01eec9f3ccaa1e8c13f88dd36)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-storage-domain': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-session-projection@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + zod: 4.4.3 + + '@deepseek-ai/dsh-session-query-sqlite@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session-query@0.1.0-rc.7(fa24861d08a9d735fc78888af6ddf326))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-query': 0.1.0-rc.7(fa24861d08a9d735fc78888af6ddf326) + '@deepseek-ai/schemastery': 3.18.1 + optionalDependencies: + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + + '@deepseek-ai/dsh-session-query@0.1.0-rc.7(fa24861d08a9d735fc78888af6ddf326)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-title': 0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2) + optionalDependencies: + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + + '@deepseek-ai/dsh-session-reference@0.1.0-rc.7(fe3daefbd216dec211872eab9ee75662)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-output-retention': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-query': 0.1.0-rc.7(fa24861d08a9d735fc78888af6ddf326) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-session-stats@0.1.0-rc.7(162e09a00c830c72cf271bc0dbd64697)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + zod: 4.4.3 + + '@deepseek-ai/dsh-session-telemetry-otel@0.1.0-rc.7(2ea544043975e11edf40fad6b8322b79)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-anonymous-user-id': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-command-feedback': 0.1.0-rc.7(8240ebd5c5c18b0099c826ca9c37a21e) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-telemetry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/schemastery': 3.18.1 + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.220.0 + '@opentelemetry/exporter-logs-otlp-http': 0.220.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.220.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.10.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.220.0(@opentelemetry/api@1.9.1) + + '@deepseek-ai/dsh-session-telemetry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + ? '@deepseek-ai/dsh-session-title-first-prompt-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session-title-llm@0.1.0-rc.7(6fcdcafdc6a942dddc20da358d69b413))(@deepseek-ai/dsh-session-title@0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))' + : dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-title': 0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2) + '@deepseek-ai/dsh-session-title-llm': 0.1.0-rc.7(6fcdcafdc6a942dddc20da358d69b413) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-session-title-llm@0.1.0-rc.7(6fcdcafdc6a942dddc20da358d69b413)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-title': 0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-session-title@0.1.0-rc.7(54a387d0d580a07b8dbef208df0b04c2)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + + '@deepseek-ai/dsh-settings-file@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-atomic-write@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-atomic-write': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/schemastery': 3.18.1 + chokidar: 4.0.3 + yaml: 2.9.0 + + '@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-shell-env@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + + ? '@deepseek-ai/dsh-skill-badge@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-skill@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))' + : dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-skill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + + '@deepseek-ai/dsh-skill-filesystem@0.1.0-rc.7(cea9f3527f4d5c630f6db1120eda1b51)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-skill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + chokidar: 5.0.0 + yaml: 2.9.0 + + '@deepseek-ai/dsh-skill@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-spill-local@0.1.0-rc.7(fa23de144536b578bc3d547e7122cf66)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-spill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-spill-policy@0.1.0-rc.7(a25502e01591be81db4b639e945e283f)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-output-retention': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-spill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-spill@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + '@deepseek-ai/dsh-storage-domain@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-storage': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-storage-json@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-storage': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-subagent-fork-in-process@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-subagent-in-process-driver@0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-subagent-in-process-driver': 0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-subagent-in-process-driver@0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + + '@deepseek-ai/dsh-subagent-spawn-in-process@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-subagent-in-process-driver@0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-subagent-in-process-driver': 0.1.0-rc.7(89bd93a5134bf339611454c0aa5ecf19) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + zod: 4.4.3 + optionalDependencies: + '@deepseek-ai/dsh-agent-presets': 0.1.0-rc.7(c0f9f44edab94cddae92cd4b4f319bab) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-projection-cache': 0.1.0-rc.7(5ae699d01eec9f3ccaa1e8c13f88dd36) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + + '@deepseek-ai/dsh-subprocess-local@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + node-pty: 1.2.0-beta.15 + + '@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-system-prompt@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-terminal-bash@0.1.0-rc.7(7aaa5987c1b1e28d6b4d7d8b7331d572)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-terminal': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-terminal@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-time-context@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-tmux-context@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-token-meter@0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-compaction': 0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-tool-ask-user@0.1.0-rc.7(05bf1b7f9211140e40ee17108b703815)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-user-questions': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + + '@deepseek-ai/dsh-tool-bash-persistent@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-terminal@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-terminal': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-bash@0.1.0-rc.7(e6524a4741ca5f7a041a012548fcf420)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/dsh-shell-env': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-call-timeout-policy@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + + '@deepseek-ai/dsh-tool-cordis@0.1.0-rc.7(95cde96399f26bc61668514b17303d00)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-cordis-host-runner': 0.1.0-rc.7(2a80d56ba6af58ca8075e00e0fa2157b) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + + '@deepseek-ai/dsh-tool-fs-search@0.1.0-rc.7(b32686f6bdfad4e2bac19ddddae90f15)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-output-retention': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-spill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-subprocess': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-timeout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + '@vscode/ripgrep': 1.18.0 + + '@deepseek-ai/dsh-tool-fs@0.1.0-rc.7(e7d989b5e5a4423849aa5d8248287fa2)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-attachment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/schemastery': 3.18.1 + diff: 9.0.0 + + '@deepseek-ai/dsh-tool-goal@0.1.0-rc.7(180e0f3f329d9b10860ecf7e00313277)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-jobs@0.1.0-rc.7(9946e50f0ee52458165c230dc9c7c6b5)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-output-retention': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-pwsh@0.1.0-rc.7(e6524a4741ca5f7a041a012548fcf420)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-shell': 0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61) + '@deepseek-ai/dsh-shell-env': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-ralph@0.1.0-rc.7(bab3281304625d6d534bd32fe485cf79)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-workflow': 0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-skill@0.1.0-rc.7(df0d23800fad5b2ada25025e060bda44)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-skill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-str-replace-editor@0.1.0-rc.7(3bd2fa864f678fb2dc668eb7729286c2)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-fs': 0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-sandbox': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-sandbox-policy': 0.1.0-rc.7(3ced98780dcdd5e8fdc23c5292f54483) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-subagent-control@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + + '@deepseek-ai/dsh-tool-subagent-report@0.1.0-rc.7(640d921ae2b98078971463f9056a34f9)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-subagent@0.1.0-rc.7(1222888b06fba7e9c8bcaa54a558d14e)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tool-todo@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-projection@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/schemastery': 3.18.1 + zod: 4.4.3 + + '@deepseek-ai/dsh-tool-web@0.1.0-rc.7(a1e227eab3db3d5fdb80246cd440578f)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-web': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + '@deepseek-ai/schemastery': 3.18.1 + '@joplin/turndown-plugin-gfm': 1.0.67 + turndown: 7.2.4 + + '@deepseek-ai/dsh-tool-workflow@0.1.0-rc.7(568ef6a59b3c44062c8cbf5cb759c397)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-workflow': 0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-code-runtime': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-user-approval': 0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-typert-loader@0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-registry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-typert-registry': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + + '@deepseek-ai/dsh-typert-registry@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-typert-protocol': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + zod: 4.4.3 + + '@deepseek-ai/dsh-user-approval@0.1.0-rc.7(6b8cefd624fd84694a941b103cc9b3fb)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-scope': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-user-questions@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + + '@deepseek-ai/dsh-web-app@0.1.0-rc.7(765dc4dc19fa92e19d2eb0b0853433c5)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/dsh-agent-presets': 0.1.0-rc.7(c0f9f44edab94cddae92cd4b4f319bab) + '@deepseek-ai/dsh-api-remotes': 0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c) + '@deepseek-ai/dsh-app-boot': 0.1.0-rc.7(aad8c687644ca696866ebd36b8ea50bc) + '@deepseek-ai/dsh-client-connection': 0.1.0-rc.7(2f10e3fb58d0d825de6c330674be43fd) + '@deepseek-ai/dsh-client-hmr': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-host-webserver@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-locale': 0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679) + '@deepseek-ai/dsh-client-modules': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-runtime': 0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85) + '@deepseek-ai/dsh-client-ui-agent-preset': 0.1.0-rc.7(af1f0dfda1b313f0e26ca09e9ae27396) + '@deepseek-ai/dsh-client-ui-commands': 0.1.0-rc.7(26504d5ecc5244ba7b677378b7933298) + '@deepseek-ai/dsh-client-ui-conversation': 0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4) + '@deepseek-ai/dsh-client-ui-cordis': 0.1.0-rc.7(bf687ae130e22673b950361a807ff16c) + '@deepseek-ai/dsh-client-ui-deliverables': 0.1.0-rc.7(7249ff3b991002071e4561a99f8ee1c2) + '@deepseek-ai/dsh-client-ui-directory-picker-browse': 0.1.0-rc.7(0dfe4bda28d14a5dd77b4a591646a18c) + '@deepseek-ai/dsh-client-ui-directory-picker-native': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-workspace@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-goal': 0.1.0-rc.7(c21ab1c36a0529cde1094ac4152e8cd0) + '@deepseek-ai/dsh-client-ui-input-trigger': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-jobs': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-client-ui-layout': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-message-feedback': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-message-feedback@0.1.0-rc.7(1fcfefbbf5e365eda1a59fadd94056b9))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-model-selection': 0.1.0-rc.7(fa7dfd679b06b363d46ed7789b85ff86) + '@deepseek-ai/dsh-client-ui-permission-presets': 0.1.0-rc.7(2d26805daefd8bdf9333cc6c10b78030) + '@deepseek-ai/dsh-client-ui-plan': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-plan-mode@0.1.0-rc.7(3abfc5979880a1c8e6bc377abfd69758))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-settings-general': 0.1.0-rc.7(7752585f0696b00bd95e546fb67ff66a) + '@deepseek-ai/dsh-client-ui-settings-models': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-schema-form@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-web-react@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-settings-plugin-inventory': 0.1.0-rc.7(cb962c4a2902db0fad3b93b45cd71c01) + '@deepseek-ai/dsh-client-ui-settings-plugins': 0.1.0-rc.7(003ac2d7911288fd946bd49107ea2822) + '@deepseek-ai/dsh-client-ui-sidebar': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-skill': 0.1.0-rc.7(152d1dcbb4454c394fd2bfff1b3ae10c) + '@deepseek-ai/dsh-client-ui-subagent': 0.1.0-rc.7(94207603c9ef3302f528dc84d74863b2) + '@deepseek-ai/dsh-client-ui-theme': 0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e) + '@deepseek-ai/dsh-client-ui-tool': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-trajectory': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@deepseek-ai/dsh-client-ui-user-questions': 0.1.0-rc.7(513da2308aa1aecd90c9e1b8fef56d3a) + '@deepseek-ai/dsh-client-ui-workflow-run': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-conversation@0.1.0-rc.7(fd775f3083faf8bf5133e7ef9e123cf4))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-tool-workflow@0.1.0-rc.7(568ef6a59b3c44062c8cbf5cb759c397))(@deepseek-ai/dsh-workflow@0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd)) + '@deepseek-ai/dsh-client-ui-workspace': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-client-locale@0.1.0-rc.7(d5ed58671774be2ef4d28a8c0a3e0679))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-primitives@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-cmdline': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-code-runtime-worker-thread': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-code-runtime@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-cordis-client-runner': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-cordis-host-runner': 0.1.0-rc.7(2a80d56ba6af58ca8075e00e0fa2157b) + '@deepseek-ai/dsh-host-apiproxy': 0.1.0-rc.7(20514f3a3e01200624daa2ce81cb702e) + '@deepseek-ai/dsh-host-directory-picker-auto': 0.1.0-rc.7(da3caeaacbe519905d0ce88b6e588026) + '@deepseek-ai/dsh-host-directory-picker-browse': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-directory-picker-native': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-frontend-static': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-host-webserver@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-host-plugin-inventory': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-host-webserver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-message-feedback': 0.1.0-rc.7(1fcfefbbf5e365eda1a59fadd94056b9) + '@deepseek-ai/dsh-session-log-export': 0.1.0-rc.7(f26d44b13c483ceafe59cc97fd2e3a49) + '@deepseek-ai/dsh-session-projection-cache': 0.1.0-rc.7(5ae699d01eec9f3ccaa1e8c13f88dd36) + '@deepseek-ai/dsh-session-stats': 0.1.0-rc.7(162e09a00c830c72cf271bc0dbd64697) + '@deepseek-ai/dsh-shell-env': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-home-paths@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-persistence@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-storage': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-storage-domain': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-storage-json': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-system-prompt': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-web-frontend': 0.1.0-rc.7(b1b4c4d8e767964f8435b704957716b7) + '@deepseek-ai/dsh-workspace': 0.1.0-rc.7(52d55750df813bb508c3c8815dfcc2bd) + '@deepseek-ai/schemastery': 3.18.1 + commander: 15.0.0 + transitivePeerDependencies: + - '@deepseek-ai/cordis-plugin-group' + - '@deepseek-ai/cordis-plugin-hmr' + - '@deepseek-ai/cordis-plugin-include' + - '@deepseek-ai/dsh-agent' + - '@deepseek-ai/dsh-api-gateway' + - '@deepseek-ai/dsh-atomic-write' + - '@deepseek-ai/dsh-attachment' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-client-schema-form' + - '@deepseek-ai/dsh-client-ui-attachment' + - '@deepseek-ai/dsh-client-ui-primitives' + - '@deepseek-ai/dsh-client-ui-slots' + - '@deepseek-ai/dsh-client-web-react' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-commands' + - '@deepseek-ai/dsh-compaction' + - '@deepseek-ai/dsh-credentials' + - '@deepseek-ai/dsh-goal' + - '@deepseek-ai/dsh-home-paths' + - '@deepseek-ai/dsh-launch-environment' + - '@deepseek-ai/dsh-llm' + - '@deepseek-ai/dsh-llm-retry' + - '@deepseek-ai/dsh-permission-presets' + - '@deepseek-ai/dsh-plan-mode' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-sandbox-policy' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-session' + - '@deepseek-ai/dsh-session-persistence' + - '@deepseek-ai/dsh-session-projection' + - '@deepseek-ai/dsh-settings' + - '@deepseek-ai/dsh-subagent' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-token-meter' + - '@deepseek-ai/dsh-tool-workflow' + - '@deepseek-ai/dsh-tools' + - '@deepseek-ai/dsh-typert-protocol' + - '@deepseek-ai/dsh-typert-registry' + - '@deepseek-ai/dsh-user-approval' + - '@deepseek-ai/dsh-workflow' + - '@types/react' + - bufferutil + - clsx + - react + - react-dom + - supports-color + - utf-8-validate + + '@deepseek-ai/dsh-web-frontend@0.1.0-rc.7(b1b4c4d8e767964f8435b704957716b7)': + dependencies: + '@deepseek-ai/dsh-client-web': 0.1.0-rc.7(b1b4c4d8e767964f8435b704957716b7) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@deepseek-ai/cordis' + - '@deepseek-ai/cordis-plugin-loader' + - '@deepseek-ai/dsh-api-remotes' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-client-connection' + - '@deepseek-ai/dsh-client-locale' + - '@deepseek-ai/dsh-client-runtime' + - '@deepseek-ai/dsh-client-ui-settings' + - '@deepseek-ai/dsh-host-webserver' + - '@deepseek-ai/dsh-invariants' + - supports-color + + '@deepseek-ai/dsh-web-search-deepseek@0.1.0-rc.7(682f945d61f3362c5b4bd1233bf7a050)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-credentials': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-launch-environment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-settings': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1) + '@deepseek-ai/dsh-web': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-web@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-workflow-worker-thread@0.1.0-rc.7(6ad95a742535dff29ed317a2fc297623)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-subagent': 0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da) + '@deepseek-ai/dsh-tools': 0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa) + '@deepseek-ai/dsh-workflow': 0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd) + '@deepseek-ai/schemastery': 3.18.1 + + '@deepseek-ai/dsh-workflow@0.1.0-rc.7(1238b6f54f01b13da1636d404c6902fd)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-agent': 0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-llm': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + + '@deepseek-ai/dsh-workspace@0.1.0-rc.7(52d55750df813bb508c3c8815dfcc2bd)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/dsh-brand': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-invariants': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-session': 0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346) + '@deepseek-ai/dsh-session-persistence': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-storage': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-storage-domain': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-storage@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + zod: 4.4.3 + + '@deepseek-ai/dsh@0.1.0-rc.7(1028bc4c4765246571adba5ae8d2d1c8)': + dependencies: + '@deepseek-ai/cordis': 4.0.1(@deepseek-ai/cordis-plugin-include@1.0.6)(@deepseek-ai/cordis-plugin-loader@1.0.2) + '@deepseek-ai/cordis-plugin-hmr': 1.0.16(@deepseek-ai/cordis-plugin-timer@1.1.3(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-include': 1.0.6(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/cordis-plugin-loader': 1.0.2(@deepseek-ai/cordis@4.0.1)(node-addon-require-builtin@0.1.5) + '@deepseek-ai/cordis-plugin-timer': 1.1.3(@deepseek-ai/cordis@4.0.1) + '@deepseek-ai/dsh-agent-instructions': 0.1.0-rc.7(93b00e8961a24ed58236184dea3d0e10) + '@deepseek-ai/dsh-agent-tool-presentation': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-app-boot': 0.1.0-rc.7(aad8c687644ca696866ebd36b8ea50bc) + '@deepseek-ai/dsh-base': 0.1.0-rc.7(4c88fd6b241c39b2a20aa507ebfa0e9c) + '@deepseek-ai/dsh-client-ui-agent-preset': 0.1.0-rc.7(af1f0dfda1b313f0e26ca09e9ae27396) + '@deepseek-ai/dsh-client-ui-cordis': 0.1.0-rc.7(bf687ae130e22673b950361a807ff16c) + '@deepseek-ai/dsh-cmdline': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-command-compact': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-command-goal': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-commands@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-typert-protocol@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-compaction-basic': 0.1.0-rc.7(f519e9ab3c16060968f3852a830521b6) + '@deepseek-ai/dsh-compaction-tool-result-pruner': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-compaction@0.1.0-rc.7(ac3d6d77b7cdaaa87ab91cb7b4cb6c97))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-token-meter@0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09)) + '@deepseek-ai/dsh-cordis-client-runner': 0.1.0-rc.7(@deepseek-ai/cordis-plugin-loader@1.0.2)(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-api-remotes@0.1.0-rc.7(022498c733cc9b813e36f108b907ce4c))(@deepseek-ai/dsh-client-connection@0.1.0-rc.7)(@deepseek-ai/dsh-client-modules@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-runtime@0.1.0-rc.7(8a84e42bf6f6b8dcb824fa2fc1444c85))(@deepseek-ai/dsh-client-ui-slots@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-client-ui-theme@0.1.0-rc.7(f4690dc977647c841a3c8df9644ee70e))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(react@18.3.1) + '@deepseek-ai/dsh-fs-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-fs@0.1.0-rc.7(7991753c264b1d907549a3df5a6ef9ed))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-goal': 0.1.0-rc.7(9616cea51a4bea931c5522310292a042) + '@deepseek-ai/dsh-goal-round-driver': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-goal@0.1.0-rc.7(9616cea51a4bea931c5522310292a042))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-headless': 0.1.0-rc.7(85cf737328c42864c624534435ec3820) + '@deepseek-ai/dsh-home-paths': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-jobs-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-jobs@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-launch-environment': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-mcp-client': 0.1.0-rc.7(8a97403e980dbcaa31e3631c5bdae10e) + '@deepseek-ai/dsh-persona': 0.1.0-rc.7(cd103793887a77cfa11721505870efe9) + '@deepseek-ai/dsh-plan-mode': 0.1.0-rc.7(3abfc5979880a1c8e6bc377abfd69758) + '@deepseek-ai/dsh-pwsh-local': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-settings@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/schemastery@3.18.1))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61))(@deepseek-ai/dsh-subprocess@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-pwsh-sandbox': 0.1.0-rc.7(01b43dee0e175c8dd5e3a7e6517088bf) + '@deepseek-ai/dsh-schedule': 0.1.0-rc.7(2a787269d0a16d51cbe6213bebf2cad4) + '@deepseek-ai/dsh-session-projection': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-session-reference': 0.1.0-rc.7(fe3daefbd216dec211872eab9ee75662) + '@deepseek-ai/dsh-skill': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-scope@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))) + '@deepseek-ai/dsh-skill-filesystem': 0.1.0-rc.7(cea9f3527f4d5c630f6db1120eda1b51) + '@deepseek-ai/dsh-terminal': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)) + '@deepseek-ai/dsh-terminal-bash': 0.1.0-rc.7(7aaa5987c1b1e28d6b4d7d8b7331d572) + '@deepseek-ai/dsh-time-context': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)) + '@deepseek-ai/dsh-tmux-context': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-shell@0.1.0-rc.7(d3f5c9e8227ec47baf7983a7b3f12a61)) + '@deepseek-ai/dsh-token-meter': 0.1.0-rc.7(2fa39e651d6b4d00840b5133c167cc09) + '@deepseek-ai/dsh-tool-ask-user': 0.1.0-rc.7(05bf1b7f9211140e40ee17108b703815) + '@deepseek-ai/dsh-tool-bash': 0.1.0-rc.7(e6524a4741ca5f7a041a012548fcf420) + '@deepseek-ai/dsh-tool-bash-persistent': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-terminal@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-tool-cordis': 0.1.0-rc.7(95cde96399f26bc61668514b17303d00) + '@deepseek-ai/dsh-tool-fs': 0.1.0-rc.7(e7d989b5e5a4423849aa5d8248287fa2) + '@deepseek-ai/dsh-tool-fs-search': 0.1.0-rc.7(b32686f6bdfad4e2bac19ddddae90f15) + '@deepseek-ai/dsh-tool-goal': 0.1.0-rc.7(180e0f3f329d9b10860ecf7e00313277) + '@deepseek-ai/dsh-tool-jobs': 0.1.0-rc.7(9946e50f0ee52458165c230dc9c7c6b5) + '@deepseek-ai/dsh-tool-pwsh': 0.1.0-rc.7(e6524a4741ca5f7a041a012548fcf420) + '@deepseek-ai/dsh-tool-ralph': 0.1.0-rc.7(bab3281304625d6d534bd32fe485cf79) + '@deepseek-ai/dsh-tool-skill': 0.1.0-rc.7(df0d23800fad5b2ada25025e060bda44) + '@deepseek-ai/dsh-tool-str-replace-editor': 0.1.0-rc.7(3bd2fa864f678fb2dc668eb7729286c2) + '@deepseek-ai/dsh-tool-subagent': 0.1.0-rc.7(1222888b06fba7e9c8bcaa54a558d14e) + '@deepseek-ai/dsh-tool-subagent-control': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-llm@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-attachment@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-brand@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-timeout@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-subagent@0.1.0-rc.7(ff6197eb44fe7f35d2672b0aeeb186da))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-tool-todo': 0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-agent@0.1.0-rc.7(1e28fca6adb316c000fd361f8e5f3a08))(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session-projection@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1)(@deepseek-ai/dsh-invariants@0.1.0-rc.7(@deepseek-ai/cordis@4.0.1))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346)))(@deepseek-ai/dsh-session@0.1.0-rc.7(1dcde9bfc9fa0140c66648fbcb67b346))(@deepseek-ai/dsh-tools@0.1.0-rc.7(38c91eb2d47c5b4ba2c8ead86dfcb4aa)) + '@deepseek-ai/dsh-tool-web': 0.1.0-rc.7(a1e227eab3db3d5fdb80246cd440578f) + '@deepseek-ai/dsh-tool-workflow': 0.1.0-rc.7(568ef6a59b3c44062c8cbf5cb759c397) + '@deepseek-ai/dsh-web-app': 0.1.0-rc.7(765dc4dc19fa92e19d2eb0b0853433c5) + '@deepseek-ai/dsh-workflow-worker-thread': 0.1.0-rc.7(6ad95a742535dff29ed317a2fc297623) + commander: 15.0.0 + js-yaml: 4.3.1 + node-addon-require-builtin: 0.1.5 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@deepseek-ai/cordis-plugin-group' + - '@deepseek-ai/dsh-agent' + - '@deepseek-ai/dsh-agent-default-model' + - '@deepseek-ai/dsh-agent-presets' + - '@deepseek-ai/dsh-anonymous-user-id' + - '@deepseek-ai/dsh-api-gateway' + - '@deepseek-ai/dsh-api-remotes' + - '@deepseek-ai/dsh-atomic-write' + - '@deepseek-ai/dsh-attachment' + - '@deepseek-ai/dsh-bash-local' + - '@deepseek-ai/dsh-brand' + - '@deepseek-ai/dsh-client-connection' + - '@deepseek-ai/dsh-client-locale' + - '@deepseek-ai/dsh-client-modules' + - '@deepseek-ai/dsh-client-runtime' + - '@deepseek-ai/dsh-client-schema-form' + - '@deepseek-ai/dsh-client-ui-attachment' + - '@deepseek-ai/dsh-client-ui-conversation' + - '@deepseek-ai/dsh-client-ui-input-trigger' + - '@deepseek-ai/dsh-client-ui-primitives' + - '@deepseek-ai/dsh-client-ui-settings' + - '@deepseek-ai/dsh-client-ui-sidebar' + - '@deepseek-ai/dsh-client-ui-slots' + - '@deepseek-ai/dsh-client-ui-theme' + - '@deepseek-ai/dsh-client-ui-tool' + - '@deepseek-ai/dsh-client-web-react' + - '@deepseek-ai/dsh-code-runtime' + - '@deepseek-ai/dsh-commands' + - '@deepseek-ai/dsh-compaction' + - '@deepseek-ai/dsh-cordis-host-runner' + - '@deepseek-ai/dsh-credentials' + - '@deepseek-ai/dsh-fs' + - '@deepseek-ai/dsh-invariants' + - '@deepseek-ai/dsh-jobs' + - '@deepseek-ai/dsh-llm' + - '@deepseek-ai/dsh-llm-retry' + - '@deepseek-ai/dsh-output-retention' + - '@deepseek-ai/dsh-permission-presets' + - '@deepseek-ai/dsh-sandbox' + - '@deepseek-ai/dsh-sandbox-policy' + - '@deepseek-ai/dsh-scope' + - '@deepseek-ai/dsh-session' + - '@deepseek-ai/dsh-session-persistence' + - '@deepseek-ai/dsh-session-projection-cache' + - '@deepseek-ai/dsh-session-query' + - '@deepseek-ai/dsh-session-telemetry' + - '@deepseek-ai/dsh-session-title-llm' + - '@deepseek-ai/dsh-settings' + - '@deepseek-ai/dsh-shell' + - '@deepseek-ai/dsh-shell-env' + - '@deepseek-ai/dsh-spill' + - '@deepseek-ai/dsh-subagent' + - '@deepseek-ai/dsh-subagent-in-process-driver' + - '@deepseek-ai/dsh-subprocess' + - '@deepseek-ai/dsh-system-prompt' + - '@deepseek-ai/dsh-timeout' + - '@deepseek-ai/dsh-tools' + - '@deepseek-ai/dsh-typert-protocol' + - '@deepseek-ai/dsh-typert-registry' + - '@deepseek-ai/dsh-user-approval' + - '@deepseek-ai/dsh-user-questions' + - '@deepseek-ai/dsh-web' + - '@deepseek-ai/dsh-workflow' + - '@modelcontextprotocol/sdk' + - '@types/node' + - '@types/react' + - bufferutil + - clsx + - react + - react-dom + - supports-color + - utf-8-validate + - ws + - zod + + '@deepseek-ai/node-addon-landlock-run-linux-arm64@0.1.1': + optional: true + + '@deepseek-ai/node-addon-landlock-run-linux-x64@0.1.1': + optional: true + + '@deepseek-ai/node-addon-landlock-run@0.1.1': + optionalDependencies: + '@deepseek-ai/node-addon-landlock-run-linux-arm64': 0.1.1 + '@deepseek-ai/node-addon-landlock-run-linux-x64': 0.1.1 + + '@deepseek-ai/schemastery@3.18.1': + dependencies: + '@deepseek-ai/cosmokit': 1.8.2 + '@standard-schema/spec': 1.1.0 + + '@earendil-works/pi-ai@0.82.1(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': + dependencies: + '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) + '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3)) + '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0) + '@opentelemetry/api': 1.9.0 + '@smithy/node-http-handler': 4.7.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + openai: 6.26.0(ws@8.21.3)(zod@4.4.3) + partial-json: 0.1.7 + typebox: 1.1.38 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@google/genai@1.52.0(@modelcontextprotocol/sdk@1.30.0(zod@4.4.3))': + dependencies: + google-auth-library: 10.9.1 + p-retry: 4.6.2 + protobufjs: 7.6.5 + ws: 8.21.3 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.30.0(zod@4.4.3) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@hono/node-server@2.1.0(hono@4.13.2)': + dependencies: + hono: 4.13.2 + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.2 + optional: true + + '@img/sharp-darwin-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.2 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.2': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.2': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.2': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + optional: true + + '@img/sharp-linux-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.2 + optional: true + + '@img/sharp-linux-arm@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.2 + optional: true + + '@img/sharp-linux-ppc64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.2 + optional: true + + '@img/sharp-linux-riscv64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.2 + optional: true + + '@img/sharp-linux-s390x@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.2 + optional: true + + '@img/sharp-linux-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.2 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + optional: true + + '@img/sharp-wasm32@0.35.3': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + + '@img/sharp-win32-arm64@0.35.3': + optional: true + + '@img/sharp-win32-ia32@0.35.3': + optional: true + + '@img/sharp-win32-x64@0.35.3': + optional: true + + '@joplin/turndown-plugin-gfm@1.0.67': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@koromix/koffi-darwin-arm64@3.1.5': + optional: true + + '@koromix/koffi-darwin-x64@3.1.5': + optional: true + + '@koromix/koffi-freebsd-arm64@3.1.5': + optional: true + + '@koromix/koffi-freebsd-ia32@3.1.5': + optional: true + + '@koromix/koffi-freebsd-x64@3.1.5': + optional: true + + '@koromix/koffi-linux-arm64@3.1.5': + optional: true + + '@koromix/koffi-linux-ia32@3.1.5': + optional: true + + '@koromix/koffi-linux-loong64@3.1.5': + optional: true + + '@koromix/koffi-linux-riscv64@3.1.5': + optional: true + + '@koromix/koffi-linux-x64@3.1.5': + optional: true + + '@koromix/koffi-openbsd-ia32@3.1.5': + optional: true + + '@koromix/koffi-openbsd-x64@3.1.5': + optional: true + + '@koromix/koffi-win32-arm64@3.1.5': + optional: true + + '@koromix/koffi-win32-ia32@3.1.5': + optional: true + + '@koromix/koffi-win32-x64@3.1.5': + optional: true + + '@mistralai/mistralai@2.2.6(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/semantic-conventions': 1.43.0 + ws: 8.21.3 + zod: 4.4.3 + zod-to-json-schema: 3.25.2(zod@4.4.3) + optionalDependencies: + '@opentelemetry/api': 1.9.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@mixmark-io/domino@2.2.0': {} + + '@modelcontextprotocol/sdk@1.30.0(zod@4.4.3)': + dependencies: + '@hono/node-server': 2.1.0(hono@4.13.2) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + express: 5.2.1 + express-rate-limit: 8.6.2(express@5.2.1) + hono: 4.13.2 + jose: 6.2.9 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.4.3 + zod-to-json-schema: 3.25.2(zod@4.4.3) + transitivePeerDependencies: + - supports-color + + '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@opentelemetry/api-logs@0.220.0': + dependencies: + '@opentelemetry/api': 1.9.1 + + '@opentelemetry/api@1.9.0': {} + + '@opentelemetry/api@1.9.1': {} + + '@opentelemetry/core@2.10.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.43.0 + + '@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.43.0 + + '@opentelemetry/exporter-logs-otlp-http@0.220.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.220.0 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.220.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.220.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.220.0(@opentelemetry/api@1.9.1) + + '@opentelemetry/otlp-exporter-base@0.220.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.220.0(@opentelemetry/api@1.9.1) + + '@opentelemetry/otlp-transformer@0.220.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.220.0 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.220.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-metrics': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace': 2.9.0(@opentelemetry/api@1.9.1) + + '@opentelemetry/resources@2.10.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.10.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.43.0 + + '@opentelemetry/resources@2.9.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.43.0 + + '@opentelemetry/sdk-logs@0.220.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.220.0 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.43.0 + + '@opentelemetry/sdk-metrics@2.9.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1) + + '@opentelemetry/sdk-trace@2.9.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.43.0 + + '@opentelemetry/semantic-conventions@1.43.0': {} + + '@oxc-project/types@0.139.0': {} + + '@oxc-project/types@0.144.0': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.1': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.2': {} + + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + + '@rolldown/binding-android-arm64@1.1.5': + optional: true + + '@rolldown/binding-android-arm64@1.2.4': + optional: true + + '@rolldown/binding-darwin-arm64@1.1.5': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.4': + optional: true + + '@rolldown/binding-darwin-x64@1.1.5': + optional: true + + '@rolldown/binding-darwin-x64@1.2.4': + optional: true + + '@rolldown/binding-freebsd-x64@1.1.5': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.4': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.4': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.4': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.1.5': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.4': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.4': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.4': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.4': + optional: true + + '@rolldown/binding-linux-x64-musl@1.1.5': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.4': + optional: true + + '@rolldown/binding-openharmony-arm64@1.1.5': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.4': + optional: true + + '@rolldown/binding-wasm32-wasi@1.1.5': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.4': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.5': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.4': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@shikijs/core@4.4.3': + dependencies: + '@shikijs/primitive': 4.4.3 + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + + '@shikijs/primitive@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/themes@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + + '@shikijs/types@4.4.3': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@smithy/core@3.33.2': + dependencies: + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.5.2': + dependencies: + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.7.2': + dependencies: + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/node-http-handler@4.11.2': + dependencies: + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.7.3': + dependencies: + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@smithy/signature-v4@5.7.2': + dependencies: + '@smithy/core': 3.33.2 + '@smithy/types': 4.17.2 + tslib: 2.8.1 + + '@smithy/types@4.17.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + + '@standard-schema/spec@1.1.0': {} + + '@tanstack/react-virtual@3.14.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/virtual-core': 3.17.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/virtual-core@3.17.7': {} + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.9': {} + + '@types/hast@3.0.5': + dependencies: + '@types/unist': 3.0.3 + + '@types/jsesc@2.5.1': {} + + '@types/katex@0.16.8': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/node@22.20.1': + dependencies: + undici-types: 6.21.0 + + '@types/retry@0.12.0': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.3': {} + + '@vitest/expect@4.1.10': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + chai: 6.2.2 + tinyrainbow: 3.1.1 + + '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.2.1(@types/node@22.20.1)(yaml@2.9.0) + + '@vitest/pretty-format@4.1.10': + dependencies: + tinyrainbow: 3.1.1 + + '@vitest/runner@4.1.10': + dependencies: + '@vitest/utils': 4.1.10 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.10': {} + + '@vitest/utils@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.1 + + '@vscode/ripgrep-darwin-arm64@1.18.0': + optional: true + + '@vscode/ripgrep-darwin-x64@1.18.0': + optional: true + + '@vscode/ripgrep-linux-arm64@1.18.0': + optional: true + + '@vscode/ripgrep-linux-arm@1.18.0': + optional: true + + '@vscode/ripgrep-linux-ia32@1.18.0': + optional: true + + '@vscode/ripgrep-linux-ppc64@1.18.0': + optional: true + + '@vscode/ripgrep-linux-riscv64@1.18.0': + optional: true + + '@vscode/ripgrep-linux-s390x@1.18.0': + optional: true + + '@vscode/ripgrep-linux-x64@1.18.0': + optional: true + + '@vscode/ripgrep-win32-arm64@1.18.0': + optional: true + + '@vscode/ripgrep-win32-ia32@1.18.0': + optional: true + + '@vscode/ripgrep-win32-x64@1.18.0': + optional: true + + '@vscode/ripgrep@1.18.0': + optionalDependencies: + '@vscode/ripgrep-darwin-arm64': 1.18.0 + '@vscode/ripgrep-darwin-x64': 1.18.0 + '@vscode/ripgrep-linux-arm': 1.18.0 + '@vscode/ripgrep-linux-arm64': 1.18.0 + '@vscode/ripgrep-linux-ia32': 1.18.0 + '@vscode/ripgrep-linux-ppc64': 1.18.0 + '@vscode/ripgrep-linux-riscv64': 1.18.0 + '@vscode/ripgrep-linux-s390x': 1.18.0 + '@vscode/ripgrep-linux-x64': 1.18.0 + '@vscode/ripgrep-win32-arm64': 1.18.0 + '@vscode/ripgrep-win32-ia32': 1.18.0 + '@vscode/ripgrep-win32-x64': 1.18.0 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + agent-base@7.1.4: {} + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.5 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + anser@2.3.5: {} + + ansis@4.3.1: {} + + argparse@2.0.1: {} + + assertion-error@2.0.1: {} + + ast-kit@3.0.0: + dependencies: + '@babel/parser': 8.0.4 + estree-walker: 3.0.3 + pathe: 2.0.3 + + base64-js@1.5.1: {} + + bignumber.js@9.3.1: {} + + birpc@4.1.0: {} + + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.15.3 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + bowser@2.14.1: {} + + buffer-equal-constant-time@1.0.1: {} + + bytes@3.1.2: {} + + cac@7.0.0: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + ccount@2.0.1: {} + + chai@6.2.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + clsx@2.1.1: {} + + comma-separated-tokens@2.0.3: {} + + commander@15.0.0: {} + + commander@8.3.0: {} + + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + content-type@2.1.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-uri-to-buffer@4.0.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + defu@6.1.7: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@9.0.0: {} + + dts-resolver@3.0.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + empathic@2.0.1: {} + + encodeurl@2.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.3.2: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + escape-html@1.0.3: {} + + escape-string-regexp@5.0.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + etag@1.8.1: {} + + eventsource-parser@3.1.1: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.1.1 + + expect-type@1.4.0: {} + + express-rate-limit@8.6.2(express@5.2.1): + dependencies: + debug: 4.4.3 + express: 5.2.1 + ip-address: 10.5.0 + transitivePeerDependencies: + - supports-color + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.3 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.5: {} + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + fflate@0.8.3: {} + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gaxios@7.3.1: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + node-fetch: 3.3.2 + transitivePeerDependencies: + - supports-color + + gcp-metadata@8.1.2: + dependencies: + gaxios: 7.3.1 + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + get-tsconfig@5.0.0-beta.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + google-auth-library@10.9.1: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.3.1 + gcp-metadata: 8.1.2 + google-logging-utils: 1.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-logging-utils@1.1.3: {} + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.5 + + hono@4.13.2: {} + + hookable@6.1.1: {} + + html-void-elements@3.0.0: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + + immer@10.2.0: {} + + import-without-cache@0.4.0: {} + + inherits@2.0.4: {} + + ip-address@10.5.0: {} + + ipaddr.js@1.9.1: {} + + is-promise@4.0.0: {} + + isexe@2.0.0: {} + + jose@6.2.9: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.29.7 + ts-algebra: 2.0.0 + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + katex@0.16.47: + dependencies: + commander: 8.3.0 + + koffi@3.1.5: + optionalDependencies: + '@koromix/koffi-darwin-arm64': 3.1.5 + '@koromix/koffi-darwin-x64': 3.1.5 + '@koromix/koffi-freebsd-arm64': 3.1.5 + '@koromix/koffi-freebsd-ia32': 3.1.5 + '@koromix/koffi-freebsd-x64': 3.1.5 + '@koromix/koffi-linux-arm64': 3.1.5 + '@koromix/koffi-linux-ia32': 3.1.5 + '@koromix/koffi-linux-loong64': 3.1.5 + '@koromix/koffi-linux-riscv64': 3.1.5 + '@koromix/koffi-linux-x64': 3.1.5 + '@koromix/koffi-openbsd-ia32': 3.1.5 + '@koromix/koffi-openbsd-x64': 3.1.5 + '@koromix/koffi-win32-arm64': 3.1.5 + '@koromix/koffi-win32-ia32': 3.1.5 + '@koromix/koffi-win32-x64': 3.1.5 + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + long@5.3.2: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.3 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + media-typer@1.1.1: {} + + merge-descriptors@2.0.0: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.47 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + ms@2.1.3: {} + + nanoid@3.3.18: {} + + negotiator@1.0.0: {} + + node-addon-api@7.1.1: {} + + node-addon-native-custom-loader@0.1.5: {} + + node-addon-require-builtin-darwin-arm64@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin-darwin-x64@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin-linux-arm64-gnu@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin-linux-x64-gnu@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin-win32-arm64-msvc@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin-win32-ia32-msvc@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin-win32-x64-msvc@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optional: true + + node-addon-require-builtin@0.1.5: + dependencies: + node-addon-native-custom-loader: 0.1.5 + optionalDependencies: + node-addon-require-builtin-darwin-arm64: 0.1.5 + node-addon-require-builtin-darwin-x64: 0.1.5 + node-addon-require-builtin-linux-arm64-gnu: 0.1.5 + node-addon-require-builtin-linux-x64-gnu: 0.1.5 + node-addon-require-builtin-win32-arm64-msvc: 0.1.5 + node-addon-require-builtin-win32-ia32-msvc: 0.1.5 + node-addon-require-builtin-win32-x64-msvc: 0.1.5 + + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-pty@1.2.0-beta.15: + dependencies: + node-addon-api: 7.1.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obug@2.1.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + + openai@6.26.0(ws@8.21.3)(zod@4.4.3): + optionalDependencies: + ws: 8.21.3 + zod: 4.4.3 + + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + + parseurl@1.3.3: {} + + partial-json@0.1.7: {} + + path-key@3.1.1: {} + + path-to-regexp@8.4.2: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.5: {} + + pkce-challenge@5.0.1: {} + + postcss@8.5.26: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + property-information@7.2.0: {} + + protobufjs@7.6.5: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.1 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.2 + '@types/node': 22.20.1 + long: 5.3.2 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.15.3: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + quansync@1.0.0: {} + + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + readdirp@4.1.2: {} + + readdirp@5.1.1: {} + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + require-from-string@2.0.2: {} + + resolve-pkg-maps@1.0.0: {} + + retry@0.13.1: {} + + rolldown-plugin-dts@0.25.2(rolldown@1.1.5)(typescript@6.0.3): + dependencies: + '@babel/generator': 8.0.0-rc.6 + '@babel/helper-validator-identifier': 8.0.0-rc.6 + '@babel/parser': 8.0.0-rc.6 + ast-kit: 3.0.0 + birpc: 4.1.0 + dts-resolver: 3.0.0 + get-tsconfig: 5.0.0-beta.5 + obug: 2.1.4 + rolldown: 1.1.5 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.1.5: + dependencies: + '@oxc-project/types': 0.139.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.5 + '@rolldown/binding-darwin-arm64': 1.1.5 + '@rolldown/binding-darwin-x64': 1.1.5 + '@rolldown/binding-freebsd-x64': 1.1.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 + '@rolldown/binding-linux-arm64-gnu': 1.1.5 + '@rolldown/binding-linux-arm64-musl': 1.1.5 + '@rolldown/binding-linux-ppc64-gnu': 1.1.5 + '@rolldown/binding-linux-s390x-gnu': 1.1.5 + '@rolldown/binding-linux-x64-gnu': 1.1.5 + '@rolldown/binding-linux-x64-musl': 1.1.5 + '@rolldown/binding-openharmony-arm64': 1.1.5 + '@rolldown/binding-wasm32-wasi': 1.1.5 + '@rolldown/binding-win32-arm64-msvc': 1.1.5 + '@rolldown/binding-win32-x64-msvc': 1.1.5 + + rolldown@1.2.4: + dependencies: + '@oxc-project/types': 0.144.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.2.4 + '@rolldown/binding-darwin-arm64': 1.2.4 + '@rolldown/binding-darwin-x64': 1.2.4 + '@rolldown/binding-freebsd-x64': 1.2.4 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.4 + '@rolldown/binding-linux-arm64-gnu': 1.2.4 + '@rolldown/binding-linux-arm64-musl': 1.2.4 + '@rolldown/binding-linux-ppc64-gnu': 1.2.4 + '@rolldown/binding-linux-s390x-gnu': 1.2.4 + '@rolldown/binding-linux-x64-gnu': 1.2.4 + '@rolldown/binding-linux-x64-musl': 1.2.4 + '@rolldown/binding-openharmony-arm64': 1.2.4 + '@rolldown/binding-win32-arm64-msvc': 1.2.4 + '@rolldown/binding-win32-x64-msvc': 1.2.4 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@7.8.5: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + sharp@0.35.3(@types/node@22.20.1): + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.3 + '@img/sharp-darwin-x64': 0.35.3 + '@img/sharp-freebsd-wasm32': 0.35.3 + '@img/sharp-libvips-darwin-arm64': 1.3.2 + '@img/sharp-libvips-darwin-x64': 1.3.2 + '@img/sharp-libvips-linux-arm': 1.3.2 + '@img/sharp-libvips-linux-arm64': 1.3.2 + '@img/sharp-libvips-linux-ppc64': 1.3.2 + '@img/sharp-libvips-linux-riscv64': 1.3.2 + '@img/sharp-libvips-linux-s390x': 1.3.2 + '@img/sharp-libvips-linux-x64': 1.3.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + '@img/sharp-linux-arm': 0.35.3 + '@img/sharp-linux-arm64': 0.35.3 + '@img/sharp-linux-ppc64': 0.35.3 + '@img/sharp-linux-riscv64': 0.35.3 + '@img/sharp-linux-s390x': 0.35.3 + '@img/sharp-linux-x64': 0.35.3 + '@img/sharp-linuxmusl-arm64': 0.35.3 + '@img/sharp-linuxmusl-x64': 0.35.3 + '@img/sharp-webcontainers-wasm32': 0.35.3 + '@img/sharp-win32-arm64': 0.35.3 + '@img/sharp-win32-ia32': 0.35.3 + '@img/sharp-win32-x64': 0.35.3 + '@types/node': 22.20.1 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@4.4.3: + dependencies: + '@shikijs/core': 4.4.3 + '@shikijs/engine-javascript': 4.4.3 + '@shikijs/engine-oniguruma': 4.4.3 + '@shikijs/langs': 4.4.3 + '@shikijs/themes': 4.4.3 + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@4.2.0: {} + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + tinybench@2.9.0: {} + + tinyexec@1.3.0: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + tinyrainbow@3.1.1: {} + + toidentifier@1.0.1: {} + + tree-kill@1.2.2: {} + + trim-lines@3.0.1: {} + + ts-algebra@2.0.0: {} + + tsdown@0.22.2(typescript@6.0.3): + dependencies: + ansis: 4.3.1 + cac: 7.0.0 + defu: 6.1.7 + empathic: 2.0.1 + hookable: 6.1.1 + import-without-cache: 0.4.0 + obug: 2.1.4 + picomatch: 4.0.5 + rolldown: 1.1.5 + rolldown-plugin-dts: 0.25.2(rolldown@1.1.5)(typescript@6.0.3) + semver: 7.8.5 + tinyexec: 1.3.0 + tinyglobby: 0.2.17 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - vue-tsc + + tslib@2.8.1: {} + + turndown@7.2.4: + dependencies: + '@mixmark-io/domino': 2.2.0 + + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + + typebox@1.1.38: {} + + typescript@6.0.3: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + undici-types@6.21.0: {} + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unpipe@1.0.0: {} + + use-sync-external-store@1.2.0(react@18.3.1): + dependencies: + react: 18.3.1 + + vary@1.1.2: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@8.2.1(@types/node@22.20.1)(yaml@2.9.0): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.5 + postcss: 8.5.26 + rolldown: 1.2.4 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 22.20.1 + fsevents: 2.3.3 + yaml: 2.9.0 + + vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@22.20.1)(vite@8.2.1(@types/node@22.20.1)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 0.30.21 + obug: 2.1.4 + pathe: 2.0.3 + picomatch: 4.0.5 + std-env: 4.2.0 + tinybench: 2.9.0 + tinyexec: 1.3.0 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.1 + vite: 8.2.1(@types/node@22.20.1)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/node': 22.20.1 + transitivePeerDependencies: + - msw + + web-streams-polyfill@3.3.3: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrappy@1.0.2: {} + + ws@8.21.3: {} + + yaml@2.9.0: {} + + zod-to-json-schema@3.25.2(zod@4.4.3): + dependencies: + zod: 4.4.3 + + zod@4.4.3: {} + + zustand@4.4.7(immer@10.2.0)(react@18.3.1): + dependencies: + use-sync-external-store: 1.2.0(react@18.3.1) + optionalDependencies: + immer: 10.2.0 + react: 18.3.1 + + zwitch@2.0.4: {} diff --git a/packages/dsh-loopx-plugin/scripts/build.mjs b/packages/dsh-loopx-plugin/scripts/build.mjs new file mode 100644 index 000000000..0e7f72707 --- /dev/null +++ b/packages/dsh-loopx-plugin/scripts/build.mjs @@ -0,0 +1,31 @@ +#!/usr/bin/env node + +import { spawnSync } from 'node:child_process' +import { rmSync } from 'node:fs' +import { createRequire } from 'node:module' +import { dirname, join, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..') +const require = createRequire(import.meta.url) +const typescriptRoot = dirname(require.resolve('typescript/package.json')) +const tsdownRoot = dirname(require.resolve('tsdown/package.json')) + +function run(modulePath, args) { + const result = spawnSync(process.execPath, [modulePath, ...args], { + cwd: packageRoot, + stdio: 'inherit', + shell: false, + }) + if (result.error) throw result.error + if (result.status !== 0) process.exit(result.status ?? 1) +} + +rmSync(join(packageRoot, 'lib'), { recursive: true, force: true }) +rmSync(join(packageRoot, 'build-temp'), { recursive: true, force: true }) +try { + run(join(typescriptRoot, 'bin', 'tsc'), ['-p', 'tsconfig.build.json']) + run(join(tsdownRoot, 'dist', 'run.mjs'), []) +} finally { + rmSync(join(packageRoot, 'build-temp'), { recursive: true, force: true }) +} diff --git a/packages/dsh-loopx-plugin/smoke/dsh-profile-smoke.mjs b/packages/dsh-loopx-plugin/smoke/dsh-profile-smoke.mjs new file mode 100644 index 000000000..50a09d97c --- /dev/null +++ b/packages/dsh-loopx-plugin/smoke/dsh-profile-smoke.mjs @@ -0,0 +1,447 @@ +#!/usr/bin/env node + +import assert from 'node:assert/strict' +import { spawnSync } from 'node:child_process' +import { chmod, mkdir, mkdtemp, readFile, realpath, rm, writeFile } from 'node:fs/promises' +import { createRequire } from 'node:module' +import { tmpdir } from 'node:os' +import { dirname, join, resolve } from 'node:path' +import { fileURLToPath, pathToFileURL } from 'node:url' + +const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..') +const dshBin = process.env.DSH_BIN || join(packageRoot, 'node_modules', '.bin', 'dsh') +const profileName = 'web' +const bundleRows = [ + ['loopx-service', 'dsh-loopx-plugin/service'], + ['loopx-command', 'dsh-loopx-plugin/command'], + ['loopx-tools', 'dsh-loopx-plugin/tools'], + ['loopx-driver', 'dsh-loopx-plugin/driver'], +] +const hostProvidedPeers = [ + '@deepseek-ai/cordis', + '@deepseek-ai/dsh-agent', + '@deepseek-ai/dsh-commands', + '@deepseek-ai/dsh-session', + '@deepseek-ai/dsh-tools', +] + +function parseSpecs(argv) { + const specs = [] + for (let index = 0; index < argv.length; index += 1) { + const flag = argv[index] + if (flag === '--') continue + if (flag !== '--package-path' && flag !== '--tarball') { + throw new Error(`unsupported argument: ${flag}`) + } + const value = argv[index + 1] + if (!value) throw new Error(`${flag} requires a path`) + specs.push({ kind: flag === '--tarball' ? 'tarball' : 'path', value: resolve(value) }) + index += 1 + } + if (specs.length === 0) throw new Error('pass --package-path and/or --tarball') + return specs +} + +function run(file, args, options = {}) { + const result = spawnSync(file, args, { + cwd: options.cwd ?? packageRoot, + env: options.env ?? process.env, + encoding: 'utf8', + maxBuffer: 8 * 1024 * 1024, + shell: false, + }) + if (result.error) throw result.error + if (result.status !== 0) { + throw new Error([ + `${file} ${args.join(' ')} failed with ${String(result.status)}`, + result.stdout, + result.stderr, + ].filter(Boolean).join('\n')) + } + return result.stdout +} + +function assertPackedFiles(tarball) { + const entries = run('tar', ['-tf', tarball]).trim().split('\n').filter(Boolean) + assert(entries.length > 0, 'tarball is empty') + for (const entry of entries) { + assert.match(entry, /^package\/(?:package\.json|README\.md|LICENSE|NOTICE|cordis\.patch\.yml|lib\/[^/]+\.js|lib\/types\/[^/]+\.d\.ts)$/u) + } + for (const required of [ + 'package/package.json', + 'package/README.md', + 'package/LICENSE', + 'package/NOTICE', + 'package/cordis.patch.yml', + 'package/lib/service.js', + 'package/lib/command.js', + 'package/lib/tools.js', + 'package/lib/driver.js', + 'package/lib/types/service.d.ts', + ]) { + assert(entries.includes(required), `tarball is missing ${required}`) + } + assert(!entries.includes('package/lib/binding.js'), 'obsolete sidecar runtime was packed') + assert(!entries.includes('package/lib/types/binding.d.ts'), 'obsolete sidecar declarations were packed') +} + +function assertInstalledConfig(dump) { + let previous = -1 + for (const [id, name] of bundleRows) { + const position = dump.indexOf(`id: ${id}`) + assert(position > previous, `missing or unordered bundle row ${id}`) + assert(dump.includes(`name: ${name}`), `missing bundle module ${name}`) + previous = position + } + assert.deepEqual( + [...dump.matchAll(/^\s*(?:-\s+)?id:\s+(loopx-[^\s]+)\s*$/gmu)].map(match => match[1]), + bundleRows.map(([id]) => id), + 'profile must contain exactly the four LoopX bundle rows', + ) + assert.deepEqual( + [...dump.matchAll(/^\s*(?:-\s+)?name:\s+(dsh-loopx-plugin\/[^\s]+)\s*$/gmu)].map(match => match[1]), + bundleRows.map(([, module]) => module), + 'profile must not expose a fifth dsh-loopx-plugin face', + ) + assert(!dump.includes('dsh.client: dsh-loopx-plugin'), 'v1 must not add a Client-plane row') +} + +const mockLoopXSource = String.raw`#!/usr/bin/env node +import { appendFile, readFile } from 'node:fs/promises' + +const args = process.argv.slice(2) +const modeFile = process.env.LOOPX_SMOKE_MODE +const callsFile = process.env.LOOPX_SMOKE_CALLS +const sentinel = process.env.LOOPX_SMOKE_SENTINEL +if (!modeFile || !callsFile || !sentinel) throw new Error('smoke environment is incomplete') +const value = flag => { + const index = args.indexOf(flag) + return index < 0 ? undefined : args[index + 1] +} +if (value('--format') !== 'json') throw new Error('JSON format is required') +const commands = new Set([ + 'resolve-agent-thread', 'status', 'bootstrap-command-pack', 'heartbeat-prompt', +]) +const command = args.find(arg => commands.has(arg)) +if (!command) throw new Error('unsupported smoke command') +await appendFile(callsFile, command + '\n') + +const mode = (await readFile(modeFile, 'utf8')).trim() +const goalId = value('--goal-id') ?? 'goal-smoke' +const agentId = value('--agent-id') ?? 'agent-smoke' +const threadId = value('--thread-id') ?? 'session-smoke' +const project = value('--project') ?? process.cwd() +const binding = { + schema_version: 'loopx_host_thread_binding_v1', + host_surface: 'dsh', + thread_id: threadId, + revision: 7, + state: 'bound', + target: { goal_id: goalId, agent_id: agentId }, +} + +let output +if (command === 'resolve-agent-thread') { + if (value('--host-surface') !== 'dsh') throw new Error('exact DSH Host surface is required') + output = mode === 'fail' + ? { + schema_version: 'loopx_host_thread_binding_command_v1', + ok: false, changed: false, application: 'no', + error_kind: 'authority_unhealthy', binding, + } + : { + schema_version: 'loopx_host_thread_binding_command_v1', + ok: true, changed: false, application: 'no', binding, + } +} else if (command === 'status') { + output = { + schema_version: 'loopx_status_v0', ok: true, goal_filter: goalId, + registry: sentinel, state_file: sentinel, raw_stderr: sentinel, trace: sentinel, + attention_queue: { + items: [{ + goal_id: goalId, status: 'active', waiting_on: sentinel, + severity: 'normal', lifecycle_phase: 'active', recommended_action: sentinel, + }], + }, + } +} else if (command === 'bootstrap-command-pack') { + output = { + schema_version: 'loopx_bootstrap_command_pack_v0', ok: true, read_only: true, + project, goal_id: goalId, agent_id: agentId, + agent_type: 'deepseek-harness-native', host_surface: 'dsh', thread_id: threadId, + host_thread_binding: binding, + host_loop_activation: { + schema_version: 'loopx_host_loop_activation_v1', + agent_type: 'deepseek-harness-native', goal_id: goalId, agent_id: agentId, + activation_allowed: true, + identity_contract: { + schema_version: 'loopx_host_loop_identity_selection_v0', + registered_agents: [agentId], + }, + identity_selection_gate: null, + host_surface: 'deepseek_harness_native_session', + activation_method: 'current_session_host_tool', + activation_input: { + schema_version: 'loopx_deepseek_harness_native_activation_input_v0', + tool: 'loopx_goal_activate', arguments: { goalId, agentId }, + }, + host_mutation: { + owner: 'DSH LoopX plugin', host_tool: 'loopx_goal_activate', + current_session_only: true, cli_can_mutate_directly: false, + forbidden_tool_arguments: ['sessionId', 'registryPath', 'taskBody', 'argv'], + }, + }, + } +} else { + output = { + schema_version: 'loopx_heartbeat_prompt_v0', ok: true, + goal_id: goalId, agent_id: agentId, runtime_profile: 'generic_cli', + task_body: 'Continue through fresh LoopX authority.', + } +} +process.stdout.write(JSON.stringify(output)) +if (output.ok === false) process.exitCode = 2 +` + +async function importFrom(requireFromPlugin, specifier) { + return import(pathToFileURL(requireFromPlugin.resolve(specifier)).href) +} + +function makeAgent(project) { + const nextTurn = [] + const nextStep = [] + const followups = [] + const steers = [] + let status = 'idle' + let maintenance = false + const session = { + id: 'session-smoke', + header: { version: 0, id: 'session-smoke', createdAt: 7, cwd: project, seedLength: 0 }, + events: [], + surface: { nodes: [] }, + } + const agent = { + id: 'session-smoke', + session, + get status() { return status }, + inbox: { + nextTurn, + nextStep, + get hasPending() { return nextTurn.length > 0 || nextStep.length > 0 }, + append(target, message) { + const queue = target === 'next-step' ? nextStep : nextTurn + queue.push(message) + }, + remove(id) { + for (const queue of [nextStep, nextTurn]) { + const position = queue.findIndex(message => message.id === id) + if (position >= 0) { + queue.splice(position, 1) + return true + } + } + return false + }, + }, + followup(message) { + followups.push(message) + nextTurn.push(message) + }, + steer(message) { steers.push(message) }, + send(message, target) { + const queue = target === 'next-step' ? nextStep : nextTurn + queue.push(message) + }, + runMaintenance(task) { + if (status === 'running' || maintenance) throw new Error('maintenance unavailable') + maintenance = true + const controller = new AbortController() + return Promise.resolve(task(controller.signal)).finally(() => { maintenance = false }) + }, + whenIdle() { return Promise.resolve() }, + cancel() { status = 'idle' }, + } + return { + agent, followups, steers, nextTurn, nextStep, + setStatus(value) { status = value }, + } +} + +async function exerciseInstalledPlugin(installedDir, home, mockLoopX, modeFile, callsFile) { + const requireFromPlugin = createRequire(join(installedDir, 'package.json')) + const [{ Context }, serviceModule, commandModule, toolsModule, driverModule] = await Promise.all([ + importFrom(requireFromPlugin, '@deepseek-ai/cordis'), + import(pathToFileURL(join(installedDir, 'lib', 'service.js')).href), + import(pathToFileURL(join(installedDir, 'lib', 'command.js')).href), + import(pathToFileURL(join(installedDir, 'lib', 'tools.js')).href), + import(pathToFileURL(join(installedDir, 'lib', 'driver.js')).href), + ]) + const project = join(home, 'behavior-project') + const runtimeRoot = join(home, 'runtime-root') + const sentinel = '/private/smoke/SECRET_TOKEN raw-stderr TRACE_ID' + await mkdir(project, { recursive: true }) + await mkdir(runtimeRoot, { recursive: true }) + const ctx = new Context() + await ctx.plugin(serviceModule.LoopXService, { + loopxBin: mockLoopX, + project, + runtimeRoot, + environment: { + LOOPX_SMOKE_MODE: modeFile, + LOOPX_SMOKE_CALLS: callsFile, + LOOPX_SMOKE_SENTINEL: sentinel, + }, + }) + assert.equal(ctx.get('goals'), undefined, 'ctx.loopx must not mount or consume ctx.goals') + const service = ctx.get('loopx') + assert(service, 'LoopX service did not activate without a storage-domain') + + const commands = new Map() + const tools = new Map() + commandModule.apply({ + loopx: service, + commands: { register: value => commands.set(value.name, value) }, + }) + toolsModule.apply({ + loopx: service, + tools: { register: value => tools.set(value.name, value) }, + }) + assert.deepEqual([...tools.keys()].sort(), [ + 'loopx_driver_pause', + 'loopx_driver_resume', + 'loopx_goal_activate', + 'loopx_goal_attach', + 'loopx_goal_detach', + 'loopx_goal_start', + 'loopx_status', + 'loopx_todo_add', + 'loopx_todo_claim', + 'loopx_todo_complete', + 'loopx_todo_update', + ], 'packed plugin must expose exactly eleven bounded model tools') + + const harness = makeAgent(project) + const { agent } = harness + const driver = new driverModule.LoopXContinuationDriver({ + service, + isLiveAgent: current => current === agent, + }) + driver.observeAgent(agent) + const command = commands.get('loopx') + assert(command, '/loopx command was not registered') + const signal = new AbortController().signal + let commandOrdinal = 0 + const invoke = async rawInput => { + const commandId = `smoke-command-${++commandOrdinal}` + driver.onSessionEvent(agent, { type: 'command/run', data: { commandId } }) + const result = await command.handler({ commandId, agent, rawInput, signal }) + driver.onSessionEvent(agent, { type: 'command/done', data: { commandId } }) + return result + } + + const installedManifest = JSON.parse(await readFile(join(installedDir, 'package.json'), 'utf8')) + assert.equal(installedManifest.version, '0.2.0') + assert.deepEqual(Object.keys(installedManifest.exports).sort(), [ + '.', './command', './cordis.patch.yml', './driver', './package.json', './service', './tools', + ], 'manifest must expose exactly four runtime faces plus root metadata') + + const statusResult = await invoke('status') + assert.equal(statusResult.kind, 'success') + assert.match(statusResult.text, /"hostSurface":"dsh"/u) + assert.match(statusResult.text, /"activation":"disarmed"/u) + assert(!statusResult.text.includes(sentinel), 'typed command receipt leaked private CLI fields') + assert.equal(harness.followups.length, 1, 'idle status must queue one bounded follow-up') + assert(!harness.followups[0].content[0].text.includes(sentinel), 'follow-up leaked private CLI fields') + + const session = commandModule.deriveLoopXSessionRef(agent, 'smoke') + assert.equal(session.ok, true) + harness.nextTurn.length = 0 + harness.followups.length = 0 + harness.setStatus('running') + const resumed = await service.resume(session.value, signal) + assert.equal(resumed.ok, true, 'fresh authoritative resume did not arm') + const armed = await service.status(session.value, signal) + assert.equal(armed.ok, true) + assert.equal(armed.value.host.activation, 'armed') + + const foreignId = 'smoke-foreign-command' + driver.onSessionEvent(agent, { type: 'command/run', data: { commandId: foreignId } }) + await Promise.resolve() + driver.onSessionEvent(agent, { type: 'command/done', data: { commandId: foreignId } }) + const disarmed = await service.status(session.value, signal) + assert.equal(disarmed.ok, true) + assert.equal(disarmed.value.host.activation, 'disarmed', 'foreign command did not latch disarm') + + let toolOrdinal = 0 + const executeStatusTool = async () => { + const definition = tools.get('loopx_status') + const callId = `smoke-tool-${++toolOrdinal}` + return definition.execute({}, { + name: 'loopx_status', callId, rootCallId: callId, arguments: {}, agent, signal, + token: Symbol(callId), concludeTurn() {}, + }) + } + await writeFile(modeFile, 'fail') + for (let attempt = 1; attempt <= 8; attempt += 1) { + const failed = await executeStatusTool() + assert.equal(failed.execution, 'rejected', `failure ${attempt} did not settle once`) + assert.equal(failed.application, 'no') + } + await writeFile(modeFile, 'ok') + const suppressed = await service.status(session.value, signal) + assert.equal(suppressed.ok, true) + assert.equal(suppressed.value.host.automaticFollowupSuppressed, true) + const recovered = await executeStatusTool() + assert.equal(recovered.execution, 'succeeded') + assert(!JSON.stringify(recovered).includes(sentinel), 'tool receipt leaked private CLI fields') + const readback = await service.status(session.value, signal) + assert.equal(readback.ok, true) + assert.equal(readback.value.host.automaticFollowupSuppressed, false) + + const calls = (await readFile(callsFile, 'utf8')).trim().split('\n') + for (const expected of ['resolve-agent-thread', 'status', 'bootstrap-command-pack', 'heartbeat-prompt']) { + assert(calls.includes(expected), `assembled lifecycle did not call ${expected}`) + } + await driver.dispose() + await ctx.fiber.dispose() +} + +async function runProfileSmoke(spec, ordinal) { + if (spec.kind === 'tarball') assertPackedFiles(spec.value) + const home = await mkdtemp(join(tmpdir(), `dsh-loopx-profile-${ordinal}-`)) + const mockLoopX = join(home, 'loopx-smoke.mjs') + const modeFile = join(home, 'loopx-mode.txt') + const callsFile = join(home, 'loopx-calls.txt') + await writeFile(mockLoopX, mockLoopXSource) + await chmod(mockLoopX, 0o755) + await writeFile(modeFile, 'ok') + await writeFile(callsFile, '') + const env = { ...process.env, DSH_HOME: home, LOOPX_BIN: mockLoopX } + try { + const installSpecs = spec.kind === 'tarball' + ? [ + ...await Promise.all(hostProvidedPeers.map(name => realpath( + join(packageRoot, 'node_modules', ...name.split('/')), + ))), + spec.value, + ] + : [spec.value] + run(dshBin, [ + 'plugin', '--profile', profileName, 'add', ...installSpecs, + spec.kind === 'tarball' ? '--prefer-offline' : '--offline', '--ignore-scripts', + ], { env }) + const dump = run(dshBin, ['--profile', profileName, '--dump-config'], { env }) + assertInstalledConfig(dump) + const installed = await realpath(join(home, 'profiles', profileName, 'node_modules', 'dsh-loopx-plugin')) + await exerciseInstalledPlugin(installed, home, mockLoopX, modeFile, callsFile) + run(dshBin, ['plugin', '--profile', profileName, 'remove', 'dsh-loopx-plugin'], { env }) + const removed = run(dshBin, ['--profile', profileName, '--dump-config'], { env }) + for (const [id] of bundleRows) assert(!removed.includes(`id: ${id}`), `remove retained ${id}`) + } finally { + await rm(home, { recursive: true, force: true }) + } +} + +const specs = parseSpecs(process.argv.slice(2)) +for (const [index, spec] of specs.entries()) await runProfileSmoke(spec, index + 1) +process.stdout.write(`dsh-loopx profile smoke passed (${specs.map(spec => spec.kind).join(', ')})\n`) diff --git a/packages/dsh-loopx-plugin/src/cli-client.ts b/packages/dsh-loopx-plugin/src/cli-client.ts new file mode 100644 index 000000000..e7cf497b1 --- /dev/null +++ b/packages/dsh-loopx-plugin/src/cli-client.ts @@ -0,0 +1,404 @@ +import { execFile as nodeExecFile } from 'node:child_process' +import { Buffer } from 'node:buffer' +import type { ChildProcess, ExecFileException, ExecFileOptionsWithStringEncoding } from 'node:child_process' +import type { ZodType } from 'zod' +import type { LoopXBindingHome } from './coordinator.ts' +import { failure } from './errors.ts' +import type { LoopXFailure } from './types.ts' + +export const DEFAULT_READ_TIMEOUT_MS = 15_000 +export const DEFAULT_WRITE_TIMEOUT_MS = 30_000 +export const DEFAULT_STDOUT_CAP_BYTES = 1_048_576 +export const DEFAULT_STDERR_CAP_BYTES = 262_144 + +export type LoopXCliOperationKind = 'read' | 'idempotent-write' | 'write' +export type LoopXBinarySource = 'config' | 'environment' | 'path' + +export interface LoopXCliClientConfig { + readonly loopxBin?: string + readonly readTimeoutMs?: number + readonly writeTimeoutMs?: number + readonly stdoutCapBytes?: number + readonly stderrCapBytes?: number + /** Explicit child-only environment additions. Parent variables are not inherited. */ + readonly environment?: Readonly> +} + +export interface LoopXCliRequest { + readonly operation: string + readonly kind: LoopXCliOperationKind + readonly args: readonly string[] + readonly cwd: string + readonly schema: ZodType + readonly signal?: AbortSignal | undefined + readonly scopeKey?: string | undefined +} + +export interface LoopXCliBindingRequest { + readonly operation: string + readonly kind: LoopXCliOperationKind + readonly args: readonly string[] + readonly home: LoopXBindingHome + readonly schema: ZodType + readonly signal?: AbortSignal | undefined + readonly scopeKey?: string | undefined +} + +type ExecFileCallback = ( + error: ExecFileException | null, + stdout: string, + stderr: string, +) => void + +export type ExecFileLike = ( + file: string, + args: readonly string[], + options: ExecFileOptionsWithStringEncoding, + callback: ExecFileCallback, +) => ChildProcess + +export interface LoopXCliClientInternals { + readonly execFile?: ExecFileLike + readonly parentEnv?: NodeJS.ProcessEnv +} + +class TimeoutReason extends Error { + constructor() { + super('loopx CLI operation timed out') + this.name = 'LoopXCliTimeout' + } +} + +class ShutdownReason extends Error { + constructor() { + super('loopx CLI client is closing') + this.name = 'LoopXCliShutdown' + } +} + +class ScopeInvalidatedReason extends Error { + constructor() { + super('LoopX Session operation invalidated') + this.name = 'LoopXCliScopeInvalidated' + } +} + +export class LoopXCliError extends Error { + readonly failure: LoopXFailure + + constructor(value: LoopXFailure) { + super(value.message) + this.name = 'LoopXCliError' + this.failure = value + } +} + +function positiveInteger(value: number | undefined, fallback: number, field: string): number { + const resolved = value ?? fallback + if (!Number.isSafeInteger(resolved) || resolved < 1) { + throw new TypeError(`${field} must be a positive safe integer`) + } + return resolved +} + +function resolveBinary(config: LoopXCliClientConfig, env: NodeJS.ProcessEnv): { + readonly file: string + readonly source: LoopXBinarySource +} { + const configured = config.loopxBin?.trim() + if (configured) return Object.freeze({ file: configured, source: 'config' }) + const fromEnvironment = env.LOOPX_BIN?.trim() + if (fromEnvironment) return Object.freeze({ file: fromEnvironment, source: 'environment' }) + return Object.freeze({ file: 'loopx', source: 'path' }) +} + +function childEnvironment( + parent: NodeJS.ProcessEnv, + explicit: Readonly> | undefined, +): NodeJS.ProcessEnv { + const env: NodeJS.ProcessEnv = {} + for (const key of ['PATH', 'PATHEXT', 'SystemRoot', 'WINDIR'] as const) { + if (parent[key] !== undefined) env[key] = parent[key] + } + if (parent.LOOPX_BIN !== undefined) env.LOOPX_BIN = parent.LOOPX_BIN + for (const [key, value] of Object.entries(explicit ?? {})) env[key] = value + return env +} + +function outcomeUncertain(kind: LoopXCliOperationKind): boolean { + return kind !== 'read' +} + +function abortFailure( + operation: string, + kind: LoopXCliOperationKind, + reason: unknown, +): LoopXFailure { + if (reason instanceof TimeoutReason) { + return failure('LOOPX_CLI_TIMEOUT', 'LoopX did not finish within the configured timeout.', { + operation, + retryable: kind === 'read', + outcomeUncertain: outcomeUncertain(kind), + }) + } + if (reason instanceof ShutdownReason) { + return failure('LOOPX_SERVICE_CLOSED', 'The LoopX Host service is shutting down.', { + operation, + outcomeUncertain: outcomeUncertain(kind), + }) + } + if (reason instanceof ScopeInvalidatedReason) { + return failure('LOOPX_DRIVER_NOT_ARMED', 'The LoopX operation was fenced locally.', { + operation, + outcomeUncertain: outcomeUncertain(kind), + }) + } + return failure('LOOPX_CLI_ABORTED', 'The LoopX operation was cancelled.', { + operation, + retryable: kind === 'read', + outcomeUncertain: outcomeUncertain(kind), + }) +} + +function schemaFailure( + operation: string, + kind: LoopXCliOperationKind, +): LoopXCliError { + return new LoopXCliError(failure( + 'LOOPX_SCHEMA_UNSUPPORTED', + 'LoopX returned JSON outside the supported contract version; upgrade the installed LoopX CLI before retrying.', + { + operation, + outcomeUncertain: outcomeUncertain(kind), + }, + )) +} + +/** Safe argv-only process boundary for the locally installed LoopX executable. */ +export class LoopXCliClient { + readonly binarySource: LoopXBinarySource + private readonly file: string + private readonly execFile: ExecFileLike + private readonly env: NodeJS.ProcessEnv + private readonly readTimeoutMs: number + private readonly writeTimeoutMs: number + private readonly stdoutCapBytes: number + private readonly stderrCapBytes: number + private readonly controllers = new Set() + private readonly scopeControllers = new Map>() + private readonly active = new Set>() + private closed = false + + constructor(config: LoopXCliClientConfig = {}, internals: LoopXCliClientInternals = {}) { + const parentEnv = internals.parentEnv ?? process.env + const binary = resolveBinary(config, parentEnv) + this.file = binary.file + this.binarySource = binary.source + this.execFile = internals.execFile ?? nodeExecFile as ExecFileLike + this.env = childEnvironment(parentEnv, config.environment) + this.readTimeoutMs = positiveInteger(config.readTimeoutMs, DEFAULT_READ_TIMEOUT_MS, 'readTimeoutMs') + this.writeTimeoutMs = positiveInteger(config.writeTimeoutMs, DEFAULT_WRITE_TIMEOUT_MS, 'writeTimeoutMs') + this.stdoutCapBytes = positiveInteger(config.stdoutCapBytes, DEFAULT_STDOUT_CAP_BYTES, 'stdoutCapBytes') + this.stderrCapBytes = positiveInteger(config.stderrCapBytes, DEFAULT_STDERR_CAP_BYTES, 'stderrCapBytes') + } + + async runJson(request: LoopXCliRequest): Promise { + if (this.closed) { + throw new LoopXCliError(failure( + 'LOOPX_SERVICE_CLOSED', + 'The LoopX Host service is not accepting new operations.', + { operation: request.operation }, + )) + } + if (request.operation.trim().length === 0 || request.args.some(arg => arg.includes('\0'))) { + throw new LoopXCliError(failure( + 'LOOPX_INVALID_REQUEST', + 'The LoopX operation contains an invalid argument.', + { operation: request.operation }, + )) + } + + const controller = new AbortController() + const unlink = this.linkAbort(request.signal, controller) + this.controllers.add(controller) + if (request.scopeKey !== undefined) { + const scoped = this.scopeControllers.get(request.scopeKey) ?? new Set() + scoped.add(controller) + this.scopeControllers.set(request.scopeKey, scoped) + } + const operation = this.execute(request, controller) + this.active.add(operation) + try { + return await operation + } finally { + unlink() + this.controllers.delete(controller) + this.active.delete(operation) + if (request.scopeKey !== undefined) { + const scoped = this.scopeControllers.get(request.scopeKey) + scoped?.delete(controller) + if (scoped?.size === 0) this.scopeControllers.delete(request.scopeKey) + } + } + } + + /** + * Run one v1 DSH binding command in exactly one selected binding home. + * The canonical home remains process-local and is never copied into errors. + */ + runBindingJson(request: LoopXCliBindingRequest): Promise { + const command = request.args[0] + const supported = command === 'bind-agent-thread' + || command === 'unbind-agent-thread' + || command === 'resolve-agent-thread' + const hostIndexes = request.args.flatMap((value, index) => ( + value === '--host-surface' ? [index] : [] + )) + const callerLocator = request.args.some(value => ( + value === '--runtime-root' || value.startsWith('--runtime-root=') + || value === '--registry' || value.startsWith('--registry=') + || value === '--project' || value.startsWith('--project=') + )) + if (!supported || callerLocator + || hostIndexes.length !== 1 + || request.args[hostIndexes[0] as number + 1] !== 'dsh') { + return Promise.reject(new LoopXCliError(failure( + 'LOOPX_INVALID_REQUEST', + 'A DSH binding operation requires one exact Host surface and binding home.', + { operation: request.operation }, + ))) + } + const args = request.home.runtimeRoot === undefined + ? request.args + : ['--runtime-root', request.home.runtimeRoot, ...request.args] + return this.runJson({ + operation: request.operation, + kind: request.kind, + args, + cwd: request.home.cwd, + schema: request.schema, + ...(request.signal === undefined ? {} : { signal: request.signal }), + ...(request.scopeKey === undefined ? {} : { scopeKey: request.scopeKey }), + }) + } + + abortScope(scopeKey: string, reason: Error = new ScopeInvalidatedReason()): void { + for (const controller of this.scopeControllers.get(scopeKey) ?? []) controller.abort(reason) + } + + async close(): Promise { + if (this.closed) return + this.closed = true + for (const controller of this.controllers) controller.abort(new ShutdownReason()) + await Promise.allSettled([...this.active]) + } + + private execute(request: LoopXCliRequest, controller: AbortController): Promise { + const timeoutMs = request.kind === 'read' ? this.readTimeoutMs : this.writeTimeoutMs + const timer = setTimeout(() => controller.abort(new TimeoutReason()), timeoutMs) + const maxBuffer = Math.max(this.stdoutCapBytes, this.stderrCapBytes) + 1 + const argv = ['--format', 'json', ...request.args] + + return new Promise((resolve, reject) => { + let settled = false + const settle = (operation: () => void): void => { + if (settled) return + settled = true + clearTimeout(timer) + operation() + } + try { + this.execFile(this.file, argv, { + cwd: request.cwd, + env: this.env, + encoding: 'utf8', + maxBuffer, + shell: false, + signal: controller.signal, + windowsHide: true, + }, (error, stdout, stderr) => { + settle(() => { + if (controller.signal.aborted) { + reject(new LoopXCliError(abortFailure( + request.operation, + request.kind, + controller.signal.reason, + ))) + return + } + const stdoutBytes = Buffer.byteLength(stdout) + const stderrBytes = Buffer.byteLength(stderr) + const maxBufferFailure = error?.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER' + if (maxBufferFailure + || stdoutBytes > this.stdoutCapBytes + || stderrBytes > this.stderrCapBytes) { + reject(new LoopXCliError(failure( + 'LOOPX_CLI_OUTPUT_LIMIT', + 'LoopX exceeded the configured output limit.', + { + operation: request.operation, + retryable: request.kind === 'read', + outcomeUncertain: outcomeUncertain(request.kind), + }, + ))) + return + } + + let decoded: unknown + try { + decoded = JSON.parse(stdout) as unknown + } catch { + if (error !== null) { + reject(this.processFailure(request, error)) + } else { + reject(schemaFailure(request.operation, request.kind)) + } + return + } + const parsed = request.schema.safeParse(decoded) + if (!parsed.success) { + reject(schemaFailure(request.operation, request.kind)) + return + } + resolve(parsed.data) + }) + }) + } catch (error) { + settle(() => reject(this.processFailure(request, error))) + } + }) + } + + private processFailure(request: LoopXCliRequest, error: unknown): LoopXCliError { + const code = typeof error === 'object' && error !== null && 'code' in error + ? String(error.code) + : '' + if (code === 'ENOENT') { + return new LoopXCliError(failure( + 'LOOPX_CLI_NOT_FOUND', + 'The configured LoopX executable could not be found.', + { operation: request.operation }, + )) + } + return new LoopXCliError(failure( + 'LOOPX_CLI_FAILED', + 'LoopX did not return a valid result for this operation.', + { + operation: request.operation, + retryable: request.kind === 'read', + outcomeUncertain: outcomeUncertain(request.kind), + }, + )) + } + + private linkAbort(signal: AbortSignal | undefined, controller: AbortController): () => void { + if (signal === undefined) return () => {} + if (signal.aborted) { + controller.abort(signal.reason) + return () => {} + } + const abort = (): void => controller.abort(signal.reason) + signal.addEventListener('abort', abort, { once: true }) + return () => signal.removeEventListener('abort', abort) + } +} diff --git a/packages/dsh-loopx-plugin/src/command.ts b/packages/dsh-loopx-plugin/src/command.ts new file mode 100644 index 000000000..0952e5f09 --- /dev/null +++ b/packages/dsh-loopx-plugin/src/command.ts @@ -0,0 +1,402 @@ +import { randomUUID } from 'node:crypto' +import { createRequire } from 'node:module' +import type { Context } from '@deepseek-ai/cordis' +import type { Agent } from '@deepseek-ai/dsh-agent' +import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands' +import type { UserMessage } from '@deepseek-ai/dsh-session' +import { + CoordinatorAdmissionCancelled, + coordinatorFor, +} from './coordinator.ts' +import type { CoordinatorRegistry } from './coordinator.ts' +import { + failureReceipt as operationFailure, + safeAttach, + safeBinding, + safeStart, + safeStatus, + serviceOperationReceipt, + successReceipt as succeeded, + unexpectedFailure, +} from './receipts.ts' +import type { + LoopXFailure, + LoopXOperationReceipt, + LoopXResult, + LoopXServiceApi, + LoopXSessionRef, +} from './types.ts' + +export const name = 'dsh-loopx-command' +export const inject = ['commands', 'loopx'] + +const PLUGIN_ID = 'dsh-loopx-plugin' +const manifest = createRequire(import.meta.url)('../package.json') as { + readonly name?: unknown + readonly version?: unknown +} +if (manifest.name !== PLUGIN_ID || typeof manifest.version !== 'string' || manifest.version.length === 0) { + throw new TypeError('dsh-loopx-plugin package version is unavailable') +} +export const PLUGIN_VERSION = manifest.version + +const USAGE = 'Usage: /loopx [status|version|pause|resume|detach|start |attach [|--new-peer]]' +const SEMANTIC_ROUTING_POLICY = [ + 'Interpret the quoted request through the registered `loopx_*` tools; never invoke a raw LoopX CLI or edit registries.', + 'Do not guess or fuzzy-match a Goal or Agent id.', + 'If no safe typed operation follows from the request, ask the user without mutating authority.', +].map((rule, index) => `${index + 1}. ${rule}`).join('\n') + +type ParsedLoopXCommand = + | { readonly kind: 'status'; readonly includeUsage: boolean } + | { readonly kind: 'version' } + | { readonly kind: 'pause' } + | { readonly kind: 'resume' } + | { readonly kind: 'detach' } + | { readonly kind: 'start'; readonly objective: string } + | { + readonly kind: 'attach' + readonly goalId: string + readonly agentId?: string | undefined + readonly newPeer?: true | undefined + } + | { readonly kind: 'semantic'; readonly originalInput: string } + +type ServiceCommand = Exclude + +/** Closed `/loopx` grammar; semantic fallthrough retains every input byte. */ +function parseLoopXCommand(rawInput: string): ParsedLoopXCommand { + if (rawInput.includes('\n') || rawInput.includes('\r')) { + return { kind: 'semantic', originalInput: rawInput } + } + const input = rawInput.trim() + if (input.length === 0) return { kind: 'status', includeUsage: true } + if (input === 'status') return { kind: 'status', includeUsage: false } + if (input === 'version') return { kind: 'version' } + if (input === 'pause') return { kind: 'pause' } + if (input === 'resume') return { kind: 'resume' } + if (input === 'detach') return { kind: 'detach' } + + const start = /^start[\t ]+([^\r\n]+)$/u.exec(input) + if (start !== null) { + const objective = start[1]?.trim() + if (objective !== undefined && objective.length > 0) return { kind: 'start', objective } + } + + const attach = input.split(/[\t ]+/u) + if (attach[0] === 'attach' && attach.length === 2) { + const goalId = attach[1] + if (goalId !== undefined && !goalId.startsWith('--')) return { kind: 'attach', goalId } + } + if (attach[0] === 'attach' && attach.length === 3) { + const goalId = attach[1] + const peer = attach[2] + if (goalId !== undefined && peer !== undefined && !goalId.startsWith('--')) { + if (peer === '--new-peer') return { kind: 'attach', goalId, newPeer: true } + if (!peer.startsWith('--')) return { kind: 'attach', goalId, agentId: peer } + } + } + return { kind: 'semantic', originalInput: rawInput } +} + +function lifecycleMismatch(message: string, operation: string): LoopXFailure { + return Object.freeze({ + code: 'LOOPX_SESSION_LIFECYCLE_MISMATCH', + message, + operation, + retryable: false, + outcomeUncertain: false, + }) +} + +/** Derive the only exact live Session identity a command or tool may operate on. */ +export function deriveLoopXSessionRef( + agent: Agent | undefined, + operation: string, +): LoopXResult { + if (agent === undefined) { + return { + ok: false, + application: 'no', + error: { + code: 'LOOPX_INVALID_REQUEST', + message: 'LoopX operations require the current DSH Agent execution.', + operation, + retryable: false, + outcomeUncertain: false, + }, + } + } + const agentId: unknown = agent.id + const sessionId: unknown = agent.session.id + const headerId: unknown = agent.session.header.id + if (typeof agentId !== 'string' || typeof sessionId !== 'string' + || typeof headerId !== 'string' || sessionId.length === 0 + || agentId !== sessionId || headerId !== sessionId) { + return { ok: false, application: 'no', error: lifecycleMismatch( + 'The current Agent and DSH Session identities do not match.', operation, + ) } + } + const { createdAt, cwd } = agent.session.header + if (!Number.isSafeInteger(createdAt) || createdAt < 0) { + return { ok: false, application: 'no', error: lifecycleMismatch( + 'The current DSH Session lifecycle identity is invalid.', operation, + ) } + } + return { + ok: true, + application: 'no', + value: Object.freeze({ + id: sessionId, + session: agent.session, + identity: Object.freeze({ createdAt, ...(cwd === undefined ? {} : { cwd }) }), + }), + } +} + +function typedIntent(parsed: Exclude, request: string): LoopXOperationReceipt { + const operation = parsed.kind === 'start' ? 'goal-start' + : parsed.kind === 'attach' ? 'goal-attach' + : parsed.kind === 'resume' ? 'driver-resume' + : 'goal-detach' + const args = parsed.kind === 'start' ? { goalText: parsed.objective } + : parsed.kind === 'attach' ? { + goalId: parsed.goalId, + ...(parsed.agentId === undefined ? {} : { agentId: parsed.agentId }), + ...(parsed.newPeer === true ? { newPeer: true } : {}), + } + : {} + return Object.freeze({ + schemaVersion: 'dsh_loopx_operation_receipt_v1', + kind: 'typed_intent', + operation, + request, + arguments: Object.freeze(args), + execution: 'not_attempted', + application: 'no', + delivery: 'not_needed', + recovery: 'none', + }) +} + +function semanticRequest(request: string): LoopXOperationReceipt { + return Object.freeze({ + schemaVersion: 'dsh_loopx_operation_receipt_v1', + kind: 'semantic_request', + operation: 'semantic-routing', + request, + execution: 'not_attempted', + application: 'no', + delivery: 'not_needed', + recovery: 'none', + }) +} + +function pluginMessage(receipt: LoopXOperationReceipt): UserMessage { + const prefix = receipt.kind === 'semantic_request' + ? `LoopX semantic routing policy (fixed plugin instruction):\n${SEMANTIC_ROUTING_POLICY}\n\n` + : receipt.kind === 'typed_intent' + ? 'Execute this validated, not-yet-attempted intent through the matching registered `loopx_*` tool.\n\n' + : 'Interpret this completed LoopX operation receipt. Do not repeat an applied write because delivery was delayed.\n\n' + return Object.freeze({ + id: randomUUID(), + role: 'user' as const, + content: Object.freeze([{ type: 'text' as const, text: `${prefix}${JSON.stringify(receipt)}` }]), + source: Object.freeze({ kind: 'plugin' as const, plugin: PLUGIN_ID }), + }) as unknown as UserMessage +} + +function withDelivery( + receipt: LoopXOperationReceipt, + delivery: LoopXOperationReceipt['delivery'], +): LoopXOperationReceipt { + return Object.freeze({ ...receipt, delivery }) +} + +function withFailureRequest( + receipt: LoopXOperationReceipt, + request: string, +): LoopXOperationReceipt { + return receipt.execution === 'rejected' || receipt.execution === 'indeterminate' + ? Object.freeze({ ...receipt, request }) + : receipt +} + +function deliver( + agent: Agent, + receipt: LoopXOperationReceipt, + route: 'steer' | 'followup', +): LoopXOperationReceipt { + const queued = withDelivery(receipt, route === 'steer' ? 'steered' : 'followup_queued') + try { + if (route === 'steer') agent.steer(pluginMessage(queued)) + else agent.followup(pluginMessage(queued)) + return queued + } catch { + return withDelivery(receipt, 'failed') + } +} + +function asCommandResult(receipt: LoopXOperationReceipt, includeUsage = false): CommandResult { + const suffix = includeUsage ? `\n\n${USAGE}` : '' + const text = `${JSON.stringify(receipt)}${suffix}` + return receipt.delivery === 'failed' + || receipt.execution === 'rejected' + || receipt.execution === 'indeterminate' + ? { kind: 'error', text } + : { kind: 'success', text } +} + +async function runServiceCommand( + service: LoopXServiceApi, + session: LoopXSessionRef, + parsed: ServiceCommand, + signal: AbortSignal, +): Promise { + if (parsed.kind === 'status') { + return serviceOperationReceipt( + service, session, signal, 'status', + () => service.status(session, signal), + safeStatus, + ) + } + if (parsed.kind === 'start') { + return serviceOperationReceipt( + service, session, signal, 'goal-start', + () => service.start(session, parsed.objective, signal), + safeStart, + ) + } + if (parsed.kind === 'attach') { + return serviceOperationReceipt( + service, session, signal, 'goal-attach', + () => service.attach(session, { + goalId: parsed.goalId, + ...(parsed.agentId === undefined ? {} : { agentId: parsed.agentId }), + ...(parsed.newPeer === true ? { newPeer: true } : {}), + }, signal), + safeAttach, + ) + } + if (parsed.kind === 'resume') { + return serviceOperationReceipt( + service, session, signal, 'driver-resume', + () => service.resume(session, signal), + value => ({ binding: safeBinding(value) }), + ) + } + return serviceOperationReceipt( + service, session, signal, 'goal-detach', + () => service.detach(session, signal), + value => ({ detached: value.detached, binding: safeBinding(value.binding) }), + ) +} + +function exactSession(agent: Agent, session: LoopXSessionRef): boolean { + return agent.session === session.session + && agent.id === session.id + && agent.session.id === session.id +} + +async function executeLoopXCommand( + service: LoopXServiceApi, + coordinators: CoordinatorRegistry, + invocation: CommandInvocation, +): Promise { + const parsed = parseLoopXCommand(invocation.rawInput) + if (parsed.kind === 'version') { + return { kind: 'success', text: `${PLUGIN_ID} ${PLUGIN_VERSION}` } + } + const current = deriveLoopXSessionRef(invocation.agent, 'command') + if (!current.ok) return asCommandResult(operationFailure('command', current.error)) + const session = current.value + + if (parsed.kind === 'pause') { + coordinators.pause(session) + const receipt = succeeded('driver-pause', 'no', { paused: true }) + return asCommandResult(invocation.agent.status === 'running' + ? deliver(invocation.agent, receipt, 'steer') + : receipt) + } + + const routeRunning = async (): Promise => { + if (parsed.kind === 'semantic') { + return asCommandResult(deliver(invocation.agent, semanticRequest(parsed.originalInput), 'steer')) + } + if (parsed.kind !== 'status') { + return asCommandResult(deliver( + invocation.agent, + typedIntent(parsed, invocation.rawInput), + 'steer', + )) + } + const receipt = withFailureRequest( + await runServiceCommand(service, session, parsed, invocation.signal), + invocation.rawInput, + ) + return asCommandResult(deliver(invocation.agent, receipt, 'steer'), parsed.includeUsage) + } + + if (invocation.agent.status === 'running') return routeRunning() + + try { + const admitted = await coordinators.admitWhenIdle( + invocation.agent, + invocation.signal, + () => exactSession(invocation.agent, session), + async maintenanceSignal => { + const signal = AbortSignal.any([invocation.signal, maintenanceSignal]) + if (parsed.kind === 'semantic') { + return deliver(invocation.agent, semanticRequest(parsed.originalInput), 'followup') + } + const receipt = withFailureRequest( + await runServiceCommand(service, session, parsed, signal), + invocation.rawInput, + ) + return deliver(invocation.agent, receipt, 'followup') + }, + ) + if (admitted.route === 'running') return routeRunning() + return asCommandResult( + admitted.value, + parsed.kind === 'status' && parsed.includeUsage, + ) + } catch (error: unknown) { + if (error instanceof CoordinatorAdmissionCancelled || invocation.signal.aborted) { + return asCommandResult(operationFailure('command', { + code: 'LOOPX_CLI_ABORTED', + message: 'The LoopX command was cancelled before Service admission.', + operation: 'command', + retryable: false, + outcomeUncertain: false, + })) + } + return asCommandResult(operationFailure('command', unexpectedFailure('command'))) + } +} + +/** Register the global command and claim its provisional barrier synchronously. */ +export function apply(ctx: Context): void { + const coordinators = coordinatorFor(ctx.loopx) + ctx.commands.register({ + name: 'loopx', + description: 'route exact LoopX controls or a semantic request in this Session', + input: { hint: '[status|version|pause|resume|detach|start ...|attach ...]' }, + handler(invocation) { + const claimed = coordinators.claimCommand( + String(invocation.commandId), invocation.agent.session, invocation.agent, + ) + if (!claimed) { + return { + kind: 'error', + text: 'LOOPX_COMMAND_BARRIER_MISSING: The resolved command did not own its provisional barrier.', + } + } + const commandId = String(invocation.commandId) + const operation = executeLoopXCommand(ctx.loopx, coordinators, invocation) + const settle = (): void => coordinators.settleOwned(commandId, invocation.agent.session) + void operation.then(settle, settle) + return operation + }, + }) +} diff --git a/packages/dsh-loopx-plugin/src/coordinator.ts b/packages/dsh-loopx-plugin/src/coordinator.ts new file mode 100644 index 000000000..0674eef28 --- /dev/null +++ b/packages/dsh-loopx-plugin/src/coordinator.ts @@ -0,0 +1,590 @@ +import { randomUUID } from 'node:crypto' +import type { Agent } from '@deepseek-ai/dsh-agent' +import type { + LoopXBoundHostThreadBindingV1, + LoopXHostThreadBindingV1, + LoopXResult, + LoopXSessionRef, +} from './types.ts' + +export const LOOPX_FAILURE_SUPPRESSION_THRESHOLD = 8 + +export interface LoopXBindingHome { + /** Canonical process-local identity. Never include this value in a receipt. */ + readonly key: string + readonly cwd: string + readonly runtimeRoot?: string | undefined +} + +export interface CoordinatorFence { + readonly sessionObject: object + readonly pluginInstanceIdentity: object + readonly bindingHome: string + readonly threadId: string + readonly bindingRevision: number + readonly goalId: string + readonly agentId: string + readonly activationEpoch: number +} + +export interface CoordinatorSnapshot { + readonly activation: 'armed' | 'disarmed' + readonly activationEpoch: number + readonly barred: boolean + readonly foreignLatched: boolean + readonly failureCount: number + readonly automaticFollowupSuppressed: boolean + readonly observedBinding?: LoopXHostThreadBindingV1 | undefined + readonly bindingHome?: LoopXBindingHome | undefined + readonly planningBody?: string | undefined + readonly taskBody?: string | undefined +} + +export type CoordinatorEventKind = + | 'armed' + | 'invalidated' + | 'barrier_opened' + | 'barrier_released' + | 'foreign_command' + | 'suppressed' + | 'recovered' + | 'disposed' + +export interface CoordinatorEvent { + readonly kind: CoordinatorEventKind + readonly sessionObject: object + readonly snapshot: CoordinatorSnapshot +} + +export interface CoordinatorArmOptions { + readonly planningBody?: string | undefined + readonly taskBody?: string | undefined +} + +export type CoordinatorOutcome = 'success' | 'failure' | 'cancelled' + +export interface CoordinatorTopLevelOperation { + succeed(): void + fail(): void + cancel(): void +} + +export type IdleAdmission = + | { readonly route: 'running' } + | { readonly route: 'idle'; readonly value: T } + +/** Internal failure-counter filter shared by command, tools, and Driver. */ +export function isCoordinatorCancellation(result: LoopXResult): boolean { + if (result.ok) return false + return result.error.code === 'LOOPX_DRIVER_NOT_ARMED' + || result.error.code === 'LOOPX_FOREIGN_COMMAND_ACTIVE' + || result.error.code === 'LOOPX_AUTOMATION_SUPPRESSED' + || result.error.code === 'LOOPX_REVISION_CONFLICT' + || result.error.code === 'LOOPX_SESSION_LIFECYCLE_MISMATCH' + || result.error.code === 'LOOPX_CLI_ABORTED' + || result.error.code === 'LOOPX_SERVICE_CLOSED' +} + +interface CoordinatorState { + readonly sessionObject: object + readonly scopeKey: string + home?: LoopXBindingHome | undefined + observed?: LoopXHostThreadBindingV1 | undefined + activation: 'armed' | 'disarmed' + activationEpoch: number + planningBody?: string | undefined + taskBody?: string | undefined + failureCount: number + suppressed: boolean + foreignLatched: boolean + closed: boolean + operationTail: Promise + confirmation?: unknown +} + +interface CommandOperation { + readonly commandId: string + readonly sessionObject: object + readonly agentObject: object + phase: 'provisional' | 'owned' | 'foreign' + commandDone: boolean +} + +export class CoordinatorAdmissionCancelled extends Error { + constructor() { + super('LoopX idle admission was fenced') + this.name = 'CoordinatorAdmissionCancelled' + } +} + +function sameTarget( + left: LoopXHostThreadBindingV1 | undefined, + right: LoopXHostThreadBindingV1, +): boolean { + if (left === undefined || left.state !== right.state) return false + if (left.threadId !== right.threadId || left.revision !== right.revision) return false + if (left.state === 'unbound' || right.state === 'unbound') return true + return left.target.goalId === right.target.goalId + && left.target.agentId === right.target.agentId +} + +function frozenBinding(binding: LoopXHostThreadBindingV1): LoopXHostThreadBindingV1 { + const base = { + schemaVersion: 'loopx_host_thread_binding_v1' as const, + hostSurface: 'dsh' as const, + threadId: binding.threadId, + revision: binding.revision, + } + return binding.state === 'bound' + ? Object.freeze({ + ...base, + state: 'bound' as const, + target: Object.freeze({ ...binding.target }), + }) + : Object.freeze({ ...base, state: 'unbound' as const }) +} + +function abortable(promise: Promise, signal: AbortSignal): Promise { + if (signal.aborted) return Promise.reject(signal.reason) + return new Promise((resolve, reject) => { + const aborted = (): void => reject(signal.reason) + signal.addEventListener('abort', aborted, { once: true }) + promise.then(resolve, reject).finally(() => signal.removeEventListener('abort', aborted)) + }) +} + +/** + * The sole process-local owner for Session activation and operation fences. + * It is constructed once by LoopXService and is intentionally not exported by + * the package entry point or registered as a Cordis component. + */ +export class CoordinatorRegistry { + private readonly pluginInstanceIdentity = Object.freeze({}) + private readonly states = new WeakMap() + private readonly liveStates = new Set() + private readonly commands = new Map>() + private readonly listeners = new Set<(event: CoordinatorEvent) => void>() + private closed = false + + constructor(private readonly abortScope: (scopeKey: string) => void = () => {}) {} + + observe(session: LoopXSessionRef, home?: LoopXBindingHome): CoordinatorSnapshot { + const state = this.stateFor(session.session) + if (home !== undefined) this.observeHome(state, home) + return this.snapshotState(state) + } + + snapshot(session: LoopXSessionRef | object): CoordinatorSnapshot | undefined { + const object = 'session' in session ? session.session : session + const state = this.states.get(object) + return state === undefined ? undefined : this.snapshotState(state) + } + + observeBinding( + session: LoopXSessionRef, + home: LoopXBindingHome, + binding: LoopXHostThreadBindingV1, + ): CoordinatorSnapshot { + const state = this.stateFor(session.session) + const homeChanged = state.home !== undefined && state.home.key !== home.key + const bindingChanged = !sameTarget(state.observed, binding) + this.observeHome(state, home) + state.observed = frozenBinding(binding) + if (!homeChanged && bindingChanged) this.invalidateState(state, true) + if (binding.state === 'unbound') { + state.activation = 'disarmed' + state.planningBody = undefined + state.taskBody = undefined + } + return this.snapshotState(state) + } + + arm( + session: LoopXSessionRef, + home: LoopXBindingHome, + binding: LoopXBoundHostThreadBindingV1, + options: CoordinatorArmOptions = {}, + ): CoordinatorFence | undefined { + const state = this.stateFor(session.session) + this.observeHome(state, home) + if (this.hasForeignBarrier(session.session) || state.closed) return undefined + state.observed = frozenBinding(binding) + state.activation = 'armed' + state.foreignLatched = false + state.activationEpoch += 1 + state.planningBody = options.planningBody + state.taskBody = options.taskBody + this.emit(state, 'armed') + return this.fence(session) + } + + pause(session: LoopXSessionRef): CoordinatorSnapshot { + const state = this.stateFor(session.session) + this.invalidateState(state, true) + return this.snapshotState(state) + } + + invalidate( + session: LoopXSessionRef, + options: { readonly foreign?: boolean; readonly clearCaches?: boolean } = {}, + ): CoordinatorSnapshot { + const state = this.stateFor(session.session) + if (options.foreign === true) state.foreignLatched = true + this.invalidateState(state, options.clearCaches ?? true) + return this.snapshotState(state) + } + + /** Retire unclaimed automatic work without changing explicit activation. */ + advanceEpoch(session: LoopXSessionRef): CoordinatorSnapshot { + const state = this.stateFor(session.session) + state.activationEpoch += 1 + this.abortScope(state.scopeKey) + this.emit(state, 'invalidated') + return this.snapshotState(state) + } + + cachePlanningBody(session: LoopXSessionRef, body: string): void { + const state = this.stateFor(session.session) + state.planningBody = body + } + + cacheTaskBody(session: LoopXSessionRef, body: string): void { + const state = this.stateFor(session.session) + state.taskBody = body + } + + scopeKey(session: LoopXSessionRef): string { + return this.stateFor(session.session).scopeKey + } + + isClosed(session: LoopXSessionRef): boolean { + return this.states.get(session.session)?.closed ?? false + } + + serialize(session: LoopXSessionRef, operation: () => Promise): Promise { + const state = this.stateFor(session.session) + if (state.closed || this.closed) return Promise.reject(new CoordinatorAdmissionCancelled()) + const result = state.operationTail.then(() => { + if (state.closed || this.closed) throw new CoordinatorAdmissionCancelled() + return operation() + }) + state.operationTail = result.then(() => undefined, () => undefined) + return result + } + + drain(session: LoopXSessionRef): Promise { + return this.states.get(session.session)?.operationTail ?? Promise.resolve() + } + + async drainAll(): Promise { + await Promise.all([...this.liveStates].map(state => state.operationTail)) + } + + setConfirmation(session: LoopXSessionRef, value: unknown): void { + this.stateFor(session.session).confirmation = value + } + + confirmation(session: LoopXSessionRef): T | undefined { + return this.states.get(session.session)?.confirmation as T | undefined + } + + clearConfirmation(session: LoopXSessionRef): void { + const state = this.states.get(session.session) + if (state !== undefined) state.confirmation = undefined + } + + fence(session: LoopXSessionRef): CoordinatorFence | undefined { + const state = this.states.get(session.session) + const binding = state?.observed + if (state === undefined || state.activation !== 'armed' || state.home === undefined + || binding?.state !== 'bound' || state.closed) return undefined + return Object.freeze({ + sessionObject: session.session, + pluginInstanceIdentity: this.pluginInstanceIdentity, + bindingHome: state.home.key, + threadId: binding.threadId, + bindingRevision: binding.revision, + goalId: binding.target.goalId, + agentId: binding.target.agentId, + activationEpoch: state.activationEpoch, + }) + } + + isCurrent(fence: CoordinatorFence): boolean { + const state = this.states.get(fence.sessionObject) + const binding = state?.observed + return state !== undefined && !state.closed && state.activation === 'armed' + && !state.suppressed && !state.foreignLatched && !this.hasBarrier(fence.sessionObject) + && fence.pluginInstanceIdentity === this.pluginInstanceIdentity + && state.home?.key === fence.bindingHome + && state.activationEpoch === fence.activationEpoch + && binding?.state === 'bound' + && binding.threadId === fence.threadId + && binding.revision === fence.bindingRevision + && binding.target.goalId === fence.goalId + && binding.target.agentId === fence.agentId + } + + commandRun(commandId: string, sessionObject: object, agentObject: object): void { + const bucket = this.commands.get(sessionObject) ?? new Map() + if (this.closed || bucket.has(commandId)) return + const state = this.stateFor(sessionObject) + if (state.closed) return + bucket.set(commandId, { + commandId, + sessionObject, + agentObject, + phase: 'provisional', + commandDone: false, + }) + this.commands.set(sessionObject, bucket) + this.emit(state, 'barrier_opened') + } + + claimCommand(commandId: string, sessionObject: object, agentObject: object): boolean { + const operation = this.commands.get(sessionObject)?.get(commandId) + if (operation === undefined || operation.phase !== 'provisional' + || operation.sessionObject !== sessionObject || operation.agentObject !== agentObject) return false + operation.phase = 'owned' + return true + } + + classifyUnclaimed( + commandId: string, + sessionObject: object, + ): 'missing' | 'owned' | 'foreign' { + const operation = this.commands.get(sessionObject)?.get(commandId) + if (operation === undefined) return 'missing' + if (operation.phase === 'owned') return 'owned' + if (operation.phase === 'provisional') { + operation.phase = 'foreign' + const state = this.stateFor(operation.sessionObject) + state.foreignLatched = true + this.invalidateState(state, true, 'foreign_command') + } + return 'foreign' + } + + commandDone(commandId: string, sessionObject: object): void { + const operation = this.commands.get(sessionObject)?.get(commandId) + if (operation === undefined) return + operation.commandDone = true + if (operation.phase === 'provisional') this.classifyUnclaimed(commandId, sessionObject) + if (operation.phase === 'foreign') this.releaseCommand(operation) + } + + settleOwned(commandId: string, sessionObject: object): void { + const operation = this.commands.get(sessionObject)?.get(commandId) + if (operation?.phase !== 'owned') return + this.releaseCommand(operation) + } + + hasBarrier(session: LoopXSessionRef | object): boolean { + const sessionObject = 'session' in session ? session.session : session + return (this.commands.get(sessionObject)?.size ?? 0) !== 0 + } + + recordOutcome(session: LoopXSessionRef, outcome: CoordinatorOutcome): CoordinatorSnapshot { + const state = this.stateFor(session.session) + if (outcome === 'cancelled') return this.snapshotState(state) + if (outcome === 'success') { + const recovered = state.failureCount !== 0 || state.suppressed + state.failureCount = 0 + state.suppressed = false + if (recovered) this.emit(state, 'recovered') + return this.snapshotState(state) + } + state.failureCount = Math.min( + LOOPX_FAILURE_SUPPRESSION_THRESHOLD, + state.failureCount + 1, + ) + state.activationEpoch += 1 + this.abortScope(state.scopeKey) + if (state.failureCount === LOOPX_FAILURE_SUPPRESSION_THRESHOLD && !state.suppressed) { + state.suppressed = true + this.emit(state, 'suppressed') + } else { + this.emit(state, 'invalidated') + } + return this.snapshotState(state) + } + + beginTopLevel(session: LoopXSessionRef): CoordinatorTopLevelOperation { + let settled = false + const settle = (outcome: CoordinatorOutcome): void => { + if (settled) return + settled = true + this.recordOutcome(session, outcome) + } + return Object.freeze({ + succeed: () => settle('success'), + fail: () => settle('failure'), + cancel: () => settle('cancelled'), + }) + } + + onInvalidated(listener: (event: CoordinatorEvent) => void): () => void { + this.listeners.add(listener) + return () => this.listeners.delete(listener) + } + + async admitWhenIdle( + agent: Agent, + signal: AbortSignal, + revalidate: () => boolean | Promise, + task: (signal: AbortSignal) => Promise, + ): Promise> { + while (true) { + if (signal.aborted) throw signal.reason + if (agent.status === 'running') return Object.freeze({ route: 'running' as const }) + let entered = false + try { + const value = await agent.runMaintenance(async maintenanceSignal => { + entered = true + if (!await revalidate()) throw new CoordinatorAdmissionCancelled() + return task(maintenanceSignal) + }) + return Object.freeze({ route: 'idle' as const, value }) + } catch (error) { + if (entered) throw error + if (this.agentIsRunning(agent)) return Object.freeze({ route: 'running' as const }) + await abortable(agent.whenIdle(), signal) + if (!await revalidate()) throw new CoordinatorAdmissionCancelled() + continue + } + } + } + + drop(session: LoopXSessionRef | object): void { + const sessionObject = 'session' in session ? session.session : session + const state = this.states.get(sessionObject) + if (state === undefined) return + state.closed = true + state.activation = 'disarmed' + state.activationEpoch += 1 + state.planningBody = undefined + state.taskBody = undefined + state.confirmation = undefined + this.commands.delete(sessionObject) + this.abortScope(state.scopeKey) + this.emit(state, 'disposed') + this.liveStates.delete(state) + } + + close(): void { + if (this.closed) return + this.closed = true + for (const state of [...this.liveStates]) this.drop(state.sessionObject) + this.commands.clear() + this.listeners.clear() + } + + private stateFor(sessionObject: object): CoordinatorState { + const found = this.states.get(sessionObject) + if (found !== undefined) return found + if (this.closed) throw new Error('LoopX coordinator is closed') + const created: CoordinatorState = { + sessionObject, + scopeKey: `dsh-loopx-scope-${randomUUID()}`, + activation: 'disarmed', + activationEpoch: 1, + failureCount: 0, + suppressed: false, + foreignLatched: false, + closed: false, + operationTail: Promise.resolve(), + } + this.states.set(sessionObject, created) + this.liveStates.add(created) + return created + } + + private observeHome(state: CoordinatorState, home: LoopXBindingHome): void { + if (state.home?.key === home.key) return + const changed = state.home !== undefined + state.home = Object.freeze({ ...home }) + if (changed) this.invalidateState(state, true) + } + + private invalidateState( + state: CoordinatorState, + clearCaches: boolean, + kind: CoordinatorEventKind = 'invalidated', + ): void { + state.activation = 'disarmed' + state.activationEpoch += 1 + if (clearCaches) { + state.planningBody = undefined + state.taskBody = undefined + } + this.abortScope(state.scopeKey) + this.emit(state, kind) + } + + private releaseCommand(operation: CommandOperation): void { + const bucket = this.commands.get(operation.sessionObject) + bucket?.delete(operation.commandId) + if (bucket?.size === 0) this.commands.delete(operation.sessionObject) + const state = this.states.get(operation.sessionObject) + if (state !== undefined && !this.hasBarrier(operation.sessionObject)) { + this.emit(state, 'barrier_released') + } + } + + private hasForeignBarrier(sessionObject: object): boolean { + for (const operation of this.commands.get(sessionObject)?.values() ?? []) { + if (operation.phase === 'foreign') return true + } + return false + } + + private snapshotState(state: CoordinatorState): CoordinatorSnapshot { + return Object.freeze({ + activation: state.activation, + activationEpoch: state.activationEpoch, + barred: this.hasBarrier(state.sessionObject), + foreignLatched: state.foreignLatched, + failureCount: state.failureCount, + automaticFollowupSuppressed: state.suppressed, + ...(state.observed === undefined ? {} : { observedBinding: state.observed }), + ...(state.home === undefined ? {} : { bindingHome: state.home }), + ...(state.planningBody === undefined ? {} : { planningBody: state.planningBody }), + ...(state.taskBody === undefined ? {} : { taskBody: state.taskBody }), + }) + } + + private emit(state: CoordinatorState, kind: CoordinatorEventKind): void { + const event = Object.freeze({ + kind, + sessionObject: state.sessionObject, + snapshot: this.snapshotState(state), + }) + for (const listener of this.listeners) listener(event) + } + + private agentIsRunning(agent: Agent): boolean { + return agent.status === 'running' + } +} + +const serviceCoordinator = Symbol.for('dsh-loopx-plugin.coordinator.v1') + +/** Package-internal attachment; the public Service API does not expose it. */ +export function installCoordinator(service: object, coordinator: CoordinatorRegistry): void { + Object.defineProperty(service, serviceCoordinator, { + value: coordinator, + configurable: false, + enumerable: false, + writable: false, + }) +} + +/** Package-internal lookup used by command, tools, and Driver composition. */ +export function coordinatorFor(service: object): CoordinatorRegistry { + const coordinator = (service as Record)[serviceCoordinator] + if (typeof coordinator !== 'object' || coordinator === null + || !('snapshot' in coordinator) || !('commandRun' in coordinator)) { + throw new Error('LoopX coordinator has an incompatible package identity') + } + return coordinator as CoordinatorRegistry +} diff --git a/packages/dsh-loopx-plugin/src/driver.ts b/packages/dsh-loopx-plugin/src/driver.ts new file mode 100644 index 000000000..d1fb86dbf --- /dev/null +++ b/packages/dsh-loopx-plugin/src/driver.ts @@ -0,0 +1,619 @@ +/** Quota-gated, exact-session automatic continuation for DeepSeek Harness. */ + +import { randomUUID } from 'node:crypto' +import { isDeepStrictEqual } from 'node:util' +import { FiberState } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' +import type { Agent, AgentStatus, PreStepDecision } from '@deepseek-ai/dsh-agent' +import type {} from '@deepseek-ai/dsh-commands' +import type { Session, SessionEvent, UserMessage } from '@deepseek-ai/dsh-session' +import { + CoordinatorAdmissionCancelled, + coordinatorFor, + isCoordinatorCancellation, +} from './coordinator.ts' +import type { + CoordinatorFence, + CoordinatorRegistry, + CoordinatorTopLevelOperation, +} from './coordinator.ts' +import type { + LoopXBoundHostThreadBindingV1, + LoopXQuotaDecision, + LoopXResult, + LoopXSchedulerHint, + LoopXServiceApi, + LoopXSessionRef, +} from './types.ts' + +export const name = 'dsh-loopx-driver' +export const inject = ['agents', 'loopx'] + +const PLUGIN_ID = 'dsh-loopx-plugin' +const DRIVER_SOURCE_ID = `${PLUGIN_ID}/driver` +const FAIL_CLOSED_RETRY_MS = 3 * 60_000 +const MAX_TIMER_DELAY_MS = 2_147_483_647 + +type TimerHandle = unknown + +export interface LoopXDriverClock { + now(): number + setTimeout(callback: () => void, delayMs: number): TimerHandle + clearTimeout(handle: TimerHandle): void +} + +export interface LoopXDriverOptions { + readonly service: LoopXServiceApi + readonly isLiveAgent: (agent: Agent) => boolean + readonly clock?: LoopXDriverClock + readonly makeTurnInstanceId?: () => string + readonly runDetached?: (operation: () => Promise) => Promise + readonly warn?: (message: string) => void +} + +type ReservationPhase = 'reserved' | 'queued' | 'claimed' | 'entered' | 'retired' + +interface AutomaticReservation { + readonly messageId: UserMessage['id'] + readonly content: UserMessage['content'] + readonly fence: CoordinatorFence + phase: ReservationPhase +} + +interface ScheduledEvaluation { + readonly handle: TimerHandle + readonly fence: CoordinatorFence +} + +interface DriverState { + readonly agent: Agent + stopping: boolean + requested: boolean + evaluation?: Promise | undefined + controller?: AbortController | undefined + timer?: ScheduledEvaluation | undefined + reservation?: AutomaticReservation | undefined + schedulerResetToken?: string | undefined + unchangedPollCount: number +} + +const systemClock: LoopXDriverClock = Object.freeze({ + now: () => Date.now(), + setTimeout(callback: () => void, delayMs: number) { + return setTimeout(callback, delayMs) + }, + clearTimeout(handle: TimerHandle) { + clearTimeout(handle as ReturnType) + }, +}) + +function sessionRef(agent: Agent): LoopXSessionRef { + const { createdAt, cwd } = agent.session.header + return Object.freeze({ + id: String(agent.id), + session: agent.session, + identity: Object.freeze({ createdAt, ...(cwd === undefined ? {} : { cwd }) }), + }) +} + +function sameBinding(binding: LoopXBoundHostThreadBindingV1, fence: CoordinatorFence): boolean { + return binding.threadId === fence.threadId + && binding.revision === fence.bindingRevision + && binding.target.goalId === fence.goalId + && binding.target.agentId === fence.agentId +} + +function isDriverSource(message: UserMessage): boolean { + return message.source.kind === 'plugin' && message.source.plugin === DRIVER_SOURCE_ID +} + +function isReservationMessage( + message: UserMessage, + reservation: AutomaticReservation, +): boolean { + return message.id === reservation.messageId + && isDriverSource(message) + && isDeepStrictEqual(message.content, reservation.content) +} + +function createAutomaticMessage(body: string): UserMessage { + const content: UserMessage['content'] = [Object.freeze({ type: 'text', text: body })] + return Object.freeze({ + id: randomUUID() as UserMessage['id'], + role: 'user' as const, + content: Object.freeze(content) as UserMessage['content'], + source: Object.freeze({ kind: 'plugin' as const, plugin: DRIVER_SOURCE_ID }), + }) +} + +function validDelay(minutes: number | undefined): number | undefined { + if (minutes === undefined || !Number.isSafeInteger(minutes) || minutes < 1) return undefined + const delay = minutes * 60_000 + return Number.isSafeInteger(delay) && delay <= MAX_TIMER_DELAY_MS ? delay : undefined +} + +function waitDelay( + state: DriverState, + hint: LoopXSchedulerHint, +): number | undefined { + const resetToken = typeof hint.resetToken === 'string' && hint.resetToken.length > 0 + ? hint.resetToken + : undefined + const sameReset = resetToken !== undefined && resetToken === state.schedulerResetToken + const unchanged = sameReset ? state.unchangedPollCount : 0 + const limit = Number.isSafeInteger(hint.unchangedPollLimit) + && (hint.unchangedPollLimit as number) >= 0 + ? hint.unchangedPollLimit + : undefined + const delay = validDelay(hint.recommendedIntervalMinutes) + const valid = resetToken !== undefined && delay !== undefined + && hint.action.length > 0 && hint.cadenceClass.length > 0 + state.schedulerResetToken = resetToken + state.unchangedPollCount = unchanged + 1 + if (valid && limit !== undefined && unchanged >= limit) return undefined + return valid ? delay : FAIL_CLOSED_RETRY_MS +} + +/** Driver-local reservation/timer mechanics over the one shared coordinator. */ +export class LoopXContinuationDriver { + private readonly service: LoopXServiceApi + private readonly coordinators: CoordinatorRegistry + private readonly isLiveAgent: (agent: Agent) => boolean + private readonly clock: LoopXDriverClock + private readonly makeTurnInstanceId: () => string + private readonly runDetached: (operation: () => Promise) => Promise + private readonly warn: (message: string) => void + private readonly states = new Map() + private readonly operations = new Set>() + private readonly stopCoordinatorEvents: () => void + private disposed = false + + constructor(options: LoopXDriverOptions) { + this.service = options.service + this.coordinators = coordinatorFor(options.service) + this.isLiveAgent = options.isLiveAgent + this.clock = options.clock ?? systemClock + this.makeTurnInstanceId = options.makeTurnInstanceId ?? (() => `dsh-loopx-${randomUUID()}`) + this.runDetached = options.runDetached ?? (operation => operation()) + this.warn = options.warn ?? (() => {}) + this.stopCoordinatorEvents = this.coordinators.onInvalidated(event => { + const state = [...this.states.values()].find(candidate => + candidate.agent.session === event.sessionObject) + if (state === undefined) return + if (event.kind === 'armed' || event.kind === 'barrier_released' + || event.kind === 'recovered') { + this.requestEvaluation(state) + return + } + this.cancelUnadmitted(state) + }) + } + + /** A newly observed exact Session never inherits activation. */ + observeAgent(agent: Agent): void { + this.stateFor(agent) + this.coordinators.observe(sessionRef(agent)) + } + + onAgentStatus(agent: Agent, status: AgentStatus): void { + const state = this.stateFor(agent) + if (status !== 'idle') return + if (state.reservation?.phase === 'claimed' || state.reservation?.phase === 'entered') { + this.retireReservation(state) + } + this.requestEvaluation(state) + } + + /** Ordinary input owns the queue until claim; a claimed automatic batch is committed. */ + onInboxInserted(agent: Agent, message: UserMessage): void { + const state = this.stateFor(agent) + const reservation = state.reservation + if (reservation !== undefined && isReservationMessage(message, reservation)) return + if (reservation?.phase === 'claimed' || reservation?.phase === 'entered') return + this.coordinators.advanceEpoch(sessionRef(agent)) + this.cancelUnadmitted(state) + } + + onInboxClaimed(agent: Agent, message: UserMessage): void { + const reservation = this.states.get(agent)?.reservation + if (reservation !== undefined && isReservationMessage(message, reservation) + && (reservation.phase === 'queued' || reservation.phase === 'reserved')) { + reservation.phase = 'claimed' + } + } + + onInboxDiscarded(agent: Agent, message: UserMessage): void { + const state = this.states.get(agent) + if (state === undefined) return + const reservation = state.reservation + if (reservation !== undefined && isReservationMessage(message, reservation)) { + this.retireReservation(state) + } + if (agent.status === 'idle') this.requestEvaluation(state) + } + + /** Open a neutral barrier, then classify unclaimed handlers in the next microtask. */ + onSessionEvent(agent: Agent, event: SessionEvent): void { + const state = this.stateFor(agent) + if (event.type === 'command/run') { + const commandId = String(event.data.commandId) + this.coordinators.commandRun(commandId, agent.session, agent) + this.cancelUnadmitted(state) + queueMicrotask(() => { + if (this.coordinators.classifyUnclaimed(commandId, agent.session) === 'foreign') { + this.cancelUnadmitted(state) + } + }) + return + } + if (event.type === 'command/done') { + this.coordinators.commandDone(String(event.data.commandId), agent.session) + } + } + + onSessionStart(agent: Agent): void { + const state = this.stateFor(agent) + this.coordinators.invalidate(sessionRef(agent), { clearCaches: true }) + this.cancelUnadmitted(state) + } + + /** Claimed identity is the cancellation cutoff; later authority/input never rejects it. */ + async onPreStep( + agent: Agent, + messages: UserMessage[], + _signal: AbortSignal, + next: () => Promise, + ): Promise { + const state = this.stateFor(agent) + const automatic = messages.filter(isDriverSource) + if (automatic.length === 0) return next() + const reservation = state.reservation + const submitted = automatic[0] + if (automatic.length !== 1 || submitted === undefined || reservation === undefined + || reservation.phase !== 'claimed' || !isReservationMessage(submitted, reservation)) { + this.restoreAndWake(agent, messages) + this.retireReservation(state) + return { kind: 'reject' } + } + let decision: PreStepDecision + try { + decision = await next() + } catch (error: unknown) { + this.restoreAndWake(agent, messages) + this.retireReservation(state) + throw error + } + if (decision.kind === 'reject') { + this.restoreAndWake(agent, messages) + this.retireReservation(state) + return decision + } + reservation.phase = 'entered' + return decision + } + + onAgentDisposed(agent: Agent): void { + const state = this.states.get(agent) + if (state === undefined) return + state.stopping = true + this.cancelUnadmitted(state) + this.states.delete(agent) + const session = sessionRef(agent) + const operation = this.service.disposeSession(session) + .catch(() => { this.warn('dsh-loopx-driver: Session disposal failed') }) + .finally(() => this.coordinators.drop(session)) + this.track(operation) + } + + onSessionDisposed(session: Session): void { + for (const state of this.states.values()) { + if (state.agent.session === session) this.onAgentDisposed(state.agent) + } + } + + async whenSettled(): Promise { + while (this.operations.size > 0) await Promise.allSettled([...this.operations]) + } + + async dispose(): Promise { + if (this.disposed) return this.whenSettled() + this.disposed = true + this.stopCoordinatorEvents() + for (const state of [...this.states.values()]) this.onAgentDisposed(state.agent) + await this.whenSettled() + } + + private stateFor(agent: Agent): DriverState { + const found = this.states.get(agent) + if (found !== undefined) return found + const state: DriverState = { + agent, + stopping: false, + requested: false, + unchangedPollCount: 0, + } + this.states.set(agent, state) + return state + } + + private hasOrdinaryPending(state: DriverState): boolean { + const reservation = state.reservation + return [...state.agent.inbox.nextStep, ...state.agent.inbox.nextTurn].some(message => + reservation === undefined || !isReservationMessage(message, reservation)) + } + + private eligible(state: DriverState, fence: CoordinatorFence): boolean { + return !this.disposed && !state.stopping && this.isLiveAgent(state.agent) + && this.coordinators.isCurrent(fence) && !this.hasOrdinaryPending(state) + && state.reservation === undefined + } + + private ready(state: DriverState): CoordinatorFence | undefined { + if (this.disposed || state.stopping || state.agent.status !== 'idle' + || state.evaluation !== undefined || state.timer !== undefined + || state.reservation !== undefined || this.hasOrdinaryPending(state)) return undefined + return this.coordinators.fence(sessionRef(state.agent)) + } + + private requestEvaluation(state: DriverState): void { + if (this.disposed || state.stopping) return + state.requested = true + const fence = this.ready(state) + if (fence === undefined) { + state.requested = false + return + } + state.requested = false + const controller = new AbortController() + state.controller = controller + let operation: Promise + try { + operation = this.runDetached(() => this.admitEvaluation(state, fence, controller.signal)) + } catch { + state.controller = undefined + this.warn('dsh-loopx-driver: evaluation could not start') + return + } + state.evaluation = operation + this.track(operation) + const finalize = (): void => { + if (state.evaluation === operation) state.evaluation = undefined + if (state.controller === controller) state.controller = undefined + if (state.requested) this.requestEvaluation(state) + } + void operation.then(finalize, finalize) + } + + private async admitEvaluation( + state: DriverState, + fence: CoordinatorFence, + signal: AbortSignal, + ): Promise { + try { + const admitted = await this.coordinators.admitWhenIdle( + state.agent, + signal, + () => this.eligible(state, fence), + maintenanceSignal => this.evaluate( + state, + fence, + AbortSignal.any([signal, maintenanceSignal]), + ), + ) + if (admitted.route === 'running') return + } catch (error: unknown) { + if (signal.aborted || error instanceof CoordinatorAdmissionCancelled) return + this.warn('dsh-loopx-driver: automatic evaluation rejected') + } + } + + private async evaluate( + state: DriverState, + fence: CoordinatorFence, + signal: AbortSignal, + ): Promise { + const session = sessionRef(state.agent) + const topLevel = this.coordinators.beginTopLevel(session) + try { + await this.evaluateAttempt(state, fence, signal, session, topLevel) + } catch { + if (signal.aborted || !this.coordinators.isCurrent(fence)) topLevel.cancel() + else { + topLevel.fail() + this.warn('dsh-loopx-driver: automatic Service attempt failed unexpectedly') + } + } + } + + private async evaluateAttempt( + state: DriverState, + fence: CoordinatorFence, + signal: AbortSignal, + session: LoopXSessionRef, + topLevel: CoordinatorTopLevelOperation, + ): Promise { + const binding = await this.service.resolveBinding(session, signal) + if (!binding.ok) { + this.failAttempt(state, fence, signal, topLevel, binding, binding.application) + return + } + if (binding.value.state !== 'bound' || !sameBinding(binding.value, fence) + || !this.eligible(state, fence)) { + topLevel.cancel() + return + } + + const turnInstanceId = this.makeTurnInstanceId() + const quota = await this.service.quotaShouldRun(session, turnInstanceId, signal) + if (!quota.ok) { + this.failAttempt(state, fence, signal, topLevel, quota, quota.application) + return + } + if (!this.validDecision(quota.value, fence, turnInstanceId) + || !this.eligible(state, fence)) { + topLevel.cancel() + return + } + if (quota.value.terminalNoFollowup) { + topLevel.succeed() + this.coordinators.pause(session) + return + } + if (!quota.value.shouldRun && quota.value.schedulerHint.action !== 'run_now') { + topLevel.succeed() + const delay = waitDelay(state, quota.value.schedulerHint) + if (delay !== undefined && this.eligible(state, fence)) this.schedule(state, fence, delay) + return + } + + const task = await this.service.taskBody(session, true, signal) + if (!task.ok) { + this.failAttempt(state, fence, signal, topLevel, task, task.application) + return + } + if (!sameBinding(task.value.binding, fence) || task.value.body.trim().length === 0 + || !this.eligible(state, fence)) { + topLevel.cancel() + return + } + topLevel.succeed() + this.queueAutomatic(state, fence, task.value.body) + } + + private validDecision( + decision: LoopXQuotaDecision, + fence: CoordinatorFence, + turnInstanceId: string, + ): boolean { + return decision.turnInstanceId === turnInstanceId + && decision.goalId === fence.goalId + && decision.agentId === fence.agentId + && sameBinding(decision.binding, fence) + } + + private failAttempt( + state: DriverState, + fence: CoordinatorFence, + signal: AbortSignal, + topLevel: CoordinatorTopLevelOperation, + result: Extract, { readonly ok: false }>, + application: 'yes' | 'no' | 'unknown', + ): void { + if (signal.aborted || isCoordinatorCancellation(result) + || !this.coordinators.isCurrent(fence)) { + topLevel.cancel() + return + } + topLevel.fail() + const session = sessionRef(state.agent) + const snapshot = this.coordinators.snapshot(session) + if (application !== 'no' || result.error.outcomeUncertain + || !result.error.retryable || snapshot?.automaticFollowupSuppressed === true) return + const retryFence = this.coordinators.fence(session) + if (retryFence !== undefined) this.schedule(state, retryFence, FAIL_CLOSED_RETRY_MS) + } + + private queueAutomatic(state: DriverState, fence: CoordinatorFence, body: string): void { + if (!this.eligible(state, fence)) return + const message = createAutomaticMessage(body) + const reservation: AutomaticReservation = { + messageId: message.id, + content: message.content, + fence, + phase: 'reserved', + } + state.reservation = reservation + try { + state.agent.followup(message) + if (state.reservation === reservation && reservation.phase === 'reserved') { + reservation.phase = 'queued' + } + } catch { + this.retireReservation(state) + this.warn('dsh-loopx-driver: automatic follow-up admission failed') + } + } + + private schedule(state: DriverState, fence: CoordinatorFence, delayMs: number): void { + if (!this.eligible(state, fence) || state.timer !== undefined) return + let scheduled: ScheduledEvaluation + const handle = this.clock.setTimeout(() => { + if (state.timer !== scheduled) return + state.timer = undefined + if (this.coordinators.isCurrent(scheduled.fence)) this.requestEvaluation(state) + }, delayMs) + scheduled = { handle, fence } + state.timer = scheduled + } + + private cancelUnadmitted(state: DriverState): void { + state.requested = false + state.controller?.abort(new Error('LoopX automatic attempt fenced')) + state.controller = undefined + if (state.timer !== undefined) { + this.clock.clearTimeout(state.timer.handle) + state.timer = undefined + } + const reservation = state.reservation + if (reservation === undefined + || reservation.phase === 'claimed' || reservation.phase === 'entered') return + state.agent.inbox.remove(reservation.messageId) + this.retireReservation(state) + } + + private retireReservation(state: DriverState): void { + const reservation = state.reservation + if (reservation === undefined) return + reservation.phase = 'retired' + state.reservation = undefined + } + + /** Requeue non-plugin claimed input through a waking boundary before rejection. */ + private restoreAndWake(agent: Agent, messages: UserMessage[]): void { + for (const message of messages) { + if (isDriverSource(message)) continue + if (agent.inbox.nextStep.some(candidate => candidate.id === message.id) + || agent.inbox.nextTurn.some(candidate => candidate.id === message.id)) continue + agent.send(message, 'next-step', true) + } + } + + private track(operation: Promise): void { + this.operations.add(operation) + void operation.then( + () => { this.operations.delete(operation) }, + () => { this.operations.delete(operation) }, + ) + } +} + +/** Install the Host-plane continuation and command-boundary listeners. */ +export function apply(ctx: Context): void { + const driver = new LoopXContinuationDriver({ + service: ctx.loopx, + isLiveAgent: agent => ctx.fiber.state === FiberState.ACTIVE + && ctx.agents.get(agent.id) === agent, + runDetached: operation => ctx.agents.withoutInitiator(operation), + warn: message => { ctx.logger.warn(message) }, + }) + + ctx.effect(function* () { + ctx.on('agent/created', ({ agent }) => { driver.observeAgent(agent) }) + ctx.on('agent/disposed', ({ agent }) => { driver.onAgentDisposed(agent) }) + ctx.on('agent/session-start', ({ agent }) => { driver.onSessionStart(agent) }) + ctx.on('agent/status', ({ agent, status }) => { driver.onAgentStatus(agent, status) }) + ctx.on('agent/inbox/inserted', ({ agent, message }) => driver.onInboxInserted(agent, message)) + ctx.on('agent/inbox/claimed', ({ agent, message }) => driver.onInboxClaimed(agent, message)) + ctx.on('agent/inbox/discarded', ({ agent, message }) => driver.onInboxDiscarded(agent, message)) + ctx.on('agent/pre-step', ({ agent, messages, signal }, next) => + driver.onPreStep(agent, messages, signal, next)) + ctx.on('session/event', (session, event) => { + const agent = ctx.agents.get(session.id) + if (agent?.session === session) driver.onSessionEvent(agent, event) + }) + ctx.on('session/disposed', session => { driver.onSessionDisposed(session) }) + + for (const agent of ctx.agents.list()) driver.observeAgent(agent) + yield () => driver.dispose() + }, 'dsh-loopx-driver lifecycle') +} diff --git a/packages/dsh-loopx-plugin/src/errors.ts b/packages/dsh-loopx-plugin/src/errors.ts new file mode 100644 index 000000000..a00aa4a95 --- /dev/null +++ b/packages/dsh-loopx-plugin/src/errors.ts @@ -0,0 +1,60 @@ +import type { + LoopXApplication, + LoopXAppliedSubEffect, + LoopXFailure, + LoopXFailureCode, + LoopXResult, +} from './types.ts' + +export interface LoopXFailureOptions { + readonly operation?: string + readonly retryable?: boolean + readonly outcomeUncertain?: boolean +} + +/** Stable failure boundary that never carries CLI output, argv, environment, or locators. */ +export function failure( + code: LoopXFailureCode, + message: string, + options: LoopXFailureOptions = {}, +): LoopXFailure { + return Object.freeze({ + code, + message, + ...(options.operation === undefined ? {} : { operation: options.operation }), + retryable: options.retryable ?? false, + outcomeUncertain: options.outcomeUncertain ?? false, + }) +} + +export function rejected( + error: LoopXFailure, + application: LoopXApplication = error.outcomeUncertain ? 'unknown' : 'no', + subEffects?: readonly LoopXAppliedSubEffect[], +): LoopXResult { + return Object.freeze({ + ok: false, + error, + application, + ...(subEffects === undefined ? {} : { subEffects: Object.freeze([...subEffects]) }), + }) +} + +export function success( + value: T, + application: LoopXApplication = 'no', + subEffects?: readonly LoopXAppliedSubEffect[], +): LoopXResult { + return Object.freeze({ + ok: true, + value, + application, + ...(subEffects === undefined ? {} : { subEffects: Object.freeze([...subEffects]) }), + }) +} + +/** Render a locator only as a non-reversible presence label. */ +export function locatorLabel(value: string | undefined): 'configured' | 'session' | 'unavailable' { + if (value === undefined) return 'unavailable' + return value.length > 0 ? 'configured' : 'session' +} diff --git a/packages/dsh-loopx-plugin/src/index.ts b/packages/dsh-loopx-plugin/src/index.ts new file mode 100644 index 000000000..ee5cdfc1a --- /dev/null +++ b/packages/dsh-loopx-plugin/src/index.ts @@ -0,0 +1,3 @@ +export { LoopXService as default, LoopXService } from './service.ts' +export type { Config as LoopXServiceConfig } from './service.ts' +export type * from './types.ts' diff --git a/packages/dsh-loopx-plugin/src/receipts.ts b/packages/dsh-loopx-plugin/src/receipts.ts new file mode 100644 index 000000000..8860fc08e --- /dev/null +++ b/packages/dsh-loopx-plugin/src/receipts.ts @@ -0,0 +1,199 @@ +import { coordinatorFor, isCoordinatorCancellation } from './coordinator.ts' +import type { + LoopXAttachValue, + LoopXAppliedSubEffect, + LoopXFailure, + LoopXHostThreadBindingV1, + LoopXOperationReceipt, + LoopXResult, + LoopXServiceApi, + LoopXSessionRef, + LoopXStartValue, + LoopXStatusValue, +} from './types.ts' + +export type ReceiptValue = Readonly> + +function recoveryFor(error: LoopXFailure): LoopXOperationReceipt['recovery'] { + if (error.outcomeUncertain) return 'read_authority_then_decide' + if (error.code === 'LOOPX_CLI_ABORTED' || error.code === 'LOOPX_SERVICE_CLOSED') return 'stop' + if (error.code === 'LOOPX_INVALID_REQUEST' + || error.code === 'LOOPX_INVALID_TARGET' + || error.code === 'LOOPX_IDENTITY_CONFLICT' + || error.code === 'LOOPX_SWITCH_CONFIRMATION_INVALID' + || error.code === 'LOOPX_REVISION_CONFLICT') return 'correct_request' + return error.retryable ? 'retry_same_tool' : 'ask_user' +} + +function safeSubEffects( + effects: readonly LoopXAppliedSubEffect[], +): readonly LoopXAppliedSubEffect[] { + return Object.freeze(effects.map(effect => Object.freeze({ + operation: effect.operation, + application: effect.application, + ...(effect.target === undefined ? {} : { target: Object.freeze({ ...effect.target }) }), + }))) +} + +export function unexpectedFailure(operation: string): LoopXFailure { + return Object.freeze({ + code: 'LOOPX_CLI_FAILED', + message: 'The LoopX operation could not be completed.', + operation, + retryable: false, + outcomeUncertain: false, + }) +} + +export function failureReceipt( + operation: string, + error: LoopXFailure, + application: LoopXOperationReceipt['application'] = error.outcomeUncertain ? 'unknown' : 'no', + subEffects?: readonly LoopXAppliedSubEffect[], +): LoopXOperationReceipt { + return Object.freeze({ + schemaVersion: 'dsh_loopx_operation_receipt_v1', + kind: 'operation_result', + operation, + execution: error.outcomeUncertain || application === 'unknown' ? 'indeterminate' : 'rejected', + application, + delivery: 'not_needed', + recovery: application === 'yes' ? 'read_authority_then_decide' : recoveryFor(error), + error: Object.freeze({ ...error }), + ...(subEffects === undefined || subEffects.length === 0 + ? {} + : { subEffects: safeSubEffects(subEffects) }), + }) +} + +export function successReceipt( + operation: string, + application: LoopXOperationReceipt['application'], + value: ReceiptValue, + subEffects?: readonly LoopXAppliedSubEffect[], +): LoopXOperationReceipt { + return Object.freeze({ + schemaVersion: 'dsh_loopx_operation_receipt_v1', + kind: 'operation_result', + operation, + execution: 'succeeded', + application, + delivery: 'not_needed', + recovery: 'none', + value: Object.freeze(value), + ...(subEffects === undefined || subEffects.length === 0 + ? {} + : { subEffects: safeSubEffects(subEffects) }), + }) +} + +export async function serviceOperationReceipt( + service: LoopXServiceApi, + session: LoopXSessionRef, + signal: AbortSignal, + operation: string, + invoke: () => Promise>, + project: (value: T) => ReceiptValue, +): Promise { + const topLevel = coordinatorFor(service).beginTopLevel(session) + let result: LoopXResult + try { + result = await invoke() + } catch { + if (signal.aborted) topLevel.cancel() + else topLevel.fail() + return failureReceipt(operation, unexpectedFailure(operation)) + } + if (!result.ok) { + if (signal.aborted || isCoordinatorCancellation(result)) topLevel.cancel() + else topLevel.fail() + return failureReceipt(operation, result.error, result.application, result.subEffects) + } + topLevel.succeed() + return successReceipt(operation, result.application, project(result.value), result.subEffects) +} + +export function safeBinding(binding: LoopXHostThreadBindingV1): ReceiptValue { + const base = { + schemaVersion: binding.schemaVersion, + hostSurface: binding.hostSurface, + threadId: binding.threadId, + revision: binding.revision, + state: binding.state, + } + return binding.state === 'bound' ? { ...base, target: { ...binding.target } } : base +} + +export function safeStatus(status: LoopXStatusValue): ReceiptValue { + const authority = status.authority + return { + host: { + binarySource: status.host.binarySource, + activation: status.host.activation, + automaticFollowupSuppressed: status.host.automaticFollowupSuppressed, + binding: status.host.binding === undefined ? null : safeBinding(status.host.binding), + }, + authority: authority === undefined ? null : { + schemaVersion: authority.schemaVersion, + ok: authority.ok, + goalId: authority.goalId, + attention: authority.attention.map(item => ({ + goalId: item.goalId, + ...(item.status === undefined ? {} : { status: item.status }), + ...(item.severity === undefined ? {} : { severity: item.severity }), + ...(item.lifecyclePhase === undefined ? {} : { lifecyclePhase: item.lifecyclePhase }), + })), + }, + } +} + +function safeSwitch( + value: Extract, +): ReceiptValue { + const requested = value.requested + return { + kind: value.kind, + confirmationToken: value.confirmationToken, + requiresUserConfirmation: value.requiresUserConfirmation, + expiresAt: value.expiresAt, + expectedRevision: value.expectedRevision, + current: { ...value.current }, + requested: { + operation: requested.operation, + ...(requested.goalId === undefined ? {} : { goalId: requested.goalId }), + ...(requested.agentId === undefined ? {} : { agentId: requested.agentId }), + ...(requested.newPeer === true ? { newPeer: true } : {}), + }, + } +} + +export function safeStart(value: LoopXStartValue): ReceiptValue { + return value.kind === 'planning' + ? { + kind: value.kind, + binding: safeBinding(value.binding), + planning: value.planning, + modelCheckpoint: value.modelCheckpoint, + } + : safeSwitch(value) +} + +export function safeAttach(value: LoopXAttachValue): ReceiptValue { + if (value.kind === 'attached') return { kind: value.kind, binding: safeBinding(value.binding) } + if (value.kind === 'switch_required') return safeSwitch(value) + return { + kind: value.kind, + goalId: value.goalId, + selection: { + kind: value.selection.kind, + defaultAction: value.selection.defaultAction, + choices: value.selection.choices.map(choice => ({ + ...(choice.goalId === undefined ? {} : { goalId: choice.goalId }), + ...(choice.agentId === undefined ? {} : { agentId: choice.agentId }), + })), + ...(value.selection.freshAgentSuggestedId === undefined + ? {} + : { freshAgentSuggestedId: value.selection.freshAgentSuggestedId }), + }, + } +} diff --git a/packages/dsh-loopx-plugin/src/schemas.ts b/packages/dsh-loopx-plugin/src/schemas.ts new file mode 100644 index 000000000..e07ff84ac --- /dev/null +++ b/packages/dsh-loopx-plugin/src/schemas.ts @@ -0,0 +1,538 @@ +import { z } from 'zod' + +const safeInteger = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER) +const nonEmpty = z.string().min(1) +const publicAgentId = z.string().regex(/^[a-z0-9][a-z0-9._-]{0,127}$/u) +const publicThreadId = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u) +const publicGoalId = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u) + +const hostThreadBindingBase = { + schema_version: z.literal('loopx_host_thread_binding_v1'), + host_surface: z.literal('dsh'), + thread_id: publicThreadId, + revision: safeInteger.min(1), +} as const + +export const hostThreadBindingSchema = z.discriminatedUnion('state', [ + z.object({ + ...hostThreadBindingBase, + state: z.literal('bound'), + target: z.object({ + goal_id: publicGoalId, + agent_id: publicAgentId, + }), + }), + z.object({ + ...hostThreadBindingBase, + state: z.literal('unbound'), + }), +]) + +const bindingApplicationSchema = z.enum(['yes', 'no', 'unknown']) +const bindingErrorKindSchema = z.enum([ + 'binding_not_found', + 'revision_conflict', + 'invalid_target', + 'binding_home_uninitialized', + 'binding_home_unavailable', + 'authority_corrupt', + 'authority_unhealthy', + 'authority_exhausted', +]) + +export const hostThreadBindingCommandSchema = z.discriminatedUnion('ok', [ + z.object({ + schema_version: z.literal('loopx_host_thread_binding_command_v1'), + ok: z.literal(true), + changed: z.boolean(), + application: z.enum(['yes', 'no']), + binding: hostThreadBindingSchema, + }), + z.object({ + schema_version: z.literal('loopx_host_thread_binding_command_v1'), + ok: z.literal(false), + changed: z.literal(false), + application: bindingApplicationSchema, + error_kind: bindingErrorKindSchema, + binding: hostThreadBindingSchema.optional(), + }), +]) + +const selectionChoiceSchema = z.looseObject({ + agent_id: publicAgentId, + label: nonEmpty.optional(), +}) + +export const identitySelectionGateSchema = z.looseObject({ + schema_version: z.literal('loopx_host_loop_identity_selection_v0'), + default_action: nonEmpty, + reason: nonEmpty.optional(), + choices: z.array(selectionChoiceSchema).default([]), + fresh_agent_registration: z.looseObject({ + agent_id: nonEmpty.optional(), + }).nullish(), +}) + +export const goalSelectionGateSchema = z.looseObject({ + schema_version: z.literal('loopx_goal_selection_gate_v0'), + state: z.literal('selection_required'), + reason: nonEmpty, + choices: z.array(z.looseObject({ + goal_id: nonEmpty, + })), +}) + +export const startGoalConnectContractSchema = z.looseObject({ + schema_version: z.literal('loopx_start_goal_connect_v0'), + operation: z.literal('bootstrap_connect'), + goal_id: nonEmpty.max(256), + objective: nonEmpty, + adapter_kind: z.literal('read_only_project_map_v0'), + adapter_status: z.literal('connected-read-only'), + onboarding_scan_enabled: z.literal(false), + fine_grained: z.boolean(), +}) + +const goalStartPlannerSchema = z.looseObject({ + required_before_todo_write: z.literal(true), + default_profile: nonEmpty, + profile_selection: nonEmpty, + profiles: z.looseObject({ + open_ended_product_direction: z.looseObject({ + suggested_items_min: safeInteger.min(1), + suggested_items_max: safeInteger.min(1), + intent: nonEmpty, + }), + clear_bounded_problem: z.looseObject({ + item_count_policy: nonEmpty, + may_reuse_current_todo_when_it_already_represents_the_plan: z.boolean(), + intent: nonEmpty, + }), + }), + allowed_priorities: z.tuple([ + z.literal('P0'), + z.literal('P1'), + z.literal('P2'), + ]), + default_role: z.literal('agent'), + default_task_class: z.literal('advancement_task'), + required_fields: z.array(nonEmpty).min(1), + public_safe_only: z.literal(true), + budget_policy: nonEmpty, + fine_grained_plan_horizon: nonEmpty.optional(), + maximum_runnable_todos_written_ahead: safeInteger.min(1).optional(), +}) + +export const goalStartCommandContractSchema = z.looseObject({ + schema_version: z.literal('loopx_goal_start_command_v0'), + goal_text: nonEmpty.nullable(), + planner: goalStartPlannerSchema, + activation: z.looseObject({ + host_loop_required_after_todo_writeback: z.literal(true), + }), + stop_conditions: z.array(nonEmpty).min(1), +}) + +const guidedCommandPackSchema = z.looseObject({ + schema_version: z.literal('loopx_bootstrap_command_pack_v0'), + goal_start_contract: goalStartCommandContractSchema, +}) + +const guidedStepSchema = z.looseObject({ + id: nonEmpty, + kind: nonEmpty, + prompt: nonEmpty.optional(), + connect_contract: startGoalConnectContractSchema.optional(), +}) + +export const projectConnectionSchema = z.looseObject({ + project: nonEmpty, + registry: nonEmpty, + goal_id: nonEmpty.nullish(), + connection_state: z.enum([ + 'not_connected', + 'registry_without_goal', + 'registry_invalid', + 'registry_goal_missing_state_file', + 'state_file_missing', + 'connected', + 'goal_selection_required', + ]), +}) + +const startGoalGuidedSuccessSchema = z.looseObject({ + schema_version: z.literal('loopx_start_goal_guided_v0'), + ok: z.literal(true), + read_only: z.literal(true).optional(), + guided: z.literal(true).optional(), + project: nonEmpty.optional(), + goal_id: nonEmpty.nullish(), + agent_id: publicAgentId.nullish(), + host_surface: z.literal('dsh').optional(), + thread_id: nonEmpty.optional(), + host_thread_binding: hostThreadBindingSchema.optional(), + goal_selection_gate: goalSelectionGateSchema.optional(), + host_surface_selection_gate: z.looseObject({}).optional(), + project_connection: projectConnectionSchema.optional(), + command_pack: guidedCommandPackSchema.optional(), + guided_transaction: z.looseObject({ + schema_version: z.literal('loopx_start_goal_guided_v0'), + blocked_by: nonEmpty.optional(), + identity_selection_gate: identitySelectionGateSchema.nullish(), + ordered_steps: z.array(guidedStepSchema), + }).optional(), +}) + +export const startGoalGuidedSchema = z.discriminatedUnion('ok', [ + startGoalGuidedSuccessSchema, + z.looseObject({ + schema_version: z.literal('loopx_start_goal_guided_v0'), + ok: z.literal(false), + error: nonEmpty, + suggested_command: nonEmpty.optional(), + }), +]) + +const nativeActivationFields = { + host_surface: z.literal('deepseek_harness_native_session'), + activation_method: z.literal('current_session_host_tool'), + activation_input: z.looseObject({ + schema_version: z.literal('loopx_deepseek_harness_native_activation_input_v0'), + tool: z.literal('loopx_goal_activate'), + arguments: z.looseObject({ + goalId: nonEmpty, + agentId: publicAgentId.optional(), + }), + }), + host_mutation: z.looseObject({ + owner: z.literal('DSH LoopX plugin'), + host_tool: z.literal('loopx_goal_activate'), + current_session_only: z.literal(true), + cli_can_mutate_directly: z.literal(false), + forbidden_tool_arguments: z.array(z.string()), + }), +} as const + +const bootstrapCommandPackSuccessSchema = z.looseObject({ + schema_version: z.literal('loopx_bootstrap_command_pack_v0'), + ok: z.literal(true), + read_only: z.literal(true), + project: nonEmpty, + goal_id: nonEmpty, + agent_id: publicAgentId.nullish(), + agent_type: z.literal('deepseek-harness-native'), + host_surface: z.literal('dsh'), + thread_id: nonEmpty.optional(), + host_thread_binding: hostThreadBindingSchema.optional(), + project_connection: projectConnectionSchema.optional(), + host_loop_activation: z.looseObject({ + schema_version: z.literal('loopx_host_loop_activation_v1'), + agent_type: z.literal('deepseek-harness-native'), + goal_id: nonEmpty, + agent_id: publicAgentId.nullish(), + activation_allowed: z.boolean(), + identity_contract: z.looseObject({ + schema_version: z.literal('loopx_host_loop_identity_selection_v0'), + registered_agents: z.array(publicAgentId), + }), + identity_selection_gate: identitySelectionGateSchema.nullish(), + ...nativeActivationFields, + }), +}) + +export const bootstrapCommandPackSchema = z.discriminatedUnion('ok', [ + bootstrapCommandPackSuccessSchema, + z.looseObject({ + schema_version: z.literal('loopx_bootstrap_command_pack_v0'), + ok: z.literal(false), + error: nonEmpty, + error_kind: nonEmpty.optional(), + }), +]) + +export const heartbeatPromptSchema = z.discriminatedUnion('ok', [ + z.looseObject({ + schema_version: z.literal('loopx_heartbeat_prompt_v0'), + ok: z.literal(true), + goal_id: nonEmpty, + agent_id: publicAgentId.nullish(), + runtime_profile: z.literal('generic_cli').optional(), + task_body: nonEmpty, + }), + z.looseObject({ + schema_version: z.literal('loopx_heartbeat_prompt_v0'), + ok: z.literal(false), + goal_id: nonEmpty, + agent_id: publicAgentId.nullish(), + error: nonEmpty, + task_body: z.null(), + }), +]) + +export const statusSchema = z.looseObject({ + schema_version: z.literal('loopx_status_v0'), + ok: z.boolean(), + goal_filter: nonEmpty.nullish(), +}) + +const schedulerHintSchema = z.looseObject({ + schema_version: z.literal('scheduler_hint_v0'), + source: z.literal('quota.should-run'), + action: nonEmpty, + cadence_class: nonEmpty, + reset_policy: z.looseObject({ + reset_token: nonEmpty, + }), + unchanged_poll: z.looseObject({ + limits: z.looseObject({ + local_scheduler: safeInteger.nullish(), + }).optional(), + after_limits: z.looseObject({ + local_scheduler: nonEmpty.optional(), + }).optional(), + }).optional(), + cold_path_detail: z.looseObject({ + schema_version: z.literal('scheduler_hint_detail_v0'), + local_scheduler: z.looseObject({ + recommended_interval_minutes: safeInteger.min(1), + unchanged_poll_limit: safeInteger.nullish(), + after_limit: nonEmpty, + }), + }), +}) + +const terminalStateSchema = z.looseObject({ + schema_version: z.literal('goal_terminal_state_v0'), + kind: z.literal('no_followup'), + derived: z.literal(true), + source: z.literal('validated_goal_closure'), +}) + +const sourceCompletenessSchema = z.looseObject({ + schema_version: z.literal('goal_terminal_source_completeness_v0'), + user_todos: z.literal('valid'), + agent_todos: z.literal('valid'), +}) + +export const quotaShouldRunSchema = z.looseObject({ + schema_version: z.literal('loopx_quota_should_run_v0'), + ok: z.boolean(), + mode: z.literal('should-run'), + goal_id: nonEmpty, + should_run: z.boolean(), + effective_action: nonEmpty, + agent_identity: z.looseObject({ + agent_id: publicAgentId, + }), + scheduler_hint: schedulerHintSchema, + heartbeat_receipt: z.looseObject({ + schema_version: z.literal('heartbeat_quota_receipt_v0'), + turn_instance_id: nonEmpty, + status: z.enum(['committed', 'replayed']), + }).optional(), + goal_frontier_projection: z.looseObject({ + terminal_state: terminalStateSchema.optional(), + source_completeness: sourceCompletenessSchema.optional(), + acceptance_gaps: z.array(z.unknown()).optional(), + autonomy_blockers: z.array(z.unknown()).optional(), + replan_required: z.boolean().optional(), + }).optional(), +}) + +export const todoCommandSchema = z.discriminatedUnion('ok', [ + z.looseObject({ + schema_version: z.literal('loopx_todo_command_v0'), + ok: z.literal(true), + dry_run: z.literal(false), + goal_id: nonEmpty, + todo_id: nonEmpty, + status: nonEmpty.optional(), + changed: z.boolean(), + }), + z.looseObject({ + schema_version: z.literal('loopx_todo_command_v0'), + ok: z.literal(false), + goal_id: nonEmpty, + changed: z.boolean().optional(), + partial_write: z.boolean().optional(), + error: nonEmpty.optional(), + error_code: nonEmpty.optional(), + }), +]) + +export const todoAddCommandSchema = z.discriminatedUnion('ok', [ + z.looseObject({ + schema_version: z.literal('loopx_todo_command_v0'), + ok: z.literal(true), + dry_run: z.literal(false), + added: z.boolean(), + already_exists: z.boolean(), + goal_id: nonEmpty, + role: z.enum(['user', 'agent']), + todo: nonEmpty, + todo_id: nonEmpty.nullable(), + status: z.enum(['open', 'done', 'blocked', 'deferred']).nullable(), + task_class: nonEmpty.nullable(), + action_kind: nonEmpty.nullable(), + claimed_by: publicAgentId.nullable(), + bound_agent: publicAgentId.nullable(), + agent_id: publicAgentId.nullable(), + blocks_agent: publicAgentId.nullable(), + target_key: nonEmpty.nullable(), + }), + z.looseObject({ + schema_version: z.literal('loopx_todo_command_v0'), + ok: z.literal(false), + dry_run: z.boolean(), + added: z.literal(false), + already_exists: z.literal(false), + goal_id: nonEmpty, + role: z.enum(['user', 'agent']).nullish(), + todo: z.string(), + error: nonEmpty, + error_kind: nonEmpty.optional(), + error_code: nonEmpty.optional(), + }), +]) + +const refreshGlobalSyncSchema = z.looseObject({ + ok: z.boolean(), + skipped: z.boolean().optional(), + reason: nonEmpty.optional(), + registry: nonEmpty.optional(), + global_registry: nonEmpty, + synced_goal_ids: z.array(nonEmpty), + wrote: z.boolean().optional(), +}) + +const refreshStateResultSuccessSchema = z.looseObject({ + schema_version: z.literal('loopx_refresh_state_result_v0'), + ok: z.literal(true), + dry_run: z.boolean(), + appended: z.boolean(), + idempotent_replay: z.boolean().optional(), + partial_write: z.boolean().optional(), + registry: nonEmpty, + project: nonEmpty, + goal_id: nonEmpty, + agent_id: publicAgentId, + agent_lane: publicAgentId, + progress_scope: z.literal('agent_lane'), + external_sink_delivery_authorized: z.boolean(), + global_sync: refreshGlobalSyncSchema, + }) + +export const refreshStateResultSchema = z.discriminatedUnion('ok', [ + refreshStateResultSuccessSchema, + z.looseObject({ + schema_version: z.literal('loopx_refresh_state_result_v0'), + ok: z.literal(false), + dry_run: z.boolean(), + appended: z.boolean(), + registry: nonEmpty, + runtime_root: z.string().nullish(), + goal_id: nonEmpty, + classification: nonEmpty.optional(), + project: nonEmpty.optional(), + agent_id: publicAgentId.optional(), + agent_lane: publicAgentId.optional(), + progress_scope: z.literal('agent_lane').optional(), + external_sink_delivery_authorized: z.boolean().optional(), + global_sync: refreshGlobalSyncSchema.optional(), + idempotent_replay: z.boolean().optional(), + error: nonEmpty.optional(), + error_kind: nonEmpty.optional(), + partial_write: z.boolean().optional(), + }), +]) + +const agentRegistrationReadbackSchema = z.looseObject({ + schema_version: z.literal('loopx_agent_registration_readback_v0'), + performed: z.boolean(), + verified: z.boolean(), + requested_agents: z.array(publicAgentId).optional(), + source_registered_agents: z.array(publicAgentId).optional(), + global_registered_agents: z.array(publicAgentId).optional(), +}) + +const agentRegistrationGlobalSyncSchema = z.looseObject({ + ok: z.boolean(), + wrote: z.boolean().optional(), + phase: z.enum(['preflight', 'commit']).optional(), + error_kind: nonEmpty.optional(), +}) + +export const registerAgentSchema = z.discriminatedUnion('ok', [ + z.looseObject({ + schema_version: z.literal('loopx_register_agent_v0'), + ok: z.literal(true), + goal_id: nonEmpty, + changed: z.literal(true), + written: z.literal(true), + partial_write: z.literal(false), + requested_agents: z.array(publicAgentId).min(1), + registered_agents: z.array(publicAgentId), + registration_readback: agentRegistrationReadbackSchema.extend({ + performed: z.literal(true), + verified: z.literal(true), + requested_agents: z.array(publicAgentId).min(1), + source_registered_agents: z.array(publicAgentId), + global_registered_agents: z.array(publicAgentId), + }), + global_sync: agentRegistrationGlobalSyncSchema.extend({ + ok: z.literal(true), + }), + }), + z.looseObject({ + schema_version: z.literal('loopx_register_agent_v0'), + ok: z.literal(false), + goal_id: nonEmpty, + changed: z.boolean(), + written: z.boolean(), + partial_write: z.boolean(), + error_kind: nonEmpty, + requested_agents: z.array(publicAgentId).optional(), + registered_agents: z.array(publicAgentId).optional(), + registration_readback: agentRegistrationReadbackSchema, + global_sync: agentRegistrationGlobalSyncSchema, + }), +]) + +const bootstrapGlobalSyncSchema = z.looseObject({ + ok: z.literal(true), + synced_goal_ids: z.array(nonEmpty), + wrote: z.boolean().optional(), +}) + +export const bootstrapResultSchema = z.discriminatedUnion('ok', [ + z.looseObject({ + schema_version: z.literal('loopx_bootstrap_result_v0'), + ok: z.literal(true), + project: nonEmpty, + goal_id: nonEmpty, + registry: nonEmpty, + state_file: nonEmpty, + registry_goal_action: nonEmpty, + state_action: nonEmpty, + global_sync: bootstrapGlobalSyncSchema, + }), + z.looseObject({ + schema_version: z.literal('loopx_bootstrap_result_v0'), + ok: z.literal(false), + error_kind: nonEmpty, + }), +]) + +export type StartGoalGuidedPayload = z.infer +export type StartGoalGuidedSuccessPayload = z.infer +export type BootstrapCommandPackPayload = z.infer +export type BootstrapCommandPackSuccessPayload = z.infer +export type BootstrapResultPayload = z.infer +export type HeartbeatPromptPayload = z.infer +export type QuotaShouldRunPayload = z.infer +export type TodoCommandPayload = z.infer +export type TodoAddCommandPayload = z.infer +export type RefreshStateResultPayload = z.infer +export type RefreshStateResultSuccessPayload = z.infer +export type HostThreadBindingPayload = z.infer +export type HostThreadBindingCommandPayload = z.infer diff --git a/packages/dsh-loopx-plugin/src/service.ts b/packages/dsh-loopx-plugin/src/service.ts new file mode 100644 index 000000000..5084fb99d --- /dev/null +++ b/packages/dsh-loopx-plugin/src/service.ts @@ -0,0 +1,2002 @@ +import { randomUUID } from 'node:crypto' +import { resolve } from 'node:path' +import { Context, Service } from '@deepseek-ai/cordis' +import s from '@deepseek-ai/schemastery' +import { + CoordinatorAdmissionCancelled, + CoordinatorRegistry, + installCoordinator, + type LoopXBindingHome, +} from './coordinator.ts' +import { LoopXCliClient, LoopXCliError } from './cli-client.ts' +import { failure, rejected, success } from './errors.ts' +import { + bootstrapCommandPackSchema, + bootstrapResultSchema, + heartbeatPromptSchema, + hostThreadBindingCommandSchema, + quotaShouldRunSchema, + refreshStateResultSchema, + registerAgentSchema, + startGoalGuidedSchema, + statusSchema, + todoAddCommandSchema, + todoCommandSchema, +} from './schemas.ts' +import type { + BootstrapCommandPackPayload, + BootstrapCommandPackSuccessPayload, + HeartbeatPromptPayload, + HostThreadBindingCommandPayload, + HostThreadBindingPayload, + QuotaShouldRunPayload, + StartGoalGuidedPayload, + StartGoalGuidedSuccessPayload, + TodoAddCommandPayload, + TodoCommandPayload, +} from './schemas.ts' +import type { + LoopXAttachRequest, + LoopXAttachValue, + LoopXApplication, + LoopXAppliedSubEffect, + LoopXBoundHostThreadBindingV1, + LoopXDetachValue, + LoopXFailure, + LoopXGoalAgentRef, + LoopXHostStatus, + LoopXHostThreadBindingV1, + LoopXIdentitySelection, + LoopXPauseValue, + LoopXPlanningCheckpoint, + LoopXQuotaDecision, + LoopXQuotaAuthority, + LoopXResult, + LoopXServiceApi, + LoopXSchedulerHint, + LoopXSessionRef, + LoopXStartOptions, + LoopXStartValue, + LoopXStatusValue, + LoopXStatusAuthority, + LoopXStatusAttentionItem, + LoopXSwitchRequired, + LoopXTaskBody, + LoopXTodoAddRequest, + LoopXTodoAddAuthority, + LoopXTodoAddValue, + LoopXTodoClaimRequest, + LoopXTodoCompleteRequest, + LoopXTodoMutationValue, + LoopXTodoMutationAuthority, + LoopXTodoUpdateRequest, +} from './types.ts' + +const HOST_SURFACE = 'dsh' +const RUNTIME_PROFILE = 'generic_cli' +const AGENT_SCOPE = 'DeepSeek Harness same-session LoopX plugin gated by LoopX' +const PUBLIC_AGENT_ID = /^[a-z0-9][a-z0-9._-]{0,127}$/u +const PUBLIC_THREAD_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u +const PUBLIC_GOAL_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u +const PUBLIC_CODE_TOKEN = /^[A-Za-z][A-Za-z0-9._:-]{0,127}$/u +const SWITCH_CONFIRMATION_TTL_MS = 2 * 60 * 1000 +const PLANNING_TODO_LIMIT_CAP = 5 +const PUBLIC_ACTION_KIND = /^[a-z][a-z0-9._:-]{0,63}$/u +const PUBLIC_TARGET_KEY = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u +const PRIORITY_PREFIX = /^\[P[012]\](?:\s|$)/iu +const UNSAFE_TODO_TEXT = /[\u0000-\u001F\u007F]/u +const FORBIDDEN_ACTIVATION_ARGUMENTS = new Set([ + 'sessionId', + 'registryPath', + 'taskBody', + 'argv', +]) + +export interface Config { + /** Explicit locally installed LoopX executable. Falls back to LOOPX_BIN, then PATH. */ + readonly loopxBin?: string + /** Child-process cwd fallback only when `runtimeRoot` explicitly selects authority. */ + readonly project?: string + /** Optional explicit LoopX binding home. */ + readonly runtimeRoot?: string + readonly readTimeoutMs?: number + readonly writeTimeoutMs?: number + readonly stdoutCapBytes?: number + readonly stderrCapBytes?: number + /** Explicit child-only variables. The ambient environment is not inherited. */ + readonly environment?: Readonly> +} + +interface NormalizedTodoAddRequest { + readonly priority: 'P0' | 'P1' | 'P2' + readonly role: 'user' | 'agent' + readonly actionKind: string + readonly targetKey?: string | undefined + readonly normalizedTodo: string +} + +interface BindingMutationBase { + readonly home: LoopXBindingHome + readonly revision: number + readonly binding?: LoopXHostThreadBindingV1 | undefined +} + +type BindingAuthorityRead = + | { + readonly ok: true + readonly binding: LoopXHostThreadBindingV1 + } + | { + readonly ok: false + readonly error: LoopXFailure + readonly application: LoopXApplication + readonly binding?: LoopXHostThreadBindingV1 | undefined + } + +interface SwitchConfirmationRecord { + readonly token: string + readonly sessionObject: object + readonly operation: 'start' | 'attach' + readonly expiresAt: number + readonly expectedRevision: number + readonly current: LoopXGoalAgentRef + readonly requested: LoopXGoalAgentRef + readonly goalText?: string | undefined + readonly newPeer: boolean +} + +declare module '@deepseek-ai/cordis' { + interface Context { + loopx: LoopXService + } +} + +function present(value: string | null | undefined): string | undefined { + const normalized = value?.trim() + return normalized ? normalized : undefined +} + +function optional(condition: boolean, value: T): T | Record { + return condition ? value : {} +} + +function argsWhen(condition: boolean, ...values: string[]): string[] { + return condition ? values : [] +} + +function isRecord(value: unknown): value is Readonly> { + return typeof value === 'object' && value !== null && !Array.isArray(value) +} + +function normalizedGoalText(value: string): string | undefined { + const normalized = value.trim().replace(/\s+/gu, ' ') + return normalized.length === 0 ? undefined : normalized +} + +function validGoalId(value: string | undefined): value is string { + return value !== undefined && PUBLIC_GOAL_ID.test(value) +} + +function validTodoId(value: string | undefined): value is string { + return value !== undefined && PUBLIC_GOAL_ID.test(value) +} + +function validateSession(session: LoopXSessionRef): LoopXFailure | undefined { + if (typeof session.session !== 'object' || session.session === null + || !PUBLIC_THREAD_ID.test(session.id)) { + return failure('LOOPX_INVALID_REQUEST', 'The current DSH Session identity is invalid.') + } + if (!Number.isSafeInteger(session.identity.createdAt) || session.identity.createdAt < 0) { + return failure('LOOPX_SESSION_LIFECYCLE_MISMATCH', 'The current DSH Session lifecycle is invalid.') + } + if (session.identity.cwd?.includes('\0')) { + return failure('LOOPX_INVALID_REQUEST', 'The current DSH Session working directory is invalid.') + } + return undefined +} + +function safeFailure(error: unknown, operation: string): LoopXFailure { + if (error instanceof LoopXCliError) return error.failure + return failure('LOOPX_CLI_FAILED', 'The LoopX operation could not be completed.', { operation }) +} + +function readbackFailure(operation: string, message: string): LoopXFailure { + return failure('LOOPX_READBACK_FAILED', message, { operation }) +} + +function applied(operation: string, target?: LoopXGoalAgentRef): LoopXAppliedSubEffect { + return Object.freeze({ + operation, + application: 'yes' as const, + ...optional(target !== undefined, { target: target as LoopXGoalAgentRef }), + }) +} + +function resultWithEffects( + result: LoopXResult, + prior: readonly LoopXAppliedSubEffect[], +): LoopXResult { + const effects = Object.freeze([...prior, ...(result.subEffects ?? [])]) + const application: LoopXApplication = result.application === 'unknown' + ? 'unknown' + : effects.length > 0 ? 'yes' : result.application + return result.ok + ? success(result.value, application, effects) + : rejected(result.error, application, effects) +} + +function sameBinding( + left: LoopXHostThreadBindingV1, + right: LoopXHostThreadBindingV1, +): boolean { + if (left.state !== right.state || left.threadId !== right.threadId + || left.revision !== right.revision) return false + if (left.state === 'unbound' || right.state === 'unbound') return true + return left.target.goalId === right.target.goalId + && left.target.agentId === right.target.agentId +} + +function bindingFromPayload(payload: HostThreadBindingPayload): LoopXHostThreadBindingV1 { + const base = { + schemaVersion: 'loopx_host_thread_binding_v1' as const, + hostSurface: 'dsh' as const, + threadId: payload.thread_id, + revision: payload.revision, + } + return payload.state === 'bound' + ? Object.freeze({ + ...base, + state: 'bound' as const, + target: Object.freeze({ + goalId: payload.target.goal_id, + agentId: payload.target.agent_id, + }), + }) + : Object.freeze({ ...base, state: 'unbound' as const }) +} + +function bindingFailure(payload: Extract, operation: string): LoopXFailure { + const codes = { + binding_not_found: 'LOOPX_BINDING_NOT_FOUND', + revision_conflict: 'LOOPX_REVISION_CONFLICT', + invalid_target: 'LOOPX_INVALID_TARGET', + binding_home_uninitialized: 'LOOPX_BINDING_HOME_UNINITIALIZED', + binding_home_unavailable: 'LOOPX_BINDING_HOME_UNAVAILABLE', + authority_corrupt: 'LOOPX_AUTHORITY_CORRUPT', + authority_unhealthy: 'LOOPX_AUTHORITY_UNHEALTHY', + authority_exhausted: 'LOOPX_AUTHORITY_EXHAUSTED', + } as const + const messages = { + binding_not_found: 'No DSH Host binding exists for this exact Session.', + revision_conflict: 'The DSH Host binding revision changed; read authority before deciding again.', + invalid_target: 'LoopX rejected the exact Goal-Agent binding target.', + binding_home_uninitialized: 'The selected LoopX binding home has not been initialized.', + binding_home_unavailable: 'The selected LoopX binding home is unavailable.', + authority_corrupt: 'The selected LoopX binding authority is corrupt.', + authority_unhealthy: 'The selected LoopX binding authority is unhealthy.', + authority_exhausted: 'The selected LoopX binding authority exhausted its revision space.', + } as const + return failure(codes[payload.error_kind], messages[payload.error_kind], { + operation, + outcomeUncertain: payload.application === 'unknown', + }) +} + +function identitySelection(gate: { + readonly default_action: string + readonly reason?: string | undefined + readonly choices: readonly { readonly agent_id: string; readonly label?: string | undefined }[] + readonly fresh_agent_registration?: { readonly agent_id?: string | undefined } | null | undefined +}): LoopXIdentitySelection { + const suggested = present(gate.fresh_agent_registration?.agent_id) + return Object.freeze({ + kind: 'agent', + defaultAction: PUBLIC_CODE_TOKEN.test(gate.default_action) + ? gate.default_action + : 'select_agent_identity', + choices: Object.freeze(gate.choices.map(choice => Object.freeze({ + agentId: choice.agent_id, + }))), + ...optional(suggested !== undefined && PUBLIC_AGENT_ID.test(suggested), { + freshAgentSuggestedId: suggested as string, + }), + }) +} + +function modelCheckpoint(payload: StartGoalGuidedSuccessPayload): string | undefined { + const checkpoints = (payload.guided_transaction?.ordered_steps ?? []) + .filter(step => step.kind === 'model_checkpoint' && present(step.prompt) !== undefined) + return checkpoints.length === 1 ? present(checkpoints[0]?.prompt) : undefined +} + +function planningCheckpoint( + payload: StartGoalGuidedSuccessPayload, + goalText: string, + goalId: string, + agentId: string, +): LoopXPlanningCheckpoint | undefined { + if (modelCheckpoint(payload) === undefined) return undefined + const contract = payload.command_pack?.goal_start_contract + const planner = contract?.planner + const openEnded = planner?.profiles.open_ended_product_direction + const bounded = planner?.profiles.clear_bounded_problem + const required = planner?.required_fields ?? [] + if (contract === undefined || planner === undefined + || contract.goal_text !== goalText || openEnded === undefined || bounded === undefined + || openEnded.suggested_items_min > openEnded.suggested_items_max + || !['priority', 'text', 'task_class', 'action_kind'] + .every(field => required.includes(field))) return undefined + const limit = Math.min( + planner.maximum_runnable_todos_written_ahead ?? PLANNING_TODO_LIMIT_CAP, + PLANNING_TODO_LIMIT_CAP, + ) + return Object.freeze({ + schemaVersion: 'dsh_loopx_planning_checkpoint_v1' as const, + goalId, + agentId, + goalText, + planner: Object.freeze({ + defaultProfile: planner.default_profile === 'open_ended_product_direction' + ? 'open_ended_product_direction' + : 'clear_bounded_problem', + profileSelection: 'choose_by_problem_shape', + openEndedProductDirection: Object.freeze({ + suggestedItemsMin: openEnded.suggested_items_min, + suggestedItemsMax: openEnded.suggested_items_max, + intent: 'Produce a bounded runnable plan before activation.', + }), + clearBoundedProblem: Object.freeze({ + itemCountPolicy: 'planner_sized', + mayReuseCurrentTodoWhenItAlreadyRepresentsThePlan: + bounded.may_reuse_current_todo_when_it_already_represents_the_plan, + intent: 'Represent the complete bounded problem with runnable Todos.', + }), + allowedPriorities: Object.freeze(['P0', 'P1', 'P2'] as const), + defaultRole: 'agent' as const, + defaultTaskClass: 'advancement_task' as const, + requiredFields: Object.freeze(['priority', 'text', 'task_class', 'action_kind']), + publicSafeOnly: true as const, + budgetPolicy: 'respect_loopx_quota', + }), + writeback: Object.freeze({ + todoTool: 'loopx_todo_add' as const, + minimumTodos: 1 as const, + maximumTodos: limit, + ordering: 'priority_then_tool_call_order' as const, + activationTool: 'loopx_goal_activate' as const, + activationArguments: Object.freeze({ goalId, agentId }), + }), + stopConditions: Object.freeze([ + 'user_gate', + 'no_runnable_agent_todo', + 'terminal_no_followup', + ]), + forbidden: Object.freeze([ + 'shell_or_bash', + 'raw_loopx_cli', + 'registry_edit', + 'ctx.goals', + ] as const), + }) +} + +function renderPlanningCheckpoint(checkpoint: LoopXPlanningCheckpoint): string { + return [ + 'Follow this DSH-native LoopX planning checkpoint. Use only the named typed tools; do not execute shell or returned CLI text.', + JSON.stringify(checkpoint), + ].join('\n') +} + +function normalizeTodoAddRequest(request: LoopXTodoAddRequest): LoopXResult { + const allowed = new Set(['text', 'priority', 'role', 'actionKind', 'targetKey']) + const text = present(request.text) + const role = request.role ?? 'agent' + const actionKind = present(request.actionKind) + ?? (role === 'agent' ? 'advance' : 'owner_decision') + const targetKey = present(request.targetKey) + if (!Object.keys(request).every(key => allowed.has(key)) + || text === undefined || text.length > 1000 || UNSAFE_TODO_TEXT.test(text) + || PRIORITY_PREFIX.test(text) || !['P0', 'P1', 'P2'].includes(request.priority) + || !['user', 'agent'].includes(role) || !PUBLIC_ACTION_KIND.test(actionKind) + || (request.actionKind !== undefined && present(request.actionKind) === undefined) + || (request.targetKey !== undefined && targetKey === undefined) + || (targetKey !== undefined && !PUBLIC_TARGET_KEY.test(targetKey)) + || (role === 'user' && targetKey !== undefined)) { + return rejected(failure( + 'LOOPX_INVALID_REQUEST', + 'Todo add requires bounded public-safe text, one P0/P1/P2 priority, and supported bounded fields.', + { operation: 'todo-add' }, + )) + } + return success(Object.freeze({ + priority: request.priority, + role, + actionKind, + ...optional(targetKey !== undefined, { targetKey: targetKey as string }), + normalizedTodo: `[${request.priority}] ${text}`, + })) +} + +function activationReadbackMatches( + payload: BootstrapCommandPackPayload, + session: LoopXSessionRef, + binding: LoopXBoundHostThreadBindingV1, +): payload is BootstrapCommandPackSuccessPayload { + if (!payload.ok) return false + const activation = payload.host_loop_activation + const input = activation.activation_input + const forbidden = activation.host_mutation.forbidden_tool_arguments + const projected = payload.host_thread_binding + return payload.goal_id === binding.target.goalId + && payload.agent_id === binding.target.agentId + && payload.thread_id === session.id + && projected !== undefined + && sameBinding(bindingFromPayload(projected), binding) + && activation.activation_allowed + && activation.agent_id === binding.target.agentId + && activation.goal_id === binding.target.goalId + && input.arguments.goalId === binding.target.goalId + && input.arguments.agentId === binding.target.agentId + && [...FORBIDDEN_ACTIVATION_ARGUMENTS].every(field => forbidden.includes(field)) + && Object.keys(input.arguments).every(field => !FORBIDDEN_ACTIVATION_ARGUMENTS.has(field)) +} + +function schedulerHint(payload: QuotaShouldRunPayload): LoopXSchedulerHint | undefined { + const hint = payload.scheduler_hint + const resetToken = hint.reset_policy.reset_token + if (!PUBLIC_CODE_TOKEN.test(hint.action) || !PUBLIC_CODE_TOKEN.test(hint.cadence_class) + || !PUBLIC_CODE_TOKEN.test(resetToken)) return undefined + const detail = payload.scheduler_hint.cold_path_detail.local_scheduler + return Object.freeze({ + action: hint.action, + cadenceClass: hint.cadence_class, + resetToken, + recommendedIntervalMinutes: detail.recommended_interval_minutes, + ...optional(detail.unchanged_poll_limit !== null, { + unchangedPollLimit: detail.unchanged_poll_limit as number, + }), + }) +} + +function terminalClosureIsComplete(payload: QuotaShouldRunPayload): boolean { + const projection = payload.goal_frontier_projection + return !payload.should_run && payload.effective_action === 'terminal_no_followup' + && projection?.terminal_state?.kind === 'no_followup' + && projection.terminal_state.derived === true + && projection.source_completeness?.user_todos === 'valid' + && projection.source_completeness.agent_todos === 'valid' + && projection.acceptance_gaps?.length === 0 + && projection.autonomy_blockers?.length === 0 + && projection.replan_required === false +} + +function boundedStatusProjection( + payload: Readonly>, + goalId: string, +): LoopXStatusAuthority { + const queue = isRecord(payload.attention_queue) ? payload.attention_queue : undefined + const rawItems = Array.isArray(queue?.items) ? queue.items : [] + const items: LoopXStatusAttentionItem[] = rawItems.flatMap((value) => { + if (!isRecord(value) || String(value.goal_id ?? '') !== goalId) return [] + const projected: LoopXStatusAttentionItem = Object.freeze({ + goalId, + ...optional(typeof value.status === 'string' && PUBLIC_CODE_TOKEN.test(value.status), { + status: value.status as string, + }), + ...optional(typeof value.severity === 'string' && PUBLIC_CODE_TOKEN.test(value.severity), { + severity: value.severity as string, + }), + ...optional(typeof value.lifecycle_phase === 'string' + && PUBLIC_CODE_TOKEN.test(value.lifecycle_phase), { + lifecyclePhase: value.lifecycle_phase as string, + }), + }) + return [Object.freeze(projected)] + }) + return Object.freeze({ + schemaVersion: 'loopx_status_projection_v1' as const, + ok: true as const, + goalId, + attention: Object.freeze(items), + }) +} + +function boundedTodoProjection( + payload: Extract, +): LoopXTodoMutationAuthority { + const projected: { + schemaVersion: 'loopx_todo_projection_v1' + goalId: string + todoId: string + status?: string + changed?: boolean + claimedBy?: string + taskClass?: string + settlementResult?: string + } = { + schemaVersion: 'loopx_todo_projection_v1' as const, + goalId: payload.goal_id, + todoId: payload.todo_id, + } + if (typeof payload.status === 'string' && PUBLIC_CODE_TOKEN.test(payload.status)) { + projected.status = payload.status + } + projected.changed = payload.changed + if (typeof payload.claimed_by === 'string' && PUBLIC_AGENT_ID.test(payload.claimed_by)) { + projected.claimedBy = payload.claimed_by + } + if (typeof payload.task_class === 'string' && PUBLIC_CODE_TOKEN.test(payload.task_class)) { + projected.taskClass = payload.task_class + } + if (typeof payload.settlement_result === 'string' + && PUBLIC_CODE_TOKEN.test(payload.settlement_result)) { + projected.settlementResult = payload.settlement_result + } + return Object.freeze(projected) +} + +function boundedTodoAddProjection( + payload: Extract, + todoId: string, + taskClass: string, + actionKind: string, +): LoopXTodoAddAuthority { + return Object.freeze({ + schemaVersion: 'loopx_todo_projection_v1' as const, + goalId: payload.goal_id, + todoId, + status: 'open' as const, + role: payload.role, + taskClass, + actionKind, + added: payload.added, + alreadyExists: payload.already_exists, + }) +} + +function boundedQuotaProjection(payload: QuotaShouldRunPayload): LoopXQuotaAuthority { + const projected: { + schemaVersion: 'loopx_quota_projection_v1' + goalId: string + shouldRun: boolean + effectiveAction: string + decision?: string + state?: string + } = { + schemaVersion: 'loopx_quota_projection_v1' as const, + goalId: payload.goal_id, + shouldRun: payload.should_run, + effectiveAction: payload.effective_action, + } + for (const key of ['decision', 'state'] as const) { + if (typeof payload[key] === 'string' && PUBLIC_CODE_TOKEN.test(payload[key])) { + projected[key] = payload[key] + } + } + return Object.freeze(projected) +} + +/** Host-only service. LoopX remains the sole durable authority. */ +export class LoopXService extends Service implements LoopXServiceApi { + static Config: s = s.object({ + loopxBin: s.string(), + project: s.string(), + runtimeRoot: s.string(), + readTimeoutMs: s.number().step(1).min(1).default(15_000), + writeTimeoutMs: s.number().step(1).min(1).default(30_000), + stdoutCapBytes: s.number().step(1).min(1).default(1_048_576), + stderrCapBytes: s.number().step(1).min(1).default(262_144), + environment: s.dict(s.string()).default({}), + }) + + private readonly config: Config + private readonly cli: LoopXCliClient + private readonly coordinators: CoordinatorRegistry + private admissionOpen = true + + constructor(ctx: Context, config: Config) { + super(ctx, 'loopx') + this.config = config + this.cli = new LoopXCliClient({ + ...optional(present(config.loopxBin) !== undefined, { + loopxBin: present(config.loopxBin) as string, + }), + ...optional(config.readTimeoutMs !== undefined, { + readTimeoutMs: config.readTimeoutMs as number, + }), + ...optional(config.writeTimeoutMs !== undefined, { + writeTimeoutMs: config.writeTimeoutMs as number, + }), + ...optional(config.stdoutCapBytes !== undefined, { + stdoutCapBytes: config.stdoutCapBytes as number, + }), + ...optional(config.stderrCapBytes !== undefined, { + stderrCapBytes: config.stderrCapBytes as number, + }), + environment: config.environment ?? {}, + }) + this.coordinators = new CoordinatorRegistry(scopeKey => this.cli.abortScope(scopeKey)) + installCoordinator(this, this.coordinators) + } + + protected async [Service.init](): Promise { + this.ctx.effect(() => async () => { + this.admissionOpen = false + const draining = this.coordinators.drainAll() + this.coordinators.close() + await this.cli.close() + await draining + }, 'dsh-loopx-plugin.close') + } + + resolveBinding( + session: LoopXSessionRef, + signal?: AbortSignal, + ): Promise> { + return this.queued(session, 'resolve-agent-thread', async () => { + const home = this.bindingHome(session) + if (!home.ok) return home + return this.resolveBindingInside(session, home.value, signal) + }) + } + + start( + session: LoopXSessionRef, + goalText: string, + signal?: AbortSignal, + options?: LoopXStartOptions, + ): Promise> { + const objective = normalizedGoalText(goalText) + const confirmationToken = present(options?.switchConfirmation) + if (objective === undefined || !Object.keys(options ?? {}).every(key => key === 'switchConfirmation') + || (options?.switchConfirmation !== undefined && confirmationToken === undefined)) { + return Promise.resolve(rejected(failure( + 'LOOPX_INVALID_REQUEST', + 'Goal start requires one non-empty objective and an optional exact switch confirmation.', + { operation: 'start' }, + ))) + } + return this.queued(session, 'start', async () => { + const current = await this.bindingForMutation(session, signal) + if (!current.ok) return current + let target: LoopXGoalAgentRef + if (current.value.binding?.state === 'bound') { + const record = confirmationToken === undefined + ? undefined + : this.validConfirmation(session, confirmationToken, 'start', current.value.binding, objective) + if (record === undefined) { + if (confirmationToken !== undefined) return rejected(this.invalidConfirmation('start')) + target = Object.freeze({ goalId: this.freshGoalId(), agentId: this.freshAgentId() }) + return success(this.prepareSwitch(session, 'start', current.value.binding, target, false, objective)) + } + target = record.requested + this.coordinators.clearConfirmation(session) + } else { + if (confirmationToken !== undefined) return rejected(this.invalidConfirmation('start')) + target = Object.freeze({ goalId: this.freshGoalId(), agentId: this.freshAgentId() }) + } + + this.coordinators.pause(session) + const effects: LoopXAppliedSubEffect[] = [] + const bootstrapped = await this.bootstrapGoal(session, current.value.home, target.goalId, objective, signal) + if (!bootstrapped.ok) return bootstrapped + effects.push(...(bootstrapped.subEffects ?? [])) + const registered = await this.registerFreshAgent(session, current.value.home, target, signal) + if (!registered.ok) return resultWithEffects(registered, effects) + effects.push(...(registered.subEffects ?? [])) + const bound = await this.bindTarget( + session, + current.value.home, + target, + current.value.revision, + signal, + ) + if (!bound.ok) return resultWithEffects(bound, effects) + effects.push(...(bound.subEffects ?? [])) + + let packet: StartGoalGuidedPayload + try { + packet = await this.readStartPacket(session, current.value.home, objective, target, signal) + } catch (error) { + return resultWithEffects(rejected(safeFailure(error, 'start-readback')), effects) + } + if (!packet.ok || packet.goal_id !== target.goalId || packet.agent_id !== target.agentId + || packet.host_thread_binding === undefined + || !sameBinding(bindingFromPayload(packet.host_thread_binding), bound.value)) { + return resultWithEffects(rejected(readbackFailure( + 'start-readback', + 'LoopX did not verify the fresh Goal-Agent binding.', + )), effects) + } + const planning = planningCheckpoint(packet, objective, target.goalId, target.agentId) + if (planning === undefined || modelCheckpoint(packet) === undefined) { + return resultWithEffects(rejected(readbackFailure( + 'start-readback', + 'LoopX did not return one bounded planning contract.', + )), effects) + } + const body = renderPlanningCheckpoint(planning) + this.coordinators.observeBinding(session, current.value.home, bound.value) + this.coordinators.cachePlanningBody(session, body) + return resultWithEffects(success(Object.freeze({ + kind: 'planning' as const, + binding: bound.value, + planning, + modelCheckpoint: body, + })), effects) + }) + } + + attach( + session: LoopXSessionRef, + request: LoopXAttachRequest, + signal?: AbortSignal, + ): Promise> { + const goalId = present(request.goalId) + const requestedAgent = present(request.agentId) + const confirmationToken = present(request.switchConfirmation) + const newPeer = request.newPeer === true + if (!validGoalId(goalId) || (newPeer && requestedAgent !== undefined) + || (request.agentId !== undefined && (requestedAgent === undefined || !PUBLIC_AGENT_ID.test(requestedAgent))) + || (request.switchConfirmation !== undefined && confirmationToken === undefined)) { + return Promise.resolve(rejected(failure( + 'LOOPX_INVALID_REQUEST', + 'Attach requires one exact Goal and a compatible exact-agent or new-peer selection.', + { operation: 'attach' }, + ))) + } + return this.queued(session, 'attach', async () => { + const current = await this.bindingForMutation(session, signal) + if (!current.ok) return current + const currentBound = current.value.binding?.state === 'bound' + ? current.value.binding + : undefined + let target: LoopXGoalAgentRef + let createPeer = newPeer + + if (confirmationToken !== undefined) { + if (currentBound === undefined) return rejected(this.invalidConfirmation('attach')) + const record = this.validConfirmation( + session, + confirmationToken, + 'attach', + currentBound, + undefined, + { + goalId, + ...optional(requestedAgent !== undefined, { agentId: requestedAgent as string }), + newPeer, + }, + ) + if (record === undefined) return rejected(this.invalidConfirmation('attach')) + target = record.requested + createPeer = record.newPeer + this.coordinators.clearConfirmation(session) + } else if (newPeer) { + target = Object.freeze({ goalId, agentId: this.freshAgentId() }) + } else if (requestedAgent !== undefined) { + target = Object.freeze({ goalId, agentId: requestedAgent }) + } else { + let packet: BootstrapCommandPackPayload + try { + packet = await this.readCommandPack(session, current.value.home, goalId, undefined, false, signal) + } catch (error) { + return rejected(safeFailure(error, 'attach-selection')) + } + if (!packet.ok) return rejected(readbackFailure('attach-selection', 'LoopX rejected the attach Goal.')) + const selected = present(packet.agent_id ?? undefined) + if (selected === undefined || !packet.host_loop_activation.activation_allowed) { + const gate = packet.host_loop_activation.identity_selection_gate + return success({ + kind: 'selection_required' as const, + goalId, + selection: gate === null || gate === undefined + ? Object.freeze({ + kind: 'agent' as const, + defaultAction: 'select_agent_identity', + choices: Object.freeze(packet.host_loop_activation.identity_contract.registered_agents + .map(agentId => Object.freeze({ agentId }))), + }) + : identitySelection(gate), + }) + } + target = Object.freeze({ goalId, agentId: selected }) + } + + const changesTarget = currentBound !== undefined + && (currentBound.target.goalId !== target.goalId + || currentBound.target.agentId !== target.agentId) + if (changesTarget) { + return success(this.prepareSwitch(session, 'attach', currentBound, target, createPeer)) + } + + this.coordinators.pause(session) + const effects: LoopXAppliedSubEffect[] = [] + if (createPeer) { + const registered = await this.registerFreshAgent(session, current.value.home, target, signal) + if (!registered.ok) return registered + effects.push(...(registered.subEffects ?? [])) + } + const bound = await this.bindTarget( + session, + current.value.home, + target, + current.value.revision, + signal, + ) + if (!bound.ok) return resultWithEffects(bound, effects) + effects.push(...(bound.subEffects ?? [])) + const armed = await this.armFromAuthority( + session, + current.value.home, + bound.value, + 'attach', + signal, + ) + if (!armed.ok) return resultWithEffects(armed, effects) + return resultWithEffects(success( + Object.freeze({ kind: 'attached' as const, binding: armed.value }), + ), effects) + }) + } + + activate( + session: LoopXSessionRef, + goalId: string, + agentId?: string, + signal?: AbortSignal, + ): Promise> { + return this.queued(session, 'activate', async () => { + const home = this.bindingHome(session) + if (!home.ok) return home + const resolved = await this.resolveBindingInside(session, home.value, signal) + if (!resolved.ok) return resolved + if (resolved.value.state !== 'bound' || resolved.value.target.goalId !== present(goalId) + || (present(agentId) !== undefined && resolved.value.target.agentId !== present(agentId))) { + return rejected(failure( + 'LOOPX_IDENTITY_CONFLICT', + 'Activation must match the exact authoritative Goal-Agent binding.', + { operation: 'activate' }, + )) + } + this.coordinators.pause(session) + const effects: LoopXAppliedSubEffect[] = [] + try { + const payload = await this.cli.runJson({ + operation: 'activate-refresh', + kind: 'write', + args: [ + ...this.runtimeArgs(home.value), + 'refresh-state', + '--goal-id', resolved.value.target.goalId, + '--project', home.value.cwd, + '--agent-id', resolved.value.target.agentId, + '--agent-lane', resolved.value.target.agentId, + '--progress-scope', 'agent_lane', + '--suppress-external-sinks', + ], + cwd: home.value.cwd, + schema: refreshStateResultSchema, + signal, + scopeKey: this.scopeFor(session), + }) + const definitelyApplied = payload.appended + || payload.global_sync?.wrote === true + const application: LoopXApplication = definitelyApplied + ? 'yes' + : payload.partial_write === true ? 'unknown' : 'no' + if (definitelyApplied) effects.push(applied('activate-refresh', resolved.value.target)) + if (!payload.ok || payload.goal_id !== resolved.value.target.goalId + || payload.agent_id !== resolved.value.target.agentId + || payload.external_sink_delivery_authorized !== false || !payload.global_sync.ok + || payload.partial_write === true) { + return rejected(readbackFailure( + 'activate-refresh', + 'LoopX did not verify the bounded suppressed-sink activation write.', + ), application, effects) + } + } catch (error) { + return rejected(safeFailure(error, 'activate-refresh')) + } + const reread = await this.resolveBindingInside(session, home.value, signal) + if (!reread.ok) return resultWithEffects(reread, effects) + if (reread.value.state !== 'bound' || !sameBinding(reread.value, resolved.value)) { + return resultWithEffects(rejected(readbackFailure( + 'activate-readback', + 'The binding changed during activation.', + )), effects) + } + return resultWithEffects( + await this.armFromAuthority(session, home.value, reread.value, 'activate', signal), + effects, + ) + }) + } + + status( + session: LoopXSessionRef, + signal?: AbortSignal, + ): Promise> { + return this.queued(session, 'status', async () => { + const home = this.bindingHome(session) + if (!home.ok) return home + const resolved = await this.resolveBindingInside(session, home.value, signal) + const snapshot = this.coordinators.snapshot(session) + const hostBase = { + binarySource: this.cli.binarySource, + activation: snapshot?.activation ?? 'disarmed', + automaticFollowupSuppressed: snapshot?.automaticFollowupSuppressed ?? false, + } as const + if (!resolved.ok) { + if (resolved.error.code === 'LOOPX_BINDING_NOT_FOUND') { + return success({ host: Object.freeze(hostBase) }) + } + return resolved + } + const host: LoopXHostStatus = Object.freeze({ ...hostBase, binding: resolved.value }) + if (resolved.value.state === 'unbound') return success({ host }) + try { + const payload = await this.cli.runJson({ + operation: 'status', + kind: 'read', + args: [ + ...this.runtimeArgs(home.value), + 'status', + '--goal-id', resolved.value.target.goalId, + '--agent-id', resolved.value.target.agentId, + ], + cwd: home.value.cwd, + schema: statusSchema, + signal, + scopeKey: this.scopeFor(session), + }) + if (!payload.ok || (payload.goal_filter !== null + && payload.goal_filter !== resolved.value.target.goalId)) { + return rejected(readbackFailure('status', 'LoopX status did not match the authoritative binding.')) + } + return success({ + host, + authority: boundedStatusProjection(payload, resolved.value.target.goalId), + }) + } catch (error) { + return rejected(safeFailure(error, 'status')) + } + }) + } + + pause(session: LoopXSessionRef): Promise> { + const invalid = validateSession(session) + if (invalid !== undefined) return Promise.resolve(rejected(invalid)) + const snapshot = this.coordinators.pause(session) + return Promise.resolve(success(Object.freeze({ + paused: true as const, + ...optional(snapshot.observedBinding !== undefined, { + binding: snapshot.observedBinding as LoopXHostThreadBindingV1, + }), + }))) + } + + resume( + session: LoopXSessionRef, + signal?: AbortSignal, + ): Promise> { + return this.queued(session, 'resume', async () => { + const home = this.bindingHome(session) + if (!home.ok) return home + const resolved = await this.resolveBindingInside(session, home.value, signal) + if (!resolved.ok) return resolved + if (resolved.value.state !== 'bound') return rejected(this.notBound('resume')) + this.coordinators.pause(session) + const observed = await this.readGoalStatus(session, home.value, resolved.value, signal) + if (!observed.ok) return observed + return this.armFromAuthority(session, home.value, resolved.value, 'resume', signal) + }) + } + + detach( + session: LoopXSessionRef, + signal?: AbortSignal, + ): Promise> { + const invalid = validateSession(session) + if (invalid !== undefined) return Promise.resolve(rejected(invalid)) + this.coordinators.pause(session) + this.coordinators.clearConfirmation(session) + return this.queued(session, 'detach', async () => { + const home = this.bindingHome(session) + if (!home.ok) return home + const authority = await this.readBindingAuthority(session, home.value, signal) + let binding: LoopXHostThreadBindingV1 + if (authority.ok) { + binding = authority.binding + } else { + if (authority.error.code !== 'LOOPX_AUTHORITY_UNHEALTHY' + || authority.application !== 'no' || authority.binding === undefined) { + return rejected(authority.error, authority.application) + } + binding = authority.binding + } + const unbound = await this.unbindTarget( + session, + home.value, + binding.revision, + signal, + ) + if (!unbound.ok) return unbound + return success( + Object.freeze({ detached: true as const, binding: unbound.value }), + unbound.application, + unbound.subEffects, + ) + }) + } + + todoAdd( + session: LoopXSessionRef, + request: LoopXTodoAddRequest, + signal?: AbortSignal, + ): Promise> { + const normalized = normalizeTodoAddRequest(request) + if (!normalized.ok) return Promise.resolve(normalized) + return this.queued(session, 'todo-add', async () => { + const snapshot = this.coordinators.snapshot(session) + if (snapshot?.planningBody === undefined) { + return rejected(failure( + 'LOOPX_DRIVER_NOT_ARMED', + 'Todo add requires the current process-local planning checkpoint.', + { operation: 'todo-add' }, + )) + } + const bound = await this.requireFreshBound(session, 'todo-add', signal) + if (!bound.ok) return bound + const todo = normalized.value + const taskClass = todo.role === 'agent' ? 'advancement_task' : 'user_gate' + const roleArgs = todo.role === 'agent' + ? ['--claimed-by', bound.value.binding.target.agentId] + : [ + '--agent-id', bound.value.binding.target.agentId, + '--bound-agent', bound.value.binding.target.agentId, + '--blocks-agent', bound.value.binding.target.agentId, + ] + try { + const payload = await this.cli.runJson({ + operation: 'todo-add', + kind: 'write', + args: [ + ...this.runtimeArgs(bound.value.home), + 'todo', 'add', + '--goal-id', bound.value.binding.target.goalId, + '--project', bound.value.home.cwd, + '--role', todo.role, + '--text', todo.normalizedTodo, + '--status', 'open', + '--task-class', taskClass, + '--action-kind', todo.actionKind, + ...roleArgs, + ...argsWhen(todo.targetKey !== undefined, '--target-key', todo.targetKey ?? ''), + ], + cwd: bound.value.home.cwd, + schema: todoAddCommandSchema, + signal, + scopeKey: this.scopeFor(session), + }) + const effects = payload.ok && payload.added + ? [applied('todo-add', bound.value.binding.target)] + : [] + const application: LoopXApplication = payload.ok && payload.added ? 'yes' : 'no' + if (!payload.ok || payload.goal_id !== bound.value.binding.target.goalId + || payload.role !== todo.role || payload.todo !== todo.normalizedTodo + || typeof payload.todo_id !== 'string' || !validTodoId(payload.todo_id) + || payload.status !== 'open' || payload.action_kind !== todo.actionKind + || payload.task_class !== taskClass || payload.added === payload.already_exists + || payload.target_key !== (todo.targetKey ?? null)) { + return rejected( + readbackFailure('todo-add', 'LoopX did not verify the typed Todo postcondition.'), + application, + effects, + ) + } + return success(Object.freeze({ + todoId: payload.todo_id, + status: 'open' as const, + priority: todo.priority, + role: todo.role, + payload: boundedTodoAddProjection(payload, payload.todo_id, taskClass, todo.actionKind), + }), application, effects) + } catch (error) { + return rejected(safeFailure(error, 'todo-add')) + } + }) + } + + todoClaim( + session: LoopXSessionRef, + request: LoopXTodoClaimRequest, + signal?: AbortSignal, + ): Promise> { + const todoId = present(request.todoId) + if (!validTodoId(todoId)) return Promise.resolve(rejected(this.invalidTodo('todo-claim'))) + return this.todoMutation(session, 'todo-claim', [ + 'todo', 'claim', '--todo-id', todoId, '--claimed-by', '__BOUND_AGENT__', + ...argsWhen(request.role !== undefined, '--role', request.role ?? ''), + ], todoId, signal) + } + + todoUpdate( + session: LoopXSessionRef, + request: LoopXTodoUpdateRequest, + signal?: AbortSignal, + ): Promise> { + const todoId = present(request.todoId) + const args = ['todo', 'update', '--todo-id', todoId ?? ''] + const fields: readonly [string, string | undefined][] = [ + ['--status', request.status], + ['--note', present(request.note)], + ['--evidence', present(request.evidence)], + ['--reason', present(request.reason)], + ['--task-class', request.taskClass], + ] + for (const [flag, value] of fields) if (value !== undefined) args.push(flag, value) + if (request.clearClaim === true) args.push('--clear-claim') + if (!validTodoId(todoId) || args.length === 4) { + return Promise.resolve(rejected(this.invalidTodo('todo-update'))) + } + return this.todoMutation(session, 'todo-update', args, todoId, signal) + } + + todoComplete( + session: LoopXSessionRef, + request: LoopXTodoCompleteRequest, + signal?: AbortSignal, + ): Promise> { + const todoId = present(request.todoId) + if (!validTodoId(todoId) || (request.taskLeaseExpectedVersion !== undefined + && (!Number.isSafeInteger(request.taskLeaseExpectedVersion) + || request.taskLeaseExpectedVersion < 0))) { + return Promise.resolve(rejected(this.invalidTodo('todo-complete'))) + } + const args = ['todo', 'complete', '--todo-id', todoId] + const fields: readonly [string, string | undefined][] = [ + ['--note', present(request.note)], + ['--evidence', present(request.evidence)], + ['--turn-instance-id', present(request.turnInstanceId)], + ['--task-lease-idempotency-key', present(request.taskLeaseIdempotencyKey)], + ['--task-lease-expected-version', request.taskLeaseExpectedVersion === undefined + ? undefined : String(request.taskLeaseExpectedVersion)], + ] + for (const [flag, value] of fields) if (value !== undefined) args.push(flag, value) + if (request.noFollowUp === true) args.push('--no-follow-up') + return this.todoMutation(session, 'todo-complete', args, todoId, signal) + } + + async quotaShouldRun( + session: LoopXSessionRef, + turnInstanceId: string, + signal?: AbortSignal, + ): Promise> { + const turnId = present(turnInstanceId) + const fence = this.coordinators.fence(session) + if (turnId === undefined || fence === undefined) { + return rejected(failure( + 'LOOPX_DRIVER_NOT_ARMED', + 'Quota evaluation requires an armed exact Session fence and turn identity.', + { operation: 'quota-should-run' }, + )) + } + const bound = await this.requireFreshBound(session, 'quota-should-run', signal) + if (!bound.ok) return bound + if (!this.coordinators.isCurrent(fence)) { + return rejected(failure('LOOPX_DRIVER_NOT_ARMED', 'The automatic attempt was fenced.', { + operation: 'quota-should-run', + })) + } + try { + const payload = await this.cli.runJson({ + operation: 'quota-should-run', + kind: 'idempotent-write', + args: [ + ...this.runtimeArgs(bound.value.home), + 'quota', 'should-run', + '--goal-id', bound.value.binding.target.goalId, + '--agent-id', bound.value.binding.target.agentId, + '--runtime-profile', RUNTIME_PROFILE, + '--include-detail', 'scheduler', + '--turn-instance-id', turnId, + ], + cwd: bound.value.home.cwd, + schema: quotaShouldRunSchema, + signal, + scopeKey: this.scopeFor(session), + }) + const application: LoopXApplication = payload.heartbeat_receipt?.status === 'committed' + ? 'yes' + : 'no' + const effects = application === 'yes' + ? [applied('quota-heartbeat-receipt', bound.value.binding.target)] + : [] + const hint = schedulerHint(payload) + if (!payload.ok || payload.goal_id !== bound.value.binding.target.goalId + || payload.agent_identity.agent_id !== bound.value.binding.target.agentId + || payload.heartbeat_receipt?.turn_instance_id !== turnId + || !PUBLIC_CODE_TOKEN.test(payload.effective_action) || hint === undefined + || !this.coordinators.isCurrent(fence)) { + return rejected( + readbackFailure( + 'quota-should-run', + 'LoopX quota did not confirm the exact current binding and turn.', + ), + application, + effects, + ) + } + return success(Object.freeze({ + binding: bound.value.binding, + goalId: bound.value.binding.target.goalId, + agentId: bound.value.binding.target.agentId, + turnInstanceId: turnId, + shouldRun: payload.should_run, + effectiveAction: payload.effective_action, + schedulerHint: hint, + terminalNoFollowup: terminalClosureIsComplete(payload), + payload: boundedQuotaProjection(payload), + }), application, effects) + } catch (error) { + return rejected(safeFailure(error, 'quota-should-run')) + } + } + + async taskBody( + session: LoopXSessionRef, + refresh = false, + signal?: AbortSignal, + ): Promise> { + const fence = this.coordinators.fence(session) + if (fence === undefined) return rejected(failure( + 'LOOPX_DRIVER_NOT_ARMED', + 'Task loading requires an armed exact Session fence.', + { operation: 'task-body' }, + )) + const cached = this.coordinators.snapshot(session)?.taskBody + const observed = this.coordinators.snapshot(session)?.observedBinding + if (!refresh && cached !== undefined && observed?.state === 'bound' + && this.coordinators.isCurrent(fence)) { + return success({ binding: observed, body: cached }) + } + const bound = await this.requireFreshBound(session, 'task-body', signal) + if (!bound.ok) return bound + if (!this.coordinators.isCurrent(fence)) { + return rejected(failure('LOOPX_DRIVER_NOT_ARMED', 'The task-body attempt was fenced.', { + operation: 'task-body', + })) + } + try { + const body = await this.readTaskBody(session, bound.value.home, bound.value.binding, signal) + if (!this.coordinators.isCurrent(fence)) { + return rejected(failure('LOOPX_DRIVER_NOT_ARMED', 'The task body became stale before delivery.', { + operation: 'task-body', + })) + } + this.coordinators.cacheTaskBody(session, body) + return success({ binding: bound.value.binding, body }) + } catch (error) { + return rejected(safeFailure(error, 'task-body')) + } + } + + async disposeSession(session: LoopXSessionRef): Promise { + if (validateSession(session) !== undefined) return + const draining = this.coordinators.drain(session) + this.coordinators.clearConfirmation(session) + this.cli.abortScope(this.scopeFor(session)) + this.coordinators.drop(session) + await draining + } + + private async resolveBindingInside( + session: LoopXSessionRef, + home: LoopXBindingHome, + signal: AbortSignal | undefined, + ): Promise> { + const authority = await this.readBindingAuthority(session, home, signal) + return authority.ok + ? success(authority.binding) + : rejected(authority.error, authority.application) + } + + private async readBindingAuthority( + session: LoopXSessionRef, + home: LoopXBindingHome, + signal: AbortSignal | undefined, + ): Promise { + this.coordinators.observe(session, home) + let payload: HostThreadBindingCommandPayload + try { + payload = await this.cli.runBindingJson({ + operation: 'resolve-agent-thread', + kind: 'read', + args: [ + 'resolve-agent-thread', + '--host-surface', HOST_SURFACE, + '--thread-id', session.id, + ], + home, + schema: hostThreadBindingCommandSchema, + signal, + scopeKey: this.scopeFor(session), + }) + } catch (error) { + this.coordinators.invalidate(session) + const resolved = safeFailure(error, 'resolve-agent-thread') + return Object.freeze({ + ok: false as const, + error: resolved, + application: resolved.outcomeUncertain ? 'unknown' as const : 'no' as const, + }) + } + if (!payload.ok) { + const binding = payload.binding === undefined + ? undefined + : bindingFromPayload(payload.binding) + if (payload.binding !== undefined) { + if (binding?.threadId !== session.id) { + this.coordinators.invalidate(session) + return Object.freeze({ + ok: false as const, + error: readbackFailure( + 'resolve-agent-thread', + 'LoopX returned a binding for another exact Session.', + ), + application: payload.application, + }) + } + this.coordinators.observeBinding(session, home, binding) + } + this.coordinators.invalidate(session) + return Object.freeze({ + ok: false as const, + error: bindingFailure(payload, 'resolve-agent-thread'), + application: payload.application, + ...optional(binding !== undefined, { binding: binding as LoopXHostThreadBindingV1 }), + }) + } + const binding = bindingFromPayload(payload.binding) + if (binding.threadId !== session.id || payload.changed || payload.application !== 'no') { + this.coordinators.invalidate(session) + return Object.freeze({ + ok: false as const, + error: readbackFailure( + 'resolve-agent-thread', + 'LoopX returned an invalid binding read projection.', + ), + application: payload.application, + }) + } + this.coordinators.observeBinding(session, home, binding) + return Object.freeze({ ok: true as const, binding }) + } + + private async bindingForMutation( + session: LoopXSessionRef, + signal: AbortSignal | undefined, + ): Promise> { + const home = this.bindingHome(session) + if (!home.ok) return home + const resolved = await this.resolveBindingInside(session, home.value, signal) + if (resolved.ok) { + return success({ home: home.value, binding: resolved.value, revision: resolved.value.revision }) + } + if (resolved.error.code === 'LOOPX_BINDING_NOT_FOUND' + || resolved.error.code === 'LOOPX_BINDING_HOME_UNINITIALIZED') { + return success({ home: home.value, revision: 0 }) + } + return resolved + } + + private async bindTarget( + session: LoopXSessionRef, + home: LoopXBindingHome, + target: LoopXGoalAgentRef, + expectedRevision: number, + signal: AbortSignal | undefined, + ): Promise> { + const result = await this.writeBinding(session, home, [ + 'bind-agent-thread', + '--host-surface', HOST_SURFACE, + '--thread-id', session.id, + '--goal-id', target.goalId, + '--agent-id', target.agentId, + '--expected-revision', String(expectedRevision), + '--execute', + ], 'bind-agent-thread', signal) + if (!result.ok) return result + if (result.value.state !== 'bound' || result.value.target.goalId !== target.goalId + || result.value.target.agentId !== target.agentId) { + return rejected( + readbackFailure('bind-agent-thread', 'LoopX did not verify the exact binding target.'), + result.application, + result.subEffects, + ) + } + return success(result.value, result.application, result.subEffects) + } + + private async unbindTarget( + session: LoopXSessionRef, + home: LoopXBindingHome, + expectedRevision: number, + signal: AbortSignal | undefined, + ): Promise>> { + const result = await this.writeBinding(session, home, [ + 'unbind-agent-thread', + '--host-surface', HOST_SURFACE, + '--thread-id', session.id, + '--expected-revision', String(expectedRevision), + '--execute', + ], 'unbind-agent-thread', signal) + if (!result.ok) return result + if (result.value.state !== 'unbound') { + return rejected( + readbackFailure('unbind-agent-thread', 'LoopX did not return an unbound tombstone.'), + result.application, + result.subEffects, + ) + } + return success(result.value, result.application, result.subEffects) + } + + private async writeBinding( + session: LoopXSessionRef, + home: LoopXBindingHome, + args: readonly string[], + operation: 'bind-agent-thread' | 'unbind-agent-thread', + signal: AbortSignal | undefined, + ): Promise> { + let payload: HostThreadBindingCommandPayload + try { + payload = await this.cli.runBindingJson({ + operation, + kind: 'write', + args, + home, + schema: hostThreadBindingCommandSchema, + signal, + scopeKey: this.scopeFor(session), + }) + } catch (error) { + this.coordinators.invalidate(session) + return rejected(safeFailure(error, operation)) + } + if (!payload.ok) { + const binding = payload.binding === undefined + ? undefined + : bindingFromPayload(payload.binding) + if (binding !== undefined && binding.threadId !== session.id) { + this.coordinators.invalidate(session) + return rejected( + readbackFailure(operation, 'LoopX returned a binding for another exact Session.'), + payload.application, + ) + } + if (binding !== undefined) { + this.coordinators.observeBinding(session, home, binding) + } else { + this.coordinators.invalidate(session) + } + const effects = payload.application === 'yes' + ? [applied(operation, binding?.state === 'bound' ? binding.target : undefined)] + : [] + return rejected(bindingFailure(payload, operation), payload.application, effects) + } + const binding = bindingFromPayload(payload.binding) + const effects = payload.application === 'yes' + ? [applied(operation, binding.state === 'bound' ? binding.target : undefined)] + : [] + if (binding.threadId !== session.id + || payload.application !== (payload.changed ? 'yes' : 'no')) { + this.coordinators.invalidate(session) + return rejected( + readbackFailure(operation, 'LoopX returned an invalid binding mutation receipt.'), + payload.application, + effects, + ) + } + this.coordinators.observeBinding(session, home, binding) + return success(binding, payload.application, effects) + } + + private async armFromAuthority( + session: LoopXSessionRef, + home: LoopXBindingHome, + binding: LoopXBoundHostThreadBindingV1, + operation: 'activate' | 'attach' | 'resume', + signal: AbortSignal | undefined, + ): Promise> { + let packet: BootstrapCommandPackPayload + let body: string + try { + packet = await this.readCommandPack( + session, + home, + binding.target.goalId, + binding.target.agentId, + false, + signal, + ) + if (!activationReadbackMatches(packet, session, binding)) { + return rejected(readbackFailure(operation, 'LoopX did not verify Goal membership and binding authority.')) + } + body = await this.readTaskBody(session, home, binding, signal) + } catch (error) { + return rejected(safeFailure(error, operation)) + } + const reread = await this.resolveBindingInside(session, home, signal) + if (!reread.ok) return reread + if (reread.value.state !== 'bound' || !sameBinding(reread.value, binding)) { + return rejected(readbackFailure(operation, 'The authoritative binding changed before arming.')) + } + const armed = this.coordinators.arm(session, home, binding, { taskBody: body }) + if (armed === undefined) { + return rejected(failure( + 'LOOPX_FOREIGN_COMMAND_ACTIVE', + 'The exact Session cannot arm while a foreign command is active.', + { operation }, + )) + } + return success(binding) + } + + private async requireFreshBound( + session: LoopXSessionRef, + operation: string, + signal: AbortSignal | undefined, + ): Promise> { + const home = this.bindingHome(session) + if (!home.ok) return home + const resolved = await this.resolveBindingInside(session, home.value, signal) + if (!resolved.ok) return resolved + if (resolved.value.state !== 'bound') return rejected(this.notBound(operation)) + return success({ home: home.value, binding: resolved.value }) + } + + private async readStartPacket( + session: LoopXSessionRef, + home: LoopXBindingHome, + goalText: string, + target: LoopXGoalAgentRef, + signal: AbortSignal | undefined, + ): Promise { + return this.cli.runJson({ + operation: 'start-goal', + kind: 'read', + args: [ + ...this.runtimeArgs(home), + 'start-goal', '--guided', + '--project', home.cwd, + '--thread-id', session.id, + '--host-surface', HOST_SURFACE, + '--goal-id', target.goalId, + '--agent-id', target.agentId, + '--goal-text', goalText, + ], + cwd: home.cwd, + schema: startGoalGuidedSchema, + signal, + scopeKey: this.scopeFor(session), + }) + } + + private async readCommandPack( + session: LoopXSessionRef, + home: LoopXBindingHome, + goalId: string, + agentId: string | undefined, + newPeer: boolean, + signal: AbortSignal | undefined, + ): Promise { + return this.cli.runJson({ + operation: 'bootstrap-command-pack', + kind: 'read', + args: [ + ...this.runtimeArgs(home), + 'bootstrap-command-pack', + '--project', home.cwd, + '--goal-id', goalId, + '--thread-id', session.id, + '--host-surface', HOST_SURFACE, + ...argsWhen(agentId !== undefined, '--agent-id', agentId ?? ''), + ...argsWhen(newPeer, '--new-peer'), + ], + cwd: home.cwd, + schema: bootstrapCommandPackSchema, + signal, + scopeKey: this.scopeFor(session), + }) + } + + private async readTaskBody( + session: LoopXSessionRef, + home: LoopXBindingHome, + binding: LoopXBoundHostThreadBindingV1, + signal: AbortSignal | undefined, + ): Promise { + const payload: HeartbeatPromptPayload = await this.cli.runJson({ + operation: 'heartbeat-prompt', + kind: 'read', + args: [ + ...this.runtimeArgs(home), + 'heartbeat-prompt', '--thin', + '--goal-id', binding.target.goalId, + '--agent-id', binding.target.agentId, + '--agent-scope', AGENT_SCOPE, + '--runtime-profile', RUNTIME_PROFILE, + ], + cwd: home.cwd, + schema: heartbeatPromptSchema, + signal, + scopeKey: this.scopeFor(session), + }) + const body = present(payload.task_body ?? undefined) + if (!payload.ok || payload.goal_id !== binding.target.goalId + || payload.agent_id !== binding.target.agentId || body === undefined) { + throw new LoopXCliError(readbackFailure( + 'heartbeat-prompt', + 'LoopX did not return the exact bound task body.', + )) + } + return body + } + + private async readGoalStatus( + session: LoopXSessionRef, + home: LoopXBindingHome, + binding: LoopXBoundHostThreadBindingV1, + signal: AbortSignal | undefined, + ): Promise> { + try { + const payload = await this.cli.runJson({ + operation: 'resume-status', + kind: 'read', + args: [ + ...this.runtimeArgs(home), + 'status', + '--goal-id', binding.target.goalId, + '--agent-id', binding.target.agentId, + ], + cwd: home.cwd, + schema: statusSchema, + signal, + scopeKey: this.scopeFor(session), + }) + if (!payload.ok || (payload.goal_filter !== null + && payload.goal_filter !== binding.target.goalId)) { + return rejected(readbackFailure('resume-status', 'LoopX did not verify the bound Goal status.')) + } + return success(undefined) + } catch (error) { + return rejected(safeFailure(error, 'resume-status')) + } + } + + private async bootstrapGoal( + session: LoopXSessionRef, + home: LoopXBindingHome, + goalId: string, + objective: string, + signal: AbortSignal | undefined, + ): Promise> { + try { + const payload = await this.cli.runJson({ + operation: 'bootstrap-connect', + kind: 'write', + args: [ + ...this.runtimeArgs(home), + 'bootstrap', + '--project', home.cwd, + '--goal-id', goalId, + '--objective', objective, + '--adapter-kind', 'read_only_project_map_v0', + '--adapter-status', 'connected-read-only', + '--no-onboarding-scan', + '--codex-app-heartbeat', 'ask', + ], + cwd: home.cwd, + schema: bootstrapResultSchema, + signal, + scopeKey: this.scopeFor(session), + }) + if (!payload.ok) { + return rejected(failure( + 'LOOPX_REGISTRY_INTEGRITY', + 'LoopX rejected fresh Goal bootstrap before a verified write.', + { operation: 'bootstrap-connect' }, + )) + } + const definitelyApplied = payload.registry_goal_action !== 'kept-existing' + || payload.state_action !== 'kept-existing' + || payload.global_sync.wrote === true + const application: LoopXApplication = definitelyApplied ? 'yes' : 'no' + const effects = definitelyApplied + ? [applied('bootstrap-goal')] + : [] + if (payload.goal_id !== goalId || payload.registry_goal_action !== 'appended' + || payload.state_action !== 'created' + || !payload.global_sync.synced_goal_ids.includes(goalId)) { + return rejected( + readbackFailure('bootstrap-connect', 'LoopX did not verify the fresh Goal.'), + application, + effects, + ) + } + return success(undefined, application, effects) + } catch (error) { + return rejected(safeFailure(error, 'bootstrap-connect')) + } + } + + private async registerFreshAgent( + session: LoopXSessionRef, + home: LoopXBindingHome, + target: LoopXGoalAgentRef, + signal: AbortSignal | undefined, + ): Promise> { + try { + const payload = await this.cli.runJson({ + operation: 'register-agent', + kind: 'write', + args: [ + ...this.runtimeArgs(home), + 'register-agent', + '--goal-id', target.goalId, + '--agent-id', target.agentId, + '--require-new', + '--execute', + ], + cwd: home.cwd, + schema: registerAgentSchema, + signal, + scopeKey: this.scopeFor(session), + }) + if (!payload.ok) { + const deterministic = !payload.written && !payload.partial_write + const application: LoopXApplication = payload.written + ? 'yes' + : payload.partial_write ? 'unknown' : 'no' + const effects = payload.written + ? [applied('register-agent-source', target)] + : [] + return rejected( + failure( + payload.error_kind === 'agent_identity_already_registered' + ? 'LOOPX_IDENTITY_CONFLICT' + : 'LOOPX_REGISTRY_INTEGRITY', + deterministic + ? 'LoopX rejected the fresh Goal-Agent identity before writing.' + : 'LoopX did not verify fresh Goal-Agent membership across its authority.', + { operation: 'register-agent', outcomeUncertain: application === 'unknown' }, + ), + application, + effects, + ) + } + const effects = [applied('register-agent', target)] + const readback = payload.registration_readback + if (payload.goal_id !== target.goalId || payload.requested_agents[0] !== target.agentId + || !payload.registered_agents.includes(target.agentId) + || !readback.source_registered_agents.includes(target.agentId) + || !readback.global_registered_agents.includes(target.agentId)) { + return rejected( + readbackFailure('register-agent', 'LoopX did not verify fresh Goal-Agent membership.'), + 'yes', + effects, + ) + } + return success(undefined, 'yes', effects) + } catch (error) { + return rejected(safeFailure(error, 'register-agent')) + } + } + + private todoMutation( + session: LoopXSessionRef, + operation: string, + commandArgs: string[], + todoId: string, + signal: AbortSignal | undefined, + ): Promise> { + return this.queued(session, operation, async () => { + const bound = await this.requireFreshBound(session, operation, signal) + if (!bound.ok) return bound + const args = commandArgs.map(value => value === '__BOUND_AGENT__' + ? bound.value.binding.target.agentId : value) + args.push( + '--goal-id', bound.value.binding.target.goalId, + '--agent-id', bound.value.binding.target.agentId, + ) + try { + const payload = await this.cli.runJson({ + operation, + kind: 'write', + args: [...this.runtimeArgs(bound.value.home), ...args], + cwd: bound.value.home.cwd, + schema: todoCommandSchema, + signal, + scopeKey: this.scopeFor(session), + }) + const definitelyApplied = payload.changed === true + const effects = definitelyApplied + ? [applied(operation, bound.value.binding.target)] + : [] + const application: LoopXApplication = definitelyApplied + ? 'yes' + : !payload.ok && payload.partial_write === true ? 'unknown' : 'no' + if (!payload.ok || payload.goal_id !== bound.value.binding.target.goalId + || payload.todo_id !== todoId) { + return rejected( + readbackFailure(operation, 'LoopX did not verify the Todo postcondition.'), + application, + effects, + ) + } + return success(Object.freeze({ + todoId, + ...optional(payload.status !== undefined, { status: payload.status as string }), + payload: boundedTodoProjection(payload), + }), application, effects) + } catch (error) { + return rejected(safeFailure(error, operation)) + } + }) + } + + private prepareSwitch( + session: LoopXSessionRef, + operation: 'start' | 'attach', + current: LoopXBoundHostThreadBindingV1, + requested: LoopXGoalAgentRef, + newPeer: boolean, + goalText?: string, + ): LoopXSwitchRequired { + const record: SwitchConfirmationRecord = Object.freeze({ + token: randomUUID(), + sessionObject: session.session, + operation, + expiresAt: Date.now() + SWITCH_CONFIRMATION_TTL_MS, + expectedRevision: current.revision, + current: current.target, + requested, + ...optional(goalText !== undefined, { goalText: goalText as string }), + newPeer, + }) + this.coordinators.setConfirmation(session, record) + return Object.freeze({ + kind: 'switch_required' as const, + confirmationToken: record.token, + requiresUserConfirmation: true as const, + expiresAt: record.expiresAt, + expectedRevision: record.expectedRevision, + current: record.current, + requested: Object.freeze({ + operation, + goalId: requested.goalId, + agentId: requested.agentId, + ...optional(newPeer, { newPeer: true as const }), + }), + }) + } + + private validConfirmation( + session: LoopXSessionRef, + token: string, + operation: 'start' | 'attach', + current: LoopXBoundHostThreadBindingV1, + goalText?: string, + request?: { readonly goalId: string; readonly agentId?: string; readonly newPeer: boolean }, + ): SwitchConfirmationRecord | undefined { + const record = this.coordinators.confirmation(session) + if (record === undefined || record.token !== token || record.operation !== operation + || record.sessionObject !== session.session || record.expiresAt <= Date.now() + || record.expectedRevision !== current.revision + || record.current.goalId !== current.target.goalId + || record.current.agentId !== current.target.agentId + || record.goalText !== goalText + || (request !== undefined && (record.requested.goalId !== request.goalId + || record.newPeer !== request.newPeer + || (!request.newPeer && record.requested.agentId !== request.agentId)))) { + this.coordinators.clearConfirmation(session) + return undefined + } + return record + } + + private invalidConfirmation(operation: 'start' | 'attach'): LoopXFailure { + return failure( + 'LOOPX_SWITCH_CONFIRMATION_INVALID', + 'The switch confirmation is missing, expired, stale, or bound to another exact request.', + { operation }, + ) + } + + private bindingHome(session: LoopXSessionRef): LoopXResult { + const root = present(this.config.runtimeRoot) + const cwd = root === undefined + ? present(session.identity.cwd) + : present(session.identity.cwd) ?? present(this.config.project) ?? root + if (cwd === undefined) { + return rejected(failure( + 'LOOPX_BINDING_HOME_UNAVAILABLE', + 'The exact DSH Session does not select one readable LoopX binding home.', + { operation: 'binding-home' }, + )) + } + const canonicalCwd = resolve(cwd) + const canonicalRoot = root === undefined ? undefined : resolve(root) + return success(Object.freeze({ + cwd: canonicalCwd, + key: canonicalRoot === undefined ? `session:${canonicalCwd}` : `runtime:${canonicalRoot}`, + ...optional(canonicalRoot !== undefined, { runtimeRoot: canonicalRoot as string }), + })) + } + + private runtimeArgs(home: LoopXBindingHome): string[] { + return home.runtimeRoot === undefined ? [] : ['--runtime-root', home.runtimeRoot] + } + + private scopeFor(session: LoopXSessionRef): string { + return this.coordinators.scopeKey(session) + } + + private freshAgentId(): string { + return `dsh-${randomUUID().replaceAll('-', '').slice(0, 20)}` + } + + private freshGoalId(): string { + return `dsh-goal-${randomUUID().replaceAll('-', '').slice(0, 20)}` + } + + private notBound(operation: string): LoopXFailure { + return failure( + 'LOOPX_SESSION_NOT_BOUND', + 'The current DSH Session has no bound LoopX Goal-Agent target.', + { operation }, + ) + } + + private invalidTodo(operation: string): LoopXFailure { + return failure( + 'LOOPX_INVALID_REQUEST', + 'The Todo operation requires one non-empty Todo id and supported bounded fields.', + { operation }, + ) + } + + private queued( + session: LoopXSessionRef, + operation: string, + body: () => Promise>, + ): Promise> { + const invalid = validateSession(session) + if (invalid !== undefined) return Promise.resolve(rejected(invalid)) + if (!this.admissionOpen || this.coordinators.isClosed(session)) { + return Promise.resolve(rejected(failure( + 'LOOPX_SERVICE_CLOSED', + 'The LoopX Host service is not accepting operations for this Session.', + { operation }, + ))) + } + const result: Promise> = this.coordinators + .serialize(session, body) + .catch>(error => rejected(error instanceof CoordinatorAdmissionCancelled + ? failure( + 'LOOPX_SERVICE_CLOSED', + 'The LoopX Host operation was retired during lifecycle disposal.', + { operation }, + ) + : failure( + 'LOOPX_CLI_FAILED', + 'The LoopX Host operation failed before a bounded result was available.', + { operation }, + ))) + return result + } +} + +export default LoopXService diff --git a/packages/dsh-loopx-plugin/src/tools.ts b/packages/dsh-loopx-plugin/src/tools.ts new file mode 100644 index 000000000..060300982 --- /dev/null +++ b/packages/dsh-loopx-plugin/src/tools.ts @@ -0,0 +1,432 @@ +import type { Context } from '@deepseek-ai/cordis' +import { defineTool } from '@deepseek-ai/dsh-tools' +import type { JsonValue, ToolRunContext } from '@deepseek-ai/dsh-tools' +import { deriveLoopXSessionRef } from './command.ts' +import { + failureReceipt as sharedFailureReceipt, + safeAttach, + safeBinding, + safeStart, + safeStatus, + serviceOperationReceipt as sharedServiceReceipt, +} from './receipts.ts' +import type { ReceiptValue } from './receipts.ts' +import type { + LoopXAttachRequest, + LoopXAppliedSubEffect, + LoopXFailure, + LoopXOperationReceipt, + LoopXResult, + LoopXServiceApi, + LoopXSessionRef, + LoopXStartOptions, + LoopXTodoAddValue, + LoopXTodoMutationValue, +} from './types.ts' + +export const name = 'dsh-loopx-tools' +export const inject = ['tools', 'loopx'] + +const RECEIPT_SCHEMA_VERSION = 'dsh_loopx_operation_receipt_v1' as const + +interface ToolReceipt { + readonly schemaVersion: typeof RECEIPT_SCHEMA_VERSION + readonly kind: 'operation_result' + readonly operation: string + readonly execution: LoopXOperationReceipt['execution'] + readonly application: LoopXOperationReceipt['application'] + readonly delivery: LoopXOperationReceipt['delivery'] + readonly recovery: LoopXOperationReceipt['recovery'] + readonly value?: JsonValue + readonly error?: { + readonly code: string + readonly message: string + readonly operation?: string + readonly retryable: boolean + readonly outcomeUncertain: boolean + } + readonly subEffects?: JsonValue +} + +const TOOL_OUTPUT = { + schema: { + type: 'object', + additionalProperties: false, + properties: { + schemaVersion: { type: 'string', const: RECEIPT_SCHEMA_VERSION, required: true }, + kind: { type: 'string', const: 'operation_result', required: true }, + operation: { type: 'string', required: true }, + execution: { + type: 'string', + enum: ['succeeded', 'rejected', 'indeterminate', 'not_attempted'], + required: true, + }, + application: { type: 'string', enum: ['yes', 'no', 'unknown'], required: true }, + delivery: { + type: 'string', + enum: ['steered', 'followup_queued', 'failed', 'not_needed'], + required: true, + }, + recovery: { + type: 'string', + enum: [ + 'none', 'retry_same_tool', 'read_authority_then_decide', + 'correct_request', 'ask_user', 'stop', + ], + required: true, + }, + value: { type: 'json' }, + error: { + type: 'object', + additionalProperties: false, + properties: { + code: { type: 'string', required: true }, + message: { type: 'string', required: true }, + operation: { type: 'string' }, + retryable: { type: 'boolean', required: true }, + outcomeUncertain: { type: 'boolean', required: true }, + }, + }, + subEffects: { type: 'json' }, + }, + }, + render: (_args: unknown, value: unknown) => [{ + type: 'text' as const, + text: JSON.stringify(value), + }], +} as const + +function invalidRequest(message: string, operation: string): LoopXFailure { + return Object.freeze({ + code: 'LOOPX_INVALID_REQUEST', + message, + operation, + retryable: false, + outcomeUncertain: false, + }) +} + +function failureReceipt( + operation: string, + error: LoopXFailure, + application?: LoopXOperationReceipt['application'], + subEffects?: readonly LoopXAppliedSubEffect[], +): ToolReceipt { + return sharedFailureReceipt(operation, error, application, subEffects) as unknown as ToolReceipt +} + +async function serviceReceipt( + service: LoopXServiceApi, + session: LoopXSessionRef, + signal: AbortSignal, + operation: string, + invoke: () => Promise>, + project: (value: T) => ReceiptValue, +): Promise { + return sharedServiceReceipt( + service, session, signal, operation, invoke, project, + ) as unknown as Promise +} + +function hasOnlyKeys(args: object, allowed: ReadonlySet): boolean { + return Object.keys(args).every(key => allowed.has(key)) +} + +function safeTodo(value: LoopXTodoMutationValue): ReceiptValue { + const authority = value.payload + return { + todoId: value.todoId, + status: value.status ?? null, + loopxAuthority: { + schemaVersion: authority.schemaVersion, + goalId: authority.goalId, + todoId: authority.todoId, + ...(authority.status === undefined ? {} : { status: authority.status }), + ...(authority.changed === undefined ? {} : { changed: authority.changed }), + ...(authority.claimedBy === undefined ? {} : { claimedBy: authority.claimedBy }), + ...(authority.taskClass === undefined ? {} : { taskClass: authority.taskClass }), + ...(authority.settlementResult === undefined + ? {} + : { settlementResult: authority.settlementResult }), + }, + } +} + +function safeTodoAdd(value: LoopXTodoAddValue): ReceiptValue { + const authority = value.payload + return { + todoId: value.todoId, + status: value.status, + priority: value.priority, + role: value.role, + loopxAuthority: { + schemaVersion: authority.schemaVersion, + goalId: authority.goalId, + todoId: authority.todoId, + status: authority.status, + role: authority.role, + taskClass: authority.taskClass, + actionKind: authority.actionKind, + added: authority.added, + alreadyExists: authority.alreadyExists, + }, + } +} + +function strictInput(definition: ReturnType): ReturnType { + return Object.freeze({ + ...definition, + parameters: Object.freeze({ ...definition.parameters, additionalProperties: false }), + }) +} + +function invalidKeys(operation: string): LoopXFailure { + return invalidRequest( + 'Unsupported arguments are forbidden; Session identity and authority locators are derived by the plugin, and raw task bodies, argv, or shell commands are never accepted.', + operation, + ) +} + +function toolSession( + exec: ToolRunContext, + operation: string, + args: object, + keys: ReadonlySet, +): LoopXResult { + const current = deriveLoopXSessionRef(exec.agent, operation) + if (!current.ok) return current + return hasOnlyKeys(args, keys) + ? current + : { ok: false, error: invalidKeys(operation), application: 'no' } +} + +const START_KEYS = new Set(['goalText', 'switchConfirmation']) +const ATTACH_KEYS = new Set(['goalId', 'agentId', 'newPeer', 'switchConfirmation']) +const ACTIVATE_KEYS = new Set(['goalId', 'agentId']) +const TODO_ADD_KEYS = new Set(['text', 'priority', 'role', 'actionKind', 'targetKey']) +const EMPTY_KEYS = new Set() +const CLAIM_KEYS = new Set(['todoId', 'role']) +const UPDATE_KEYS = new Set(['todoId', 'status', 'note', 'evidence', 'reason', 'taskClass', 'clearClaim']) +const COMPLETE_KEYS = new Set([ + 'todoId', 'note', 'evidence', 'noFollowUp', 'turnInstanceId', + 'taskLeaseIdempotencyKey', 'taskLeaseExpectedVersion', +]) + +function loopXToolDefinitions(service: LoopXServiceApi): readonly ReturnType[] { + const goalStart = strictInput(defineTool({ + name: 'loopx_goal_start', + description: 'Start a fresh LoopX Goal and lane for this DSH Session; activation remains disarmed.', + parameters: { + goalText: { type: 'string', required: true, description: 'Non-empty Goal objective.' }, + switchConfirmation: { type: 'string', description: 'Opaque confirmed-switch token.' }, + }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'goal-start' + const current = toolSession(exec, operation, args, START_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + const options: LoopXStartOptions = { + ...(args.switchConfirmation === undefined ? {} : { switchConfirmation: args.switchConfirmation }), + } + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.start(current.value, args.goalText, exec.signal, options), + safeStart) + }, + })) + + const goalAttach = strictInput(defineTool({ + name: 'loopx_goal_attach', + description: 'Attach this DSH Session to one exact existing Goal-Agent lane.', + parameters: { + goalId: { type: 'string', required: true }, + agentId: { type: 'string' }, + newPeer: { type: 'boolean' }, + switchConfirmation: { type: 'string' }, + }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'goal-attach' + const current = toolSession(exec, operation, args, ATTACH_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + const request: LoopXAttachRequest = { + goalId: args.goalId, + ...(args.agentId === undefined ? {} : { agentId: args.agentId }), + ...(args.newPeer === true ? { newPeer: true } : {}), + ...(args.switchConfirmation === undefined ? {} : { switchConfirmation: args.switchConfirmation }), + } + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.attach(current.value, request, exec.signal), + safeAttach) + }, + })) + + const goalActivate = strictInput(defineTool({ + name: 'loopx_goal_activate', + description: 'Activate the exact pending Goal-Agent lane after fresh authority readback.', + parameters: { goalId: { type: 'string', required: true }, agentId: { type: 'string' } }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'goal-activate' + const current = toolSession(exec, operation, args, ACTIVATE_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.activate(current.value, args.goalId, args.agentId, exec.signal), + binding => ({ binding: safeBinding(binding) })) + }, + })) + + const loopxStatus = strictInput(defineTool({ + name: 'loopx_status', + description: 'Read exact Host binding and LoopX authority without mutation or activation.', + parameters: {}, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'status' + const current = toolSession(exec, operation, args, EMPTY_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.status(current.value, exec.signal), safeStatus) + }, + })) + + const goalDetach = strictInput(defineTool({ + name: 'loopx_goal_detach', + description: 'CAS-unbind this DSH Host thread and retain its revision tombstone.', + parameters: {}, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'goal-detach' + const current = toolSession(exec, operation, args, EMPTY_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.detach(current.value, exec.signal), + value => ({ detached: value.detached, binding: safeBinding(value.binding) })) + }, + })) + + const driverPause = strictInput(defineTool({ + name: 'loopx_driver_pause', + description: 'Disarm only process-local continuation; durable LoopX state is unchanged.', + parameters: {}, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'driver-pause' + const current = toolSession(exec, operation, args, EMPTY_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.pause(current.value), value => ({ + paused: value.paused, + ...(value.binding === undefined ? {} : { binding: safeBinding(value.binding) }), + })) + }, + })) + + const driverResume = strictInput(defineTool({ + name: 'loopx_driver_resume', + description: 'Arm continuation only after fresh exact authority readback.', + parameters: {}, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'driver-resume' + const current = toolSession(exec, operation, args, EMPTY_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.resume(current.value, exec.signal), + binding => ({ binding: safeBinding(binding) })) + }, + })) + + const todoAdd = strictInput(defineTool({ + name: 'loopx_todo_add', + description: 'Add one bounded public-safe Todo to the currently bound lane.', + parameters: { + text: { type: 'string', required: true }, + priority: { type: 'string', required: true, enum: ['P0', 'P1', 'P2'] }, + role: { type: 'string', enum: ['agent', 'user'] }, + actionKind: { type: 'string' }, + targetKey: { type: 'string' }, + }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'todo-add' + const current = toolSession(exec, operation, args, TODO_ADD_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.todoAdd(current.value, args, exec.signal), safeTodoAdd) + }, + })) + + const todoClaim = strictInput(defineTool({ + name: 'loopx_todo_claim', + description: 'Claim one Todo for the currently bound Goal-Agent lane.', + parameters: { + todoId: { type: 'string', required: true }, + role: { type: 'string', enum: ['user', 'agent'] }, + }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'todo-claim' + const current = toolSession(exec, operation, args, CLAIM_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.todoClaim(current.value, args, exec.signal), safeTodo) + }, + })) + + const todoUpdate = strictInput(defineTool({ + name: 'loopx_todo_update', + description: 'Update bounded fields of one Todo for the currently bound lane.', + parameters: { + todoId: { type: 'string', required: true }, + status: { type: 'string', enum: ['open', 'done', 'blocked', 'deferred'] }, + note: { type: 'string' }, + evidence: { type: 'string' }, + reason: { type: 'string' }, + taskClass: { + type: 'string', + enum: ['advancement_task', 'continuous_monitor', 'user_gate', 'user_action', 'blocker'], + }, + clearClaim: { type: 'boolean' }, + }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'todo-update' + const current = toolSession(exec, operation, args, UPDATE_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.todoUpdate(current.value, args, exec.signal), safeTodo) + }, + })) + + const todoComplete = strictInput(defineTool({ + name: 'loopx_todo_complete', + description: 'Complete one Todo with bounded evidence for the currently bound lane.', + parameters: { + todoId: { type: 'string', required: true }, + note: { type: 'string' }, + evidence: { type: 'string' }, + noFollowUp: { type: 'boolean' }, + turnInstanceId: { type: 'string' }, + taskLeaseIdempotencyKey: { type: 'string' }, + taskLeaseExpectedVersion: { type: 'integer' }, + }, + output: TOOL_OUTPUT, + async execute(args, exec): Promise { + const operation = 'todo-complete' + const current = toolSession(exec, operation, args, COMPLETE_KEYS) + if (!current.ok) return failureReceipt(operation, current.error) + return serviceReceipt(service, current.value, exec.signal, operation, + () => service.todoComplete(current.value, args, exec.signal), safeTodo) + }, + })) + + return Object.freeze([ + goalStart, goalAttach, goalActivate, loopxStatus, goalDetach, driverPause, + driverResume, todoAdd, todoClaim, todoUpdate, todoComplete, + ]) +} + +/** Register the closed model-tool catalog over the current Host service. */ +export function apply(ctx: Context): void { + for (const definition of loopXToolDefinitions(ctx.loopx)) ctx.tools.register(definition) +} diff --git a/packages/dsh-loopx-plugin/src/types.ts b/packages/dsh-loopx-plugin/src/types.ts new file mode 100644 index 000000000..37514af7e --- /dev/null +++ b/packages/dsh-loopx-plugin/src/types.ts @@ -0,0 +1,380 @@ +/** Public Host authority and receipt contracts shared by the plugin surfaces. */ + +export const LOOPX_HOST_SURFACE = 'dsh' as const + +export interface LoopXSessionIdentity { + readonly createdAt: number + readonly cwd?: string | undefined +} + +/** `session` is the exact live DSH Session object and is never serialized. */ +export interface LoopXSessionRef { + readonly id: string + readonly session: object + readonly identity: LoopXSessionIdentity +} + +export interface LoopXGoalAgentRef { + readonly goalId: string + readonly agentId: string +} + +interface LoopXHostThreadBindingBase { + readonly schemaVersion: 'loopx_host_thread_binding_v1' + readonly hostSurface: typeof LOOPX_HOST_SURFACE + readonly threadId: string + readonly revision: number +} + +export interface LoopXBoundHostThreadBindingV1 extends LoopXHostThreadBindingBase { + readonly state: 'bound' + readonly target: LoopXGoalAgentRef +} + +export interface LoopXUnboundHostThreadBindingV1 extends LoopXHostThreadBindingBase { + readonly state: 'unbound' +} + +export type LoopXHostThreadBindingV1 = + | LoopXBoundHostThreadBindingV1 + | LoopXUnboundHostThreadBindingV1 + +export type LoopXFailureCode = + | 'LOOPX_SESSION_NOT_BOUND' + | 'LOOPX_SESSION_LIFECYCLE_MISMATCH' + | 'LOOPX_IDENTITY_CONFLICT' + | 'LOOPX_SELECTION_REQUIRED' + | 'LOOPX_SWITCH_CONFIRMATION_INVALID' + | 'LOOPX_INVALID_REQUEST' + | 'LOOPX_INVALID_TARGET' + | 'LOOPX_BINDING_NOT_FOUND' + | 'LOOPX_REVISION_CONFLICT' + | 'LOOPX_BINDING_HOME_UNINITIALIZED' + | 'LOOPX_BINDING_HOME_UNAVAILABLE' + | 'LOOPX_AUTHORITY_CORRUPT' + | 'LOOPX_AUTHORITY_UNHEALTHY' + | 'LOOPX_AUTHORITY_EXHAUSTED' + | 'LOOPX_DRIVER_NOT_ARMED' + | 'LOOPX_FOREIGN_COMMAND_ACTIVE' + | 'LOOPX_AUTOMATION_SUPPRESSED' + | 'LOOPX_SCHEMA_UNSUPPORTED' + | 'LOOPX_CLI_NOT_FOUND' + | 'LOOPX_CLI_TIMEOUT' + | 'LOOPX_CLI_ABORTED' + | 'LOOPX_CLI_OUTPUT_LIMIT' + | 'LOOPX_CLI_FAILED' + | 'LOOPX_READBACK_FAILED' + | 'LOOPX_REGISTRY_INTEGRITY' + | 'LOOPX_SERVICE_CLOSED' + +export interface LoopXFailure { + readonly code: LoopXFailureCode + readonly message: string + readonly operation?: string + readonly retryable: boolean + readonly outcomeUncertain: boolean +} + +export interface LoopXAppliedSubEffect { + readonly operation: string + readonly application: 'yes' + readonly target?: LoopXGoalAgentRef | undefined +} + +export type LoopXResult = + | { + readonly ok: true + readonly value: T + readonly application: LoopXApplication + readonly subEffects?: readonly LoopXAppliedSubEffect[] | undefined + } + | { + readonly ok: false + readonly error: LoopXFailure + readonly application: LoopXApplication + readonly subEffects?: readonly LoopXAppliedSubEffect[] | undefined + } + +export type LoopXReceiptKind = 'typed_intent' | 'operation_result' | 'semantic_request' +export type LoopXExecution = 'succeeded' | 'rejected' | 'indeterminate' | 'not_attempted' +export type LoopXApplication = 'yes' | 'no' | 'unknown' +export type LoopXDelivery = 'steered' | 'followup_queued' | 'failed' | 'not_needed' +export type LoopXRecoveryAction = + | 'none' + | 'retry_same_tool' + | 'read_authority_then_decide' + | 'correct_request' + | 'ask_user' + | 'stop' + +export interface LoopXOperationReceipt { + readonly schemaVersion: 'dsh_loopx_operation_receipt_v1' + readonly kind: LoopXReceiptKind + readonly operation: string + readonly request?: string | undefined + readonly arguments?: Readonly> | undefined + readonly execution: LoopXExecution + readonly application: LoopXApplication + readonly delivery: LoopXDelivery + readonly recovery: LoopXRecoveryAction + readonly value?: Readonly> | undefined + readonly error?: LoopXFailure | undefined + readonly subEffects?: readonly LoopXAppliedSubEffect[] | undefined +} + +export interface LoopXIdentitySelectionChoice { + readonly agentId?: string | undefined + readonly goalId?: string | undefined +} + +export interface LoopXIdentitySelection { + readonly kind: 'agent' | 'goal' + readonly defaultAction: string + readonly choices: readonly LoopXIdentitySelectionChoice[] + readonly freshAgentSuggestedId?: string | undefined +} + +export interface LoopXStartOptions { + readonly switchConfirmation?: string | undefined +} + +export interface LoopXPlanningCheckpoint { + readonly schemaVersion: 'dsh_loopx_planning_checkpoint_v1' + readonly goalId: string + readonly agentId: string + readonly goalText: string + readonly planner: { + readonly defaultProfile: string + readonly profileSelection: string + readonly openEndedProductDirection: { + readonly suggestedItemsMin: number + readonly suggestedItemsMax: number + readonly intent: string + } + readonly clearBoundedProblem: { + readonly itemCountPolicy: string + readonly mayReuseCurrentTodoWhenItAlreadyRepresentsThePlan: boolean + readonly intent: string + } + readonly allowedPriorities: readonly ['P0', 'P1', 'P2'] + readonly defaultRole: 'agent' + readonly defaultTaskClass: 'advancement_task' + readonly requiredFields: readonly string[] + readonly publicSafeOnly: true + readonly budgetPolicy: string + readonly fineGrainedPlanHorizon?: string | undefined + } + readonly writeback: { + readonly todoTool: 'loopx_todo_add' + readonly minimumTodos: 1 + readonly maximumTodos: number + readonly ordering: 'priority_then_tool_call_order' + readonly activationTool: 'loopx_goal_activate' + readonly activationArguments: LoopXGoalAgentRef + } + readonly stopConditions: readonly string[] + readonly forbidden: readonly [ + 'shell_or_bash', + 'raw_loopx_cli', + 'registry_edit', + 'ctx.goals', + ] +} + +export interface LoopXSwitchRequired { + readonly kind: 'switch_required' + readonly confirmationToken: string + readonly requiresUserConfirmation: true + readonly expiresAt: number + readonly expectedRevision: number + readonly current: LoopXGoalAgentRef + readonly requested: { + readonly operation: 'start' | 'attach' + readonly goalId?: string | undefined + readonly agentId?: string | undefined + readonly newPeer?: true | undefined + } +} + +export type LoopXStartValue = + | { + readonly kind: 'planning' + readonly binding: LoopXBoundHostThreadBindingV1 + readonly planning: LoopXPlanningCheckpoint + readonly modelCheckpoint: string + } + | LoopXSwitchRequired + +export interface LoopXAttachRequest { + readonly goalId: string + readonly agentId?: string | undefined + readonly newPeer?: boolean | undefined + readonly switchConfirmation?: string | undefined +} + +export type LoopXAttachValue = + | { + readonly kind: 'selection_required' + readonly goalId: string + readonly selection: LoopXIdentitySelection + } + | { readonly kind: 'attached'; readonly binding: LoopXBoundHostThreadBindingV1 } + | LoopXSwitchRequired + +export interface LoopXHostStatus { + readonly binarySource: 'config' | 'environment' | 'path' + readonly binding?: LoopXHostThreadBindingV1 | undefined + readonly activation: 'armed' | 'disarmed' + readonly automaticFollowupSuppressed: boolean +} + +export interface LoopXStatusAttentionItem { + readonly goalId: string + readonly status?: string | undefined + readonly severity?: string | undefined + readonly lifecyclePhase?: string | undefined +} + +export interface LoopXStatusAuthority { + readonly schemaVersion: 'loopx_status_projection_v1' + readonly ok: true + readonly goalId: string + readonly attention: readonly LoopXStatusAttentionItem[] +} + +export interface LoopXStatusValue { + readonly host: LoopXHostStatus + readonly authority?: LoopXStatusAuthority | undefined +} + +export interface LoopXTodoClaimRequest { + readonly todoId: string + readonly role?: 'user' | 'agent' | undefined +} + +export interface LoopXTodoAddRequest { + readonly text: string + readonly priority: 'P0' | 'P1' | 'P2' + readonly role?: 'user' | 'agent' | undefined + readonly actionKind?: string | undefined + readonly targetKey?: string | undefined +} + +export interface LoopXTodoAddValue { + readonly todoId: string + readonly status: 'open' + readonly priority: 'P0' | 'P1' | 'P2' + readonly role: 'user' | 'agent' + readonly payload: LoopXTodoAddAuthority +} + +export interface LoopXTodoAddAuthority { + readonly schemaVersion: 'loopx_todo_projection_v1' + readonly goalId: string + readonly todoId: string + readonly status: 'open' + readonly role: 'user' | 'agent' + readonly taskClass: string + readonly actionKind: string + readonly added: boolean + readonly alreadyExists: boolean +} + +export interface LoopXTodoUpdateRequest { + readonly todoId: string + readonly status?: 'open' | 'done' | 'blocked' | 'deferred' | undefined + readonly note?: string | undefined + readonly evidence?: string | undefined + readonly reason?: string | undefined + readonly taskClass?: 'advancement_task' | 'continuous_monitor' | 'user_gate' | 'user_action' | 'blocker' | undefined + readonly clearClaim?: boolean | undefined +} + +export interface LoopXTodoCompleteRequest { + readonly todoId: string + readonly note?: string | undefined + readonly evidence?: string | undefined + readonly noFollowUp?: boolean | undefined + readonly turnInstanceId?: string | undefined + readonly taskLeaseIdempotencyKey?: string | undefined + readonly taskLeaseExpectedVersion?: number | undefined +} + +export interface LoopXTodoMutationValue { + readonly todoId: string + readonly status?: string | undefined + readonly payload: LoopXTodoMutationAuthority +} + +export interface LoopXTodoMutationAuthority { + readonly schemaVersion: 'loopx_todo_projection_v1' + readonly goalId: string + readonly todoId: string + readonly status?: string | undefined + readonly changed?: boolean | undefined + readonly claimedBy?: string | undefined + readonly taskClass?: string | undefined + readonly settlementResult?: string | undefined +} + +export interface LoopXSchedulerHint { + readonly action: string + readonly cadenceClass: string + readonly resetToken?: string | undefined + readonly recommendedIntervalMinutes?: number | undefined + readonly unchangedPollLimit?: number | undefined +} + +export interface LoopXQuotaDecision { + readonly binding: LoopXBoundHostThreadBindingV1 + readonly goalId: string + readonly agentId: string + readonly turnInstanceId: string + readonly shouldRun: boolean + readonly effectiveAction: string + readonly schedulerHint: LoopXSchedulerHint + readonly terminalNoFollowup: boolean + readonly payload: LoopXQuotaAuthority +} + +export interface LoopXQuotaAuthority { + readonly schemaVersion: 'loopx_quota_projection_v1' + readonly goalId: string + readonly shouldRun: boolean + readonly effectiveAction: string + readonly decision?: string | undefined + readonly state?: string | undefined +} + +export interface LoopXTaskBody { + readonly binding: LoopXBoundHostThreadBindingV1 + readonly body: string +} + +export interface LoopXPauseValue { + readonly paused: true + readonly binding?: LoopXHostThreadBindingV1 | undefined +} + +export interface LoopXDetachValue { + readonly detached: true + readonly binding: LoopXUnboundHostThreadBindingV1 +} + +export interface LoopXServiceApi { + resolveBinding(session: LoopXSessionRef, signal?: AbortSignal): Promise> + start(session: LoopXSessionRef, goalText: string, signal?: AbortSignal, options?: LoopXStartOptions): Promise> + attach(session: LoopXSessionRef, request: LoopXAttachRequest, signal?: AbortSignal): Promise> + activate(session: LoopXSessionRef, goalId: string, agentId?: string, signal?: AbortSignal): Promise> + status(session: LoopXSessionRef, signal?: AbortSignal): Promise> + pause(session: LoopXSessionRef): Promise> + resume(session: LoopXSessionRef, signal?: AbortSignal): Promise> + detach(session: LoopXSessionRef, signal?: AbortSignal): Promise> + todoAdd(session: LoopXSessionRef, request: LoopXTodoAddRequest, signal?: AbortSignal): Promise> + todoClaim(session: LoopXSessionRef, request: LoopXTodoClaimRequest, signal?: AbortSignal): Promise> + todoUpdate(session: LoopXSessionRef, request: LoopXTodoUpdateRequest, signal?: AbortSignal): Promise> + todoComplete(session: LoopXSessionRef, request: LoopXTodoCompleteRequest, signal?: AbortSignal): Promise> + quotaShouldRun(session: LoopXSessionRef, turnInstanceId: string, signal?: AbortSignal): Promise> + taskBody(session: LoopXSessionRef, refresh?: boolean, signal?: AbortSignal): Promise> + disposeSession(session: LoopXSessionRef): Promise +} diff --git a/packages/dsh-loopx-plugin/tests/cli-client.spec.ts b/packages/dsh-loopx-plugin/tests/cli-client.spec.ts new file mode 100644 index 000000000..5913dd5e9 --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/cli-client.spec.ts @@ -0,0 +1,298 @@ +import { EventEmitter } from 'node:events' +import type { ChildProcess, ExecFileException } from 'node:child_process' +import { describe, expect, it, vi } from 'vitest' +import { z } from 'zod' +import { + LoopXCliClient, + LoopXCliError, + type ExecFileLike, +} from '../src/cli-client.ts' + +const packetSchema = z.looseObject({ + schema_version: z.literal('fixture_v0'), + ok: z.boolean(), +}) + +function childProcess(): ChildProcess { + return new EventEmitter() as ChildProcess +} + +function immediateExecutor( + stdout: string, + stderr = '', + error: ExecFileException | null = null, +): ExecFileLike { + return (_file, _args, _options, callback) => { + queueMicrotask(() => callback(error, stdout, stderr)) + return childProcess() + } +} + +function request(kind: 'read' | 'idempotent-write' | 'write' = 'read') { + return { + operation: 'fixture', + kind, + args: ['status', '--goal-id', 'goal-a'], + cwd: '/tmp', + schema: packetSchema, + } as const +} + +describe('LoopXCliClient', () => { + it('uses config then LOOPX_BIN then PATH and always executes an argv array without a shell', async () => { + const calls: Parameters[] = [] + const execFile: ExecFileLike = (file, args, options, callback) => { + calls.push([file, args, options, callback]) + queueMicrotask(() => callback(null, JSON.stringify({ + schema_version: 'fixture_v0', + ok: true, + additive: 'accepted', + }), '')) + return childProcess() + } + const configured = new LoopXCliClient({ + loopxBin: '/opt/loopx/bin/loopx', + environment: { LOOPX_TEST_MODE: '1' }, + }, { + execFile, + parentEnv: { + LOOPX_BIN: '/env/loopx', + PATH: '/usr/bin', + PRIVATE_TOKEN: 'must-not-cross', + }, + }) + + await expect(configured.runJson(request())).resolves.toMatchObject({ + schema_version: 'fixture_v0', + ok: true, + additive: 'accepted', + }) + expect(configured.binarySource).toBe('config') + expect(calls[0]?.[0]).toBe('/opt/loopx/bin/loopx') + expect(calls[0]?.[1]).toEqual([ + '--format', 'json', 'status', '--goal-id', 'goal-a', + ]) + expect(calls[0]?.[2]).toMatchObject({ shell: false, encoding: 'utf8' }) + expect(calls[0]?.[2].env).toEqual({ + LOOPX_BIN: '/env/loopx', + LOOPX_TEST_MODE: '1', + PATH: '/usr/bin', + }) + + const environment = new LoopXCliClient({}, { + execFile: immediateExecutor('{"schema_version":"fixture_v0","ok":true}'), + parentEnv: { LOOPX_BIN: '/env/loopx' }, + }) + expect(environment.binarySource).toBe('environment') + await environment.runJson(request()) + + let pathFile = '' + const path = new LoopXCliClient({}, { + execFile: (file, _args, _options, callback) => { + pathFile = file + queueMicrotask(() => callback(null, '{"schema_version":"fixture_v0","ok":true}', '')) + return childProcess() + }, + parentEnv: { PATH: '/usr/bin' }, + }) + expect(path.binarySource).toBe('path') + await path.runJson(request()) + expect(pathFile).toBe('loopx') + }) + + it('rejects unsupported schemas while accepting additive fields and valid JSON on nonzero exit', async () => { + const old = new LoopXCliClient({}, { + execFile: immediateExecutor('{"schema_version":"fixture_v1","ok":true}'), + parentEnv: {}, + }) + await expect(old.runJson(request())).rejects.toMatchObject({ + failure: { code: 'LOOPX_SCHEMA_UNSUPPORTED', outcomeUncertain: false }, + }) + + const exitError = Object.assign(new Error('private process detail'), { code: 1 }) + const validFailure = new LoopXCliClient({}, { + execFile: immediateExecutor( + '{"schema_version":"fixture_v0","ok":false,"new_field":1}', + 'private stderr', + exitError, + ), + parentEnv: {}, + }) + await expect(validFailure.runJson(request())).resolves.toMatchObject({ + schema_version: 'fixture_v0', + ok: false, + new_field: 1, + }) + }) + + it('enforces independent output caps without returning raw output', async () => { + const stdoutClient = new LoopXCliClient({ stdoutCapBytes: 32 }, { + execFile: immediateExecutor(JSON.stringify({ + schema_version: 'fixture_v0', + ok: true, + raw: 'secret-output-that-is-too-large', + })), + parentEnv: {}, + }) + const stdoutError = await stdoutClient.runJson(request()).catch(error => error as LoopXCliError) + expect(stdoutError.failure).toMatchObject({ code: 'LOOPX_CLI_OUTPUT_LIMIT' }) + expect(JSON.stringify(stdoutError.failure)).not.toContain('secret-output') + + const stderrClient = new LoopXCliClient({ stderrCapBytes: 8 }, { + execFile: immediateExecutor( + '{"schema_version":"fixture_v0","ok":true}', + 'private-stderr-value', + ), + parentEnv: {}, + }) + await expect(stderrClient.runJson(request())).rejects.toMatchObject({ + failure: { code: 'LOOPX_CLI_OUTPUT_LIMIT' }, + }) + }) + + it('marks every admitted write timeout uncertain and never makes it blindly retryable', async () => { + const hanging: ExecFileLike = (_file, _args, options, callback) => { + const onAbort = (): void => callback( + Object.assign(new Error('raw abort reason'), { code: 'ABORT_ERR' }), + '', + '', + ) + options.signal?.addEventListener('abort', onAbort, { once: true }) + return childProcess() + } + const writes = new LoopXCliClient({ writeTimeoutMs: 5 }, { + execFile: hanging, + parentEnv: {}, + }) + await expect(writes.runJson(request('write'))).rejects.toMatchObject({ + failure: { + code: 'LOOPX_CLI_TIMEOUT', + retryable: false, + outcomeUncertain: true, + }, + }) + + const idempotent = new LoopXCliClient({ writeTimeoutMs: 5 }, { + execFile: hanging, + parentEnv: {}, + }) + await expect(idempotent.runJson(request('idempotent-write'))).rejects.toMatchObject({ + failure: { + code: 'LOOPX_CLI_TIMEOUT', + retryable: false, + outcomeUncertain: true, + }, + }) + + const controller = new AbortController() + const reads = new LoopXCliClient({ readTimeoutMs: 1_000 }, { + execFile: hanging, + parentEnv: {}, + }) + const pending = reads.runJson({ ...request(), signal: controller.signal }) + controller.abort(new Error('private caller detail')) + await expect(pending).rejects.toMatchObject({ + failure: { code: 'LOOPX_CLI_ABORTED', outcomeUncertain: false }, + }) + }) + + it('pins each binding command to one exact DSH surface and process-local home', async () => { + const calls: Parameters[] = [] + const client = new LoopXCliClient({}, { + execFile: (file, args, options, callback) => { + calls.push([file, args, options, callback]) + queueMicrotask(() => callback(null, '{"schema_version":"fixture_v0","ok":true}', '')) + return childProcess() + }, + parentEnv: {}, + }) + const home = { + key: 'runtime:private', + cwd: '/private/process-cwd', + runtimeRoot: '/private/runtime-root', + } + await client.runBindingJson({ + operation: 'resolve-agent-thread', + kind: 'read', + args: [ + 'resolve-agent-thread', + '--host-surface', 'dsh', + '--thread-id', 'session-a', + ], + home, + schema: packetSchema, + }) + expect(calls[0]?.[1]).toEqual([ + '--format', 'json', + '--runtime-root', '/private/runtime-root', + 'resolve-agent-thread', + '--host-surface', 'dsh', + '--thread-id', 'session-a', + ]) + expect(calls[0]?.[2].cwd).toBe('/private/process-cwd') + + const invalid = await client.runBindingJson({ + operation: 'resolve-agent-thread', + kind: 'read', + args: [ + '--runtime-root', '/caller-selected', + 'resolve-agent-thread', + '--host-surface', 'dsh', + '--thread-id', 'session-a', + ], + home, + schema: packetSchema, + }).catch(error => error as LoopXCliError) + expect(invalid.failure).toMatchObject({ code: 'LOOPX_INVALID_REQUEST' }) + expect(JSON.stringify(invalid.failure)).not.toContain('/private/') + expect(JSON.stringify(invalid.failure)).not.toContain('/caller-selected') + }) + + it('distinguishes an internal scope fence while preserving uncertain write application', async () => { + const hanging: ExecFileLike = (_file, _args, options, callback) => { + options.signal?.addEventListener('abort', () => callback( + Object.assign(new Error('private scope reason'), { code: 'ABORT_ERR' }), + '', + '', + ), { once: true }) + return childProcess() + } + const client = new LoopXCliClient({ writeTimeoutMs: 1_000 }, { + execFile: hanging, + parentEnv: {}, + }) + const pending = client.runJson({ ...request('write'), scopeKey: 'scope-a' }) + .catch(error => error as LoopXCliError) + client.abortScope('scope-a') + await expect(pending).resolves.toMatchObject({ + failure: { + code: 'LOOPX_DRIVER_NOT_ARMED', + outcomeUncertain: true, + }, + }) + }) + + it('aborts and drains active children before closing', async () => { + const callback = vi.fn() + const hanging: ExecFileLike = (_file, _args, options, done) => { + options.signal?.addEventListener('abort', () => { + callback() + done(Object.assign(new Error('closed'), { code: 'ABORT_ERR' }), '', '') + }, { once: true }) + return childProcess() + } + const client = new LoopXCliClient({ readTimeoutMs: 1_000 }, { + execFile: hanging, + parentEnv: {}, + }) + const pending = client.runJson(request()).catch(error => error as LoopXCliError) + await client.close() + expect(callback).toHaveBeenCalledOnce() + await expect(pending).resolves.toMatchObject({ + failure: { code: 'LOOPX_SERVICE_CLOSED' }, + }) + await expect(client.runJson(request())).rejects.toMatchObject({ + failure: { code: 'LOOPX_SERVICE_CLOSED' }, + }) + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/command-tools.spec.ts b/packages/dsh-loopx-plugin/tests/command-tools.spec.ts new file mode 100644 index 000000000..1de4d9c8f --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/command-tools.spec.ts @@ -0,0 +1,831 @@ +import { createRequire } from 'node:module' +import { pathToFileURL } from 'node:url' +import { describe, expect, it } from 'vitest' +import { Context } from '@deepseek-ai/cordis' +import { Inbox } from '@deepseek-ai/dsh-agent' +import type { Agent } from '@deepseek-ai/dsh-agent' +import { CommandRuntime } from '@deepseek-ai/dsh-commands' +import type { CommandDefinition, CommandInvocation } from '@deepseek-ai/dsh-commands' +import { SessionId, SessionStore } from '@deepseek-ai/dsh-session' +import type { UserMessage } from '@deepseek-ai/dsh-session' +import { validateJsonSchemaValue } from '@deepseek-ai/dsh-tools' +import type { ToolDefinition, ToolRunContext } from '@deepseek-ai/dsh-tools' +import { PLUGIN_VERSION, apply as applyCommand } from '../src/command.ts' +import { + CoordinatorRegistry, + installCoordinator, +} from '../src/coordinator.ts' +import { LoopXContinuationDriver } from '../src/driver.ts' +import { apply as applyTools } from '../src/tools.ts' +import type { + LoopXAppliedSubEffect, + LoopXAttachValue, + LoopXBoundHostThreadBindingV1, + LoopXFailure, + LoopXResult, + LoopXServiceApi, + LoopXStartValue, + LoopXStatusValue, + LoopXTodoMutationValue, +} from '../src/types.ts' + +const signal = new AbortController().signal + +function success( + value: T, + application: 'yes' | 'no' = 'no', +): LoopXResult { + return { ok: true, value, application } +} + +function failure( + code: LoopXFailure['code'], + operation: string, + application: 'yes' | 'no' | 'unknown' = 'no', + subEffects?: readonly LoopXAppliedSubEffect[], +): LoopXResult { + return { + ok: false, + application, + error: { + code, + message: `safe ${operation} failure`, + operation, + retryable: false, + outcomeUncertain: application === 'unknown', + }, + ...(subEffects === undefined ? {} : { subEffects }), + } +} + +function bound(revision = 3): LoopXBoundHostThreadBindingV1 { + return Object.freeze({ + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId: 'session-a', + revision, + state: 'bound', + target: Object.freeze({ goalId: 'goal-a', agentId: 'agent-a' }), + }) +} + +function planning(binding = bound()): LoopXStartValue { + return { + kind: 'planning', + binding, + planning: { + schemaVersion: 'dsh_loopx_planning_checkpoint_v1', + goalId: binding.target.goalId, + agentId: binding.target.agentId, + goalText: 'bounded objective', + planner: { + defaultProfile: 'clear_bounded_problem', + profileSelection: 'select', + openEndedProductDirection: { suggestedItemsMin: 2, suggestedItemsMax: 5, intent: 'rank' }, + clearBoundedProblem: { + itemCountPolicy: 'planner_sized', + mayReuseCurrentTodoWhenItAlreadyRepresentsThePlan: true, + intent: 'plan', + }, + allowedPriorities: ['P0', 'P1', 'P2'], + defaultRole: 'agent', + defaultTaskClass: 'advancement_task', + requiredFields: ['priority', 'text'], + publicSafeOnly: true, + budgetPolicy: 'minimum', + }, + writeback: { + todoTool: 'loopx_todo_add', + minimumTodos: 1, + maximumTodos: 5, + ordering: 'priority_then_tool_call_order', + activationTool: 'loopx_goal_activate', + activationArguments: { ...binding.target }, + }, + stopConditions: ['user gate'], + forbidden: ['shell_or_bash', 'raw_loopx_cli', 'registry_edit', 'ctx.goals'], + }, + modelCheckpoint: 'plan', + } +} + +function statusValue(binding = bound()): LoopXStatusValue { + return { + host: { + binarySource: 'path', + binding, + activation: 'disarmed', + automaticFollowupSuppressed: false, + }, + authority: { + schemaVersion: 'loopx_status_projection_v1', + ok: true, + goalId: binding.target.goalId, + attention: [{ + goalId: binding.target.goalId, + status: 'active', + }], + }, + } +} + +interface StubAgent { + agent: Agent + readonly followups: UserMessage[] + readonly steers: UserMessage[] + readonly nextTurn: UserMessage[] + maintenanceClaims: number + whenIdleCalls: number + maintenanceCollisions: number + throwDelivery: boolean + setStatus(value: 'idle' | 'running'): void +} + +interface CommandScope { + readonly ctx: Context + dispose(): Promise +} + +async function createCommandScope(ctx: Context, key: object): Promise { + const require = createRequire(import.meta.url) + const commandsManifest = require.resolve('@deepseek-ai/dsh-commands/package.json') + const commandsRequire = createRequire(commandsManifest) + const scopeEntry = commandsRequire.resolve('@deepseek-ai/dsh-scope') + const scopeModule = await import(/* @vite-ignore */ pathToFileURL(scopeEntry).href) as { + createScope(context: Context, scopeKey: object): CommandScope + } + return scopeModule.createScope(ctx, key) +} + +function stubAgent(id = 'session-a'): StubAgent { + let status: 'idle' | 'running' = 'idle' + const followups: UserMessage[] = [] + const steers: UserMessage[] = [] + const nextTurn: UserMessage[] = [] + const stub: StubAgent = { + agent: undefined as unknown as Agent, + followups, + steers, + nextTurn, + maintenanceClaims: 0, + whenIdleCalls: 0, + maintenanceCollisions: 0, + throwDelivery: false, + setStatus(value) { status = value }, + } + const session = { id, header: { version: 0, id, createdAt: 42, cwd: '/PRIVATE/CWD' } } + stub.agent = { + id, + session, + get status() { return status }, + inbox: { + get nextTurn() { return nextTurn }, + nextStep: [], + get hasPending() { return nextTurn.length > 0 }, + remove(messageId: UserMessage['id']) { + const index = nextTurn.findIndex(message => message.id === messageId) + if (index < 0) return false + nextTurn.splice(index, 1) + return true + }, + }, + runMaintenance(task: (taskSignal: AbortSignal) => Promise): Promise { + stub.maintenanceClaims += 1 + if (stub.maintenanceCollisions > 0) { + stub.maintenanceCollisions -= 1 + throw new Error('hidden maintenance owns idle') + } + return task(new AbortController().signal) + }, + whenIdle() { + stub.whenIdleCalls += 1 + return Promise.resolve() + }, + followup(message: UserMessage) { + if (stub.throwDelivery) throw new Error('followup failed') + followups.push(message) + nextTurn.push(message) + }, + steer(message: UserMessage) { + if (stub.throwDelivery) throw new Error('steer failed') + steers.push(message) + }, + send() {}, + cancel() {}, + } as unknown as Agent + return stub +} + +class FakeService { + readonly coordinator = new CoordinatorRegistry() + readonly calls: string[] = [] + startResult: LoopXResult = success(planning(), 'yes') + attachResult: LoopXResult = success({ kind: 'attached', binding: bound() }, 'yes') + statusResult: LoopXResult = success(statusValue()) + detachResult = success({ + detached: true as const, + binding: { + schemaVersion: 'loopx_host_thread_binding_v1' as const, + hostSurface: 'dsh' as const, + threadId: 'session-a', + revision: 4, + state: 'unbound' as const, + }, + }, 'yes') + + constructor() { + installCoordinator(this, this.coordinator) + } + + status(): Promise> { + this.calls.push('status') + return Promise.resolve(this.statusResult) + } + + start(): Promise> { + this.calls.push('start') + return Promise.resolve(this.startResult) + } + + attach(): Promise> { + this.calls.push('attach') + return Promise.resolve(this.attachResult) + } + + resume() { + this.calls.push('resume') + return Promise.resolve(success(bound(), 'no')) + } + + detach() { + this.calls.push('detach') + return Promise.resolve(this.detachResult) + } + + pause() { + this.calls.push('pause') + return Promise.resolve(success({ paused: true as const, binding: bound() }, 'no')) + } + + activate() { + this.calls.push('activate') + return Promise.resolve(success(bound(), 'yes')) + } + + todoAdd() { + this.calls.push('todoAdd') + return Promise.resolve(success({ + todoId: 'todo-a', status: 'open' as const, priority: 'P0' as const, role: 'agent' as const, + payload: { + schemaVersion: 'loopx_todo_projection_v1' as const, + goalId: 'goal-a', todoId: 'todo-a', status: 'open' as const, role: 'agent' as const, + taskClass: 'advancement_task', actionKind: 'implement', added: true, alreadyExists: false, + }, + }, 'yes')) + } + + todoClaim() { return this.todoMutation('todoClaim') } + todoUpdate() { return this.todoMutation('todoUpdate') } + todoComplete() { return this.todoMutation('todoComplete') } + + private todoMutation(name: string) { + this.calls.push(name) + return Promise.resolve(success({ + todoId: 'todo-a', status: 'done', + payload: { + schemaVersion: 'loopx_todo_projection_v1' as const, + goalId: 'goal-a', todoId: 'todo-a', status: 'done', changed: true, + }, + }, 'yes')) + } + + disposeSession(): Promise { + return Promise.resolve() + } +} + +function registerCommand(service: FakeService): CommandDefinition { + let definition: CommandDefinition | undefined + applyCommand({ + loopx: service, + commands: { register(value: CommandDefinition) { definition = value } }, + } as unknown as Context) + if (definition === undefined) throw new Error('command missing') + return definition +} + +async function runCommand( + service: FakeService, + current: StubAgent, + rawInput: string, + commandId = `cmd-${randomId++}`, +) { + service.coordinator.commandRun(commandId, current.agent.session, current.agent) + return registerCommand(service).handler({ + commandId, + agent: current.agent, + rawInput, + signal, + } as unknown as CommandInvocation) +} + +let randomId = 1 + +function receiptFrom(message: UserMessage): Record { + const text = (message.content[0] as { readonly text: string }).text + const start = text.indexOf('{"schemaVersion"') + if (start < 0) throw new Error('receipt missing') + return JSON.parse(text.slice(start)) as Record +} + +function receiptFromResult(result: { readonly text?: string }): Record { + if (result.text === undefined) throw new Error('command text missing') + return JSON.parse(result.text.split('\n\nUsage:')[0] as string) as Record +} + +function registerTools(service: FakeService): ReadonlyMap { + const tools = new Map() + applyTools({ + loopx: service, + tools: { register(value: ToolDefinition) { tools.set(value.name, value) } }, + } as unknown as Context) + return tools +} + +async function callTool( + service: FakeService, + name: string, + args: unknown, + agent: Agent, +): Promise> { + const definition = registerTools(service).get(name) + if (definition === undefined) throw new Error(`missing tool ${name}`) + const value = await definition.execute(args, { + name, + arguments: args, + agent, + signal, + callId: `call-${name}`, + rootCallId: `call-${name}`, + token: Symbol(name), + deferContext() {}, + concludeTurn() {}, + } as unknown as ToolRunContext) + expect(validateJsonSchemaValue(definition.output.schema, value, '')).toEqual([]) + return value as Record +} + +describe('/loopx closed grammar and routing', () => { + it('returns exact version locally under an owned barrier', async () => { + const service = new FakeService() + const current = stubAgent() + expect(await runCommand(service, current, ' version ')).toEqual({ + kind: 'success', text: `dsh-loopx-plugin ${PLUGIN_VERSION}`, + }) + expect(service.calls).toEqual([]) + expect(current.followups).toEqual([]) + }) + + it.each([ + ['', true], + ['status', false], + ] as const)('routes exact read %j through idle maintenance and followup', async (input, usage) => { + const service = new FakeService() + const current = stubAgent() + const result = await runCommand(service, current, input) + expect(service.calls).toEqual(['status']) + expect(current.maintenanceClaims).toBe(1) + expect(current.followups).toHaveLength(1) + expect(receiptFrom(current.followups[0] as UserMessage)).toMatchObject({ + kind: 'operation_result', operation: 'status', execution: 'succeeded', + application: 'no', delivery: 'followup_queued', + }) + expect(result.text?.includes('Usage: /loopx')).toBe(usage) + expect(JSON.stringify(result)).not.toContain('/PRIVATE/CWD') + }) + + it.each([ + ['start ship it', 'start'], + ['attach goal-a', 'attach'], + ['attach goal-a agent-a', 'attach'], + ['attach goal-a --new-peer', 'attach'], + ['resume', 'resume'], + ['detach', 'detach'], + ] as const)('executes exact idle write %j once', async (input, call) => { + const service = new FakeService() + const current = stubAgent() + await runCommand(service, current, input) + expect(service.calls).toEqual([call]) + expect(current.maintenanceClaims).toBe(1) + expect(current.followups).toHaveLength(1) + expect(receiptFrom(current.followups[0] as UserMessage)).toMatchObject({ + kind: 'operation_result', execution: 'succeeded', delivery: 'followup_queued', + }) + }) + + it.each([ + 'start', 'attach', 'attach --new-peer', 'attach --new-peer goal-a', + 'attach goal-a --new-peer extra', 'attach goal-a agent-a extra', + 'status now', 'pause please', 'resume later', 'detach goal-a', + 'version with details', 'please status', 'start\nobjective', + 'status\n', 'attach goal-a\r\n', 'start objective\n', + ])('preserves non-grammar input %j as semantic data', async (input) => { + const service = new FakeService() + const current = stubAgent() + await runCommand(service, current, input) + expect(service.calls).toEqual([]) + const receipt = receiptFrom(current.followups[0] as UserMessage) + expect(receipt).toMatchObject({ + kind: 'semantic_request', request: input, execution: 'not_attempted', application: 'no', + }) + }) + + it('uses running steer for reads and typed not-attempted intent for writes', async () => { + const service = new FakeService() + const current = stubAgent() + current.setStatus('running') + await runCommand(service, current, 'status') + expect(service.calls).toEqual(['status']) + expect(receiptFrom(current.steers[0] as UserMessage)).toMatchObject({ + kind: 'operation_result', delivery: 'steered', + }) + + service.calls.length = 0 + await runCommand(service, current, 'attach goal-a --new-peer') + expect(service.calls).toEqual([]) + expect(receiptFrom(current.steers[1] as UserMessage)).toMatchObject({ + kind: 'typed_intent', operation: 'goal-attach', execution: 'not_attempted', + arguments: { goalId: 'goal-a', newPeer: true }, delivery: 'steered', + }) + }) + + it('pauses synchronously without Service admission and only steers while running', async () => { + const service = new FakeService() + const current = stubAgent() + const ref = { + id: 'session-a', session: current.agent.session, + identity: { createdAt: 42, cwd: '/PRIVATE/CWD' }, + } + service.coordinator.observeBinding(ref, { key: 'home', cwd: '/PRIVATE/CWD' }, bound()) + service.coordinator.arm(ref, { key: 'home', cwd: '/PRIVATE/CWD' }, bound()) + expect((await runCommand(service, current, 'pause')).kind).toBe('success') + expect(service.calls).toEqual([]) + expect(service.coordinator.snapshot(ref)?.activation).toBe('disarmed') + expect(current.followups).toEqual([]) + + service.coordinator.arm(ref, { key: 'home', cwd: '/PRIVATE/CWD' }, bound()) + current.setStatus('running') + await runCommand(service, current, 'pause') + expect(receiptFrom(current.steers[0] as UserMessage)).toMatchObject({ + operation: 'driver-pause', application: 'no', delivery: 'steered', + }) + }) + + it('waits for a hidden maintenance owner without busy-running the Service', async () => { + const service = new FakeService() + const current = stubAgent() + current.maintenanceCollisions = 1 + await runCommand(service, current, 'status') + expect(current.maintenanceClaims).toBe(2) + expect(current.whenIdleCalls).toBe(1) + expect(service.calls).toEqual(['status']) + }) + + it('keeps an applied write receipt non-retryable when delivery fails', async () => { + const service = new FakeService() + const current = stubAgent() + current.throwDelivery = true + const result = await runCommand(service, current, 'detach') + expect(result.kind).toBe('error') + expect(receiptFromResult(result)).toMatchObject({ + execution: 'succeeded', application: 'yes', delivery: 'failed', recovery: 'none', + }) + expect(service.calls).toEqual(['detach']) + }) + + it('does not release an owned barrier on early command/done', async () => { + const service = new FakeService() + const current = stubAgent() + const pending = Promise.withResolvers>() + service.status = () => pending.promise + const commandId = 'early-done' + service.coordinator.commandRun(commandId, current.agent.session, current.agent) + const operation = registerCommand(service).handler({ + commandId, agent: current.agent, rawInput: 'status', signal, + } as unknown as CommandInvocation) + service.coordinator.commandDone(commandId, current.agent.session) + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(true) + pending.resolve(success(statusValue())) + await operation + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(false) + }) + + it('settles a synchronous Service throw once and releases its owned barrier', async () => { + const service = new FakeService() + const current = stubAgent() + current.setStatus('running') + service.status = () => { throw new Error('synchronous Service failure') } + let releases = 0 + const stop = service.coordinator.onInvalidated(event => { + if (event.kind === 'barrier_released') releases += 1 + }) + const commandId = 'synchronous-throw' + service.coordinator.commandRun(commandId, current.agent.session, current.agent) + const operation = registerCommand(service).handler({ + commandId, agent: current.agent, rawInput: 'status', signal, + } as unknown as CommandInvocation) + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(true) + await operation + stop() + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(false) + expect(service.coordinator.snapshot(current.agent.session)?.failureCount).toBe(1) + expect(releases).toBe(1) + }) + + it('keeps overlapping owned command ids isolated within one Session', async () => { + const service = new FakeService() + const current = stubAgent() + current.setStatus('running') + const first = Promise.withResolvers>() + const second = Promise.withResolvers>() + const pending = [first, second] + service.status = () => { + const operation = pending.shift() + if (operation === undefined) throw new Error('unexpected status call') + return operation.promise + } + const handler = registerCommand(service).handler + service.coordinator.commandRun('overlap-a', current.agent.session, current.agent) + const operationA = handler({ + commandId: 'overlap-a', agent: current.agent, rawInput: 'status', signal, + } as unknown as CommandInvocation) + service.coordinator.commandRun('overlap-b', current.agent.session, current.agent) + const operationB = handler({ + commandId: 'overlap-b', agent: current.agent, rawInput: 'status', signal, + } as unknown as CommandInvocation) + + service.coordinator.commandDone('overlap-a', current.agent.session) + first.resolve(success(statusValue())) + await operationA + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(true) + + service.coordinator.commandDone('overlap-b', current.agent.session) + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(true) + second.resolve(success(statusValue())) + await operationB + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(false) + }) + + it('keeps an owned barrier through UI abort until raw cancellation settles', async () => { + const service = new FakeService() + const current = stubAgent() + current.setStatus('running') + const controller = new AbortController() + const pending = Promise.withResolvers>() + service.status = (...args: unknown[]) => { + expect(args[1]).toBe(controller.signal) + return pending.promise + } + const commandId = 'ui-abort' + service.coordinator.commandRun(commandId, current.agent.session, current.agent) + const operation = registerCommand(service).handler({ + commandId, agent: current.agent, rawInput: 'status', signal: controller.signal, + } as unknown as CommandInvocation) + + controller.abort(new Error('UI request cancelled')) + service.coordinator.commandDone(commandId, current.agent.session) + await Promise.resolve() + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(true) + expect(service.coordinator.snapshot(current.agent.session)?.failureCount).toBe(0) + + pending.resolve(failure('LOOPX_CLI_ABORTED', 'status')) + await operation + expect(service.coordinator.hasBarrier(current.agent.session)).toBe(false) + expect(service.coordinator.snapshot(current.agent.session)?.failureCount).toBe(0) + expect(receiptFrom(current.steers[0] as UserMessage)).toMatchObject({ + error: { code: 'LOOPX_CLI_ABORTED' }, + }) + }) + + it('does not count a coordinator-cancelled command as a breaker failure', async () => { + const service = new FakeService() + const current = stubAgent() + service.statusResult = failure('LOOPX_DRIVER_NOT_ARMED', 'status') + await runCommand(service, current, ' status ') + expect(service.coordinator.snapshot(current.agent.session)?.failureCount).toBe(0) + expect(receiptFrom(current.followups[0] as UserMessage)).toMatchObject({ + request: ' status ', + error: { code: 'LOOPX_DRIVER_NOT_ARMED' }, + }) + }) + + it('uses real CommandRuntime ownership for global /loopx and an agent-scoped shadow', async () => { + const ctx = new Context() + const service = new FakeService() + let driver: LoopXContinuationDriver | undefined + let agentScope: CommandScope | undefined + let stopEvents: (() => void) | undefined + try { + await ctx.plugin(SessionStore) + await ctx.plugin(CommandRuntime) + let commandsCtx: Context | undefined + await ctx.inject(['commands'], injected => { commandsCtx = injected }) + if (commandsCtx === undefined) throw new Error('commands dependency context missing') + const session = ctx.sessions.create(SessionId('session-a'), { meta: { cwd: '/workspace' } }) + const agent = {} as Agent + agentScope = await createCommandScope(commandsCtx, agent) + const inbox = new Inbox(session, { + inserted() {}, + discarded() {}, + claimed() {}, + }) + Object.assign(agent, { + id: session.id, + options: Object.freeze({}), + session, + inbox, + status: 'running' as const, + ctx: agentScope.ctx, + cancel() {}, + whenIdle: () => Promise.resolve(), + runMaintenance: (task: (taskSignal: AbortSignal) => Promise) => + task(new AbortController().signal), + send() {}, + followup() {}, + steer() {}, + inject() {}, + }) + + driver = new LoopXContinuationDriver({ + service: service as unknown as LoopXServiceApi, + isLiveAgent: candidate => candidate === agent, + }) + driver.observeAgent(agent) + stopEvents = ctx.on('session/event', (published, event) => { + if (published === session) driver?.onSessionEvent(agent, event) + }) + const current = Object.freeze({ + id: String(session.id), + session, + identity: Object.freeze({ + createdAt: session.header.createdAt, + cwd: session.header.cwd, + }), + }) + service.coordinator.observeBinding(current, { key: 'home', cwd: '/workspace' }, bound()) + service.coordinator.arm(current, { key: 'home', cwd: '/workspace' }, bound()) + + applyCommand(commandsCtx.extend({ loopx: service }) as Context) + const globalExecution = await ctx.commands.execute(agent, '/loopx version', signal) + await Promise.resolve() + expect(globalExecution).toMatchObject({ + result: { kind: 'success', text: `dsh-loopx-plugin ${PLUGIN_VERSION}` }, + }) + expect(service.coordinator.snapshot(current)).toMatchObject({ + activation: 'armed', foreignLatched: false, barred: false, + }) + + agentScope.ctx.commands.register({ + name: 'loopx', + description: 'agent-owned shadow', + handler: () => ({ kind: 'success', text: 'shadow-owned' }), + }) + const shadowExecution = await ctx.commands.execute(agent, '/loopx version', signal) + await Promise.resolve() + expect(shadowExecution).toMatchObject({ + result: { kind: 'success', text: 'shadow-owned' }, + }) + expect(service.coordinator.snapshot(current)).toMatchObject({ + activation: 'disarmed', foreignLatched: true, barred: false, + }) + + const lifecycle = session.events.filter(event => + event.type === 'command/run' || event.type === 'command/done') + expect(lifecycle).toMatchObject([ + { type: 'command/run', data: { name: 'loopx' } }, + { type: 'command/done', data: { kind: 'success' } }, + { type: 'command/run', data: { name: 'loopx' } }, + { type: 'command/done', data: { kind: 'success', text: 'shadow-owned' } }, + ]) + expect(lifecycle[0]?.data.commandId).toBe(lifecycle[1]?.data.commandId) + expect(lifecycle[2]?.data.commandId).toBe(lifecycle[3]?.data.commandId) + } finally { + stopEvents?.() + await driver?.dispose() + await agentScope?.dispose() + await ctx.fiber.dispose() + } + }) +}) + +describe('typed tool receipts', () => { + it('registers eleven closed tools and removes obsolete start selectors', () => { + const tools = registerTools(new FakeService()) + expect(tools.size).toBe(11) + for (const tool of tools.values()) { + expect(tool.parameters).toMatchObject({ type: 'object', additionalProperties: false }) + } + expect(Object.keys(tools.get('loopx_goal_start')?.parameters.properties ?? {})).toEqual([ + 'goalText', 'switchConfirmation', + ]) + }) + + it('takes application from Service, including a successful no-op', async () => { + const service = new FakeService() + service.attachResult = success({ kind: 'attached', binding: bound() }, 'no') + const result = await callTool(service, 'loopx_goal_attach', { + goalId: 'goal-a', agentId: 'agent-a', + }, stubAgent().agent) + expect(result).toMatchObject({ + schemaVersion: 'dsh_loopx_operation_receipt_v1', + kind: 'operation_result', execution: 'succeeded', application: 'no', + delivery: 'not_needed', + }) + }) + + it('filters coordinator cancellation but counts a terminal tool failure', async () => { + const service = new FakeService() + const current = stubAgent().agent + service.startResult = failure('LOOPX_FOREIGN_COMMAND_ACTIVE', 'goal-start') + await callTool(service, 'loopx_goal_start', { goalText: 'safe' }, current) + expect(service.coordinator.snapshot(current.session)?.failureCount).toBe(0) + + service.startResult = failure('LOOPX_READBACK_FAILED', 'goal-start') + await callTool(service, 'loopx_goal_start', { goalText: 'safe' }, current) + expect(service.coordinator.snapshot(current.session)?.failureCount).toBe(1) + }) + + it('preserves bounded committed sub-effects on a rejected operation', async () => { + const service = new FakeService() + service.attachResult = failure('LOOPX_CLI_FAILED', 'goal-attach', 'yes', [{ + operation: 'register-agent', application: 'yes', + target: { goalId: 'goal-a', agentId: 'fresh-a' }, + }]) + const result = await callTool(service, 'loopx_goal_attach', { + goalId: 'goal-a', newPeer: true, + }, stubAgent().agent) + expect(result).toMatchObject({ + execution: 'rejected', application: 'yes', recovery: 'read_authority_then_decide', + subEffects: [{ operation: 'register-agent', application: 'yes' }], + }) + }) + + it('maps an indeterminate write to unknown application and authoritative readback', async () => { + const service = new FakeService() + service.detachResult = failure('LOOPX_CLI_TIMEOUT', 'goal-detach', 'unknown') + const result = await callTool(service, 'loopx_goal_detach', {}, stubAgent().agent) + expect(result).toMatchObject({ + execution: 'indeterminate', application: 'unknown', + recovery: 'read_authority_then_decide', delivery: 'not_needed', + }) + }) + + it('projects only bounded status and Todo fields', async () => { + const service = new FakeService() + const current = stubAgent().agent + service.statusResult = success({ + ...statusValue(), + authority: { + ...statusValue().authority, + runtimeRoot: '/PRIVATE/RUNTIME', + rawStderr: 'SECRET STDERR', + }, + } as unknown as LoopXStatusValue) + service.todoUpdate = (() => Promise.resolve(success({ + todoId: 'todo-a', + status: 'done', + payload: { + schemaVersion: 'loopx_todo_projection_v1', + goalId: 'goal-a', + todoId: 'todo-a', + status: 'done', + changed: true, + project: '/PRIVATE/PROJECT', + registry: '/PRIVATE/REGISTRY', + state_file: '/PRIVATE/STATE', + }, + } as unknown as LoopXTodoMutationValue, 'yes'))) as unknown as FakeService['todoUpdate'] + const status = await callTool(service, 'loopx_status', {}, current) + const todo = await callTool(service, 'loopx_todo_update', { + todoId: 'todo-a', status: 'done', + }, current) + const rendered = JSON.stringify([status, todo]) + expect(rendered).toContain('loopx_status_projection_v1') + expect(rendered).toContain('loopx_todo_projection_v1') + expect(rendered).not.toContain('/PRIVATE/CWD') + expect(rendered).not.toContain('SECRET STDERR') + expect(rendered).not.toMatch(/projectLocator|registryLocator|runtimeRoot|state_file|raw stderr/i) + expect(rendered).not.toMatch(/PRIVATE\/(?:PROJECT|REGISTRY|STATE|RUNTIME)/) + }) + + it('rejects alternate identity and locator keys before Service admission', async () => { + const service = new FakeService() + const result = await callTool(service, 'loopx_goal_start', { + goalText: 'safe objective', runtimeRoot: '/PRIVATE/RUNTIME', argv: ['loopx'], + }, stubAgent().agent) + expect(result).toMatchObject({ + execution: 'rejected', application: 'no', error: { code: 'LOOPX_INVALID_REQUEST' }, + }) + expect(service.calls).toEqual([]) + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/coordinator.spec.ts b/packages/dsh-loopx-plugin/tests/coordinator.spec.ts new file mode 100644 index 000000000..e0b87f06d --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/coordinator.spec.ts @@ -0,0 +1,250 @@ +import { describe, expect, it, vi } from 'vitest' +import type { Agent } from '@deepseek-ai/dsh-agent' +import { + CoordinatorAdmissionCancelled, + CoordinatorRegistry, + LOOPX_FAILURE_SUPPRESSION_THRESHOLD, + isCoordinatorCancellation, +} from '../src/coordinator.ts' +import type { + LoopXBoundHostThreadBindingV1, + LoopXResult, + LoopXSessionRef, +} from '../src/types.ts' + +const home = Object.freeze({ key: 'runtime:fixture', cwd: '/fixture', runtimeRoot: '/fixture' }) + +function session(object: object = {}): LoopXSessionRef { + return Object.freeze({ + id: 'session-a', + session: object, + identity: Object.freeze({ createdAt: 1, cwd: '/fixture' }), + }) +} + +function binding(revision = 1): LoopXBoundHostThreadBindingV1 { + return Object.freeze({ + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId: 'session-a', + revision, + state: 'bound', + target: Object.freeze({ goalId: 'goal-a', agentId: 'agent-a' }), + }) +} + +describe('CoordinatorRegistry', () => { + it('keys lifecycle and fences by exact Session object rather than structural identity', () => { + const registry = new CoordinatorRegistry() + const first = session({}) + const second = session({}) + const firstFence = registry.arm(first, home, binding()) + const secondFence = registry.arm(second, home, binding()) + expect(firstFence).toBeDefined() + expect(secondFence).toBeDefined() + expect(registry.isCurrent(firstFence!)).toBe(true) + expect(registry.isCurrent(secondFence!)).toBe(true) + + registry.advanceEpoch(second) + expect(registry.isCurrent(firstFence!)).toBe(true) + expect(registry.isCurrent(secondFence!)).toBe(false) + + registry.drop(first) + expect(registry.isClosed(first)).toBe(true) + expect(registry.snapshot(first)?.activation).toBe('disarmed') + }) + + it('keeps equal command ids independent across exact Sessions', () => { + const registry = new CoordinatorRegistry() + const first = session({}) + const second = session({}) + const firstAgent = {} + const secondAgent = {} + registry.commandRun('same-command', first.session, firstAgent) + registry.commandRun('same-command', second.session, secondAgent) + + expect(registry.claimCommand('same-command', first.session, firstAgent)).toBe(true) + expect(registry.classifyUnclaimed('same-command', second.session)).toBe('foreign') + expect(registry.hasBarrier(first)).toBe(true) + expect(registry.hasBarrier(second)).toBe(true) + + registry.commandDone('same-command', first.session) + expect(registry.hasBarrier(first)).toBe(true) + registry.settleOwned('same-command', first.session) + expect(registry.hasBarrier(first)).toBe(false) + expect(registry.hasBarrier(second)).toBe(true) + + registry.commandDone('same-command', second.session) + expect(registry.hasBarrier(second)).toBe(false) + expect(registry.snapshot(second)).toMatchObject({ + activation: 'disarmed', + foreignLatched: true, + }) + }) + + it('invalidates each failed attempt without disarming and suppresses only automation at eight', () => { + const abort = vi.fn() + const registry = new CoordinatorRegistry(abort) + const current = session() + expect(registry.arm(current, home, binding())).toBeDefined() + const initialEpoch = registry.snapshot(current)?.activationEpoch ?? 0 + + for (let count = 1; count < LOOPX_FAILURE_SUPPRESSION_THRESHOLD; count += 1) { + expect(registry.recordOutcome(current, 'failure')).toMatchObject({ + activation: 'armed', + failureCount: count, + automaticFollowupSuppressed: false, + activationEpoch: initialEpoch + count, + }) + } + expect(registry.recordOutcome(current, 'failure')).toMatchObject({ + activation: 'armed', + failureCount: LOOPX_FAILURE_SUPPRESSION_THRESHOLD, + automaticFollowupSuppressed: true, + activationEpoch: initialEpoch + LOOPX_FAILURE_SUPPRESSION_THRESHOLD, + }) + expect(abort).toHaveBeenCalledTimes(LOOPX_FAILURE_SUPPRESSION_THRESHOLD) + + const recoveryFence = registry.arm(current, home, binding()) + expect(recoveryFence).toBeDefined() + expect(registry.isCurrent(recoveryFence!)).toBe(false) + expect(registry.recordOutcome(current, 'success')).toMatchObject({ + activation: 'armed', + failureCount: 0, + automaticFollowupSuppressed: false, + }) + expect(registry.isCurrent(recoveryFence!)).toBe(true) + }) + + it('fences home and revision changes and never restores activation from observation', () => { + const registry = new CoordinatorRegistry() + const current = session() + const fence = registry.arm(current, home, binding()) + expect(registry.isCurrent(fence!)).toBe(true) + + registry.observeBinding(current, home, binding(2)) + expect(registry.snapshot(current)).toMatchObject({ activation: 'disarmed' }) + expect(registry.isCurrent(fence!)).toBe(false) + + const changedHome = Object.freeze({ key: 'runtime:other', cwd: '/other', runtimeRoot: '/other' }) + registry.observe(current, changedHome) + expect(registry.snapshot(current)).toMatchObject({ + activation: 'disarmed', + bindingHome: { key: 'runtime:other' }, + }) + }) + + it('classifies local fencing and lifecycle cancellation as non-countable', () => { + const cancelled = (code: 'LOOPX_DRIVER_NOT_ARMED' | 'LOOPX_SERVICE_CLOSED') => ({ + ok: false, + application: 'unknown', + error: { + code, + message: 'bounded', + retryable: false, + outcomeUncertain: true, + }, + }) satisfies LoopXResult + expect(isCoordinatorCancellation(cancelled('LOOPX_DRIVER_NOT_ARMED'))).toBe(true) + expect(isCoordinatorCancellation(cancelled('LOOPX_SERVICE_CLOSED'))).toBe(true) + expect(isCoordinatorCancellation({ ok: true, value: undefined, application: 'no' })).toBe(false) + }) + + it('waits and retries an asynchronous hidden-maintenance collision without busy looping', async () => { + const registry = new CoordinatorRegistry() + const whenIdle = vi.fn(() => Promise.resolve()) + let attempts = 0 + const agent = { + status: 'idle', + whenIdle, + runMaintenance(task: (signal: AbortSignal) => Promise): Promise { + attempts += 1 + if (attempts === 1) return Promise.reject(new Error('hidden maintenance owns idle')) + return task(new AbortController().signal) + }, + } as unknown as Agent + + await expect(registry.admitWhenIdle( + agent, + new AbortController().signal, + () => true, + async () => 'admitted', + )).resolves.toEqual({ route: 'idle', value: 'admitted' }) + expect(attempts).toBe(2) + expect(whenIdle).toHaveBeenCalledOnce() + }) + + it('cancels a hidden-maintenance wait when the caller aborts', async () => { + const registry = new CoordinatorRegistry() + let waitStarted: (() => void) | undefined + const waiting = new Promise((resolve) => { waitStarted = resolve }) + const whenIdle = vi.fn(() => { + waitStarted?.() + return new Promise(() => {}) + }) + const task = vi.fn(async () => 'must-not-run') + const agent = { + status: 'idle', + whenIdle, + runMaintenance: vi.fn(() => Promise.reject(new Error('maintenance collision'))), + } as unknown as Agent + const controller = new AbortController() + const admission = registry.admitWhenIdle(agent, controller.signal, () => true, task) + + await waiting + const reason = new Error('caller aborted') + const rejected = expect(admission).rejects.toBe(reason) + controller.abort(reason) + await rejected + expect(whenIdle).toHaveBeenCalledOnce() + expect(task).not.toHaveBeenCalled() + }) + + it('routes running when the Agent starts running during a maintenance-collision wait', async () => { + const registry = new CoordinatorRegistry() + let status: 'idle' | 'running' = 'idle' + let waitStarted: (() => void) | undefined + let releaseIdle: (() => void) | undefined + const waiting = new Promise((resolve) => { waitStarted = resolve }) + const whenIdle = vi.fn(() => new Promise((resolve) => { + releaseIdle = resolve + waitStarted?.() + })) + const task = vi.fn(async () => 'must-not-run') + const agent = { + get status() { return status }, + whenIdle, + runMaintenance: vi.fn(() => Promise.reject(new Error('maintenance collision'))), + } as unknown as Agent + const admission = registry.admitWhenIdle( + agent, + new AbortController().signal, + () => true, + task, + ) + + await waiting + status = 'running' + releaseIdle?.() + await expect(admission).resolves.toEqual({ route: 'running' }) + expect(agent.runMaintenance).toHaveBeenCalledOnce() + expect(task).not.toHaveBeenCalled() + }) + + it('retires serialized work that had not entered before exact Session disposal', async () => { + const registry = new CoordinatorRegistry() + const current = session() + let release: (() => void) | undefined + const gate = new Promise((resolve) => { release = resolve }) + const first = registry.serialize(current, () => gate) + let entered = false + const second = registry.serialize(current, async () => { entered = true }) + await Promise.resolve() + + registry.drop(current) + release?.() + await first + await expect(second).rejects.toBeInstanceOf(CoordinatorAdmissionCancelled) + expect(entered).toBe(false) + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/driver.spec.ts b/packages/dsh-loopx-plugin/tests/driver.spec.ts new file mode 100644 index 000000000..40f22eaff --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/driver.spec.ts @@ -0,0 +1,593 @@ +import { describe, expect, it } from 'vitest' +import type { Agent } from '@deepseek-ai/dsh-agent' +import type { SessionEvent, UserMessage } from '@deepseek-ai/dsh-session' +import { CoordinatorRegistry, installCoordinator } from '../src/coordinator.ts' +import { + LoopXContinuationDriver, + type LoopXDriverClock, +} from '../src/driver.ts' +import type { + LoopXBoundHostThreadBindingV1, + LoopXFailure, + LoopXQuotaDecision, + LoopXResult, + LoopXSessionRef, + LoopXTaskBody, +} from '../src/types.ts' + +function ok(value: T, application: 'yes' | 'no' = 'no'): LoopXResult { + return { ok: true, value, application } +} + +function failed( + operation: string, + application: 'yes' | 'no' | 'unknown' = 'no', +): LoopXResult { + const error: LoopXFailure = { + code: application === 'unknown' ? 'LOOPX_CLI_TIMEOUT' : 'LOOPX_READBACK_FAILED', + message: `safe ${operation} failure`, + operation, + retryable: application === 'no', + outcomeUncertain: application === 'unknown', + } + return { ok: false, error, application } +} + +function cancelled( + operation: string, + code: 'LOOPX_DRIVER_NOT_ARMED' | 'LOOPX_FOREIGN_COMMAND_ACTIVE', +): LoopXResult { + return { + ok: false, + application: 'no', + error: { + code, + message: `safe ${operation} cancellation`, + operation, + retryable: false, + outcomeUncertain: false, + }, + } +} + +function binding(revision = 1): LoopXBoundHostThreadBindingV1 { + return { + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId: 'session-a', + revision, + state: 'bound', + target: { goalId: 'goal-a', agentId: 'agent-a' }, + } +} + +function ref(agent: Agent): LoopXSessionRef { + return { + id: String(agent.id), + session: agent.session, + identity: { createdAt: agent.session.header.createdAt, cwd: agent.session.header.cwd }, + } +} + +function decision(current: LoopXBoundHostThreadBindingV1, turnInstanceId: string): LoopXQuotaDecision { + return { + binding: current, + goalId: current.target.goalId, + agentId: current.target.agentId, + turnInstanceId, + shouldRun: true, + effectiveAction: 'run_now', + schedulerHint: { + action: 'run_now', cadenceClass: 'immediate', resetToken: 'reset-a', + recommendedIntervalMinutes: 1, unchangedPollLimit: 2, + }, + terminalNoFollowup: false, + payload: { + schemaVersion: 'loopx_quota_projection_v1', + goalId: current.target.goalId, + shouldRun: true, + effectiveAction: 'run_now', + }, + } +} + +class FakeService { + readonly coordinator = new CoordinatorRegistry() + current = binding() + resolveCalls = 0 + quotaCalls = 0 + taskCalls = 0 + disposeCalls = 0 + quotaResult?: LoopXResult + taskResult?: LoopXResult + resolvePromise?: Promise> + quotaError?: Error + + constructor() { installCoordinator(this, this.coordinator) } + + resolveBinding(session: LoopXSessionRef) { + this.resolveCalls += 1 + this.coordinator.observeBinding(session, { + key: 'home-a', cwd: '/workspace', runtimeRoot: '/runtime', + }, this.current) + return this.resolvePromise ?? Promise.resolve(ok(this.current)) + } + + quotaShouldRun(_session: LoopXSessionRef, turnInstanceId: string) { + this.quotaCalls += 1 + if (this.quotaError !== undefined) return Promise.reject(this.quotaError) + return Promise.resolve(this.quotaResult ?? ok(decision(this.current, turnInstanceId), 'yes')) + } + + taskBody() { + this.taskCalls += 1 + return Promise.resolve(this.taskResult ?? ok({ + binding: this.current, + body: `fresh task body ${this.taskCalls}`, + })) + } + + disposeSession() { + this.disposeCalls += 1 + return Promise.resolve() + } +} + +interface AgentHarness { + agent: Agent + readonly followups: UserMessage[] + readonly nextTurn: UserMessage[] + readonly nextStep: UserMessage[] + readonly removed: UserMessage['id'][] + readonly restored: Array<{ readonly message: UserMessage; readonly wakeup: boolean }> + maintenanceClaims: number + maintenanceCollisions: number + whenIdleCalls: number + duringFollowup?: (() => void) | undefined + setStatus(value: 'idle' | 'running'): void + connect(driver: LoopXContinuationDriver): void +} + +function fakeAgent(): AgentHarness { + let status: 'idle' | 'running' = 'running' + let driver: LoopXContinuationDriver | undefined + const followups: UserMessage[] = [] + const nextTurn: UserMessage[] = [] + const nextStep: UserMessage[] = [] + const removed: UserMessage['id'][] = [] + const restored: Array<{ readonly message: UserMessage; readonly wakeup: boolean }> = [] + const harness: AgentHarness = { + agent: undefined as unknown as Agent, + followups, + nextTurn, + nextStep, + removed, + restored, + maintenanceClaims: 0, + maintenanceCollisions: 0, + whenIdleCalls: 0, + duringFollowup: undefined, + setStatus(value) { status = value }, + connect(value) { driver = value }, + } + const session = { + id: 'session-a', + header: { version: 0, id: 'session-a', createdAt: 42, cwd: '/workspace' }, + } + harness.agent = { + id: 'session-a', + session, + get status() { return status }, + inbox: { + get nextTurn() { return nextTurn }, + get nextStep() { return nextStep }, + get hasPending() { return nextTurn.length > 0 || nextStep.length > 0 }, + remove(messageId: UserMessage['id']) { + for (const list of [nextStep, nextTurn]) { + const index = list.findIndex(message => message.id === messageId) + if (index >= 0) { + const [message] = list.splice(index, 1) + removed.push(messageId) + if (message !== undefined) driver?.onInboxDiscarded(harness.agent, message) + return true + } + } + return false + }, + }, + runMaintenance(task: (taskSignal: AbortSignal) => Promise): Promise { + harness.maintenanceClaims += 1 + if (harness.maintenanceCollisions > 0) { + harness.maintenanceCollisions -= 1 + throw new Error('maintenance collision') + } + return task(new AbortController().signal) + }, + whenIdle() { + harness.whenIdleCalls += 1 + return Promise.resolve() + }, + followup(message: UserMessage) { + followups.push(message) + nextTurn.push(message) + harness.duringFollowup?.() + driver?.onInboxInserted(harness.agent, message) + }, + send(message: UserMessage, target: 'next-turn' | 'next-step', wakeup: boolean) { + ;(target === 'next-turn' ? nextTurn : nextStep).push(message) + restored.push({ message, wakeup }) + }, + steer() {}, + cancel() {}, + } as unknown as Agent + return harness +} + +interface FakeTimer { + readonly id: number + readonly callback: () => void +} + +class FakeClock implements LoopXDriverClock { + private id = 0 + readonly timers = new Map() + now() { return 1_000 } + setTimeout(callback: () => void, _delayMs: number): number { + const id = ++this.id + this.timers.set(id, { id, callback }) + return id + } + clearTimeout(handle: unknown): void { + if (typeof handle === 'number') this.timers.delete(handle) + } + fireNext(): void { + const timer = this.timers.values().next().value as FakeTimer | undefined + if (timer === undefined) throw new Error('no timer') + this.timers.delete(timer.id) + timer.callback() + } +} + +interface Harness { + readonly service: FakeService + readonly current: AgentHarness + readonly driver: LoopXContinuationDriver + readonly clock: FakeClock + arm(): void + idle(): Promise + claim(message: UserMessage): void + human(id: string): UserMessage +} + +function harness(): Harness { + const service = new FakeService() + const current = fakeAgent() + const clock = new FakeClock() + const driver = new LoopXContinuationDriver({ + service: service as unknown as import('../src/types.ts').LoopXServiceApi, + isLiveAgent: candidate => candidate === current.agent, + clock, + makeTurnInstanceId: () => `turn-${service.quotaCalls + 1}`, + }) + current.connect(driver) + driver.observeAgent(current.agent) + return { + service, + current, + driver, + clock, + arm() { + const session = ref(current.agent) + const home = { key: 'home-a', cwd: '/workspace', runtimeRoot: '/runtime' } + service.coordinator.observeBinding(session, home, service.current) + service.coordinator.arm(session, home, service.current) + }, + async idle() { + current.setStatus('idle') + driver.onAgentStatus(current.agent, 'idle') + await driver.whenSettled() + }, + claim(message) { + const index = current.nextTurn.findIndex(candidate => candidate.id === message.id) + if (index >= 0) current.nextTurn.splice(index, 1) + current.setStatus('running') + driver.onInboxClaimed(current.agent, message) + }, + human(id) { + return { + id: id as UserMessage['id'], role: 'user', + content: [{ type: 'text', text: id }], source: { kind: 'user' }, + } + }, + } +} + +function commandEvent(type: 'command/run' | 'command/done', id: string): SessionEvent { + return { + type, seq: 0, time: 1, + data: type === 'command/run' + ? { commandId: id, name: 'anything', source: { kind: 'user' } } + : { commandId: id, kind: 'success' }, + } as SessionEvent +} + +describe('automatic continuation driver', () => { + it('starts disarmed and queues only after an explicit arm plus idle admission', async () => { + const test = harness() + await test.idle() + expect(test.service.resolveCalls).toBe(0) + expect(test.current.followups).toEqual([]) + + test.current.setStatus('running') + test.arm() + await test.idle() + expect(test.service.resolveCalls).toBe(1) + expect(test.service.quotaCalls).toBe(1) + expect(test.service.taskCalls).toBe(1) + expect(test.current.followups[0]?.content).toEqual([ + { type: 'text', text: 'fresh task body 1' }, + ]) + await test.driver.dispose() + }) + + it('freshly resolves binding, quota, and task body on every admitted round', async () => { + const test = harness() + test.arm() + await test.idle() + const first = test.current.followups[0] as UserMessage + test.claim(first) + expect(await test.driver.onPreStep( + test.current.agent, [first], new AbortController().signal, + () => Promise.resolve({ kind: 'enter', messages: [first] }), + )).toMatchObject({ kind: 'enter' }) + await test.idle() + expect(test.service.resolveCalls).toBe(2) + expect(test.service.quotaCalls).toBe(2) + expect(test.service.taskCalls).toBe(2) + expect(test.current.followups[1]?.content).toEqual([ + { type: 'text', text: 'fresh task body 2' }, + ]) + await test.driver.dispose() + }) + + it('fences a stale cached binding revision before quota or queue admission', async () => { + const test = harness() + test.arm() + test.service.current = binding(2) + await test.idle() + expect(test.service.resolveCalls).toBe(1) + expect(test.service.quotaCalls).toBe(0) + expect(test.current.followups).toEqual([]) + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.activation).toBe('disarmed') + await test.driver.dispose() + }) + + it('lets human input remove queued automatic work before claim without disarming', async () => { + const test = harness() + test.arm() + await test.idle() + const automatic = test.current.followups[0] as UserMessage + const human = test.human('human-first') + test.current.nextTurn.push(human) + test.driver.onInboxInserted(test.current.agent, human) + expect(test.current.removed).toEqual([automatic.id]) + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.activation).toBe('armed') + + test.current.nextTurn.splice(test.current.nextTurn.indexOf(human), 1) + await test.idle() + expect(test.current.followups).toHaveLength(2) + expect(test.service.quotaCalls).toBe(2) + await test.driver.dispose() + }) + + it('removes exact reserved work when ordinary input reenters synchronous followup', async () => { + const test = harness() + const human = test.human('human-during-followup') + test.current.duringFollowup = () => { + test.current.duringFollowup = undefined + test.current.nextTurn.push(human) + test.driver.onInboxInserted(test.current.agent, human) + } + test.arm() + await test.idle() + const automatic = test.current.followups[0] as UserMessage + expect(test.current.removed).toEqual([automatic.id]) + expect(test.current.nextTurn).toEqual([human]) + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.activation).toBe('armed') + await test.driver.dispose() + }) + + it('honors claim as the cutoff across later human input and authority invalidation', async () => { + const test = harness() + test.arm() + await test.idle() + const automatic = test.current.followups[0] as UserMessage + test.claim(automatic) + const human = test.human('human-after-claim') + test.current.nextTurn.push(human) + test.driver.onInboxInserted(test.current.agent, human) + test.service.coordinator.pause(ref(test.current.agent)) + let downstream = false + const decision = await test.driver.onPreStep( + test.current.agent, + [automatic, human], + new AbortController().signal, + () => { + downstream = true + return Promise.resolve({ kind: 'enter', messages: [automatic, human] }) + }, + ) + expect(decision).toEqual({ kind: 'enter', messages: [automatic, human] }) + expect(downstream).toBe(true) + expect(test.current.removed).toEqual([]) + await test.driver.dispose() + }) + + it('restores and wakes non-plugin messages on an exceptional identity mismatch', async () => { + const test = harness() + const stale: UserMessage = { + id: 'stale-auto' as UserMessage['id'], role: 'user', + content: [{ type: 'text', text: 'stale' }], + source: { kind: 'plugin', plugin: 'dsh-loopx-plugin/driver' }, + } + const human = test.human('retained-human') + const result = await test.driver.onPreStep( + test.current.agent, + [human, stale], + new AbortController().signal, + () => Promise.reject(new Error('stale work reached downstream')), + ) + expect(result).toEqual({ kind: 'reject' }) + expect(test.current.restored).toEqual([{ message: human, wakeup: true }]) + expect(test.current.nextStep).toEqual([human]) + await test.driver.dispose() + }) + + it('rejects same-id automatic content tampering before the claim cutoff', async () => { + const test = harness() + test.arm() + await test.idle() + const automatic = test.current.followups[0] as UserMessage + const tampered: UserMessage = { + ...automatic, + content: [{ type: 'text', text: 'tampered automatic body' }], + } + test.claim(tampered) + const human = test.human('human-with-tamper') + let downstream = false + expect(await test.driver.onPreStep( + test.current.agent, + [tampered, human], + new AbortController().signal, + () => { + downstream = true + return Promise.resolve({ kind: 'enter', messages: [tampered, human] }) + }, + )).toEqual({ kind: 'reject' }) + expect(downstream).toBe(false) + expect(test.current.restored).toEqual([{ message: human, wakeup: true }]) + await test.driver.dispose() + }) + + it('waits and retries a true-idle maintenance collision', async () => { + const test = harness() + test.current.maintenanceCollisions = 1 + test.arm() + await test.idle() + expect(test.current.maintenanceClaims).toBe(2) + expect(test.current.whenIdleCalls).toBe(1) + expect(test.service.quotaCalls).toBe(1) + await test.driver.dispose() + }) + + it('counts one terminal outcome per attempt and suppresses the eighth failure', async () => { + const test = harness() + test.service.quotaResult = failed('quota') + test.arm() + await test.idle() + for (let count = 1; count < 8; count += 1) { + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.failureCount).toBe(count) + expect(test.clock.timers.size).toBe(1) + test.clock.fireNext() + await test.driver.whenSettled() + } + expect(test.service.resolveCalls).toBe(8) + expect(test.service.quotaCalls).toBe(8) + expect(test.service.taskCalls).toBe(0) + expect(test.service.coordinator.snapshot(ref(test.current.agent))).toMatchObject({ + activation: 'armed', failureCount: 8, automaticFollowupSuppressed: true, + }) + expect(test.clock.timers.size).toBe(0) + await test.driver.dispose() + }) + + it('does not count an ordinary-input scope abort as an automatic failure', async () => { + const test = harness() + const pending = Promise.withResolvers>() + test.service.resolvePromise = pending.promise + test.arm() + const idle = test.idle() + await Promise.resolve() + expect(test.service.resolveCalls).toBe(1) + const human = test.human('human-cancels-scope') + test.current.nextTurn.push(human) + test.driver.onInboxInserted(test.current.agent, human) + pending.resolve(cancelled('binding-resolve', 'LOOPX_DRIVER_NOT_ARMED')) + await idle + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.failureCount).toBe(0) + await test.driver.dispose() + }) + + it('does not count a foreign-command scope abort as an automatic failure', async () => { + const test = harness() + const pending = Promise.withResolvers>() + test.service.resolvePromise = pending.promise + test.arm() + const idle = test.idle() + await Promise.resolve() + expect(test.service.resolveCalls).toBe(1) + test.driver.onSessionEvent(test.current.agent, commandEvent('command/run', 'foreign-pending')) + await Promise.resolve() + pending.resolve(cancelled('binding-resolve', 'LOOPX_FOREIGN_COMMAND_ACTIVE')) + await idle + expect(test.service.coordinator.snapshot(ref(test.current.agent))).toMatchObject({ + failureCount: 0, foreignLatched: true, + }) + test.driver.onSessionEvent(test.current.agent, commandEvent('command/done', 'foreign-pending')) + await test.driver.dispose() + }) + + it('never schedules a blind retry after an applied or indeterminate failure', async () => { + for (const application of ['yes', 'unknown'] as const) { + const test = harness() + test.service.quotaResult = failed('quota', application) + test.arm() + await test.idle() + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.failureCount).toBe(1) + expect(test.clock.timers.size).toBe(0) + await test.driver.dispose() + } + }) + + it('counts one unexpected terminal Service rejection without retrying it', async () => { + const test = harness() + test.service.quotaError = new Error('terminal Service rejection') + test.arm() + await test.idle() + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.failureCount).toBe(1) + expect(test.clock.timers.size).toBe(0) + await test.driver.dispose() + }) + + it('classifies an unclaimed resolved command as foreign and latches disarm', async () => { + const test = harness() + test.arm() + await test.idle() + const automatic = test.current.followups[0] as UserMessage + test.driver.onSessionEvent(test.current.agent, commandEvent('command/run', 'foreign-a')) + await Promise.resolve() + expect(test.current.removed).toEqual([automatic.id]) + expect(test.service.coordinator.snapshot(ref(test.current.agent))).toMatchObject({ + activation: 'disarmed', foreignLatched: true, + }) + test.driver.onSessionEvent(test.current.agent, commandEvent('command/done', 'foreign-a')) + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.foreignLatched).toBe(true) + await test.driver.dispose() + }) + + it('keeps an owned barrier through early command/done until raw settlement', async () => { + const test = harness() + test.arm() + test.driver.onSessionEvent(test.current.agent, commandEvent('command/run', 'owned-a')) + expect(test.service.coordinator.claimCommand( + 'owned-a', test.current.agent.session, test.current.agent, + )).toBe(true) + await Promise.resolve() + test.driver.onSessionEvent(test.current.agent, commandEvent('command/done', 'owned-a')) + expect(test.service.coordinator.hasBarrier(test.current.agent.session)).toBe(true) + expect(test.service.coordinator.snapshot(ref(test.current.agent))?.activation).toBe('armed') + test.service.coordinator.settleOwned('owned-a', test.current.agent.session) + expect(test.service.coordinator.hasBarrier(test.current.agent.session)).toBe(false) + await test.driver.dispose() + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/goal-round-continuation-driver.spec.ts b/packages/dsh-loopx-plugin/tests/goal-round-continuation-driver.spec.ts new file mode 100644 index 000000000..2756bde61 --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/goal-round-continuation-driver.spec.ts @@ -0,0 +1,328 @@ +import { describe, expect, it } from 'vitest' +import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' +import type { UserMessage } from '@deepseek-ai/dsh-session' +import { CoordinatorRegistry, installCoordinator } from '../src/coordinator.ts' +import { LoopXContinuationDriver } from '../src/driver.ts' +import type { + LoopXBoundHostThreadBindingV1, + LoopXQuotaDecision, + LoopXResult, + LoopXSessionRef, + LoopXTaskBody, +} from '../src/types.ts' + +const DRIVER_SOURCE = 'dsh-loopx-plugin/driver' + +function ok(value: T): LoopXResult { + return { ok: true, value, application: 'no' } +} + +function binding(revision = 1): LoopXBoundHostThreadBindingV1 { + return { + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId: 'session-a', + revision, + state: 'bound', + target: { goalId: 'goal-a', agentId: 'agent-a' }, + } +} + +function sessionRef(agent: Agent): LoopXSessionRef { + return { + id: String(agent.id), + session: agent.session, + identity: { + createdAt: agent.session.header.createdAt, + ...(agent.session.header.cwd === undefined ? {} : { cwd: agent.session.header.cwd }), + }, + } +} + +function human(id: string): UserMessage { + return { + id: id as UserMessage['id'], + role: 'user', + content: [{ type: 'text', text: id }], + source: { kind: 'user' }, + } +} + +function pluginMessage(id: string, plugin: string): UserMessage { + return { + id: id as UserMessage['id'], + role: 'user', + content: [{ type: 'text', text: id }], + source: { kind: 'plugin', plugin }, + } +} + +function quota( + current: LoopXBoundHostThreadBindingV1, + turnInstanceId: string, +): LoopXQuotaDecision { + return { + binding: current, + goalId: current.target.goalId, + agentId: current.target.agentId, + turnInstanceId, + shouldRun: true, + effectiveAction: 'run_now', + schedulerHint: { + action: 'run_now', cadenceClass: 'immediate', resetToken: 'round-reset', + recommendedIntervalMinutes: 1, unchangedPollLimit: 1, + }, + terminalNoFollowup: false, + payload: { + schemaVersion: 'loopx_quota_projection_v1', + goalId: current.target.goalId, + shouldRun: true, + effectiveAction: 'run_now', + }, + } +} + +class RoundService { + readonly coordinator = new CoordinatorRegistry() + readonly home = { key: 'home-a', cwd: '/workspace', runtimeRoot: '/runtime' } + current = binding() + resolveCalls = 0 + quotaCalls = 0 + taskCalls = 0 + + constructor() { installCoordinator(this, this.coordinator) } + + resolveBinding(session: LoopXSessionRef) { + this.resolveCalls += 1 + this.coordinator.observeBinding(session, this.home, this.current) + return Promise.resolve(ok(this.current)) + } + + quotaShouldRun(_session: LoopXSessionRef, turnInstanceId: string) { + this.quotaCalls += 1 + return Promise.resolve(ok(quota(this.current, turnInstanceId))) + } + + taskBody(): Promise> { + this.taskCalls += 1 + return Promise.resolve(ok({ binding: this.current, body: `active round ${this.taskCalls}` })) + } + + disposeSession() { return Promise.resolve() } +} + +interface RoundHarness { + agent: Agent + readonly service: RoundService + readonly driver: LoopXContinuationDriver + readonly followups: UserMessage[] + readonly nextTurn: UserMessage[] + readonly nextStep: UserMessage[] + readonly removed: UserMessage['id'][] + readonly restored: Array<{ readonly message: UserMessage; readonly wakeup: boolean }> + setStatus(status: 'idle' | 'running'): void + arm(): void + idle(): Promise + claim(message: UserMessage): void + discard(message: UserMessage): void +} + +function roundHarness(): RoundHarness { + const service = new RoundService() + let status: 'idle' | 'running' = 'running' + let driver: LoopXContinuationDriver | undefined + const followups: UserMessage[] = [] + const nextTurn: UserMessage[] = [] + const nextStep: UserMessage[] = [] + const removed: UserMessage['id'][] = [] + const restored: Array<{ readonly message: UserMessage; readonly wakeup: boolean }> = [] + const harness = {} as RoundHarness + const session = { + id: 'session-a', + header: { version: 0, id: 'session-a', createdAt: 42, cwd: '/workspace' }, + } + const agent = { + id: 'session-a', + session, + get status() { return status }, + inbox: { + get nextTurn() { return nextTurn }, + get nextStep() { return nextStep }, + get hasPending() { return nextTurn.length > 0 || nextStep.length > 0 }, + remove(messageId: UserMessage['id']) { + for (const queue of [nextStep, nextTurn]) { + const index = queue.findIndex(message => message.id === messageId) + if (index < 0) continue + const [message] = queue.splice(index, 1) + removed.push(messageId) + if (message !== undefined) driver?.onInboxDiscarded(agent as unknown as Agent, message) + return true + } + return false + }, + }, + runMaintenance(task: (signal: AbortSignal) => Promise) { + return task(new AbortController().signal) + }, + whenIdle() { return Promise.resolve() }, + followup(message: UserMessage) { + followups.push(message) + nextTurn.push(message) + driver?.onInboxInserted(agent as unknown as Agent, message) + }, + send(message: UserMessage, target: 'next-turn' | 'next-step', wakeup: boolean) { + ;(target === 'next-turn' ? nextTurn : nextStep).push(message) + restored.push({ message, wakeup }) + }, + steer() {}, + cancel() {}, + } as unknown as Agent + driver = new LoopXContinuationDriver({ + service: service as unknown as import('../src/types.ts').LoopXServiceApi, + isLiveAgent: candidate => candidate === agent, + makeTurnInstanceId: () => `turn-${service.quotaCalls + 1}`, + }) + driver.observeAgent(agent) + Object.assign(harness, { + agent, service, driver, followups, nextTurn, nextStep, removed, restored, + setStatus(value: 'idle' | 'running') { status = value }, + arm() { + const ref = sessionRef(agent) + service.coordinator.observeBinding(ref, service.home, service.current) + service.coordinator.arm(ref, service.home, service.current) + }, + async idle() { + status = 'idle' + driver?.onAgentStatus(agent, 'idle') + await driver?.whenSettled() + }, + claim(message: UserMessage) { + const index = nextTurn.findIndex(candidate => candidate.id === message.id) + if (index >= 0) nextTurn.splice(index, 1) + status = 'running' + driver?.onInboxClaimed(agent, message) + }, + discard(message: UserMessage) { + for (const queue of [nextStep, nextTurn]) { + const index = queue.findIndex(candidate => candidate.id === message.id) + if (index >= 0) queue.splice(index, 1) + } + driver?.onInboxDiscarded(agent, message) + }, + }) + return harness +} + +function preStep( + test: RoundHarness, + messages: UserMessage[], + next: () => Promise, +): Promise { + return test.driver.onPreStep(test.agent, messages, new AbortController().signal, next) +} + +describe('Goal-round continuation lifecycle', () => { + it('keeps cached planning disarmed and uses only the fresh active lane after explicit arm', async () => { + const test = roundHarness() + const ref = sessionRef(test.agent) + test.service.coordinator.observeBinding(ref, test.service.home, test.service.current) + test.service.coordinator.cachePlanningBody(ref, 'planning checkpoint must not auto-run') + await test.idle() + expect(test.service.resolveCalls).toBe(0) + expect(test.followups).toEqual([]) + + test.setStatus('running') + test.arm() + await test.idle() + expect(test.service.quotaCalls).toBe(1) + expect(test.service.taskCalls).toBe(1) + expect(test.followups[0]?.content).toEqual([{ type: 'text', text: 'active round 1' }]) + expect(JSON.stringify(test.followups)).not.toContain('planning checkpoint') + await test.driver.dispose() + }) + + it('passes non-driver plugin input but rejects orphan driver work and wakes human input', async () => { + const test = roundHarness() + const command = pluginMessage('command-result', 'dsh-loopx-plugin/command') + expect(await preStep(test, [command], () => Promise.resolve({ + kind: 'enter', messages: [command], + }))).toEqual({ kind: 'enter', messages: [command] }) + + const orphan = pluginMessage('orphan-driver', DRIVER_SOURCE) + const person = human('retained-human') + let reachedDownstream = false + expect(await preStep(test, [person, orphan], () => { + reachedDownstream = true + return Promise.resolve({ kind: 'enter', messages: [person, orphan] }) + })).toEqual({ kind: 'reject' }) + expect(reachedDownstream).toBe(false) + expect(test.restored).toEqual([{ message: person, wakeup: true }]) + expect(test.nextStep).toEqual([person]) + await test.driver.dispose() + }) + + it('treats exact claim as irrevocable across downstream input and authority races', async () => { + const test = roundHarness() + test.arm() + await test.idle() + const automatic = test.followups[0] as UserMessage + test.claim(automatic) + const person = human('human-after-claim') + test.nextTurn.push(person) + test.driver.onInboxInserted(test.agent, person) + const decision = await preStep(test, [automatic, person], async () => { + const ref = sessionRef(test.agent) + test.service.coordinator.advanceEpoch(ref) + test.service.coordinator.pause(ref) + return { kind: 'enter', messages: [automatic, person] } + }) + expect(decision).toEqual({ kind: 'enter', messages: [automatic, person] }) + expect(test.removed).toEqual([]) + expect(test.restored).toEqual([]) + await test.driver.dispose() + }) + + it('restores human input when downstream rejects and retires the exact reservation', async () => { + const test = roundHarness() + test.arm() + await test.idle() + const automatic = test.followups[0] as UserMessage + test.claim(automatic) + const person = human('human-in-rejected-batch') + expect(await preStep(test, [automatic, person], () => Promise.resolve({ + kind: 'reject', reason: 'downstream gate', + }))).toMatchObject({ kind: 'reject' }) + expect(test.restored).toEqual([{ message: person, wakeup: true }]) + + let reachedDownstream = false + expect(await preStep(test, [automatic], () => { + reachedDownstream = true + return Promise.resolve({ kind: 'enter', messages: [automatic] }) + })).toEqual({ kind: 'reject' }) + expect(reachedDownstream).toBe(false) + await test.driver.dispose() + }) + + it('settles automatic work before fresh quota and gives queued human work priority', async () => { + const test = roundHarness() + test.arm() + await test.idle() + const automatic = test.followups[0] as UserMessage + test.claim(automatic) + expect((await preStep(test, [automatic], () => Promise.resolve({ + kind: 'enter', messages: [automatic], + }))).kind).toBe('enter') + + const person = human('human-next-round') + test.nextTurn.push(person) + test.driver.onInboxInserted(test.agent, person) + await test.idle() + expect(test.service.quotaCalls).toBe(1) + + test.discard(person) + await test.driver.whenSettled() + expect(test.service.quotaCalls).toBe(2) + expect(test.followups[1]?.content).toEqual([{ type: 'text', text: 'active round 2' }]) + await test.driver.dispose() + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/package-boundary.spec.ts b/packages/dsh-loopx-plugin/tests/package-boundary.spec.ts new file mode 100644 index 000000000..2bf414ac5 --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/package-boundary.spec.ts @@ -0,0 +1,63 @@ +import { readFile, readdir } from 'node:fs/promises' +import { dirname, join, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' + +const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..') + +async function text(path: string): Promise { + return readFile(join(packageRoot, path), 'utf8') +} + +describe('sidecar-free package boundary', () => { + it('ships the deliberate 0.2.0 contract without a direct storage dependency', async () => { + const manifest = JSON.parse(await text('package.json')) as { + version: string + dependencies?: Record + peerDependencies?: Record + optionalDependencies?: Record + devDependencies?: Record + } + + expect(manifest.version).toBe('0.2.0') + for (const dependencies of [ + manifest.dependencies, + manifest.peerDependencies, + manifest.optionalDependencies, + manifest.devDependencies, + ]) { + expect(Object.keys(dependencies ?? {}).filter(name => ( + name.startsWith('@deepseek-ai/dsh-storage') + ))).toEqual([]) + } + }) + + it('contains no plugin-owned sidecar schema, injection, or compatibility file', async () => { + const sourceNames = (await readdir(join(packageRoot, 'src'))).sort() + expect(sourceNames).not.toContain('binding.ts') + + const source = ( + await Promise.all(sourceNames.map(name => text(join('src', name)))) + ).join('\n') + expect(source).not.toContain('@deepseek-ai/dsh-storage-domain') + expect(source).not.toContain('dsh_loopx_plugin') + expect(source).not.toContain('storageDomain') + expect(source).not.toContain('loopxBindingDomainSpec') + + const installMetadata = `${await text('cordis.patch.yml')}\n${await text('install.sh')}` + expect(installMetadata).not.toContain('storage-domain') + }) + + it('keeps the coordinator private and the existing four Cordis faces', async () => { + const rootExports = await text('src/index.ts') + expect(rootExports).not.toMatch(/coordinator/iu) + + const patch = await text('cordis.patch.yml') + expect([...patch.matchAll(/^\s*- id: (loopx-[^\s]+)$/gmu)].map(match => match[1])).toEqual([ + 'loopx-service', + 'loopx-command', + 'loopx-tools', + 'loopx-driver', + ]) + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/semantic-tools.spec.ts b/packages/dsh-loopx-plugin/tests/semantic-tools.spec.ts new file mode 100644 index 000000000..4a063a819 --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/semantic-tools.spec.ts @@ -0,0 +1,277 @@ +import { describe, expect, it } from 'vitest' +import type { Context } from '@deepseek-ai/cordis' +import type { Agent } from '@deepseek-ai/dsh-agent' +import { validateJsonSchemaValue } from '@deepseek-ai/dsh-tools' +import type { ToolDefinition, ToolRunContext } from '@deepseek-ai/dsh-tools' +import { CoordinatorRegistry, installCoordinator } from '../src/coordinator.ts' +import { apply as applyTools } from '../src/tools.ts' +import type { + LoopXAttachRequest, + LoopXAttachValue, + LoopXBoundHostThreadBindingV1, + LoopXFailure, + LoopXResult, + LoopXSessionRef, + LoopXStartOptions, + LoopXStartValue, + LoopXStatusValue, +} from '../src/types.ts' + +const signal = new AbortController().signal + +function ok(value: T, application: 'yes' | 'no' = 'no'): LoopXResult { + return { ok: true, value, application } +} + +function rejected(operation: string): LoopXResult { + const error: LoopXFailure = { + code: 'LOOPX_AUTHORITY_UNHEALTHY', + message: `safe ${operation} failure`, + operation, + retryable: false, + outcomeUncertain: false, + } + return { ok: false, error, application: 'no' } +} + +function binding(): LoopXBoundHostThreadBindingV1 { + return { + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId: 'session-a', + revision: 1, + state: 'bound', + target: { goalId: 'goal-a', agentId: 'agent-a' }, + } +} + +function planning(): LoopXStartValue { + return { + kind: 'planning', + binding: binding(), + planning: { + schemaVersion: 'dsh_loopx_planning_checkpoint_v1', + goalId: 'goal-a', + agentId: 'agent-a', + goalText: 'bounded objective', + planner: { + defaultProfile: 'clear_bounded_problem', profileSelection: 'select', + openEndedProductDirection: { suggestedItemsMin: 2, suggestedItemsMax: 5, intent: 'rank' }, + clearBoundedProblem: { + itemCountPolicy: 'planner_sized', + mayReuseCurrentTodoWhenItAlreadyRepresentsThePlan: true, + intent: 'plan', + }, + allowedPriorities: ['P0', 'P1', 'P2'], defaultRole: 'agent', + defaultTaskClass: 'advancement_task', requiredFields: ['text'], + publicSafeOnly: true, budgetPolicy: 'minimum', + }, + writeback: { + todoTool: 'loopx_todo_add', minimumTodos: 1, maximumTodos: 5, + ordering: 'priority_then_tool_call_order', activationTool: 'loopx_goal_activate', + activationArguments: { goalId: 'goal-a', agentId: 'agent-a' }, + }, + stopConditions: ['user gate'], + forbidden: ['shell_or_bash', 'raw_loopx_cli', 'registry_edit', 'ctx.goals'], + }, + modelCheckpoint: 'plan', + } +} + +function agent(id = 'session-a'): Agent { + return { + id, + session: { id, header: { version: 0, id, createdAt: 77, cwd: '/SENSITIVE/CWD' } }, + } as unknown as Agent +} + +class EntryService { + readonly coordinator = new CoordinatorRegistry() + readonly starts: Array<{ + readonly session: LoopXSessionRef + readonly objective: string + readonly options?: LoopXStartOptions + }> = [] + readonly attaches: Array<{ readonly session: LoopXSessionRef; readonly request: LoopXAttachRequest }> = [] + startResult: LoopXResult = ok(planning(), 'yes') + attachResult: LoopXResult = ok({ kind: 'attached', binding: binding() }, 'yes') + statusResult: LoopXResult = ok({ + host: { + binarySource: 'path', binding: binding(), activation: 'disarmed', + automaticFollowupSuppressed: false, + }, + }) + + constructor() { installCoordinator(this, this.coordinator) } + + start( + session: LoopXSessionRef, + objective: string, + _signal?: AbortSignal, + options?: LoopXStartOptions, + ) { + this.starts.push({ session, objective, ...(options === undefined ? {} : { options }) }) + return Promise.resolve(this.startResult) + } + + attach(session: LoopXSessionRef, request: LoopXAttachRequest) { + this.attaches.push({ session, request }) + if (this.attachResult.ok && this.attachResult.value.kind === 'attached') { + const home = { key: 'home-a', cwd: '/SENSITIVE/CWD', runtimeRoot: '/SENSITIVE/RUNTIME' } + this.coordinator.observeBinding(session, home, this.attachResult.value.binding) + this.coordinator.arm(session, home, this.attachResult.value.binding) + } + return Promise.resolve(this.attachResult) + } + + status() { return Promise.resolve(this.statusResult) } +} + +function tools(service: EntryService): ReadonlyMap { + const found = new Map() + applyTools({ + loopx: service, + tools: { register(definition: ToolDefinition) { found.set(definition.name, definition) } }, + } as unknown as Context) + return found +} + +async function call( + service: EntryService, + name: string, + args: unknown, + current = agent(), +): Promise> { + const definition = tools(service).get(name) + if (definition === undefined) throw new Error(`missing ${name}`) + const value = await definition.execute(args, { + name, + arguments: args, + agent: current, + signal, + callId: `call-${name}`, + rootCallId: `call-${name}`, + token: Symbol(name), + deferContext() {}, + concludeTurn() {}, + } as unknown as ToolRunContext) + expect(validateJsonSchemaValue(definition.output.schema, value, '')).toEqual([]) + return value as Record +} + +describe('semantic entry tools', () => { + it('publishes a closed fresh-start surface without obsolete identity selectors', () => { + const definitions = tools(new EntryService()) + const start = definitions.get('loopx_goal_start') + expect(start?.parameters).toMatchObject({ + type: 'object', required: ['goalText'], additionalProperties: false, + }) + expect(Object.keys(start?.parameters.properties ?? {})).toEqual([ + 'goalText', 'switchConfirmation', + ]) + expect(definitions.get('loopx_status')?.parameters).toMatchObject({ + type: 'object', additionalProperties: false, + }) + }) + + it('passes the exact live Session object and leaves fresh start disarmed', async () => { + const service = new EntryService() + const current = agent() + const result = await call(service, 'loopx_goal_start', { + goalText: 'implement the bounded change', + switchConfirmation: 'confirmed-revision-token', + }, current) + expect(result).toMatchObject({ + kind: 'operation_result', execution: 'succeeded', application: 'yes', + value: { kind: 'planning', binding: { hostSurface: 'dsh', revision: 1 } }, + }) + expect(service.starts[0]).toMatchObject({ + objective: 'implement the bounded change', + options: { switchConfirmation: 'confirmed-revision-token' }, + }) + expect(service.starts[0]?.session.session).toBe(current.session) + expect(service.coordinator.snapshot(current.session)?.activation).toBe('disarmed') + expect(JSON.stringify(result)).not.toContain('/SENSITIVE/CWD') + }) + + it('forwards exact attach and fresh-peer intent only', async () => { + const service = new EntryService() + await call(service, 'loopx_goal_attach', { + goalId: 'goal-a', agentId: 'agent-a', switchConfirmation: 'token-a', + }) + await call(service, 'loopx_goal_attach', { goalId: 'goal-a', newPeer: true }) + expect(service.attaches.map(entry => entry.request)).toEqual([ + { goalId: 'goal-a', agentId: 'agent-a', switchConfirmation: 'token-a' }, + { goalId: 'goal-a', newPeer: true }, + ]) + }) + + it('projects selection and confirmed-switch readback as no application', async () => { + const service = new EntryService() + service.attachResult = ok({ + kind: 'selection_required', + goalId: 'goal-a', + selection: { + kind: 'agent', defaultAction: 'select_agent', + choices: [{ agentId: 'agent-a' }], + }, + }, 'no') + expect(await call(service, 'loopx_goal_attach', { goalId: 'goal-a' })).toMatchObject({ + application: 'no', value: { kind: 'selection_required' }, + }) + + service.attachResult = ok({ + kind: 'switch_required', confirmationToken: 'opaque', requiresUserConfirmation: true, + expiresAt: 9000, expectedRevision: 7, + current: { goalId: 'goal-old', agentId: 'agent-old' }, + requested: { operation: 'attach', goalId: 'goal-new', agentId: 'agent-new' }, + }, 'no') + expect(await call(service, 'loopx_goal_attach', { + goalId: 'goal-new', agentId: 'agent-new', + })).toMatchObject({ + application: 'no', + value: { kind: 'switch_required', expectedRevision: 7 }, + }) + }) + + it('rejects alternate Session/locator/shell arguments before Service entry', async () => { + const service = new EntryService() + for (const args of [ + { goalText: 'safe', goalId: 'old-goal' }, + { goalText: 'safe', sessionId: 'other' }, + { goalText: 'safe', runtimeRoot: '/SENSITIVE/RUNTIME' }, + { goalText: 'safe', shell: 'loopx start-goal' }, + ]) { + expect(await call(service, 'loopx_goal_start', args)).toMatchObject({ + execution: 'rejected', application: 'no', + error: { code: 'LOOPX_INVALID_REQUEST' }, + }) + } + expect(service.starts).toEqual([]) + }) + + it('rejects mismatched Agent/Session identity before Service entry', async () => { + const service = new EntryService() + const mismatched = agent('session-a') + Object.defineProperty(mismatched, 'id', { value: 'session-b' }) + expect(await call(service, 'loopx_goal_start', { goalText: 'safe' }, mismatched)).toMatchObject({ + error: { code: 'LOOPX_SESSION_LIFECYCLE_MISMATCH' }, application: 'no', + }) + expect(service.starts).toEqual([]) + }) + + it('lets successful explicit attach arm and clear eighth-failure suppression', async () => { + const service = new EntryService() + const current = agent() + service.startResult = rejected('goal-start') + for (let count = 1; count <= 8; count += 1) { + await call(service, 'loopx_goal_start', { goalText: 'safe' }, current) + expect(service.coordinator.snapshot(current.session)?.failureCount).toBe(count) + } + expect(service.coordinator.snapshot(current.session)?.automaticFollowupSuppressed).toBe(true) + await call(service, 'loopx_goal_attach', { goalId: 'goal-a', agentId: 'agent-a' }, current) + expect(service.coordinator.snapshot(current.session)).toMatchObject({ + activation: 'armed', failureCount: 0, automaticFollowupSuppressed: false, + }) + }) +}) diff --git a/packages/dsh-loopx-plugin/tests/service.spec.ts b/packages/dsh-loopx-plugin/tests/service.spec.ts new file mode 100644 index 000000000..b419b72a4 --- /dev/null +++ b/packages/dsh-loopx-plugin/tests/service.spec.ts @@ -0,0 +1,616 @@ +import { Context } from '@deepseek-ai/cordis' +import { afterEach, describe, expect, it, vi } from 'vitest' +import type { + LoopXCliBindingRequest, + LoopXCliRequest, +} from '../src/cli-client.ts' +import { coordinatorFor } from '../src/coordinator.ts' +import LoopXService, { type Config } from '../src/service.ts' +import type { + LoopXBoundHostThreadBindingV1, + LoopXHostThreadBindingV1, + LoopXSessionRef, +} from '../src/types.ts' + +interface Call { + readonly operation: string + readonly args: readonly string[] + readonly cwd: string +} + +interface AuthorityOptions { + unhealthy?: boolean + commandPackValid?: boolean + refreshAppended?: boolean +} + +function arg(args: readonly string[], flag: string): string | undefined { + const index = args.indexOf(flag) + return index < 0 ? undefined : args[index + 1] +} + +function wireBinding(binding: LoopXHostThreadBindingV1) { + const base = { + schema_version: binding.schemaVersion, + host_surface: binding.hostSurface, + thread_id: binding.threadId, + revision: binding.revision, + state: binding.state, + } + return binding.state === 'bound' + ? { ...base, target: { goal_id: binding.target.goalId, agent_id: binding.target.agentId } } + : base +} + +function bound(threadId = 'session-a', revision = 1): LoopXBoundHostThreadBindingV1 { + return Object.freeze({ + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId, + revision, + state: 'bound', + target: Object.freeze({ goalId: 'goal-a', agentId: 'agent-a' }), + }) +} + +function unbound(revision = 2): LoopXHostThreadBindingV1 { + return Object.freeze({ + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId: 'session-a', + revision, + state: 'unbound', + }) +} + +class FakeAuthorityCli { + readonly binarySource = 'config' as const + readonly calls: Call[] = [] + binding: LoopXHostThreadBindingV1 | undefined + unhealthy = false + commandPackValid = true + refreshAppended = true + bindConflict = false + bindConflictBinding: LoopXHostThreadBindingV1 | undefined + statusItems: readonly unknown[] = [] + + constructor(binding?: LoopXHostThreadBindingV1, options: AuthorityOptions = {}) { + this.binding = binding + this.unhealthy = options.unhealthy ?? false + this.commandPackValid = options.commandPackValid ?? true + this.refreshAppended = options.refreshAppended ?? true + } + + runBindingJson(request: LoopXCliBindingRequest): Promise { + this.calls.push({ operation: request.operation, args: request.args, cwd: request.home.cwd }) + const command = request.args[0] + if (command === 'resolve-agent-thread') { + if (this.unhealthy) { + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: false, + changed: false, + application: 'no', + error_kind: 'authority_unhealthy', + ...(this.binding === undefined ? {} : { binding: wireBinding(this.binding) }), + }) + } + if (this.binding === undefined) { + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: false, + changed: false, + application: 'no', + error_kind: 'binding_not_found', + }) + } + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: true, + changed: false, + application: 'no', + binding: wireBinding(this.binding), + }) + } + + const expected = Number(arg(request.args, '--expected-revision')) + const currentRevision = this.binding?.revision ?? 0 + if (expected !== currentRevision) { + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: false, + changed: false, + application: 'no', + error_kind: 'revision_conflict', + ...(this.binding === undefined ? {} : { binding: wireBinding(this.binding) }), + }) + } + const threadId = arg(request.args, '--thread-id') ?? 'session-a' + if (command === 'bind-agent-thread') { + if (this.bindConflict) { + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: false, + changed: false, + application: 'no', + error_kind: 'revision_conflict', + ...(this.bindConflictBinding === undefined + ? {} + : { binding: wireBinding(this.bindConflictBinding) }), + }) + } + const target = { + goalId: arg(request.args, '--goal-id') ?? '', + agentId: arg(request.args, '--agent-id') ?? '', + } + const unchanged = this.binding?.state === 'bound' + && this.binding.target.goalId === target.goalId + && this.binding.target.agentId === target.agentId + if (!unchanged) { + this.binding = Object.freeze({ + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId, + revision: currentRevision + 1, + state: 'bound', + target: Object.freeze(target), + }) + } + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: true, + changed: !unchanged, + application: unchanged ? 'no' : 'yes', + binding: wireBinding(this.binding as LoopXHostThreadBindingV1), + }) + } + + const unchanged = this.binding?.state === 'unbound' + if (!unchanged) { + this.binding = Object.freeze({ + schemaVersion: 'loopx_host_thread_binding_v1', + hostSurface: 'dsh', + threadId, + revision: currentRevision + 1, + state: 'unbound', + }) + } + return this.value({ + schema_version: 'loopx_host_thread_binding_command_v1', + ok: true, + changed: !unchanged, + application: unchanged ? 'no' : 'yes', + binding: wireBinding(this.binding as LoopXHostThreadBindingV1), + }) + } + + runJson(request: LoopXCliRequest): Promise { + this.calls.push({ operation: request.operation, args: request.args, cwd: request.cwd }) + const goalId = arg(request.args, '--goal-id') ?? 'goal-a' + const agentId = arg(request.args, '--agent-id') ?? 'agent-a' + if (request.operation === 'bootstrap-connect') { + return this.value({ + ok: true, + goal_id: goalId, + registry_goal_action: 'appended', + state_action: 'created', + global_sync: { ok: true, synced_goal_ids: [goalId], wrote: true }, + }) + } + if (request.operation === 'register-agent') { + return this.value({ + ok: true, + goal_id: goalId, + changed: true, + written: true, + partial_write: false, + requested_agents: [agentId], + registered_agents: [agentId], + registration_readback: { + performed: true, + verified: true, + requested_agents: [agentId], + source_registered_agents: [agentId], + global_registered_agents: [agentId], + }, + global_sync: { ok: true }, + }) + } + if (request.operation === 'start-goal') return this.value(this.startPacket(goalId, agentId)) + if (request.operation === 'activate-refresh') { + return this.value({ + ok: true, + goal_id: goalId, + agent_id: agentId, + appended: this.refreshAppended, + idempotent_replay: !this.refreshAppended, + partial_write: false, + external_sink_delivery_authorized: false, + global_sync: { ok: true, wrote: this.refreshAppended }, + }) + } + if (request.operation === 'bootstrap-command-pack') { + return this.value(this.commandPack(goalId, agentId)) + } + if (request.operation === 'heartbeat-prompt') { + return this.value({ + ok: true, + goal_id: goalId, + agent_id: agentId, + task_body: 'internal task body', + }) + } + if (request.operation === 'resume-status' || request.operation === 'status') { + return this.value({ + ok: true, + goal_filter: goalId, + attention_queue: { items: this.statusItems }, + }) + } + throw new Error(`unexpected fake operation: ${request.operation}`) + } + + abortScope(): void {} + close(): Promise { return Promise.resolve() } + + private startPacket(goalId: string, agentId: string) { + return { + ok: true, + goal_id: goalId, + agent_id: agentId, + host_thread_binding: wireBinding(this.binding as LoopXHostThreadBindingV1), + command_pack: { + goal_start_contract: { + goal_text: arg(this.calls.at(-1)?.args ?? [], '--goal-text'), + planner: { + default_profile: 'clear_bounded_problem', + profile_selection: '/private/sentinel-profile', + profiles: { + open_ended_product_direction: { + suggested_items_min: 2, + suggested_items_max: 4, + intent: '/private/sentinel-open-intent', + }, + clear_bounded_problem: { + item_count_policy: '/private/sentinel-policy', + may_reuse_current_todo_when_it_already_represents_the_plan: true, + intent: '/private/sentinel-bounded-intent', + }, + }, + required_fields: ['priority', 'text', 'task_class', 'action_kind'], + maximum_runnable_todos_written_ahead: 3, + budget_policy: '/private/sentinel-budget', + }, + stop_conditions: ['/private/sentinel-stop'], + }, + }, + guided_transaction: { + ordered_steps: [{ kind: 'model_checkpoint', prompt: '/private/sentinel-prompt' }], + }, + } + } + + private commandPack(goalId: string, agentId: string) { + const binding = wireBinding(this.binding as LoopXHostThreadBindingV1) + return { + ok: true, + goal_id: goalId, + agent_id: agentId, + thread_id: binding.thread_id, + host_thread_binding: binding, + host_loop_activation: { + activation_allowed: this.commandPackValid, + goal_id: goalId, + agent_id: agentId, + identity_contract: { registered_agents: [agentId] }, + identity_selection_gate: this.commandPackValid ? null : { + default_action: 'select_agent_identity', + reason: '/private/sentinel-selection-reason', + choices: [{ agent_id: agentId, label: '/private/sentinel-choice-label' }], + fresh_agent_registration: null, + }, + activation_input: { + arguments: { goalId, agentId }, + }, + host_mutation: { + forbidden_tool_arguments: ['sessionId', 'registryPath', 'taskBody', 'argv'], + }, + }, + } + } + + private value(value: unknown): Promise { + return Promise.resolve(value as T) + } +} + +const cleanups: Array<() => Promise> = [] + +afterEach(async () => { + while (cleanups.length > 0) await cleanups.pop()?.() +}) + +function session( + object: object = {}, + cwd: string | null = '/project', +): LoopXSessionRef { + return Object.freeze({ + id: 'session-a', + session: object, + identity: Object.freeze({ + createdAt: 1, + ...(cwd === null ? {} : { cwd }), + }), + }) +} + +async function serviceWith( + cli: FakeAuthorityCli, + config: Config = { loopxBin: 'loopx', runtimeRoot: '/runtime' }, +): Promise { + const ctx = new Context() + await ctx.plugin(LoopXService, config) + const service = ctx.loopx + Reflect.set(service, 'cli', cli) + cleanups.push(async () => { await ctx.fiber.dispose() }) + return service +} + +describe('LoopXService v1 authority and lifecycle', () => { + it('starts a fresh Goal-Agent binding, remains disarmed, and omits CLI prose and paths', async () => { + const cli = new FakeAuthorityCli() + const service = await serviceWith(cli) + const current = session() + + const result = await service.start(current, 'Build the bounded feature') + + expect(result).toMatchObject({ + ok: true, + application: 'yes', + value: { + kind: 'planning', + planning: { schemaVersion: 'dsh_loopx_planning_checkpoint_v1' }, + }, + subEffects: [ + { operation: 'bootstrap-goal', application: 'yes' }, + { operation: 'register-agent', application: 'yes' }, + { operation: 'bind-agent-thread', application: 'yes' }, + ], + }) + expect(JSON.stringify(result)).not.toContain('/private/sentinel') + expect(coordinatorFor(service).snapshot(current)).toMatchObject({ + activation: 'disarmed', + observedBinding: { state: 'bound', revision: 1 }, + }) + }) + + it('uses a fresh disarmed coordinator after plugin reload', async () => { + const shared = bound() + const first = await serviceWith(new FakeAuthorityCli(shared)) + const current = session() + await expect(first.attach(current, { goalId: 'goal-a', agentId: 'agent-a' })) + .resolves.toMatchObject({ ok: true }) + expect(coordinatorFor(first).snapshot(current)?.activation).toBe('armed') + + const second = await serviceWith(new FakeAuthorityCli(shared)) + const secondSession = session({}) + await expect(second.resolveBinding(secondSession)).resolves.toMatchObject({ ok: true }) + expect(coordinatorFor(second).snapshot(secondSession)?.activation).toBe('disarmed') + }) + + it('reports committed bootstrap and registration sub-effects when binding CAS loses', async () => { + const cli = new FakeAuthorityCli() + cli.bindConflict = true + const service = await serviceWith(cli) + const current = session() + const result = await service.start(current, 'Build the bounded feature') + expect(result).toMatchObject({ + ok: false, + application: 'yes', + error: { code: 'LOOPX_REVISION_CONFLICT' }, + subEffects: [ + { operation: 'bootstrap-goal', application: 'yes' }, + { operation: 'register-agent', application: 'yes' }, + ], + }) + expect(coordinatorFor(service).snapshot(current)?.activation).toBe('disarmed') + }) + + it('rejects and never caches a wrong-thread binding attached to a mutation failure', async () => { + const cli = new FakeAuthorityCli() + cli.bindConflict = true + cli.bindConflictBinding = bound('other-session', 1) + const service = await serviceWith(cli) + const current = session() + const result = await service.start(current, 'Build the bounded feature') + expect(result).toMatchObject({ + ok: false, + application: 'yes', + error: { code: 'LOOPX_READBACK_FAILED' }, + }) + expect(coordinatorFor(service).snapshot(current)?.observedBinding).toBeUndefined() + const paused = await service.pause(current) + expect(paused).toMatchObject({ ok: true, value: { paused: true } }) + expect(paused.ok && 'binding' in paused.value).toBe(false) + }) + + it('propagates binding no-op application through attach', async () => { + const cli = new FakeAuthorityCli(bound()) + const service = await serviceWith(cli) + const result = await service.attach(session(), { goalId: 'goal-a', agentId: 'agent-a' }) + expect(result).toMatchObject({ ok: true, application: 'no', value: { kind: 'attached' } }) + expect(result.subEffects).toEqual([]) + }) + + it('resumes only after fresh binding, status, membership, task, and final binding readback', async () => { + const cli = new FakeAuthorityCli(bound()) + const service = await serviceWith(cli) + const current = session() + await expect(service.resume(current)).resolves.toMatchObject({ + ok: true, + application: 'no', + value: { state: 'bound', revision: 1 }, + }) + expect(cli.calls.map(call => call.operation)).toEqual([ + 'resolve-agent-thread', + 'resume-status', + 'bootstrap-command-pack', + 'heartbeat-prompt', + 'resolve-agent-thread', + ]) + expect(coordinatorFor(service).snapshot(current)?.activation).toBe('armed') + }) + + it('serializes simultaneous writes through the exact Session coordinator', async () => { + const cli = new FakeAuthorityCli(bound()) + const service = await serviceWith(cli) + const current = session() + const runJson = cli.runJson.bind(cli) + let releaseFirstWrite: (() => void) | undefined + let firstWriteEntered: (() => void) | undefined + const firstWriteGate = new Promise((resolve) => { releaseFirstWrite = resolve }) + const firstWriteStarted = new Promise((resolve) => { firstWriteEntered = resolve }) + let activeWrites = 0 + let maximumActiveWrites = 0 + let writeEntries = 0 + vi.spyOn(cli, 'runJson').mockImplementation(async (request: LoopXCliRequest) => { + if (request.operation !== 'activate-refresh') return runJson(request) + writeEntries += 1 + activeWrites += 1 + maximumActiveWrites = Math.max(maximumActiveWrites, activeWrites) + if (writeEntries === 1) { + firstWriteEntered?.() + await firstWriteGate + } + const result = await runJson(request) + activeWrites -= 1 + return result + }) + + const first = service.activate(current, 'goal-a', 'agent-a') + const second = service.activate(current, 'goal-a', 'agent-a') + await firstWriteStarted + await Promise.resolve() + await Promise.resolve() + expect(writeEntries).toBe(1) + expect(cli.calls.map(call => call.operation)).toEqual(['resolve-agent-thread']) + + releaseFirstWrite?.() + await expect(Promise.all([first, second])).resolves.toEqual([ + expect.objectContaining({ ok: true }), + expect.objectContaining({ ok: true }), + ]) + expect(writeEntries).toBe(2) + expect(maximumActiveWrites).toBe(1) + expect(cli.calls.map(call => call.operation)).toEqual([ + 'resolve-agent-thread', + 'activate-refresh', + 'resolve-agent-thread', + 'bootstrap-command-pack', + 'heartbeat-prompt', + 'resolve-agent-thread', + 'resolve-agent-thread', + 'activate-refresh', + 'resolve-agent-thread', + 'bootstrap-command-pack', + 'heartbeat-prompt', + 'resolve-agent-thread', + ]) + }) + + it('preserves an applied activation refresh when later readback rejects arming', async () => { + const cli = new FakeAuthorityCli(bound(), { commandPackValid: false }) + const service = await serviceWith(cli) + const current = session() + const result = await service.activate(current, 'goal-a', 'agent-a') + expect(result).toMatchObject({ + ok: false, + application: 'yes', + subEffects: [{ operation: 'activate-refresh', application: 'yes' }], + }) + expect(coordinatorFor(service).snapshot(current)?.activation).toBe('disarmed') + }) + + it('omits selected free-text status and identity fields from model-facing values', async () => { + const cli = new FakeAuthorityCli(bound(), { commandPackValid: false }) + cli.statusItems = [{ + goal_id: 'goal-a', + status: '/private/sentinel-status', + waiting_on: '/private/sentinel-waiting', + severity: 'warning', + lifecycle_phase: 'active', + recommended_action: '/private/sentinel-action', + }] + const service = await serviceWith(cli) + const current = session() + + const status = await service.status(current) + expect(status).toMatchObject({ + ok: true, + value: { authority: { attention: [{ severity: 'warning', lifecyclePhase: 'active' }] } }, + }) + expect(JSON.stringify(status)).not.toContain('/private/sentinel') + + const selection = await service.attach(current, { goalId: 'goal-a' }) + expect(selection).toMatchObject({ + ok: true, + value: { + kind: 'selection_required', + selection: { choices: [{ agentId: 'agent-a' }] }, + }, + }) + expect(JSON.stringify(selection)).not.toContain('/private/sentinel') + }) + + it('reports an unbound tombstone through pure status without a second command', async () => { + const cli = new FakeAuthorityCli(unbound(4)) + const service = await serviceWith(cli) + const result = await service.status(session()) + expect(result).toMatchObject({ + ok: true, + application: 'no', + value: { + host: { + activation: 'disarmed', + binding: { state: 'unbound', revision: 4 }, + }, + }, + }) + expect(cli.calls.map(call => call.operation)).toEqual(['resolve-agent-thread']) + }) + + it('disarms on unhealthy authority and CAS-unbinds the bounded dangling ref', async () => { + const cli = new FakeAuthorityCli(bound()) + const service = await serviceWith(cli) + const current = session() + await service.attach(current, { goalId: 'goal-a', agentId: 'agent-a' }) + expect(coordinatorFor(service).snapshot(current)?.activation).toBe('armed') + + cli.unhealthy = true + await expect(service.resolveBinding(current)).resolves.toMatchObject({ + ok: false, + error: { code: 'LOOPX_AUTHORITY_UNHEALTHY' }, + }) + expect(coordinatorFor(service).snapshot(current)?.activation).toBe('disarmed') + + const detached = await service.detach(current) + expect(detached).toMatchObject({ + ok: true, + application: 'yes', + value: { binding: { state: 'unbound', revision: 2 } }, + }) + expect(cli.calls.at(-1)?.args).toContain('1') + }) + + it('fails closed before invoking the CLI when no exact Session cwd selects authority', async () => { + const cli = new FakeAuthorityCli(bound()) + const service = await serviceWith(cli, { loopxBin: 'loopx' }) + const result = await service.resolveBinding(session({}, null)) + expect(result).toMatchObject({ + ok: false, + application: 'no', + error: { code: 'LOOPX_BINDING_HOME_UNAVAILABLE' }, + }) + expect(cli.calls).toEqual([]) + }) +}) diff --git a/packages/dsh-loopx-plugin/tsconfig.build.json b/packages/dsh-loopx-plugin/tsconfig.build.json new file mode 100644 index 000000000..04895f353 --- /dev/null +++ b/packages/dsh-loopx-plugin/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "declarationMap": false, + "declarationDir": "./lib/types", + "emitDeclarationOnly": false, + "outDir": "./build-temp", + "rootDir": "./src", + "sourceMap": false, + "types": ["node"] + }, + "include": ["src"], + "exclude": ["tests"] +} diff --git a/packages/dsh-loopx-plugin/tsconfig.json b/packages/dsh-loopx-plugin/tsconfig.json new file mode 100644 index 000000000..8895f3b47 --- /dev/null +++ b/packages/dsh-loopx-plugin/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2024", + "module": "ESNext", + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noImplicitOverride": true, + "noFallthroughCasesInSwitch": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "skipLibCheck": true, + "types": ["node", "vitest/globals"] + }, + "include": ["src", "tests"] +} diff --git a/packages/dsh-loopx-plugin/tsdown.config.ts b/packages/dsh-loopx-plugin/tsdown.config.ts new file mode 100644 index 000000000..abde9abbf --- /dev/null +++ b/packages/dsh-loopx-plugin/tsdown.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsdown' + +/** Build the four DSH plugin faces plus the package service entry as Node ESM. */ +export default defineConfig({ + entry: [ + 'build-temp/index.js', + 'build-temp/service.js', + 'build-temp/command.js', + 'build-temp/tools.js', + 'build-temp/driver.js', + ], + outDir: 'lib', + format: ['esm'], + platform: 'node', + target: 'es2024', + fixedExtension: false, + dts: false, + clean: false, + sourcemap: false, +}) diff --git a/tests/cli_commands/test_project_lifecycle_goal_channel.py b/tests/cli_commands/test_project_lifecycle_goal_channel.py index 95bca8581..2d108ab8c 100644 --- a/tests/cli_commands/test_project_lifecycle_goal_channel.py +++ b/tests/cli_commands/test_project_lifecycle_goal_channel.py @@ -127,6 +127,7 @@ def test_refresh_state_applies_goal_channel_delivery_postcondition( ) assert result == expected_exit + assert captured["schema_version"] == "loopx_refresh_state_result_v0" assert captured["ok"] is expected_ok assert captured["goal_channel_gate_sync"] == gate_sync if expected_ok: diff --git a/tests/control_plane/test_cli_output_budget.py b/tests/control_plane/test_cli_output_budget.py index ba709c6cd..48f217f3f 100644 --- a/tests/control_plane/test_cli_output_budget.py +++ b/tests/control_plane/test_cli_output_budget.py @@ -891,7 +891,9 @@ def test_quota_should_run_no_format_uses_machine_contract_json( markdown_exit_code, markdown_text = _invoke_cli(explicit_markdown_command) assert no_format_exit_code == 0, no_format_text - assert json.loads(no_format_text)["goal_id"] == GOAL_ID + no_format_payload = json.loads(no_format_text) + assert no_format_payload["schema_version"] == "loopx_quota_should_run_v0" + assert no_format_payload["goal_id"] == GOAL_ID assert markdown_exit_code == 0, markdown_text assert markdown_text.startswith("# LoopX Quota Should Run") assert not markdown_text.lstrip().startswith("{") @@ -984,6 +986,7 @@ def test_malformed_todo_state_fails_closed_without_dropping_bounded_detail( measurement=status_measurement, ) status_payload = json.loads(status_text) + assert status_payload["schema_version"] == "loopx_status_v0" error_codes = { row.get("code") for row in status_payload["contract"]["error_diagnostics"] @@ -1410,7 +1413,9 @@ def test_collection_growth_and_bootstrap_duplication_are_explicit(tmp_path: Path bootstrap_payload = small["bootstrap_command_pack"]["json"]["payload"] start_duplication = start_payload["packet_summary"]["duplication_measurement"] bootstrap_duplication = bootstrap_payload["packet_summary"]["duplication_measurement"] - assert start_duplication["objective_content"]["duplicate_occurrences"] <= 11 + # The versioned connect contract intentionally carries one additional + # allowlisted objective copy for the conditional bootstrap mutation. + assert start_duplication["objective_content"]["duplicate_occurrences"] <= 12 assert start_duplication["command_content"]["duplicate_occurrences"] <= 13 assert bootstrap_duplication["objective_content"]["duplicate_occurrences"] <= 8 assert bootstrap_duplication["command_content"]["duplicate_occurrences"] <= 9 diff --git a/tests/control_plane/test_heartbeat_prompt_support.py b/tests/control_plane/test_heartbeat_prompt_support.py index b850591f2..4997abe36 100644 --- a/tests/control_plane/test_heartbeat_prompt_support.py +++ b/tests/control_plane/test_heartbeat_prompt_support.py @@ -22,6 +22,7 @@ ) from loopx.heartbeat_prompt import ( build_heartbeat_prompt, + build_heartbeat_prompt_error_payload, render_heartbeat_prompt_markdown, ) @@ -122,7 +123,17 @@ def test_visible_goal_policy_rejects_heartbeat_only_vocabulary() -> None: def test_public_facade_still_builds_and_renders_prompts() -> None: payload = build_heartbeat_prompt(goal_id="loopx-meta") + assert payload["schema_version"] == "loopx_heartbeat_prompt_v0" assert payload["ok"] is True assert payload["goal_id"] == "loopx-meta" assert payload["task_body"] + assert "pr_review_pre_quota_command" not in payload + assert "scheduler_execution_context" not in payload assert render_heartbeat_prompt_markdown(payload) + + error = build_heartbeat_prompt_error_payload( + goal_id="loopx-meta", + error="fixture failure", + ) + assert error["schema_version"] == "loopx_heartbeat_prompt_v0" + assert error["ok"] is False diff --git a/tests/control_plane/test_quota_settlement_cli.py b/tests/control_plane/test_quota_settlement_cli.py index dd6847fef..1969d486e 100644 --- a/tests/control_plane/test_quota_settlement_cli.py +++ b/tests/control_plane/test_quota_settlement_cli.py @@ -366,6 +366,7 @@ def test_standard_codex_app_settlement_is_receipted_and_idempotent( ) assert guard_rc == 0, guard + assert guard["schema_version"] == "loopx_quota_should_run_v0" identity = guard["heartbeat_receipt"]["settlement_identity"] assert identity["todo_id"] == TODO_ID assert identity["effect_id"] == (f"{GOAL_ID}:{AGENT_ID}:{TODO_ID}:{TURN_ID}") @@ -394,6 +395,7 @@ def test_standard_codex_app_settlement_is_receipted_and_idempotent( ) assert complete_rc == 0, complete + assert complete["schema_version"] == "loopx_todo_command_v0" assert complete["settlement_result"]["ok"] is True assert [ receipt["step_kind"] for receipt in complete["settlement_result"]["receipts"] diff --git a/tests/control_plane/test_start_goal_compact_projection.py b/tests/control_plane/test_start_goal_compact_projection.py index 2df933c15..708124c27 100644 --- a/tests/control_plane/test_start_goal_compact_projection.py +++ b/tests/control_plane/test_start_goal_compact_projection.py @@ -25,6 +25,7 @@ validate_shared_todo_options, validate_todo_add_options, ) +from loopx.thread_agent_binding import resolve_dsh_thread_agent_binding GOAL_ID = "guided-projection-goal" AGENT_ID = "codex-guided-projection" @@ -194,6 +195,68 @@ def test_default_projection_preserves_host_actions_and_json_anchors( _resolve_pointer(projection, ref["json_pointer"]) +@pytest.mark.parametrize("fine_grained", [False, True]) +def test_connect_contract_is_data_only_and_matches_full_compact_guidance( + tmp_path: Path, + fine_grained: bool, +) -> None: + project = tmp_path / "fresh-project" + project.mkdir() + common = { + "project": project, + "goal_id": GOAL_ID, + "agent_id": AGENT_ID, + "cli_bin": "loopx", + "host_surface": "codex-app", + "goal_text": f" {GOAL_TEXT} ", + "available_capabilities": ["network"], + "fine_grained": fine_grained, + } + + compact = build_start_goal_guided_packet( + **common, + include_command_pack_detail=False, + ) + detailed = build_start_goal_guided_packet( + **common, + include_command_pack_detail=True, + ) + + compact_step = next( + step + for step in compact["guided_transaction"]["ordered_steps"] + if step["id"] == "connect_if_needed" + ) + detailed_step = next( + step + for step in detailed["guided_transaction"]["ordered_steps"] + if step["id"] == "connect_if_needed" + ) + expected_contract = { + "schema_version": "loopx_start_goal_connect_v0", + "operation": "bootstrap_connect", + "goal_id": GOAL_ID, + "objective": GOAL_TEXT, + "adapter_kind": "read_only_project_map_v0", + "adapter_status": "connected-read-only", + "onboarding_scan_enabled": False, + "fine_grained": fine_grained, + } + + assert compact_step["connect_contract"] == expected_contract + assert detailed_step["connect_contract"] == expected_contract + assert set(compact_step["connect_contract"]) == set(expected_contract) + assert "command" not in compact_step["connect_contract"] + assert "argv" not in compact_step["connect_contract"] + assert compact_step["command"] == compact["command_pack"]["commands"][ + "goal_start_connect_if_needed" + ] + assert detailed_step["command"] == detailed["command_pack"]["commands"][ + "goal_start_connect_if_needed" + ] + assert "--no-onboarding-scan" in compact_step["command"] + + def test_goal_start_packet_is_parity_complete_behavior_authority( tmp_path: Path, ) -> None: @@ -625,7 +688,9 @@ def test_projection_materially_reduces_repetition_without_hiding_measurement( assert len(compact_json) <= int(len(detailed_json) * 0.65) compact_duplication = compact["packet_summary"]["duplication_measurement"] detailed_duplication = detailed["packet_summary"]["duplication_measurement"] - assert compact_duplication["objective_content"]["duplicate_occurrences"] <= 11 + # The versioned connect contract intentionally repeats the objective once as + # an allowlisted mutation input; keep every other compact duplication bounded. + assert compact_duplication["objective_content"]["duplicate_occurrences"] <= 12 assert compact_duplication["command_content"]["duplicate_occurrences"] <= 13 assert ( compact_duplication["objective_content"]["duplicate_occurrences"] @@ -866,6 +931,36 @@ def test_start_goal_with_unbound_thread_requires_existing_lane_selection( ) +def test_dsh_native_start_goal_with_unbound_session_defaults_to_fresh_identity( + tmp_path: Path, +) -> None: + project = _write_connected_project(tmp_path) + registry_path = project / ".loopx" / "registry.json" + registry = json.loads(registry_path.read_text(encoding="utf-8")) + registry["goals"][0]["coordination"]["registered_agents"].append("dsh-existing-peer") + registry_path.write_text(json.dumps(registry, indent=2) + "\n", encoding="utf-8") + + payload = build_start_goal_guided_packet( + project=project, + goal_id=GOAL_ID, + agent_id=None, + thread_id="dsh-session-unbound", + cli_bin="loopx", + host_surface="deepseek-harness-native", + goal_text=GOAL_TEXT, + available_capabilities=["network"], + ) + + gate = payload["guided_transaction"]["identity_selection_gate"] + assert gate["state"] == "fresh_agent_registration_required" + assert gate["default_action"] == "register_fresh_agent" + assert gate["fresh_agent_registration"]["recommended"] is True + assert all( + choice["requires_explicit_takeover_intent"] is True + for choice in gate["choices"] + ) + + def test_start_goal_unbound_thread_requires_lane_selection_even_for_single_registered_agent( tmp_path: Path, ) -> None: @@ -1286,6 +1381,8 @@ def test_cli_without_host_returns_read_only_host_selection_gate( "pi", "gemini-cli", "cursor-agent", + "dsh", + "deepseek-harness-native", "deepseek-harness", "ark-managed-agent", "shell", @@ -1472,6 +1569,283 @@ def test_codex_ide_plugin_uses_visible_goal_and_preserves_compact_parity( ) +def test_dsh_native_alias_is_canonical_before_thread_lookup_and_binding( + tmp_path: Path, +) -> None: + project = _write_connected_project(tmp_path) + payload = build_start_goal_guided_packet( + project=project, + goal_id=GOAL_ID, + agent_id=AGENT_ID, + thread_id="dsh-session-fixture", + cli_bin="loopx", + host_surface="dsh-native", + goal_text=GOAL_TEXT, + include_command_pack_detail=True, + ) + + command_pack = payload["command_pack"] + activation = command_pack["host_loop_activation"] + assert payload["host_surface"] == "deepseek-harness-native" + assert command_pack["host_surface"] == "deepseek-harness-native" + assert command_pack["agent_type"] == "deepseek-harness-native" + assert activation["host_surface"] == "deepseek_harness_native_session" + bind_command = command_pack["commands"]["goal_start_bind_thread"] + assert "--host-surface deepseek-harness-native" in bind_command + assert "dsh-native" not in bind_command + assert "--host-surface deepseek-harness-native" in command_pack[ + "canonical_cli_command" + ] + assert "dsh-native" not in json.dumps(payload) + + +def test_dsh_v1_bootstrap_projects_the_global_binding_and_cas_command( + tmp_path: Path, +) -> None: + project = _write_connected_project(tmp_path) + source_path = project / ".loopx" / "registry.json" + runtime_root = tmp_path / "runtime" + global_path = runtime_root / "registry.global.json" + source = json.loads(source_path.read_text(encoding="utf-8")) + source["common_runtime_root"] = str(runtime_root) + source_path.write_text(json.dumps(source, indent=2) + "\n", encoding="utf-8") + global_goal = { + **source["goals"][0], + "source_registry": str(source_path), + } + tombstone = { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": "dsh", + "thread_id": "dsh-session-v1", + "revision": 7, + "state": "unbound", + } + global_path.parent.mkdir(parents=True) + global_path.write_text( + json.dumps( + { + "schema_version": "0.1", + "registry_role": "global-local", + "goals": [global_goal], + "dsh_host_thread_bindings": { + "schema_version": "loopx_dsh_host_thread_bindings_v1", + "records": {"dsh-session-v1": tombstone}, + }, + }, + indent=2, + ) + + "\n", + encoding="utf-8", + ) + + payload = build_start_goal_guided_packet( + project=project, + goal_id=GOAL_ID, + agent_id=AGENT_ID, + thread_id="dsh-session-v1", + cli_bin="loopx", + host_surface="dsh", + goal_text=GOAL_TEXT, + include_command_pack_detail=True, + ) + + command_pack = payload["command_pack"] + assert payload["host_surface"] == "dsh" + assert command_pack["host_surface"] == "dsh" + assert command_pack["agent_type"] == "deepseek-harness-native" + assert command_pack["host_thread_binding"] == tombstone + resolved = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="dsh-session-v1", + ) + assert resolved["binding"] == command_pack["host_thread_binding"] + assert "thread_agent_binding" not in command_pack + bind_command = command_pack["commands"]["goal_start_bind_thread"] + assert "--host-surface dsh" in bind_command + assert "--expected-revision 7" in bind_command + assert command_pack["canonical_cli_command"].count("--host-surface dsh") == 1 + binding_step = next( + step + for step in payload["guided_transaction"]["ordered_steps"] + if step["id"] == "bind_thread_identity" + ) + assert binding_step["result_contract"] == { + "schema_version": "loopx_host_thread_binding_command_v1", + "required_result": { + "ok": True, + "application": "yes", + "binding": { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": "dsh", + "state": "bound", + }, + }, + } + + bound = { + **tombstone, + "revision": 8, + "state": "bound", + "target": {"goal_id": GOAL_ID, "agent_id": AGENT_ID}, + } + authority = json.loads(global_path.read_text(encoding="utf-8")) + authority["dsh_host_thread_bindings"]["records"]["dsh-session-v1"] = bound + global_path.write_text(json.dumps(authority) + "\n", encoding="utf-8") + activated = build_loopx_bootstrap_command_pack( + project=project, + goal_id=GOAL_ID, + agent_id=AGENT_ID, + thread_id="dsh-session-v1", + cli_bin="loopx", + host_surface="dsh", + goal_text=GOAL_TEXT, + ) + assert activated["ok"] is True + assert activated["agent_id"] == AGENT_ID + assert activated["host_thread_binding"] == bound + assert activated["host_loop_activation"]["activation_allowed"] is True + assert activated["commands"]["goal_start_bind_thread"] is None + + +def test_dsh_v1_bootstrap_projects_a_bounded_authority_failure(tmp_path: Path) -> None: + project = _write_connected_project(tmp_path) + source_path = project / ".loopx" / "registry.json" + missing_runtime = tmp_path / "missing-runtime" + source = json.loads(source_path.read_text(encoding="utf-8")) + source["common_runtime_root"] = str(missing_runtime) + source_path.write_text(json.dumps(source) + "\n", encoding="utf-8") + + payload = build_start_goal_guided_packet( + project=project, + goal_id=GOAL_ID, + agent_id=AGENT_ID, + thread_id="dsh-session-missing-home", + cli_bin="loopx", + host_surface="dsh", + goal_text=GOAL_TEXT, + include_command_pack_detail=True, + ) + + expected_resolution = { + "schema_version": "loopx_host_thread_binding_command_v1", + "ok": False, + "changed": False, + "application": "no", + "error_kind": "binding_home_unavailable", + } + assert payload["ok"] is False + assert payload["error_kind"] == "binding_home_unavailable" + assert payload["error"] == "DSH Host binding authority could not be resolved" + assert payload["host_thread_binding_resolution"] == expected_resolution + assert payload["command_pack"]["host_thread_binding_resolution"] == expected_resolution + assert str(missing_runtime) not in json.dumps(expected_resolution) + + +def test_dsh_v1_explicit_runtime_root_wins_for_resolve_bootstrap_and_start( + tmp_path: Path, +) -> None: + project = _write_connected_project(tmp_path) + source_path = project / ".loopx" / "registry.json" + project_runtime = tmp_path / "project-runtime" + explicit_runtime = tmp_path / "explicit-runtime" + thread_id = "dsh-explicit-root-session" + source = json.loads(source_path.read_text(encoding="utf-8")) + source["common_runtime_root"] = str(project_runtime) + source_path.write_text(json.dumps(source) + "\n", encoding="utf-8") + global_goal = {**source["goals"][0], "source_registry": str(source_path)} + decoy = { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": "dsh", + "thread_id": thread_id, + "revision": 4, + "state": "unbound", + } + expected = { + **decoy, + "revision": 9, + "state": "bound", + "target": {"goal_id": GOAL_ID, "agent_id": AGENT_ID}, + } + for runtime_root, binding in ( + (project_runtime, decoy), + (explicit_runtime, expected), + ): + runtime_root.mkdir(parents=True) + (runtime_root / "registry.global.json").write_text( + json.dumps( + { + "schema_version": "0.1", + "registry_role": "global-local", + "goals": [global_goal], + "dsh_host_thread_bindings": { + "schema_version": "loopx_dsh_host_thread_bindings_v1", + "records": {thread_id: binding}, + }, + } + ) + + "\n", + encoding="utf-8", + ) + + def invoke(*argv: str) -> dict[str, Any]: + output = io.StringIO() + with contextlib.redirect_stdout(output): + exit_code = cli_main( + [ + "--format", + "json", + "--runtime-root", + str(explicit_runtime), + *argv, + ] + ) + assert exit_code == 0, output.getvalue() + return json.loads(output.getvalue()) + + resolved = invoke( + "resolve-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + thread_id, + ) + bootstrapped = invoke( + "bootstrap-command-pack", + "--project", + str(project), + "--goal-id", + GOAL_ID, + "--agent-id", + AGENT_ID, + "--thread-id", + thread_id, + "--host-surface", + "dsh", + ) + started = invoke( + "start-goal", + "--guided", + "--project", + str(project), + "--goal-id", + GOAL_ID, + "--agent-id", + AGENT_ID, + "--thread-id", + thread_id, + "--host-surface", + "dsh", + "--goal-text", + GOAL_TEXT, + ) + + assert resolved["binding"] == expected + assert bootstrapped["host_thread_binding"] == expected + assert started["host_thread_binding"] == expected + assert started["command_pack"]["host_thread_binding"] == expected + + def _runnable_todo_add_argv(command_template: str) -> list[str]: """Drop the documented optional span so the template can be parsed as argv.""" tokens = shlex.split(command_template) diff --git a/tests/control_plane/test_todo_decision_scope_cli_validation.py b/tests/control_plane/test_todo_decision_scope_cli_validation.py index 8a6d9b896..6bd09e077 100644 --- a/tests/control_plane/test_todo_decision_scope_cli_validation.py +++ b/tests/control_plane/test_todo_decision_scope_cli_validation.py @@ -62,7 +62,7 @@ def _register_agents(registry_path: Path) -> None: def _add_global_gate(registry_path: Path) -> dict: - return run_json_cli( + payload = run_json_cli( "todo", "add", "--goal-id", @@ -76,6 +76,8 @@ def _add_global_gate(registry_path: Path) -> dict: "--global-gate", registry_path=registry_path, ) + assert payload["schema_version"] == "loopx_todo_command_v0" + return payload def test_todo_update_can_narrow_global_gate_without_consuming_decision( diff --git a/tests/test_agent_onboarding_dsh_native_host.py b/tests/test_agent_onboarding_dsh_native_host.py new file mode 100644 index 000000000..0a32fbf90 --- /dev/null +++ b/tests/test_agent_onboarding_dsh_native_host.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +import json +from pathlib import Path + +from loopx.agent_onboarding import build_agent_onboarding_packet + + +def _connected_project(tmp_path: Path) -> Path: + project = tmp_path / "project" + registry = project / ".loopx" / "registry.json" + registry.parent.mkdir(parents=True) + registry.write_text( + json.dumps( + { + "schema_version": "0.1", + "goals": [ + { + "id": "dsh-native-goal", + "status": "active", + "repo": str(project), + "adapter": { + "kind": "generic_project_goal_v0", + "status": "connected", + }, + "coordination": { + "agent_model": "peer_v1", + "registered_agents": ["dsh-native-agent"], + }, + } + ], + } + ) + + "\n", + encoding="utf-8", + ) + return project + + +def test_dsh_native_onboarding_discovers_independent_same_session_plugin( + tmp_path: Path, +) -> None: + project = _connected_project(tmp_path) + packet = build_agent_onboarding_packet( + project=project, + agent_type="dsh-native", + goal_id="dsh-native-goal", + agent_id="dsh-native-agent", + ) + + activation = packet["host_loop_activation"] + assert packet["agent_type"] == "deepseek-harness-native" + assert activation["host_surface"] == "deepseek_harness_native_session" + assert activation["host_mutation"]["host_tool"] == "loopx_goal_activate" + assert activation["setup"]["package_path"] == "packages/dsh-loopx-plugin" + assert "install_command_facade" not in packet["commands"] + assert "--host-surface deepseek-harness-native" in packet["commands"][ + "bootstrap_command_pack" + ] + assert "packages/dsh-loopx-plugin" in packet["recommended_start"] + assert "loopx_goal_activate" in packet["recommended_start"] + assert "scripts/dsh_turn_host_adapter.py" not in json.dumps(packet) + + +def test_dsh_external_onboarding_keeps_existing_adapter_contract(tmp_path: Path) -> None: + project = _connected_project(tmp_path) + packet = build_agent_onboarding_packet( + project=project, + agent_type="dsh", + goal_id="dsh-native-goal", + agent_id="dsh-native-agent", + ) + + activation = packet["host_loop_activation"] + assert packet["agent_type"] == "deepseek-harness" + assert activation["host_surface"] == "deepseek_harness_automation_loop" + assert activation["activation_method"] == "external_loop_driver" + assert "scripts/dsh_turn_host_adapter.py" in activation["entry_command_hint"] + assert "loopx[deepseek-harness]" in packet["recommended_start"] diff --git a/tests/test_bootstrap_connect_contract.py b/tests/test_bootstrap_connect_contract.py new file mode 100644 index 000000000..be801f4e9 --- /dev/null +++ b/tests/test_bootstrap_connect_contract.py @@ -0,0 +1,237 @@ +from __future__ import annotations + +import contextlib +import io +import json +from pathlib import Path +from typing import Any + +import pytest + +from loopx.cli import build_parser, main as cli_main +from loopx.cli_commands import bootstrap_connect + + +BOOTSTRAP_RESULT_SCHEMA_VERSION = "loopx_bootstrap_result_v0" + + +def _run_cli(argv: list[str]) -> tuple[int, dict[str, Any]]: + output = io.StringIO() + with contextlib.redirect_stdout(output): + exit_code = cli_main(argv) + payload = json.loads(output.getvalue()) + assert isinstance(payload, dict) + return exit_code, payload + + +def _base_argv(project: Path, runtime_root: Path, command: str) -> list[str]: + return [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "--registry", + str(project / ".loopx" / "registry.json"), + command, + "--project", + str(project), + "--adapter-kind", + "read_only_project_map_v0", + "--adapter-status", + "connected-read-only", + "--no-onboarding-scan", + "--codex-app-heartbeat", + "ask", + ] + + +def test_bootstrap_and_connect_results_are_versioned_for_reuse_and_fork( + tmp_path: Path, +) -> None: + project = tmp_path / "project" + project.mkdir() + runtime_root = tmp_path / "runtime" + current_goal = "current-project-goal" + forked_goal = "independent-goal" + + first_exit, first = _run_cli( + [ + *_base_argv(project, runtime_root, "bootstrap"), + "--goal-id", + current_goal, + "--objective", + "Keep the current project goal.", + ] + ) + reuse_exit, reuse = _run_cli( + [ + *_base_argv(project, runtime_root, "connect"), + "--goal-id", + current_goal, + "--objective", + "This objective must not replace reused state.", + ] + ) + fork_exit, fork = _run_cli( + [ + *_base_argv(project, runtime_root, "connect"), + "--fork-goal", + forked_goal, + "--objective", + "Start an independent goal.", + ] + ) + + assert (first_exit, reuse_exit, fork_exit) == (0, 0, 0) + assert first["schema_version"] == BOOTSTRAP_RESULT_SCHEMA_VERSION + assert reuse["schema_version"] == BOOTSTRAP_RESULT_SCHEMA_VERSION + assert fork["schema_version"] == BOOTSTRAP_RESULT_SCHEMA_VERSION + assert first["registry_goal_action"] == "appended" + assert first["state_action"] == "created" + assert reuse["goal_id"] == current_goal + assert reuse["registry_goal_action"] == "kept-existing" + assert reuse["state_action"] == "kept-existing" + assert reuse["global_sync"]["ok"] is True + assert fork["goal_id"] == forked_goal + assert fork["registry_goal_action"] == "appended" + assert fork["state_action"] == "created" + assert fork["global_sync"]["ok"] is True + + registry = json.loads( + (project / ".loopx" / "registry.json").read_text(encoding="utf-8") + ) + assert [goal["id"] for goal in registry["goals"]] == [ + current_goal, + forked_goal, + ] + current_state = project / ".codex" / "goals" / current_goal / "ACTIVE_GOAL_STATE.md" + assert "Keep the current project goal." in current_state.read_text(encoding="utf-8") + assert "This objective must not replace reused state." not in current_state.read_text( + encoding="utf-8" + ) + + +@pytest.mark.parametrize("command", ["bootstrap", "connect"]) +def test_bootstrap_validation_failure_has_version_and_typed_category( + tmp_path: Path, + command: str, +) -> None: + project = tmp_path / "project" + project.mkdir() + exit_code, payload = _run_cli( + [ + *_base_argv(project, tmp_path / "runtime", command), + "--goal-id", + "requested-goal", + "--fork-goal", + "different-goal", + ] + ) + + assert exit_code == 1 + assert payload["ok"] is False + assert payload["schema_version"] == BOOTSTRAP_RESULT_SCHEMA_VERSION + assert payload["error_kind"] == "invalid_bootstrap_request" + assert payload["error"] == ( + "--fork-goal cannot be combined with a different --goal-id" + ) + + +def test_bootstrap_internal_value_error_is_not_request_validation( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + def raise_internal_value_error(**_kwargs: object) -> dict[str, object]: + raise ValueError("malformed project registry record") + + monkeypatch.setattr( + bootstrap_connect, + "bootstrap_project", + raise_internal_value_error, + ) + args = build_parser().parse_args( + [ + "--format", + "json", + "connect", + "--project", + str(tmp_path), + "--goal-id", + "requested-goal", + ] + ) + captured: dict[str, object] = {} + + exit_code = bootstrap_connect.handle_bootstrap_connect_command( + args, + registry_path=tmp_path / ".loopx" / "registry.json", + print_payload=lambda payload, *_args: captured.update(payload), + ) + + assert exit_code == 1 + assert captured["schema_version"] == BOOTSTRAP_RESULT_SCHEMA_VERSION + assert captured["error_kind"] == "bootstrap_connect_failed" + assert captured["error"] == "malformed project registry record" + + +@pytest.mark.parametrize( + ("failure_payload", "expected_error_kind"), + [ + ( + { + "ok": False, + "error_kind": "project_connection_failed", + "global_sync": {"error_kind": "must-not-override-top-level"}, + }, + "project_connection_failed", + ), + ( + { + "ok": False, + "global_sync": {"error_kind": "global_registry_write_denied"}, + }, + "global_registry_write_denied", + ), + ({"ok": False}, "bootstrap_connect_failed"), + ], +) +def test_bootstrap_runtime_failure_has_stable_typed_category( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, + failure_payload: dict[str, object], + expected_error_kind: str, +) -> None: + def return_bootstrap_failure(**_kwargs: object) -> dict[str, object]: + return { + "goal_id": "requested-goal", + "error": "global registry is not writable", + **failure_payload, + } + + monkeypatch.setattr( + bootstrap_connect, + "bootstrap_project", + return_bootstrap_failure, + ) + args = build_parser().parse_args( + [ + "--format", + "json", + "bootstrap", + "--project", + str(tmp_path), + "--goal-id", + "requested-goal", + ] + ) + captured: dict[str, object] = {} + + exit_code = bootstrap_connect.handle_bootstrap_connect_command( + args, + registry_path=tmp_path / ".loopx" / "registry.json", + print_payload=lambda payload, *_args: captured.update(payload), + ) + + assert exit_code == 1 + assert captured["schema_version"] == BOOTSTRAP_RESULT_SCHEMA_VERSION + assert captured["error_kind"] == expected_error_kind diff --git a/tests/test_global_registry_write_serialization.py b/tests/test_global_registry_write_serialization.py index 400bd2046..45f77b25a 100644 --- a/tests/test_global_registry_write_serialization.py +++ b/tests/test_global_registry_write_serialization.py @@ -11,13 +11,22 @@ from loopx import global_registry from loopx import project_uninstall as project_uninstall_module +from loopx import thread_agent_binding as thread_agent_binding_module +from loopx.control_plane.goals import configure_goal_service from loopx.file_lock import fcntl from loopx.global_registry import ( global_registry_path, retire_global_registry_goals, sync_project_registry_to_global, ) +from loopx.control_plane.goals.configure_goal_service import ( + configure_goal_with_global_sync, +) from loopx.project_uninstall import uninstall_project +from loopx.thread_agent_binding import ( + bind_dsh_thread_agent_in_global_registry, + unbind_dsh_thread_agent_in_global_registry, +) GOAL_COUNT = 6 @@ -64,6 +73,35 @@ def _project_registry(root: Path, name: str, runtime_root: Path) -> Path: return registry_path +def _bound_dsh_project( + tmp_path: Path, +) -> tuple[Path, Path, Path]: + runtime_root = tmp_path / "runtime" + registry_path = _project_registry(tmp_path, "alpha", runtime_root) + payload = json.loads(registry_path.read_text(encoding="utf-8")) + payload["goals"][0]["coordination"] = { + "registered_agents": ["agent-a", "agent-b"] + } + registry_path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + sync_project_registry_to_global( + registry_path=registry_path, + runtime_root_override=str(runtime_root), + dry_run=False, + ) + global_path = global_registry_path(runtime_root) + result = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal-alpha", + agent_id="agent-a", + expected_revision=0, + execute=True, + ) + assert result["ok"] is True, result + return runtime_root, registry_path, global_path + + def test_sync_reads_and_writes_inside_the_global_registry_lock( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: @@ -382,6 +420,218 @@ def backup_then_commit_concurrent_goal( assert [goal.get("id") for goal in remaining] == ["goal-beta"] +def test_global_sync_preserves_the_dsh_binding_collection_exactly( + tmp_path: Path, +) -> None: + runtime_root, registry_path, global_path = _bound_dsh_project(tmp_path) + before = json.loads(global_path.read_text(encoding="utf-8"))[ + "dsh_host_thread_bindings" + ] + source = json.loads(registry_path.read_text(encoding="utf-8")) + source["goals"][0]["objective"] = "updated without touching Host authority" + registry_path.write_text(json.dumps(source) + "\n", encoding="utf-8") + + result = sync_project_registry_to_global( + registry_path=registry_path, + runtime_root_override=str(runtime_root), + dry_run=False, + ) + + assert result["ok"] is True + after = json.loads(global_path.read_text(encoding="utf-8"))[ + "dsh_host_thread_bindings" + ] + assert after == before + + +def test_configure_goal_rejects_bound_agent_removal_before_source_write( + tmp_path: Path, +) -> None: + runtime_root, registry_path, _global_path = _bound_dsh_project(tmp_path) + before = registry_path.read_bytes() + + with pytest.raises(ValueError, match="DSH Host binding blocks Agent membership"): + configure_goal_with_global_sync( + registry_path=registry_path, + goal_id="goal-alpha", + runtime_root_override=str(runtime_root), + registered_agents=["agent-b"], + execute=True, + ) + + assert registry_path.read_bytes() == before + + +def test_dsh_bind_and_membership_change_hold_source_before_global( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + runtime_root, registry_path, global_path = _bound_dsh_project(tmp_path) + held: list[str] = [] + events: list[str] = [] + + @contextmanager + def source_lock(_path: Path, **_kwargs: Any) -> Iterator[Path]: + assert not held + held.append("source") + events.append("source-enter") + try: + yield registry_path + finally: + assert held.pop() == "source" + events.append("source-exit") + + @contextmanager + def global_lock(_path: Path, **_kwargs: Any) -> Iterator[Path]: + assert held == ["source"] + held.append("global") + events.append("global-enter") + try: + yield global_path + finally: + assert held.pop() == "global" + events.append("global-exit") + + monkeypatch.setattr(configure_goal_service, "exclusive_file_lock", source_lock) + monkeypatch.setattr(thread_agent_binding_module, "exclusive_file_lock", source_lock) + monkeypatch.setattr(global_registry, "exclusive_file_lock", global_lock) + + configured = configure_goal_with_global_sync( + registry_path=registry_path, + goal_id="goal-alpha", + runtime_root_override=str(runtime_root), + registered_agents=["agent-a"], + execute=True, + ) + assert configured["ok"] is True + bound = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-lock-order", + goal_id="goal-alpha", + agent_id="agent-a", + expected_revision=0, + execute=True, + ) + assert bound["ok"] is True + assert held == [] + assert events.count("source-enter") == 2 + assert events.count("global-enter") >= 3 + + +def test_route_replacement_and_project_uninstall_are_blocked_while_dsh_bound( + tmp_path: Path, +) -> None: + runtime_root, registry_path, global_path = _bound_dsh_project(tmp_path) + source_before = registry_path.read_bytes() + global_before = global_path.read_bytes() + source = json.loads(registry_path.read_text(encoding="utf-8")) + source["goals"][0]["repo"] = str(tmp_path / "replacement") + registry_path.write_text(json.dumps(source) + "\n", encoding="utf-8") + + with pytest.raises(ValueError, match="DSH Host binding blocks Goal route"): + sync_project_registry_to_global( + registry_path=registry_path, + runtime_root_override=str(runtime_root), + dry_run=False, + allow_route_replacement=True, + ) + assert global_path.read_bytes() == global_before + + registry_path.write_bytes(source_before) + with pytest.raises(ValueError, match="DSH Host binding blocks Goal route"): + uninstall_project( + registry_path=registry_path, + runtime_root_override=str(runtime_root), + goal_ids=["goal-alpha"], + archive_state=False, + remove_empty_registry=False, + execute=True, + ) + assert registry_path.read_bytes() == source_before + assert global_path.read_bytes() == global_before + + +@pytest.mark.skipif(fcntl is None, reason="POSIX flock is required") +def test_dsh_concurrent_process_cas_has_one_winner_and_one_stale_loser( + tmp_path: Path, +) -> None: + _runtime_root, _registry_path, global_path = _bound_dsh_project(tmp_path) + script = """ +import json, sys +from pathlib import Path +from loopx.thread_agent_binding import bind_dsh_thread_agent_in_global_registry +print(json.dumps(bind_dsh_thread_agent_in_global_registry( + global_path=Path(sys.argv[1]), host_surface="dsh", thread_id="session-race", + goal_id="goal-alpha", agent_id=sys.argv[2], expected_revision=0, execute=True, +))) +""" + processes = [ + subprocess.Popen( + [sys.executable, "-c", script, str(global_path), agent_id], + cwd=Path(__file__).resolve().parents[1], + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + for agent_id in ("agent-a", "agent-b") + ] + results = [] + for process in processes: + stdout, stderr = process.communicate(timeout=30) + assert process.returncode == 0, stderr + results.append(json.loads(stdout)) + + winners = [result for result in results if result.get("ok") is True] + losers = [ + result + for result in results + if result.get("error_kind") == "revision_conflict" + ] + assert len(winners) == 1, results + assert len(losers) == 1, results + assert winners[0]["binding"]["revision"] == 1 + assert losers[0]["binding"] == winners[0]["binding"] + + +def test_retirement_requires_unbind_and_preserves_the_tombstone( + tmp_path: Path, +) -> None: + runtime_root, registry_path, global_path = _bound_dsh_project(tmp_path) + state_path = tmp_path / "alpha" / "ACTIVE_GOAL_STATE.md" + registry_path.unlink() + state_path.unlink() + before = global_path.read_bytes() + + with pytest.raises(ValueError, match="DSH Host binding blocks Goal route"): + retire_global_registry_goals( + runtime_root_override=str(runtime_root), + goal_ids=["goal-alpha"], + execute=True, + ) + assert global_path.read_bytes() == before + + unbound = unbind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + expected_revision=1, + execute=True, + ) + assert unbound["ok"] is True + retired = retire_global_registry_goals( + runtime_root_override=str(runtime_root), + goal_ids=["goal-alpha"], + execute=True, + ) + assert retired["ok"] is True + payload = json.loads(global_path.read_text(encoding="utf-8")) + assert payload["goals"] == [] + assert payload["dsh_host_thread_bindings"]["records"]["session-a"] == unbound[ + "binding" + ] + + _CONCURRENT_SYNC_SCRIPT = """ import sys from pathlib import Path diff --git a/tests/test_host_loop_activation.py b/tests/test_host_loop_activation.py index 6a28cf9d5..ab6918611 100644 --- a/tests/test_host_loop_activation.py +++ b/tests/test_host_loop_activation.py @@ -25,6 +25,7 @@ agent_type_uses_host_managed_skills, build_host_loop_activation_packet, normalize_agent_type, + normalize_host_surface, scheduler_command_binding_for_agent_type, ) from loopx.project_prompt import render_accountable_progress_refresh_command @@ -180,6 +181,7 @@ def test_codex_ide_plugin_is_an_exact_host_type_with_visible_goal_activation() - ("opencode", "generic_cli"), ("traex-cli", "generic_cli"), ("pi", "generic_cli"), + ("deepseek-harness-native", "generic_cli"), ), ) def test_first_class_hosts_bind_one_runtime_profile( @@ -263,6 +265,9 @@ def test_pi_is_not_a_native_goal_host() -> None: def test_deepseek_harness_is_an_exact_host_type_with_external_loop_activation() -> None: assert normalize_agent_type("dsh") == "deepseek-harness" assert normalize_agent_type("DeepSeek Harness") == "deepseek-harness" + assert normalize_host_surface("dsh") == "deepseek-harness" + assert normalize_host_surface("deepseek_harness") == "deepseek-harness" + assert normalize_host_surface("deepseek harness") == "deepseek-harness" assert agent_type_for_host_surface("deepseek-harness") == "deepseek-harness" assert agent_type_for_host_surface("dsh") == "deepseek-harness" assert scheduler_command_binding_for_agent_type("deepseek-harness") == { @@ -283,6 +288,63 @@ def test_deepseek_harness_is_an_exact_host_type_with_external_loop_activation() assert "scripts/dsh_turn_host_adapter.py" in packet["entry_command_hint"], packet +def test_deepseek_harness_native_is_a_distinct_same_session_host_contract() -> None: + assert normalize_agent_type("dsh-native") == "deepseek-harness-native" + assert normalize_host_surface("dsh-native") == "deepseek-harness-native" + assert agent_type_for_host_surface("dsh-native") == "deepseek-harness-native" + assert normalize_agent_type("dsh") == "deepseek-harness" + assert scheduler_command_binding_for_agent_type("deepseek-harness-native") == { + "runtime_profile": "generic_cli" + } + + packet = build_host_loop_activation_packet( + agent_type="deepseek-harness-native", + goal_id="fixture-goal", + agent_id="dsh-native-fixture", + registered_agents=["dsh-native-fixture"], + ) + + assert packet["host_surface"] == "deepseek_harness_native_session" + assert packet["activation_method"] == "current_session_host_tool" + assert packet["entry_command_hint"] == "/loopx " + assert packet["host_mutation"]["owner"] == "DSH LoopX plugin" + assert packet["host_mutation"]["host_tool"] == "loopx_goal_activate" + assert packet["host_mutation"]["current_session_only"] is True + assert packet["setup"]["package_path"] == "packages/dsh-loopx-plugin" + assert "slash-commands" not in json.dumps(packet["setup"]) + assert json.loads(packet["activation_input_command"]) == { + "schema_version": "loopx_deepseek_harness_native_activation_input_v0", + "tool": "loopx_goal_activate", + "arguments": { + "goalId": "fixture-goal", + "agentId": "dsh-native-fixture", + }, + } + activation_mapping = json.dumps(packet["host_mutation"]["tool_argument_mapping"]) + assert "taskBody" not in activation_mapping + assert "registry" not in activation_mapping + assert "argv" not in activation_mapping + assert "scripts/dsh_turn_host_adapter.py" not in json.dumps(packet) + + +def test_deepseek_harness_native_identity_gate_does_not_expose_task_body() -> None: + packet = build_host_loop_activation_packet( + agent_type="deepseek-harness-native", + goal_id="fixture-goal", + registered_agents=["dsh-native-existing", "dsh-native-reviewer"], + ) + + choice = packet["identity_selection_gate"]["choices"][0] + activation_input = json.loads(choice["activation_input_command"]) + assert activation_input["tool"] == "loopx_goal_activate" + assert activation_input["arguments"] == { + "goalId": "fixture-goal", + "agentId": "dsh-native-existing", + } + assert "heartbeat_prompt" not in choice + assert "task_body" not in json.dumps(choice) + + @pytest.mark.parametrize( "runtime_profile", ("ark_managed_agent_goal", "codex_app_ssh_goal"), diff --git a/tests/test_register_agent_fresh_identity.py b/tests/test_register_agent_fresh_identity.py index 35ed34d31..378c5c669 100644 --- a/tests/test_register_agent_fresh_identity.py +++ b/tests/test_register_agent_fresh_identity.py @@ -5,7 +5,11 @@ from concurrent.futures import ThreadPoolExecutor from pathlib import Path +import pytest + +from loopx import paths as loopx_paths from loopx.cli_commands import registry_admin +from loopx.cli import main GOAL_ID = "fresh-agent-race-fixture" @@ -58,6 +62,100 @@ def _fixture(tmp_path: Path) -> tuple[Path, Path, Path]: return runtime_root, source_registry, global_registry +def test_dsh_binding_home_selection_is_exact_and_fail_closed( + tmp_path: Path, + monkeypatch, + capsys, +) -> None: + project_registry = tmp_path / "project" / ".loopx" / "registry.json" + default_root = tmp_path / "default-runtime" + custom_root = tmp_path / "custom-runtime" + explicit_root = tmp_path / "explicit-runtime" + payload: dict[str, object] = {"schema_version": "0.1", "goals": []} + _write_json(project_registry, payload) + monkeypatch.setattr(loopx_paths, "DEFAULT_RUNTIME_ROOT", default_root) + + assert registry_admin.dsh_binding_global_registry( + registry_path=project_registry, + runtime_root_arg=None, + ) == default_root / "registry.global.json" + binding = { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": "dsh", + "thread_id": "root-selection-session", + "revision": 1, + "state": "unbound", + } + authority = { + "schema_version": "0.1", + "goals": [], + "dsh_host_thread_bindings": { + "schema_version": "loopx_dsh_host_thread_bindings_v1", + "records": {"root-selection-session": binding}, + }, + } + _write_json(default_root / "registry.global.json", authority) + assert main( + [ + "--format", + "json", + "--registry", + str(project_registry), + "resolve-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + "root-selection-session", + ] + ) == 0 + assert json.loads(capsys.readouterr().out)["binding"] == binding + + payload["common_runtime_root"] = str(custom_root) + _write_json(project_registry, payload) + custom_binding = {**binding, "revision": 2} + authority["dsh_host_thread_bindings"]["records"] = { + "root-selection-session": custom_binding + } + _write_json(custom_root / "registry.global.json", authority) + assert registry_admin.dsh_binding_global_registry( + registry_path=project_registry, + runtime_root_arg=None, + ) == custom_root / "registry.global.json" + assert main( + [ + "--format", + "json", + "--registry", + str(project_registry), + "resolve-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + "root-selection-session", + ] + ) == 0 + assert json.loads(capsys.readouterr().out)["binding"] == custom_binding + + payload["common_runtime_root"] = [str(custom_root), str(explicit_root)] + _write_json(project_registry, payload) + assert registry_admin.dsh_binding_global_registry( + registry_path=project_registry, + runtime_root_arg=str(explicit_root), + ) == explicit_root / "registry.global.json" + with pytest.raises(registry_admin.DshBindingAuthorityError) as ambiguous: + registry_admin.dsh_binding_global_registry( + registry_path=project_registry, + runtime_root_arg=None, + ) + assert ambiguous.value.error_kind == "binding_home_unavailable" + with pytest.raises(registry_admin.DshBindingAuthorityError) as missing: + registry_admin.dsh_binding_global_registry( + registry_path=tmp_path / "missing" / ".loopx" / "registry.json", + runtime_root_arg=None, + ) + assert missing.value.error_kind == "binding_home_unavailable" + + def test_require_new_registration_is_atomic_under_concurrency( tmp_path: Path, monkeypatch, @@ -94,13 +192,519 @@ def register() -> dict[str, object]: assert len(successes) == 1, results assert successes[0]["changed"] is True assert successes[0]["written"] is True + assert successes[0]["partial_write"] is False + assert successes[0]["global_sync"]["ok"] is True + assert successes[0]["global_sync"]["phase"] == "commit" assert successes[0]["registration_readback"]["verified"] is True + assert successes[0]["registration_readback"]["requested_agents"] == [ + "codex-fresh" + ] + assert "codex-fresh" in successes[0]["registration_readback"][ + "source_registered_agents" + ] + assert "codex-fresh" in successes[0]["registration_readback"][ + "global_registered_agents" + ] assert len(collisions) == 1, results assert collisions[0]["changed"] is False assert collisions[0]["written"] is False + assert collisions[0]["partial_write"] is False source_goal = json.loads(source_registry.read_text(encoding="utf-8"))["goals"][0] assert source_goal["coordination"]["registered_agents"] == [ "codex-existing", "codex-fresh", ] + + +def test_registration_sync_integrity_is_preflighted_before_source_write( + tmp_path: Path, + capsys, +) -> None: + runtime_root, source_registry, global_registry = _fixture(tmp_path) + source_payload = json.loads(source_registry.read_text(encoding="utf-8")) + source_payload["goals"][0]["project_id"] = GOAL_ID + _write_json(source_registry, source_payload) + global_before = global_registry.read_text(encoding="utf-8") + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "register-agent", + "--goal-id", + GOAL_ID, + "--agent-id", + "dsh-preflight-fixture", + "--require-new", + "--execute", + ] + ) == 1 + result = json.loads(capsys.readouterr().out) + + assert result["schema_version"] == "loopx_register_agent_v0" + assert result["ok"] is False + assert result["error_kind"] == "agent_registration_sync_preflight_failed" + assert result["changed"] is False + assert result["written"] is False + assert result["partial_write"] is False + assert result["global_sync"]["phase"] == "preflight" + assert result["registration_readback"] == { + "schema_version": "loopx_agent_registration_readback_v0", + "performed": False, + "verified": False, + } + source_after = json.loads(source_registry.read_text(encoding="utf-8")) + assert source_after["goals"][0]["coordination"]["registered_agents"] == [ + "codex-existing" + ] + assert global_registry.read_text(encoding="utf-8") == global_before + + +def test_post_source_sync_exception_preserves_partial_write_evidence( + tmp_path: Path, + monkeypatch, +) -> None: + runtime_root, source_registry, _global_registry = _fixture(tmp_path) + real_sync = registry_admin.sync_project_registry_to_global + + def fail_commit_sync(**kwargs): + if kwargs.get("dry_run") is True: + return real_sync(**kwargs) + raise RuntimeError("fixture sync failure") + + monkeypatch.setattr( + registry_admin, + "sync_project_registry_to_global", + fail_commit_sync, + ) + + result = registry_admin.register_agent_via_source_registry( + runtime_root_arg=str(runtime_root), + goal_id=GOAL_ID, + agent_ids=["dsh-partial-fixture"], + require_new=True, + execute=True, + ) + + assert result["ok"] is False + assert result["error_kind"] == "agent_registration_global_sync_failed" + assert result["changed"] is True + assert result["written"] is True + assert result["partial_write"] is True + assert result["global_sync"]["phase"] == "commit" + assert result["registration_readback"]["performed"] is False + source_goal = json.loads(source_registry.read_text(encoding="utf-8"))["goals"][0] + assert source_goal["coordination"]["registered_agents"] == [ + "codex-existing", + "dsh-partial-fixture", + ] + + +def test_commit_sync_rejection_preserves_partial_write_and_readback_evidence( + tmp_path: Path, + monkeypatch, +) -> None: + runtime_root, source_registry, global_registry = _fixture(tmp_path) + real_sync = registry_admin.sync_project_registry_to_global + global_before = global_registry.read_text(encoding="utf-8") + + def reject_commit_sync(**kwargs): + if kwargs.get("dry_run") is True: + return real_sync(**kwargs) + return { + "ok": False, + "wrote": False, + "error_kind": "global_registry_sync_failed", + "error": "fixture commit sync rejection", + } + + monkeypatch.setattr( + registry_admin, + "sync_project_registry_to_global", + reject_commit_sync, + ) + + result = registry_admin.register_agent_via_source_registry( + runtime_root_arg=str(runtime_root), + goal_id=GOAL_ID, + agent_ids=["dsh-returned-failure-fixture"], + require_new=True, + execute=True, + ) + + assert result["ok"] is False + assert result["error_kind"] == "global_registry_sync_failed" + assert result["changed"] is True + assert result["written"] is True + assert result["partial_write"] is True + assert result["global_sync"]["phase"] == "commit" + assert result["registration_readback"]["performed"] is True + assert result["registration_readback"]["verified"] is False + source_goal = json.loads(source_registry.read_text(encoding="utf-8"))["goals"][0] + assert source_goal["coordination"]["registered_agents"] == [ + "codex-existing", + "dsh-returned-failure-fixture", + ] + assert global_registry.read_text(encoding="utf-8") == global_before + + +def test_successful_sync_claim_still_requires_exact_registration_readback( + tmp_path: Path, + monkeypatch, +) -> None: + runtime_root, source_registry, global_registry = _fixture(tmp_path) + real_sync = registry_admin.sync_project_registry_to_global + global_before = global_registry.read_text(encoding="utf-8") + + def claim_commit_without_write(**kwargs): + if kwargs.get("dry_run") is True: + return real_sync(**kwargs) + return {"ok": True, "wrote": False} + + monkeypatch.setattr( + registry_admin, + "sync_project_registry_to_global", + claim_commit_without_write, + ) + + result = registry_admin.register_agent_via_source_registry( + runtime_root_arg=str(runtime_root), + goal_id=GOAL_ID, + agent_ids=["dsh-readback-mismatch-fixture"], + require_new=True, + execute=True, + ) + + assert result["ok"] is False + assert result["error_kind"] == "agent_registration_readback_failed" + assert result["changed"] is True + assert result["written"] is True + assert result["partial_write"] is True + assert result["global_sync"] == {"ok": True, "wrote": False, "phase": "commit"} + assert result["registration_readback"]["performed"] is True + assert result["registration_readback"]["verified"] is False + assert result["registration_readback"]["source_registered_agents"] == [ + "codex-existing", + "dsh-readback-mismatch-fixture", + ] + assert result["registration_readback"]["global_registered_agents"] == [ + "codex-existing" + ] + assert global_registry.read_text(encoding="utf-8") == global_before + + +def test_non_fresh_registration_remains_an_idempotent_verified_noop( + tmp_path: Path, +) -> None: + runtime_root, _source_registry, _global_registry = _fixture(tmp_path) + + result = registry_admin.register_agent_via_source_registry( + runtime_root_arg=str(runtime_root), + goal_id=GOAL_ID, + agent_ids=["codex-existing"], + require_new=False, + execute=True, + ) + + assert result["ok"] is True + assert result["changed"] is False + assert result["written"] is False + assert result["partial_write"] is False + assert result["global_sync"]["ok"] is True + assert result["registration_readback"]["verified"] is True + + +def test_agent_and_thread_mutation_cli_envelopes_are_versioned( + tmp_path: Path, + capsys, +) -> None: + runtime_root, _source_registry, _global_registry = _fixture(tmp_path) + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "register-agent", + "--goal-id", + GOAL_ID, + "--agent-id", + "dsh-native-fixture", + "--require-new", + "--execute", + ] + ) == 0 + registered = json.loads(capsys.readouterr().out) + assert registered["schema_version"] == "loopx_register_agent_v0" + assert registered["registration_readback"]["verified"] is True + + for command, expected_status in ( + ("bind-agent-thread", "bound"), + ("unbind-agent-thread", "missing"), + ): + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + command, + "--goal-id", + GOAL_ID, + "--thread-id", + "dsh-session-fixture", + "--host-surface", + "dsh-native", + "--agent-id", + "dsh-native-fixture", + "--execute", + ] + ) == 0 + payload = json.loads(capsys.readouterr().out) + assert ( + payload["schema_version"] + == "loopx_thread_agent_binding_command_v0" + ) + assert payload["host_surface"] == "deepseek-harness-native" + assert payload["binding"]["status"] == expected_status + + +def test_dsh_thread_binding_cli_uses_the_strict_global_v1_contract( + tmp_path: Path, + capsys, +) -> None: + runtime_root, source_registry, global_registry = _fixture(tmp_path) + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "bind-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + "dsh-session-v1", + "--goal-id", + GOAL_ID, + "--agent-id", + "codex-existing", + "--expected-revision", + "0", + "--execute", + ] + ) == 0 + bound = json.loads(capsys.readouterr().out) + expected_binding = { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": "dsh", + "thread_id": "dsh-session-v1", + "revision": 1, + "state": "bound", + "target": {"goal_id": GOAL_ID, "agent_id": "codex-existing"}, + } + assert bound == { + "schema_version": "loopx_host_thread_binding_command_v1", + "ok": True, + "changed": True, + "application": "yes", + "binding": expected_binding, + } + assert "thread_agent_bindings" not in json.loads( + source_registry.read_text(encoding="utf-8") + )["goals"][0]["coordination"] + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "resolve-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + "dsh-session-v1", + ] + ) == 0 + resolved = json.loads(capsys.readouterr().out) + assert resolved == { + "schema_version": "loopx_host_thread_binding_command_v1", + "ok": True, + "changed": False, + "application": "no", + "binding": expected_binding, + } + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "unbind-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + "dsh-session-v1", + "--expected-revision", + "1", + "--execute", + ] + ) == 0 + unbound = json.loads(capsys.readouterr().out) + assert unbound == { + "schema_version": "loopx_host_thread_binding_command_v1", + "ok": True, + "changed": True, + "application": "yes", + "binding": { + "schema_version": "loopx_host_thread_binding_v1", + "host_surface": "dsh", + "thread_id": "dsh-session-v1", + "revision": 2, + "state": "unbound", + }, + } + stored = json.loads(global_registry.read_text(encoding="utf-8")) + assert stored["dsh_host_thread_bindings"]["records"]["dsh-session-v1"] == unbound[ + "binding" + ] + + +def test_dsh_cli_requires_cas_and_does_not_leak_binding_home( + tmp_path: Path, + capsys, +) -> None: + runtime_root, _source_registry, _global_registry = _fixture(tmp_path) + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "bind-agent-thread", + "--host-surface", + "dsh", + "--thread-id", + "dsh-session-no-cas", + "--goal-id", + GOAL_ID, + "--agent-id", + "codex-existing", + "--execute", + ] + ) == 1 + rejected = json.loads(capsys.readouterr().out) + assert rejected == { + "schema_version": "loopx_host_thread_binding_command_v1", + "ok": False, + "changed": False, + "application": "no", + "error_kind": "invalid_target", + } + assert str(runtime_root) not in json.dumps(rejected) + + +def test_fresh_registration_survives_a_failed_dsh_binding_cas(tmp_path: Path) -> None: + runtime_root, source_registry, global_registry = _fixture(tmp_path) + first = registry_admin.bind_dsh_thread_agent_in_global_registry( + global_path=global_registry, + host_surface="dsh", + thread_id="dsh-session-registration", + goal_id=GOAL_ID, + agent_id="codex-existing", + expected_revision=0, + execute=True, + ) + assert first["ok"] is True + + registered = registry_admin.register_agent_via_source_registry( + runtime_root_arg=str(runtime_root), + goal_id=GOAL_ID, + agent_ids=["dsh-fresh-unbound"], + require_new=True, + execute=True, + ) + assert registered["registration_readback"]["verified"] is True + rejected = registry_admin.bind_dsh_thread_agent_in_global_registry( + global_path=global_registry, + host_surface="dsh", + thread_id="dsh-session-registration", + goal_id=GOAL_ID, + agent_id="dsh-fresh-unbound", + expected_revision=0, + execute=True, + ) + assert rejected["error_kind"] == "revision_conflict" + assert rejected["binding"] == first["binding"] + + for path in (source_registry, global_registry): + goal = json.loads(path.read_text(encoding="utf-8"))["goals"][0] + assert "dsh-fresh-unbound" in goal["coordination"]["registered_agents"] + assert "thread_agent_bindings" not in json.loads( + source_registry.read_text(encoding="utf-8") + )["goals"][0]["coordination"] + + +def test_thread_binding_write_denial_keeps_versioned_failure_envelope( + tmp_path: Path, + monkeypatch, + capsys, +) -> None: + runtime_root, source_registry, _global_registry = _fixture(tmp_path) + source_before = source_registry.read_bytes() + + monkeypatch.setattr( + registry_admin, + "probe_registry_write_path", + lambda _path, *, create_parent: { + "ok": False, + "create_parent": create_parent, + "recommended_action": "repair fixture permissions", + }, + ) + + assert main( + [ + "--format", + "json", + "--runtime-root", + str(runtime_root), + "bind-agent-thread", + "--goal-id", + GOAL_ID, + "--thread-id", + "dsh-session-write-denied", + "--host-surface", + "dsh-native", + "--agent-id", + "codex-existing", + "--execute", + ] + ) == 1 + payload = json.loads(capsys.readouterr().out) + + assert payload == { + "schema_version": "loopx_thread_agent_binding_command_v0", + "ok": False, + "dry_run": False, + "execute": True, + "goal_id": GOAL_ID, + "changed": False, + "written": False, + "error_kind": "global_registry_write_denied", + "global_registry_writability": { + "ok": False, + "create_parent": True, + "recommended_action": "repair fixture permissions", + }, + "recommended_action": "repair fixture permissions", + } + assert source_registry.read_bytes() == source_before diff --git a/tests/test_slash_command_install.py b/tests/test_slash_command_install.py index 7b300b820..73146fff5 100644 --- a/tests/test_slash_command_install.py +++ b/tests/test_slash_command_install.py @@ -46,6 +46,7 @@ def test_host_materialization_installs_generated_loopx_entry_skill( } assert 'name: "loopx"' in skill_text assert "ark-managed-agent" in skill_text + assert "deepseek-harness-native" in skill_text assert "--slash-command-arguments" in skill_text assert "The CLI, not the model, owns parsing" in skill_text assert "Never split or recompose" in skill_text @@ -115,6 +116,7 @@ def test_codex_install_upgrades_managed_loopx_facade(tmp_path: Path) -> None: assert "--host-surface " in skill_text assert "Identify the exact current host surface" in skill_text assert "ark-managed-agent" in skill_text + assert "deepseek-harness-native" in skill_text assert "`ordered_steps` and `goal_start_contract` as authoritative" in skill_text assert "use `codex-ide` for the IDE" not in skill_text assert "surface the exact pasteable gate" in skill_text diff --git a/tests/test_thread_agent_binding.py b/tests/test_thread_agent_binding.py index 8e8d41638..42edc3afa 100644 --- a/tests/test_thread_agent_binding.py +++ b/tests/test_thread_agent_binding.py @@ -6,9 +6,17 @@ import pytest from loopx.thread_agent_binding import ( + DSH_BINDING_COLLECTION_KEY, + DSH_BINDING_COLLECTION_SCHEMA_VERSION, + HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + HOST_THREAD_BINDING_SCHEMA_VERSION, + JAVASCRIPT_SAFE_INTEGER_MAX, + bind_dsh_thread_agent_in_global_registry, bind_thread_agent_in_registry, normalize_thread_id, + resolve_dsh_thread_agent_binding, resolve_thread_agent_binding, + unbind_dsh_thread_agent_in_global_registry, unbind_thread_agent_in_registry, ) @@ -34,6 +42,58 @@ def _registry(tmp_path: Path, agents: list[str]) -> Path: return path +def _dsh_authority( + tmp_path: Path, + agents: list[str] | None = None, +) -> tuple[Path, Path]: + agents = agents or ["agent-a", "agent-b"] + project = tmp_path / "project" + source = project / ".loopx" / "registry.json" + global_path = tmp_path / "runtime" / "registry.global.json" + source.parent.mkdir(parents=True) + global_path.parent.mkdir(parents=True) + goal = { + "id": "goal", + "repo": str(project), + "state_file": ".codex/goals/goal/ACTIVE_GOAL_STATE.md", + "coordination": {"registered_agents": agents}, + } + source.write_text( + json.dumps({"schema_version": "0.1", "goals": [goal]}) + "\n", + encoding="utf-8", + ) + global_goal = {**goal, "source_registry": str(source)} + global_path.write_text( + json.dumps( + { + "schema_version": "0.1", + "registry_role": "global-local", + "goals": [global_goal], + } + ) + + "\n", + encoding="utf-8", + ) + return source, global_path + + +def _bound_v1( + *, + thread_id: str, + revision: int, + goal_id: str = "goal", + agent_id: str = "agent-a", +) -> dict[str, object]: + return { + "schema_version": HOST_THREAD_BINDING_SCHEMA_VERSION, + "host_surface": "dsh", + "thread_id": thread_id, + "revision": revision, + "state": "bound", + "target": {"goal_id": goal_id, "agent_id": agent_id}, + } + + def test_thread_id_is_bounded_and_opaque() -> None: assert normalize_thread_id(" thread-1 ") == "thread-1" assert normalize_thread_id(None) is None @@ -70,6 +130,64 @@ def test_binding_lookup_is_fail_closed_without_thread_id() -> None: ) +def test_dsh_native_alias_shares_one_canonical_thread_binding(tmp_path: Path) -> None: + path = _registry(tmp_path, ["agent-a"]) + result = bind_thread_agent_in_registry( + registry_path=path, + goal_id="goal", + host_surface="dsh-native", + thread_id="session-a", + agent_id="agent-a", + execute=True, + ) + + assert result["host_surface"] == "deepseek-harness-native" + goal = json.loads(path.read_text(encoding="utf-8"))["goals"][0] + canonical = resolve_thread_agent_binding( + goal, + host_surface="deepseek-harness-native", + thread_id="session-a", + ) + shorthand = resolve_thread_agent_binding( + goal, + host_surface="dsh-native", + thread_id="session-a", + ) + assert canonical["status"] == "bound" + assert canonical["agent_id"] == "agent-a" + assert shorthand == canonical + + +def test_external_dsh_aliases_share_the_existing_canonical_thread_binding( + tmp_path: Path, +) -> None: + path = _registry(tmp_path, ["agent-a"]) + result = bind_thread_agent_in_registry( + registry_path=path, + goal_id="goal", + host_surface="dsh", + thread_id="session-external", + agent_id="agent-a", + execute=True, + ) + + assert result["host_surface"] == "deepseek-harness" + goal = json.loads(path.read_text(encoding="utf-8"))["goals"][0] + for spelling in ( + "deepseek-harness", + "deepseek_harness", + "deepseek harness", + "dsh", + ): + resolved = resolve_thread_agent_binding( + goal, + host_surface=spelling, + thread_id="session-external", + ) + assert resolved["status"] == "bound" + assert resolved["agent_id"] == "agent-a" + + def test_binding_is_idempotent_and_conflicts_fail_closed(tmp_path: Path) -> None: path = _registry(tmp_path, ["agent-a", "agent-b"]) first = bind_thread_agent_in_registry( @@ -219,3 +337,323 @@ def test_unbind_is_idempotent_and_expected_agent_mismatch_fails_closed( assert missing["ok"] is True assert missing["changed"] is False assert path.read_bytes() == before + + +def test_dsh_v1_first_bind_freezes_wire_shape_and_does_not_write_goal_local_copy( + tmp_path: Path, +) -> None: + source, global_path = _dsh_authority(tmp_path) + expected_binding = _bound_v1(thread_id="session-a", revision=1) + legacy_binding = { + "thread_id": "session-a", + "host_surface": "deepseek-harness", + "agent_id": "agent-b", + } + for path in (source, global_path): + payload = json.loads(path.read_text(encoding="utf-8")) + payload["goals"][0]["coordination"]["thread_agent_bindings"] = [ + legacy_binding + ] + path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + + result = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=0, + execute=True, + ) + + assert result == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": True, + "changed": True, + "application": "yes", + "binding": expected_binding, + } + global_payload = json.loads(global_path.read_text(encoding="utf-8")) + assert global_payload[DSH_BINDING_COLLECTION_KEY] == { + "schema_version": DSH_BINDING_COLLECTION_SCHEMA_VERSION, + "records": {"session-a": expected_binding}, + } + source_goal = json.loads(source.read_text(encoding="utf-8"))["goals"][0] + assert source_goal["coordination"]["thread_agent_bindings"] == [legacy_binding] + assert global_payload["goals"][0]["coordination"]["thread_agent_bindings"] == [ + legacy_binding + ] + + +def test_dsh_v1_cas_precedes_idempotence_and_current_cas_is_no_write( + tmp_path: Path, +) -> None: + _source, global_path = _dsh_authority(tmp_path) + first = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=0, + execute=True, + ) + assert first["ok"] is True + before = global_path.read_bytes() + + stale = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=0, + execute=True, + ) + assert stale == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": False, + "changed": False, + "application": "no", + "error_kind": "revision_conflict", + "binding": _bound_v1(thread_id="session-a", revision=1), + } + assert global_path.read_bytes() == before + + idempotent = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=1, + execute=True, + ) + assert idempotent == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": True, + "changed": False, + "application": "no", + "binding": _bound_v1(thread_id="session-a", revision=1), + } + assert global_path.read_bytes() == before + + +def test_dsh_v1_switch_unbind_and_same_target_rebind_advance_one_revision( + tmp_path: Path, +) -> None: + source, global_path = _dsh_authority(tmp_path) + for path in (source, global_path): + payload = json.loads(path.read_text(encoding="utf-8")) + second_goal = { + **payload["goals"][0], + "id": "goal-b", + "state_file": ".codex/goals/goal-b/ACTIVE_GOAL_STATE.md", + } + payload["goals"].append(second_goal) + path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + assert bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=0, + execute=True, + )["ok"] is True + + switched = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal-b", + agent_id="agent-a", + expected_revision=1, + execute=True, + ) + assert switched["binding"] == _bound_v1( + thread_id="session-a", + revision=2, + goal_id="goal-b", + ) + assert switched["changed"] is True + stored_after_switch = json.loads(global_path.read_text(encoding="utf-8"))[ + DSH_BINDING_COLLECTION_KEY + ]["records"]["session-a"] + assert stored_after_switch == switched["binding"] + + unbound = unbind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + expected_revision=2, + execute=True, + ) + tombstone = { + "schema_version": HOST_THREAD_BINDING_SCHEMA_VERSION, + "host_surface": "dsh", + "thread_id": "session-a", + "revision": 3, + "state": "unbound", + } + assert unbound == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": True, + "changed": True, + "application": "yes", + "binding": tombstone, + } + assert resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + )["binding"] == tombstone + + rebound = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=3, + execute=True, + ) + assert rebound["binding"] == _bound_v1(thread_id="session-a", revision=4) + + +def test_dsh_v1_resolve_failures_are_bounded_and_fail_closed(tmp_path: Path) -> None: + _source, global_path = _dsh_authority(tmp_path) + invalid_surface = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="DSH", + thread_id="session-a", + ) + assert invalid_surface["error_kind"] == "invalid_target" + missing_home = resolve_dsh_thread_agent_binding( + global_path=tmp_path / "missing" / "registry.global.json", + host_surface="dsh", + thread_id="session-a", + ) + assert missing_home == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": False, + "changed": False, + "application": "no", + "error_kind": "binding_home_unavailable", + } + uninitialized = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + ) + assert uninitialized["error_kind"] == "binding_home_uninitialized" + + payload = json.loads(global_path.read_text(encoding="utf-8")) + payload[DSH_BINDING_COLLECTION_KEY] = { + "schema_version": DSH_BINDING_COLLECTION_SCHEMA_VERSION, + "records": {}, + } + global_path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + not_found = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + ) + assert not_found["error_kind"] == "binding_not_found" + + payload[DSH_BINDING_COLLECTION_KEY]["unexpected"] = True + global_path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + corrupt = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + ) + assert corrupt == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": False, + "changed": False, + "application": "no", + "error_kind": "authority_corrupt", + } + + malformed = _bound_v1(thread_id="session-a", revision=1) + malformed["revision"] = True + payload[DSH_BINDING_COLLECTION_KEY] = { + "schema_version": DSH_BINDING_COLLECTION_SCHEMA_VERSION, + "records": {"session-a": malformed}, + } + global_path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + assert resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + )["error_kind"] == "authority_corrupt" + + +def test_dsh_v1_exact_unbind_allows_dangling_target(tmp_path: Path) -> None: + source, global_path = _dsh_authority(tmp_path) + assert bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-a", + expected_revision=0, + execute=True, + )["ok"] is True + source_payload = json.loads(source.read_text(encoding="utf-8")) + source_payload["goals"][0]["coordination"]["registered_agents"] = ["agent-b"] + source.write_text(json.dumps(source_payload) + "\n", encoding="utf-8") + + unhealthy = resolve_dsh_thread_agent_binding( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + ) + assert unhealthy["error_kind"] == "authority_unhealthy" + assert unhealthy["binding"] == _bound_v1(thread_id="session-a", revision=1) + + unbound = unbind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + expected_revision=1, + execute=True, + ) + assert unbound["ok"] is True + assert unbound["binding"]["state"] == "unbound" + assert unbound["binding"]["revision"] == 2 + + +def test_dsh_v1_revision_overflow_is_typed_and_does_not_write(tmp_path: Path) -> None: + _source, global_path = _dsh_authority(tmp_path) + payload = json.loads(global_path.read_text(encoding="utf-8")) + binding = _bound_v1( + thread_id="session-a", + revision=JAVASCRIPT_SAFE_INTEGER_MAX, + ) + payload[DSH_BINDING_COLLECTION_KEY] = { + "schema_version": DSH_BINDING_COLLECTION_SCHEMA_VERSION, + "records": {"session-a": binding}, + } + global_path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + before = global_path.read_bytes() + + exhausted = bind_dsh_thread_agent_in_global_registry( + global_path=global_path, + host_surface="dsh", + thread_id="session-a", + goal_id="goal", + agent_id="agent-b", + expected_revision=JAVASCRIPT_SAFE_INTEGER_MAX, + execute=True, + ) + assert exhausted == { + "schema_version": HOST_THREAD_BINDING_COMMAND_SCHEMA_VERSION, + "ok": False, + "changed": False, + "application": "no", + "error_kind": "authority_exhausted", + "binding": binding, + } + assert global_path.read_bytes() == before