dsh-agent-plugins-market 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +29 -24
  2. package/README.zh.md +29 -24
  3. package/client/client.js +1172 -159
  4. package/client/client.js.map +1 -1
  5. package/lib/application/catalog.js +14 -2
  6. package/lib/application/install-store.js +1 -1
  7. package/lib/application/mcp-service.js +185 -30
  8. package/lib/catalog/archive.js +15 -0
  9. package/lib/catalog/manifests.js +124 -13
  10. package/lib/catalog/scan-resolvers.js +117 -12
  11. package/lib/catalog/surfaces.js +73 -27
  12. package/lib/catalog/validate.js +205 -54
  13. package/lib/contracts/market.js +2 -0
  14. package/lib/index.js +6 -2
  15. package/lib/model/layouts.js +34 -0
  16. package/lib/model/preset-source.js +8 -0
  17. package/lib/routes.js +31 -2
  18. package/lib/runtime/agent-role-router.js +176 -51
  19. package/lib/runtime/host-locale.js +6 -12
  20. package/lib/runtime/mcp-client/connection.js +3 -2
  21. package/lib/runtime/mcp-client/oauth.js +82 -14
  22. package/lib/runtime/mcp-client/tools.js +2 -1
  23. package/lib/runtime/mcp-config.js +178 -34
  24. package/lib/runtime/mcp-direct-config.js +49 -6
  25. package/lib/runtime/mcp-mounts.js +15 -3
  26. package/lib/runtime/mcp-overrides.js +131 -1
  27. package/lib/runtime/mcp-redaction.js +8 -0
  28. package/lib/runtime/mcp-status.js +21 -5
  29. package/lib/runtime/server-config.js +49 -8
  30. package/lib/runtime/subagent-catalog.js +62 -22
  31. package/lib/runtime/tool-registry-observer.js +8 -4
  32. package/lib/types/application/catalog.d.ts +10 -1
  33. package/lib/types/application/install-store.d.ts +1 -1
  34. package/lib/types/application/mcp-service.d.ts +32 -3
  35. package/lib/types/application/queries.d.ts +6 -1
  36. package/lib/types/catalog/manifests.d.ts +6 -2
  37. package/lib/types/catalog/surfaces.d.ts +14 -4
  38. package/lib/types/catalog/validate.d.ts +72 -11
  39. package/lib/types/contracts/market.d.ts +67 -0
  40. package/lib/types/contracts/mcp-status.d.ts +11 -0
  41. package/lib/types/model/layouts.d.ts +20 -0
  42. package/lib/types/model/preset-source.d.ts +18 -0
  43. package/lib/types/model/types.d.ts +37 -1
  44. package/lib/types/runtime/agent-role-router.d.ts +90 -16
  45. package/lib/types/runtime/host-locale.d.ts +1 -1
  46. package/lib/types/runtime/mcp-client/oauth.d.ts +4 -0
  47. package/lib/types/runtime/mcp-config.d.ts +75 -13
  48. package/lib/types/runtime/mcp-direct-config.d.ts +22 -0
  49. package/lib/types/runtime/mcp-overrides.d.ts +44 -0
  50. package/lib/types/runtime/mcp-redaction.d.ts +6 -0
  51. package/lib/types/runtime/server-config.d.ts +26 -1
  52. package/lib/types/runtime/subagent-catalog.d.ts +14 -2
  53. package/lib/types/runtime/tool-registry-observer.d.ts +5 -3
  54. package/package.json +8 -8
  55. package/schemas/1.0.0/mcp.schema.json +0 -22
  56. package/schemas/1.1.0/mcp.schema.json +120 -0
  57. package/schemas/1.1.0/plugin.schema.json +65 -0
  58. package/schemas/README.md +25 -19
  59. package/schemas/agent-plugins/spec.md +23 -9
  60. package/schemas/com.deepseek.harness/namespace.schema.json +42 -0
  61. package/schemas/com.deepseek.harness/spec.md +52 -0
@@ -6,6 +6,7 @@ export declare const MARKET_ROUTES: {
6
6
  readonly overview: "/api/agent-plugins/overview";
7
7
  readonly mcpStatus: "/api/agent-plugins/mcp-status";
8
8
  readonly addMcpServer: "/api/agent-plugins/mcp-servers/add";
9
+ readonly importMcpServers: "/api/agent-plugins/mcp-servers/import";
9
10
  readonly lspStatus: "/api/agent-plugins/lsp-status";
10
11
  readonly lspServers: "/api/agent-plugins/lsp-servers";
11
12
  readonly addLspServer: "/api/agent-plugins/lsp-servers/add";
@@ -29,18 +30,81 @@ export declare const MARKET_ROUTES: {
29
30
  readonly mcpOverrides: "/api/agent-plugins/mcp-overrides";
30
31
  readonly setMcpOverride: "/api/agent-plugins/set-mcp-override";
31
32
  readonly setMcpServerEnabled: "/api/agent-plugins/set-mcp-server-enabled";
33
+ readonly setMcpServerTool: "/api/agent-plugins/set-mcp-server-tool";
32
34
  readonly mcpRetry: "/api/agent-plugins/mcp-retry";
33
35
  readonly mcpReauthorize: "/api/agent-plugins/mcp-reauthorize";
34
36
  readonly mcpBackend: "/api/agent-plugins/mcp-backend";
35
37
  readonly setMcpBackend: "/api/agent-plugins/set-mcp-backend";
36
38
  readonly userPanel: "/api/agent-plugins/user-panel";
37
39
  };
40
+ /** One timeout's three layers: the user's value, the suite declaration, and the value in force. */
41
+ export interface ServerTimeoutPolicy {
42
+ /** The user's stored value; null when the user inherits. */
43
+ user: number | null;
44
+ /** The suite's declared value; null when the suite declares none. */
45
+ suite: number | null;
46
+ /** The value in force. */
47
+ effective: number;
48
+ /** Which layer supplied `effective`. */
49
+ source: 'user' | 'suite' | 'default';
50
+ }
51
+ /** One tool list's layers: what the user stored and what the suite declares. */
52
+ export interface ServerToolPolicy {
53
+ /** The user's stored list; null when the user set none. */
54
+ user: string[] | null;
55
+ /** The suite's declared list; null when the suite declares none. */
56
+ suite: string[] | null;
57
+ /** The list in force. */
58
+ effective: string[];
59
+ }
60
+ /** The OAuth opt-in's two layers. */
61
+ export interface ServerAuthPolicy {
62
+ /** The user's stored value; null when the user set none. */
63
+ user: boolean | null;
64
+ /** The suite's declared value; null when the suite declares none. */
65
+ suite: boolean | null;
66
+ /** The value in force. */
67
+ effective: boolean;
68
+ }
69
+ /** The MCP per-server client policy as the service editor renders it. */
70
+ export interface ServerPolicyPayload {
71
+ /** Per-tool-call timeout. */
72
+ toolCallTimeout: ServerTimeoutPolicy;
73
+ /** Startup timeout. */
74
+ startupTimeout: ServerTimeoutPolicy;
75
+ /** The tools the service denies. */
76
+ deniedTools: ServerToolPolicy;
77
+ /** The OAuth opt-in. */
78
+ auth: ServerAuthPolicy;
79
+ }
38
80
  /** Editable service configuration; masked values are preserved when unchanged. */
39
81
  export interface ServerConfigPayload {
40
82
  kind: 'mcp' | 'lsp';
41
83
  id: string;
84
+ /** The declaration key this service carries, used to compose the document view. */
85
+ key: string;
42
86
  editable: boolean;
43
87
  config: Record<string, unknown>;
88
+ /** The stored policy and the suite declaration behind it; present for MCP services. */
89
+ policy?: ServerPolicyPayload;
90
+ /** The MCP mount backend; `host` cannot enforce startup timeouts or tool filters. */
91
+ backend?: 'builtin' | 'host';
92
+ }
93
+ /** The policy a service-config save sets (`number`/value) or clears back to inheritance (`null`). */
94
+ export interface ServerPolicyRequest {
95
+ toolCallTimeoutMs?: number | null;
96
+ startupTimeoutMs?: number | null;
97
+ /** The user's deny list; null clears it. The suite's own entries stay in force. */
98
+ disabledTools?: string[] | null;
99
+ /** The user's OAuth opt-in; null clears it back to the suite's declaration. */
100
+ auth?: {
101
+ enabled: boolean;
102
+ } | null;
103
+ }
104
+ /** One rejected value as the API reports it: the field it belongs to and why. */
105
+ export interface MarketFieldError {
106
+ field: string;
107
+ message: string;
44
108
  }
45
109
  /** Public model identities and exact-model reasoning options; never provider configuration. */
46
110
  export interface ModelCatalogPayload {
@@ -135,6 +199,9 @@ export type McpServerOverrideWire = {
135
199
  headers?: Record<string, string>;
136
200
  env?: Record<string, string>;
137
201
  args?: string[];
202
+ toolCallTimeoutMs?: number;
203
+ startupTimeoutMs?: number;
204
+ disabledTools?: string[];
138
205
  };
139
206
  /** Overrides for one suite keyed by mcp.json server key. */
140
207
  export type McpSuiteOverridesWire = Record<string, McpServerOverrideWire>;
@@ -3,6 +3,8 @@
3
3
  export interface McpStatusTool {
4
4
  name: string;
5
5
  description?: string;
6
+ /** The advertised input schema, kept only while it stays small enough to transport; absent otherwise. */
7
+ parameters?: unknown;
6
8
  }
7
9
  /** Whether an MCP row comes from a suite or direct host observation. */
8
10
  export type McpStatusKind = 'plugin' | 'direct';
@@ -39,6 +41,12 @@ export interface McpStatusEntry {
39
41
  * runs the OAuth flow when the server answers 401, which the redacted
40
42
  * configuration alone cannot show. */
41
43
  oauthDefault?: boolean;
44
+ /** Suite allow-list for this server's tools; absent when the suite narrows nothing. */
45
+ suiteEnabledTools?: string[];
46
+ /** Tools the suite's own declaration leaves out. */
47
+ suiteDisabledTools?: string[];
48
+ /** Tools the user turned off through the panel. */
49
+ userDisabledTools?: string[];
42
50
  }
43
51
  /** The MCP status response returned by the host. */
44
52
  export interface McpStatusPayload {
@@ -55,4 +63,7 @@ export interface McpStatusPayload {
55
63
  foreign: number;
56
64
  };
57
65
  directObservationOnly: boolean;
66
+ /** The mount backend the rows were observed under; `host` cannot enforce tool
67
+ * filters or startup timeouts, so the panel disables those controls. */
68
+ backend?: 'builtin' | 'host';
58
69
  }
@@ -39,6 +39,19 @@ export declare const PLUGIN_LAYOUTS: readonly [{
39
39
  export type ManifestKind = (typeof PLUGIN_LAYOUTS)[number]['kind'];
40
40
  /** Kimi Code's primary spelling precedes its compatibility spelling within that dialect. */
41
41
  export declare const MANIFEST_ALIASES: Partial<Record<ManifestKind, readonly string[]>>;
42
+ /**
43
+ * This client's Agent Plugins extension namespace (§8): manifest data rides
44
+ * `plugin.json` `extensions` under this key, and file-based extensions live
45
+ * in the top-level directory named exactly this. The namespace contract
46
+ * version is declared inside the manifest data.
47
+ */
48
+ export declare const EXTENSION_NAMESPACE = "com.deepseek.harness";
49
+ /** Namespace contract versions this manager implements. */
50
+ export declare const NAMESPACE_SCHEMA_VERSIONS: ReadonlySet<string>;
51
+ /** Namespace directory locations, relative to the plugin root. */
52
+ export declare const NAMESPACE_DIR = "com.deepseek.harness";
53
+ export declare const NAMESPACE_HOOKS_FILE: string;
54
+ export declare const NAMESPACE_LSP_FILE: string;
42
55
  /** Equivalent plugin-owned path variables; these never resolve as credentials. */
43
56
  export declare const PLUGIN_ROOT_VARIABLES: ReadonlySet<string>;
44
57
  export declare const PLUGIN_DATA_VARIABLES: ReadonlySet<string>;
@@ -110,3 +123,10 @@ export declare const PROJECT_LAYOUTS: readonly [{
110
123
  }];
111
124
  /** Marketplace catalogs follow manifest layout order; the shared root catalog is the fallback. */
112
125
  export declare const MARKETPLACE_PATHS: readonly string[];
126
+ /**
127
+ * Inline top-level manifest keys this manager reads for the portable v1
128
+ * dialect. The specification's closed manifest schema carries none of them
129
+ * (§5.2, §6.1), so under `agent-plugin-v1` they are reported as unknown
130
+ * top-level fields and ignored; every other dialect keeps reading them.
131
+ */
132
+ export declare const V1_IGNORED_MANIFEST_KEYS: readonly string[];
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The source record this plugin presets.
3
+ *
4
+ * The first-party collection lives in its own repository. The plugin ships one
5
+ * registration pointing at it, so a fresh install lists the repository without
6
+ * anyone pasting a URL; from there it is an ordinary Git source — refresh to
7
+ * clone, then install and toggle its suites. Nothing marks it as different, and
8
+ * no setting owns it.
9
+ *
10
+ * @module model/preset-source
11
+ */
12
+ import type { SourceRef } from './types.js';
13
+ /** Source id the preset record registers under. */
14
+ export declare const PRESET_SOURCE_ID = "dsh-agent-plugins";
15
+ /** Repository the preset record points at. */
16
+ export declare const PRESET_SOURCE_URL = "https://github.com/Sivan757/dsh-agent-plugins.git";
17
+ /** The preset registration, as the market stores it. */
18
+ export declare function presetSourceRef(): SourceRef;
@@ -67,6 +67,8 @@ export interface SuiteManifest {
67
67
  keywords?: string[];
68
68
  /** For agent-plugin-v1: the recognized `$schema` identifier. */
69
69
  schemaVersion?: string;
70
+ /** Parsed `com.deepseek.harness` extension data; present when the suite declares the namespace. */
71
+ harness?: HarnessNamespace;
70
72
  }
71
73
  /** Raw layout declarations are resolved once by the catalog into runtime resources. */
72
74
  export interface SuiteComponents {
@@ -110,6 +112,40 @@ export interface SuiteSurfaceCounts {
110
112
  agents: number;
111
113
  lsp: number;
112
114
  }
115
+ /**
116
+ * Client-specific manifest data under the `com.deepseek.harness` extension
117
+ * namespace (Agent Plugins §8.1), carried by `plugin.json` `extensions`.
118
+ */
119
+ export interface HarnessExtension {
120
+ /** Namespace contract version this suite was written against. */
121
+ schemaVersion: string;
122
+ /**
123
+ * Client policy for portable `mcp.json` servers, keyed by the server's own
124
+ * name in `mcp.json`; entries without a matching server are reported and
125
+ * ignored.
126
+ */
127
+ mcpServers?: Record<string, HarnessMcpPolicy>;
128
+ }
129
+ /**
130
+ * dsh-owned per-server policy for a portable MCP server: OAuth 2.1
131
+ * authorization for servers that answer `401` with a challenge, tool
132
+ * allow/deny lists, and timeout policies. These fields are outside the
133
+ * portable `mcp.json` schema by design (§7.2.1), so they ride the extension
134
+ * namespace instead of the package file.
135
+ */
136
+ export interface HarnessMcpPolicy extends McpServerPolicy {
137
+ /** Opt in to OAuth 2.1 authorization (on by default; `enabled: false` opts out). */
138
+ auth?: {
139
+ enabled: boolean;
140
+ scope?: string;
141
+ };
142
+ }
143
+ /** Parsed namespace extension data of one suite, with server names pre-matched. */
144
+ export interface HarnessNamespace {
145
+ schemaVersion: string;
146
+ /** Policy applied on top of the suite's portable MCP servers. */
147
+ mcpServers: Record<string, HarnessMcpPolicy>;
148
+ }
113
149
  /** agent-plugins.org v1 `mcp.json` server variants. */
114
150
  export interface McpServerPolicy {
115
151
  enabledTools?: string[];
@@ -128,7 +164,7 @@ export interface McpServerStreamableHttp extends McpServerPolicy {
128
164
  type: 'streamable-http';
129
165
  url: string;
130
166
  headers?: Record<string, string>;
131
- /** Opt in to OAuth 2.1 authorization for servers that answer `401` with a challenge (on by default; `enabled: false` opts out). */
167
+ /** OAuth 2.1 authorization; portable files take it from the namespace policy, dialect-native files declare it inline. */
132
168
  auth?: {
133
169
  enabled: boolean;
134
170
  scope?: string;
@@ -1,7 +1,6 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import { type SubagentCatalogEntry } from './subagent-catalog.js';
3
- import { type HostTranslate } from './host-locale.js';
4
- export declare const AGENT_ROLE_TOOL_NAME = "subagent_run";
3
+ export declare const AGENT_ROLE_TOOL_NAME = "subagent_role";
5
4
  /** Panel identity is preserved so identically named cards from different suites remain addressable. */
6
5
  export interface AgentRoleEntry {
7
6
  name: string;
@@ -45,6 +44,10 @@ export interface AgentRoleDelegation {
45
44
  persona: string;
46
45
  agentOptions?: AgentRoleOptions;
47
46
  }
47
+ /** A one-shot foreground run carries its own cancellation signal on the request. */
48
+ export interface AgentRoleRunRequest extends AgentRoleDelegation {
49
+ signal: AbortSignal;
50
+ }
48
51
  export interface AgentRoleHost {
49
52
  tools: {
50
53
  register(definition: unknown): () => void;
@@ -66,18 +69,59 @@ export interface AgentRoleHost {
66
69
  childId: string;
67
70
  messageId: string;
68
71
  }>;
72
+ /** One-shot foreground run: the host settles it and hands back the child's output. */
73
+ start(provider: string, request: AgentRoleRunRequest): Promise<AgentRoleRun>;
69
74
  };
70
75
  }
76
+ /**
77
+ * JSON value crossing the tool-result boundary. Declared locally so this plugin
78
+ * keeps its declared host surface: the registry performs the authoritative
79
+ * lossless snapshot of the child's content blocks on the way out.
80
+ */
81
+ export type AgentRoleJson = null | boolean | number | string | AgentRoleJson[] | {
82
+ [key: string]: AgentRoleJson;
83
+ };
84
+ /** One settled foreground role run; `result` resolves with the child's terminal output. */
85
+ export interface AgentRoleRun {
86
+ id: string;
87
+ result: Promise<{
88
+ output: unknown[];
89
+ stopReason: string;
90
+ diagnostic?: string;
91
+ }>;
92
+ dispose(): Promise<void>;
93
+ }
94
+ /** One tracked background role job as the host `jobs` registry sees it. */
95
+ export interface AgentRoleJob {
96
+ cancel(reason?: string): void;
97
+ done: Promise<{
98
+ status: string;
99
+ detail?: string;
100
+ }>;
101
+ }
102
+ /** The host `jobs` registry seam, reached through `ctx.get('jobs')`. */
103
+ export interface AgentRoleJobs {
104
+ start(spec: {
105
+ kind: string;
106
+ label: string;
107
+ owner?: unknown;
108
+ run(): AgentRoleJob;
109
+ }): string;
110
+ }
71
111
  /** Strict YAML parsing prevents malformed routing metadata from silently inheriting wider privileges. */
72
112
  export declare function parseAgentRole(text: string): AgentRolePolicy;
73
113
  /**
74
- * Resolve the child LLM options one card may contribute.
114
+ * Resolve the child LLM options for one role call.
75
115
  *
76
- * A card route is advisory. Only an exact `provider` plus `model` pair is
77
- * applied, and only when the live LLM runtime accepts it; every other
78
- * declaration — a bare id, a Claude alias, a lone `provider`, an unsupported
79
- * effort — degrades to inheriting the parent route and reports a diagnostic.
80
- * @param policy - the card's parsed routing metadata.
116
+ * The call's own `provider` + `model` pair wins, and the role card supplies the
117
+ * default when the call names neither. Only an exact pair is applied, and only
118
+ * when the live LLM runtime accepts it; a bare id, a Claude alias, a lone
119
+ * `provider` or an unsupported effort degrades to inheriting the parent route
120
+ * and reports a diagnostic. An explicit route with no explicit effort uses the
121
+ * selected model's default, so a card's effort never leaks onto a route it was
122
+ * not written for.
123
+ * @param policy - the card's parsed routing metadata, used as the default route.
124
+ * @param requested - the route the call itself asked for.
81
125
  * @param parent - the calling Agent whose route an unusable declaration falls back to.
82
126
  * @param llm - live LLM runtime owning provider, model and effort validation.
83
127
  * @param signal - tool-call cancellation signal.
@@ -85,18 +129,48 @@ export declare function parseAgentRole(text: string): AgentRolePolicy;
85
129
  * @param diagnose - diagnostic sink; degradation is reported, never silent.
86
130
  * @returns the options to send, or undefined for pure inheritance.
87
131
  */
88
- export declare function resolveAgentOptions(policy: AgentRolePolicy, parent: unknown, llm: AgentRoleHost['llm'], signal: AbortSignal, subject: string, diagnose: (message: string) => void): Promise<AgentRoleOptions | undefined>;
132
+ export declare function resolveAgentOptions(policy: AgentRolePolicy, requested: AgentRoleOptions, parent: unknown, llm: AgentRoleHost['llm'], signal: AbortSignal, subject: string, diagnose: (message: string) => void): Promise<AgentRoleOptions | undefined>;
89
133
  /** Stable summaries; invalid declarations are excluded and transient read failures abort publication. */
90
134
  export declare function agentRoleCatalog(entries: AgentRoleEntry[], signal: AbortSignal, diagnose?: (message: string) => void, projectDir?: string): Promise<SubagentCatalogEntry[]>;
91
135
  /** Read the same declaration for catalog summaries and execution, including inline resources. */
92
136
  export declare function readAgentRole(entry: AgentRoleEntry, projectDir?: string): Promise<AgentRolePolicy>;
93
137
  /**
94
- * Start one role child and return its durable id without waiting for the result.
95
- * Resume state, steering, and the settlement notice belong to the host's
96
- * continuation manager; this executor owns only role resolution.
138
+ * How one role call reaches a child, mirroring the host's own delegation tool.
139
+ *
140
+ * `continuable` is the default: the host establishes a durable child and this
141
+ * returns its id immediately, leaving resume state, steering and the settlement
142
+ * notice to the continuation manager. `foreground` starts a one-shot run and
143
+ * returns its report as this call's result, for a caller that needs the answer
144
+ * before its next action. `background` starts the same one-shot run as a tracked
145
+ * job, so the caller collects it later with `job_output` and can stop it with
146
+ * `job_kill` instead of holding the turn open.
97
147
  */
98
- export declare function executeAgentRole(host: AgentRoleHost, listRoles: (parent?: unknown) => Promise<AgentRoleEntry[]>, agentName: string, prompt: string, parent: unknown, signal: AbortSignal, diagnose?: (message: string) => void): Promise<{
148
+ export type AgentRoleRunMode = 'continuable' | 'background' | 'foreground';
149
+ /** One role call's outcome, discriminated so the tool can render each channel. */
150
+ export type AgentRoleResult = {
151
+ kind: 'continuable';
99
152
  subagentId: string;
100
- }>;
101
- /** Mount once after tools, llm and subagents are available; the returned disposer belongs to the plugin lifecycle. */
102
- export declare function mountAgentRoleTool(ctx: Context, listRoles: (parent?: unknown) => Promise<AgentRoleEntry[]>, t?: HostTranslate): () => void;
153
+ } | {
154
+ kind: 'background';
155
+ jobId: string;
156
+ } | {
157
+ kind: 'foreground';
158
+ runId: string;
159
+ output: AgentRoleJson[];
160
+ };
161
+ /**
162
+ * Run one role child through the requested channel.
163
+ * @param host - the exact live seams this executor owns: tools, llm and subagents.
164
+ * @param mode - which channel the call asked for.
165
+ * @param jobs - the host jobs registry; only the `background` channel needs it.
166
+ */
167
+ export declare function executeAgentRole(host: AgentRoleHost, listRoles: (parent?: unknown) => Promise<AgentRoleEntry[]>, agentName: string, prompt: string, parent: unknown, requestedRoute: AgentRoleOptions, mode: AgentRoleRunMode, signal: AbortSignal, diagnose?: (message: string) => void, jobs?: AgentRoleJobs): Promise<AgentRoleResult>;
168
+ /**
169
+ * Mount once after tools, llm and subagents are available; the returned disposer belongs to the plugin lifecycle.
170
+ *
171
+ * The delegation contract lives here rather than in the injected catalog: a tool
172
+ * description is present in every request, while the catalog message is
173
+ * re-published whenever roles change, so guidance kept out of the catalog is
174
+ * sent once and stays readable through compaction.
175
+ */
176
+ export declare function mountAgentRoleTool(ctx: Context, listRoles: (parent?: unknown) => Promise<AgentRoleEntry[]>): () => void;
@@ -1,5 +1,5 @@
1
1
  /** Host runtime dictionary keys (mirrored for zh and en). */
2
- export type HostLocaleKey = 'subagentCatalogIntro' | 'subagentCatalogUpdated' | 'subagentCatalogEmpty' | 'subagentCatalogCall' | 'commandAcknowledged' | 'userCommandSourceLabel' | 'feedbackToolCardTitle';
2
+ export type HostLocaleKey = 'commandAcknowledged' | 'userCommandSourceLabel' | 'feedbackToolCardTitle';
3
3
  export type HostTranslate = (key: HostLocaleKey, params?: Record<string, string>) => string;
4
4
  interface ResolvedLocale {
5
5
  t: HostTranslate;
@@ -63,6 +63,8 @@ export declare class LoopbackOAuthClientProvider implements OAuthClientProvider
63
63
  private providerState;
64
64
  /** The transport generation whose `finishAuth` completes the browser leg. */
65
65
  private activeTransport;
66
+ /** One process-local OAuth state value for the current browser leg. */
67
+ private expectedState;
66
68
  /** Resolves `true` when the leg saved tokens, `false` when it failed; undefined while no leg is open. */
67
69
  private browserLegSettled;
68
70
  private callbackServer;
@@ -73,6 +75,8 @@ export declare class LoopbackOAuthClientProvider implements OAuthClientProvider
73
75
  constructor(serverName: string, storage: OAuthStorageConfig, scope: string | undefined, log: (message: string) => void, store: unknown, opener?: BrowserOpener);
74
76
  get redirectUrl(): string;
75
77
  get clientMetadata(): OAuthClientMetadata;
78
+ /** Issue one unpredictable state value for the SDK's authorization request. */
79
+ state(): string;
76
80
  clientInformation(): Promise<OAuthClientInformationMixed | undefined>;
77
81
  saveClientInformation(clientInformation: OAuthClientInformationMixed): Promise<void>;
78
82
  tokens(): Promise<OAuthTokens | undefined>;
@@ -1,6 +1,6 @@
1
1
  import type { Config } from './mcp-client/config.js';
2
2
  import { type McpServerOverride, type McpSuiteOverrides } from './mcp-overrides.js';
3
- import type { McpServer, McpServerSse, McpServerStdio, McpServerStreamableHttp, Suite } from '../model/types.js';
3
+ import type { HarnessMcpPolicy, McpServer, McpServerPolicy, McpServerSse, McpServerStdio, McpServerStreamableHttp, Suite } from '../model/types.js';
4
4
  export interface McpMountRequest {
5
5
  suiteId: string;
6
6
  serverKey: string;
@@ -16,6 +16,32 @@ export interface EffectiveMcpServer {
16
16
  enabled: boolean;
17
17
  /** External credential references the effective definition needs. */
18
18
  credentialRefs: string[];
19
+ /** The suite declaration and the user's override as they resolved. */
20
+ policy: ResolvedMcpPolicy;
21
+ }
22
+ /** One timeout as three layers: what the user set, what the suite declared, and the value in force. */
23
+ export interface McpTimeoutResolution {
24
+ /** The user's stored value; null when the user inherits. */
25
+ user: number | null;
26
+ /** The suite's declared value; null when the suite declares none. */
27
+ suite: number | null;
28
+ /** The value in force. */
29
+ effective: number;
30
+ /** Which layer supplied `effective`. */
31
+ source: 'user' | 'suite' | 'default';
32
+ }
33
+ /** One server's client policy after the suite declaration and the user's override meet. */
34
+ export interface ResolvedMcpPolicy {
35
+ /** Suite allow-list; the user cannot widen it. */
36
+ enabledTools?: string[];
37
+ /** The suite's own deny list. */
38
+ suiteDisabledTools?: string[];
39
+ /** Effective deny list: the suite's own entries unioned with the user's. */
40
+ disabledTools?: string[];
41
+ /** Per-tool-call timeout. */
42
+ toolCallTimeout: McpTimeoutResolution;
43
+ /** Startup timeout. */
44
+ startupTimeout: McpTimeoutResolution;
19
45
  }
20
46
  export type McpMountFailureCode = 'unsupported-transport' | 'missing-credential' | 'credential-error' | 'unmount-failed' | 'mount-failed'
21
47
  /** The derived serverName's namespace is already mounted by another MCP client — informational, not a failure. */
@@ -36,18 +62,10 @@ export interface McpCredentialResolver {
36
62
  } | undefined>;
37
63
  }
38
64
  /**
39
- * The effective view of one suite's `mcp.json` servers: the user's per-server
40
- * overrides applied, every row flagged with whether it is used at all, and each
41
- * row's credential references read off the effective shape. Mounting, status
42
- * and detail rendering read this one projection, so a server cannot be listed
43
- * as enabled while mounting something else.
44
- */
45
- export declare function effectiveMcpServers(suite: Suite, overrides?: McpSuiteOverrides): EffectiveMcpServer[];
46
- /**
47
- * Build one mount request per supported mcp.json server, resolving every
48
- * `${NAME}` through the credential resolver before a child process or HTTP
49
- * request is created. Missing references fail closed per server instead of
50
- * becoming empty strings.
65
+ * Build one mount request per supported mcp.json server, expanding built-in
66
+ * variables (and, for user-owned data, `${NAME}` credential references)
67
+ * before a child process or HTTP request is created. Missing references fail
68
+ * closed per server instead of becoming empty strings.
51
69
  *
52
70
  * @param overrides user-owned per-server overrides (url/headers/env/args
53
71
  * replacement plus enable/disable); applied before mount. Disabled servers
@@ -61,6 +79,50 @@ export declare function toMcpMounts(suite: Suite, pluginDataRoot: string, overri
61
79
  failures: McpMountFailure[];
62
80
  credentialRefs: string[];
63
81
  }>;
82
+ /**
83
+ * Whether a suite's MCP declarations are package data under the portable
84
+ * format. Installed v1 suites are; the user's own `~/.agents/mcp.json`,
85
+ * project-native config, and every dialect-native file are user-owned data
86
+ * where `${NAME}` credential references stay resolvable.
87
+ */
88
+ export declare function isPortableMcp(suite: Suite): boolean;
89
+ /**
90
+ * The `com.deepseek.harness` policy declared for one portable server.
91
+ * Server keys in the namespace match the server's own name in `mcp.json`;
92
+ * `serverKey` is that name at discovery time.
93
+ */
94
+ export declare function namespaceMcpPolicy(suite: Suite, serverKey: string): HarnessMcpPolicy | undefined;
95
+ /**
96
+ * The effective view of one suite's `mcp.json` servers: the user's per-server
97
+ * overrides applied, every row flagged with whether it is used at all, and each
98
+ * row's credential references read off the effective shape. Mounting, status
99
+ * and detail rendering read this one projection, so a server cannot be listed
100
+ * as enabled while mounting something else.
101
+ *
102
+ * Portable v1 suites (`isPortableMcp`) carry package data: their credential
103
+ * reference list is empty by definition (§9.2 leaves unrecognized
104
+ * placeholder-like text literal), and client policy comes from the
105
+ * `com.deepseek.harness` namespace instead. Overrides applied by the user are
106
+ * user-owned data, so a reference a user typed into an override still
107
+ * resolves.
108
+ */
109
+ export declare function effectiveMcpServers(suite: Suite, overrides?: McpSuiteOverrides): EffectiveMcpServer[];
110
+ /**
111
+ * The suite's declared per-server policy. The `com.deepseek.harness`
112
+ * namespace seat carries the policy a portable `mcp.json` has no room for and
113
+ * wins over an inline declaration; dialect-native files declare it inline.
114
+ */
115
+ export declare function declaredMcpPolicy(server: McpServerPolicy, policy: HarnessMcpPolicy | undefined): McpServerPolicy;
116
+ /**
117
+ * Bring the suite's declaration and the user's override together.
118
+ *
119
+ * A timeout is a plain override: the user's value wins, a declaration fills in
120
+ * when the user set none, and the built-in default stands behind both. Tool
121
+ * filtering only tightens: the effective deny list is the suite's entries
122
+ * unioned with the user's, and the suite's allow-list stands as declared, so a
123
+ * user cannot open a tool the suite left out.
124
+ */
125
+ export declare function resolveMcpPolicy(declared: McpServerPolicy, override: McpServerOverride | undefined): ResolvedMcpPolicy;
64
126
  /** Find external credential references used by one MCP server definition. */
65
127
  export declare function credentialRefsInServer(server: McpServer): string[];
66
128
  /**
@@ -19,3 +19,25 @@ export declare function loadUserMcpSuite(agentsRoot: string): Promise<Suite & {
19
19
  export declare function addUserMcpServer(agentsRoot: string, name: string, server: unknown): Promise<void>;
20
20
  /** The user's hand-written MCP declaration file: `<agentsRoot>/mcp.json`. */
21
21
  export declare function userMcpPath(agentsRoot: string): string;
22
+ /** One pasted entry: the key it lands under and the server definition it carries. */
23
+ export interface McpImportEntry {
24
+ name: string;
25
+ server: unknown;
26
+ }
27
+ /** What one pasted import wrote, and what it left out with a reason each. */
28
+ export interface McpImportResult {
29
+ imported: string[];
30
+ skipped: Array<{
31
+ name: string;
32
+ reason: string;
33
+ }>;
34
+ }
35
+ /**
36
+ * Import several pasted servers in one write.
37
+ *
38
+ * Every entry is judged on its own so one bad definition cannot take the rest
39
+ * of the paste with it, and an existing name is kept unless the caller asked to
40
+ * overwrite. The file is written once, after every entry has been checked, so a
41
+ * rejected entry never lands half-written beside the accepted ones.
42
+ */
43
+ export declare function importUserMcpServers(agentsRoot: string, entries: readonly McpImportEntry[], overwrite?: boolean): Promise<McpImportResult>;
@@ -1,6 +1,8 @@
1
1
  import type { McpServerSse, McpServerStreamableHttp, McpServerStdio } from '../model/types.js';
2
2
  /** HTTP-shaped server sources (url + headers carriers) overrides can edit. */
3
3
  type McpServerHttp = McpServerStreamableHttp | McpServerSse;
4
+ /** The largest timeout a bridge config and the host timer can hold. */
5
+ export declare const MAX_TIMEOUT_MS = 2147483647;
4
6
  /** Per-server override record; absent fields pass through from the source. */
5
7
  export type McpServerOverride = {
6
8
  /** Validated complete user configuration, retaining source-owned identity. */
@@ -20,7 +22,18 @@ export type McpServerOverride = {
20
22
  enabled: boolean;
21
23
  scope?: string;
22
24
  };
25
+ /** Per-tool-call timeout in milliseconds; absent inherits the suite's value or the bridge default. */
26
+ toolCallTimeoutMs?: number;
27
+ /** Startup timeout in milliseconds; absent inherits the suite's value or the bridge default. */
28
+ startupTimeoutMs?: number;
29
+ /** Tool names the user turned off; the suite's own deny list stays in force beside them. */
30
+ disabledTools?: string[];
23
31
  };
32
+ /** Timeout fields a policy save can set (`number`) or clear back to inheritance (`null`). */
33
+ export interface McpTimeoutPatch {
34
+ toolCallTimeoutMs?: number | null;
35
+ startupTimeoutMs?: number | null;
36
+ }
24
37
  /** Overrides for one suite, keyed by mcp.json server key. */
25
38
  export type McpSuiteOverrides = Record<string, McpServerOverride>;
26
39
  /** The overrides directory under the plugin data root. */
@@ -35,6 +48,31 @@ export declare function saveSuiteOverrides(dataRoot: string, suiteId: string, ov
35
48
  export declare function sanitizeOverrides(raw: unknown): McpSuiteOverrides;
36
49
  /** Validate a client-supplied patch for one server into an override value. */
37
50
  export declare function sanitizeOverridePatch(patch: unknown): McpServerOverride | undefined;
51
+ /**
52
+ * Validate one policy save as it arrives over the wire. An absent field leaves
53
+ * its stored value alone, `null` clears one back to inheritance, and a positive
54
+ * whole number of milliseconds within the timer range sets it; anything else
55
+ * rejects the save with a readable reason.
56
+ */
57
+ export declare function parseTimeoutPatch(raw: unknown): McpTimeoutPatch;
58
+ /** The client policy a service-config save may carry alongside the definition. */
59
+ export interface McpPolicyPatch {
60
+ toolCallTimeoutMs?: number | null;
61
+ startupTimeoutMs?: number | null;
62
+ /** The user's deny list; null clears it, an absent field keeps it. */
63
+ disabledTools?: string[] | null;
64
+ /** The user's OAuth opt-in; null clears it, an absent field keeps it. */
65
+ auth?: {
66
+ enabled: boolean;
67
+ scope?: string;
68
+ } | null;
69
+ }
70
+ /**
71
+ * Validate a client-supplied policy patch. An absent field keeps its stored
72
+ * value, `null` clears it back to the suite's declaration or the default, and
73
+ * any other shape is rejected with the reason it failed.
74
+ */
75
+ export declare function parseMcpPolicyPatch(raw: unknown): McpPolicyPatch;
38
76
  /**
39
77
  * Merge one client patch into the override already on disk.
40
78
  *
@@ -55,4 +93,10 @@ export declare function mergeOverridePatch(existing: McpServerOverride, patch: M
55
93
  * persisting them here.
56
94
  */
57
95
  export declare function applyOverride(server: McpServerStdio | McpServerHttp, override: McpServerOverride | undefined): McpServerStdio | McpServerHttp;
96
+ /**
97
+ * One server with its client policy fields removed: the shape the portable
98
+ * `mcp.json` schema accepts. The service editor renders and saves this shape,
99
+ * so a timeout never reaches a document that has no seat for it.
100
+ */
101
+ export declare function withoutPolicyFields<T extends McpServerStdio | McpServerHttp>(server: T): T;
58
102
  export {};
@@ -5,3 +5,9 @@ export declare function redactMcpOverrides(value: Record<string, Record<string,
5
5
  export declare function isSensitiveKey(key: string): boolean;
6
6
  /** Redact credential-bearing query values from an endpoint URL. */
7
7
  export declare function redactUrl(raw: string): string;
8
+ /**
9
+ * Redact every URL embedded in an error message before the message reaches a
10
+ * log line or a diagnostic: connection failures echo the server's endpoint,
11
+ * and endpoints carry credential-bearing queries.
12
+ */
13
+ export declare function redactErrorMessage(raw: string): string;