dsh-agent-plugins-market 0.7.0 → 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 (114) hide show
  1. package/README.md +31 -26
  2. package/README.zh.md +31 -26
  3. package/client/client.js +29164 -1136
  4. package/client/client.js.map +1 -1
  5. package/lib/application/catalog-context.js +8 -1
  6. package/lib/application/catalog.js +27 -2
  7. package/lib/application/details.js +13 -2
  8. package/lib/application/install-store.js +1 -1
  9. package/lib/application/mcp-service.js +191 -19
  10. package/lib/application/panel-resources.js +16 -4
  11. package/lib/application/project-agent-roles.js +7 -1
  12. package/lib/catalog/archive.js +16 -1
  13. package/lib/catalog/manifests.js +124 -13
  14. package/lib/catalog/paths.js +8 -0
  15. package/lib/catalog/plugin-variables.js +38 -0
  16. package/lib/catalog/project-hooks.js +14 -1
  17. package/lib/catalog/scan-resolvers.js +117 -12
  18. package/lib/catalog/skills-parse.js +47 -0
  19. package/lib/catalog/source-catalog.js +8 -3
  20. package/lib/catalog/suite-components.js +2 -2
  21. package/lib/catalog/surfaces.js +73 -27
  22. package/lib/catalog/validate.js +205 -54
  23. package/lib/contracts/market.js +3 -0
  24. package/lib/contracts/settings.js +63 -0
  25. package/lib/index.js +32 -13
  26. package/lib/model/layouts.js +44 -1
  27. package/lib/model/preset-source.js +8 -0
  28. package/lib/routes.js +43 -2
  29. package/lib/runtime/agent-role-router.js +203 -56
  30. package/lib/runtime/commands-mounts.js +50 -9
  31. package/lib/runtime/deadline.js +32 -6
  32. package/lib/runtime/dynamic-context.js +140 -0
  33. package/lib/runtime/feedback-tool.js +7 -3
  34. package/lib/runtime/host-locale.js +45 -15
  35. package/lib/runtime/lsp-mounts.js +23 -2
  36. package/lib/runtime/mcp-backend.js +14 -15
  37. package/lib/runtime/mcp-client/config.js +8 -0
  38. package/lib/runtime/mcp-client/connection.js +9 -8
  39. package/lib/runtime/mcp-client/host-seams.js +8 -88
  40. package/lib/runtime/mcp-client/oauth.js +82 -14
  41. package/lib/runtime/mcp-client/tools.js +2 -1
  42. package/lib/runtime/mcp-config.js +182 -35
  43. package/lib/runtime/mcp-direct-config.js +49 -6
  44. package/lib/runtime/mcp-mounts.js +15 -3
  45. package/lib/runtime/mcp-overrides.js +131 -1
  46. package/lib/runtime/mcp-redaction.js +8 -0
  47. package/lib/runtime/mcp-status.js +21 -5
  48. package/lib/runtime/project-runtime.js +23 -9
  49. package/lib/runtime/reconcile-scheduler.js +6 -8
  50. package/lib/runtime/reconciler.js +2 -1
  51. package/lib/runtime/regions.js +0 -19
  52. package/lib/runtime/server-config.js +49 -8
  53. package/lib/runtime/settings-namespace.js +21 -13
  54. package/lib/runtime/skills-provider.js +33 -11
  55. package/lib/runtime/source-auto-update.js +10 -14
  56. package/lib/runtime/subagent-catalog.js +62 -22
  57. package/lib/runtime/timer-seat.js +80 -0
  58. package/lib/runtime/tool-registry-observer.js +24 -20
  59. package/lib/runtime/user-commands.js +5 -1
  60. package/lib/runtime/user-panels.js +110 -41
  61. package/lib/runtime/user-store.js +114 -58
  62. package/lib/types/application/catalog-context.d.ts +6 -0
  63. package/lib/types/application/catalog.d.ts +19 -1
  64. package/lib/types/application/install-store.d.ts +1 -1
  65. package/lib/types/application/mcp-service.d.ts +38 -3
  66. package/lib/types/application/ports.d.ts +1 -1
  67. package/lib/types/application/queries.d.ts +8 -1
  68. package/lib/types/catalog/manifests.d.ts +6 -2
  69. package/lib/types/catalog/paths.d.ts +6 -0
  70. package/lib/types/catalog/plugin-variables.d.ts +16 -0
  71. package/lib/types/catalog/skills-parse.d.ts +13 -0
  72. package/lib/types/catalog/source-catalog.d.ts +7 -2
  73. package/lib/types/catalog/surfaces.d.ts +14 -4
  74. package/lib/types/catalog/validate.d.ts +72 -11
  75. package/lib/types/contracts/market.d.ts +77 -0
  76. package/lib/types/contracts/mcp-status.d.ts +11 -0
  77. package/lib/types/contracts/settings.d.ts +59 -0
  78. package/lib/types/model/layouts.d.ts +30 -0
  79. package/lib/types/model/preset-source.d.ts +18 -0
  80. package/lib/types/model/types.d.ts +37 -1
  81. package/lib/types/runtime/agent-role-router.d.ts +96 -18
  82. package/lib/types/runtime/commands-mounts.d.ts +15 -7
  83. package/lib/types/runtime/deadline.d.ts +10 -11
  84. package/lib/types/runtime/dynamic-context.d.ts +81 -0
  85. package/lib/types/runtime/host-locale.d.ts +20 -2
  86. package/lib/types/runtime/lsp-mounts.d.ts +7 -0
  87. package/lib/types/runtime/mcp-backend.d.ts +8 -15
  88. package/lib/types/runtime/mcp-client/config.d.ts +8 -0
  89. package/lib/types/runtime/mcp-client/host-seams.d.ts +20 -64
  90. package/lib/types/runtime/mcp-client/oauth.d.ts +4 -0
  91. package/lib/types/runtime/mcp-config.d.ts +75 -13
  92. package/lib/types/runtime/mcp-direct-config.d.ts +22 -0
  93. package/lib/types/runtime/mcp-overrides.d.ts +44 -0
  94. package/lib/types/runtime/mcp-redaction.d.ts +6 -0
  95. package/lib/types/runtime/project-runtime.d.ts +10 -3
  96. package/lib/types/runtime/reconcile-scheduler.d.ts +1 -1
  97. package/lib/types/runtime/regions.d.ts +1 -4
  98. package/lib/types/runtime/server-config.d.ts +26 -1
  99. package/lib/types/runtime/settings-namespace.d.ts +10 -10
  100. package/lib/types/runtime/skills-provider.d.ts +11 -2
  101. package/lib/types/runtime/source-auto-update.d.ts +3 -4
  102. package/lib/types/runtime/subagent-catalog.d.ts +14 -2
  103. package/lib/types/runtime/timer-seat.d.ts +51 -0
  104. package/lib/types/runtime/tool-registry-observer.d.ts +14 -6
  105. package/lib/types/runtime/user-panels.d.ts +65 -12
  106. package/lib/types/runtime/user-store.d.ts +65 -16
  107. package/package.json +23 -6
  108. package/schemas/1.0.0/mcp.schema.json +0 -22
  109. package/schemas/1.1.0/mcp.schema.json +120 -0
  110. package/schemas/1.1.0/plugin.schema.json +65 -0
  111. package/schemas/README.md +25 -19
  112. package/schemas/agent-plugins/spec.md +23 -9
  113. package/schemas/com.deepseek.harness/namespace.schema.json +42 -0
  114. package/schemas/com.deepseek.harness/spec.md +52 -0
@@ -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;
@@ -10,6 +9,10 @@ export interface AgentRoleEntry {
10
9
  disabled: boolean;
11
10
  title?: string;
12
11
  rawText?: string;
12
+ /** Suite checkout root the card's `${PLUGIN_ROOT}` variables resolve to; absent for project-native files. */
13
+ suiteRoot?: string;
14
+ /** The suite's `${PLUGIN_DATA}` directory; absent for project-native files. */
15
+ suiteData?: string;
13
16
  }
14
17
  /**
15
18
  * The executable part of one card. `tools` / `disallowedTools` stay in the file
@@ -41,6 +44,10 @@ export interface AgentRoleDelegation {
41
44
  persona: string;
42
45
  agentOptions?: AgentRoleOptions;
43
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
+ }
44
51
  export interface AgentRoleHost {
45
52
  tools: {
46
53
  register(definition: unknown): () => void;
@@ -62,18 +69,59 @@ export interface AgentRoleHost {
62
69
  childId: string;
63
70
  messageId: string;
64
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>;
65
74
  };
66
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
+ }
67
111
  /** Strict YAML parsing prevents malformed routing metadata from silently inheriting wider privileges. */
68
112
  export declare function parseAgentRole(text: string): AgentRolePolicy;
69
113
  /**
70
- * Resolve the child LLM options one card may contribute.
114
+ * Resolve the child LLM options for one role call.
71
115
  *
72
- * A card route is advisory. Only an exact `provider` plus `model` pair is
73
- * applied, and only when the live LLM runtime accepts it; every other
74
- * declaration — a bare id, a Claude alias, a lone `provider`, an unsupported
75
- * effort — degrades to inheriting the parent route and reports a diagnostic.
76
- * @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.
77
125
  * @param parent - the calling Agent whose route an unusable declaration falls back to.
78
126
  * @param llm - live LLM runtime owning provider, model and effort validation.
79
127
  * @param signal - tool-call cancellation signal.
@@ -81,18 +129,48 @@ export declare function parseAgentRole(text: string): AgentRolePolicy;
81
129
  * @param diagnose - diagnostic sink; degradation is reported, never silent.
82
130
  * @returns the options to send, or undefined for pure inheritance.
83
131
  */
84
- 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>;
85
133
  /** Stable summaries; invalid declarations are excluded and transient read failures abort publication. */
86
- export declare function agentRoleCatalog(entries: AgentRoleEntry[], signal: AbortSignal, diagnose?: (message: string) => void): Promise<SubagentCatalogEntry[]>;
134
+ export declare function agentRoleCatalog(entries: AgentRoleEntry[], signal: AbortSignal, diagnose?: (message: string) => void, projectDir?: string): Promise<SubagentCatalogEntry[]>;
87
135
  /** Read the same declaration for catalog summaries and execution, including inline resources. */
88
- export declare function readAgentRole(entry: AgentRoleEntry): Promise<AgentRolePolicy>;
136
+ export declare function readAgentRole(entry: AgentRoleEntry, projectDir?: string): Promise<AgentRolePolicy>;
89
137
  /**
90
- * Start one role child and return its durable id without waiting for the result.
91
- * Resume state, steering, and the settlement notice belong to the host's
92
- * 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.
93
147
  */
94
- 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';
95
152
  subagentId: string;
96
- }>;
97
- /** Mount once after tools, llm and subagents are available; the returned disposer belongs to the plugin lifecycle. */
98
- 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;
@@ -3,12 +3,13 @@
3
3
  * register as dsh slash commands.
4
4
  *
5
5
  * A CC command is a prompt template the model executes (its body carries
6
- * `$ARGUMENTS` and execution rules), so the handler maps it onto the
7
- * harness's follow-up mechanism: the template with `$ARGUMENTS` substituted
8
- * becomes one durable user-role follow-up message on the receiving agent.
9
- * Registrations reconcile on every enable/disable/install/uninstall; a
10
- * broken command file or an unavailable `ctx.commands` is contained per
11
- * command and reported as a diagnostic.
6
+ * `$ARGUMENTS`, path variables and `` !`cmd` `` dynamic-context placeholders),
7
+ * so the handler maps it onto the harness's follow-up mechanism: the template
8
+ * with those placeholders resolved becomes one durable user-role follow-up
9
+ * message on the receiving agent. Registrations reconcile on every
10
+ * enable/disable/install/uninstall; a broken command file, a failed injected
11
+ * command, or an unavailable `ctx.commands` is contained per command and
12
+ * reported as a diagnostic.
12
13
  */
13
14
  import type { Context } from '@deepseek-ai/cordis';
14
15
  import type { Suite, SuiteMarkdownResource } from '../model/types.js';
@@ -23,13 +24,20 @@ interface CommandSpec {
23
24
  description: string;
24
25
  body: string;
25
26
  hint?: string;
27
+ /** Set when the command file belongs to a suite with a plugin root; absent for project-native files. */
28
+ suiteRoot?: string;
29
+ /** The suite's `${PLUGIN_DATA}` directory; absent for project-native files. */
30
+ suiteData?: string;
26
31
  }
27
32
  export declare class CommandMountRegistry {
28
33
  private readonly ctx;
29
34
  private readonly t;
35
+ private readonly dataRoot?;
30
36
  private readonly fingerprints;
31
37
  private readonly live;
32
- constructor(ctx: Context, t?: HostTranslate);
38
+ constructor(ctx: Context, t?: HostTranslate, dataRoot?: string | undefined);
39
+ /** The live shell seam, when the profile has one; dynamic context stays literal without it. */
40
+ private shell;
33
41
  /** Register/unregister suite commands to match the enabled suites exactly. */
34
42
  reconcile(enabledSuites: Suite[]): Promise<CommandMountDiagnostic[]>;
35
43
  /** Dispose every registered command; used at plugin teardown. */
@@ -1,18 +1,17 @@
1
- /**
2
- * Bounded waits for work this plugin cannot cancel.
3
- *
4
- * Every wait here is a race against a timer: the caller stops waiting and the
5
- * underlying work keeps running. That is the only safe shape for a mount and
6
- * for the change pipeline that drives it — a spawned server process or a
7
- * browser authorization the user is completing must not be abandoned just
8
- * because nobody is waiting for it any more.
9
- *
10
- * @module runtime/deadline
11
- */
1
+ /** Identifies this plugin's bounded waits inside a timeout reason. */
2
+ export declare const MARKET_DEADLINE_CODE = "MARKET_DEADLINE";
12
3
  /**
13
4
  * Resolve `true` once `work` settles, or `false` when `deadlineMs` elapses.
14
5
  *
15
6
  * A rejection counts as settled: this helper only reports timing, so callers
16
7
  * that need the failure attach their own handler to `work`.
8
+ *
9
+ * A non-positive wait means "do not wait": the answer is simply whether the
10
+ * work had already settled. That is deliberately not the host primitive's own
11
+ * reading of a non-positive timeout, which is "arm no timer at all" — the floor
12
+ * below keeps the two from collapsing into opposite behaviors.
13
+ * @param work - the work to wait for; it is never cancelled, only stopped being awaited.
14
+ * @param deadlineMs - how long to wait, in milliseconds.
15
+ * @returns whether the work settled before the deadline.
17
16
  */
18
17
  export declare function settlesWithin(work: Promise<unknown>, deadlineMs: number): Promise<boolean>;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Claude Code dynamic context injection: `` !`command` `` in a command body or
3
+ * skill body runs the command and the placeholder becomes its output.
4
+ *
5
+ * One pass over the original text recognizes both spellings — the inline
6
+ * `` !`cmd` `` (only at a line start or after whitespace, matching the authoring
7
+ * rule) and the multi-line ```` ```! ```` fence — and every command runs
8
+ * sequentially in the calling session's directory. Outputs are inserted as
9
+ * plain text and never re-read, so a command cannot emit another placeholder.
10
+ *
11
+ * Failure is contained per invocation rather than per placeholder: the caller
12
+ * aborts the whole invocation with the command's own output, so a model never
13
+ * reads half-injected text. Exit code 1 counts as a result for the commands
14
+ * whose benign outcome it is (`grep`, `rg`, `find`, `diff`, `test`, …).
15
+ *
16
+ * The shell service is reached structurally: {@link shellSeamOf} resolves it
17
+ * from any context, and a profile without one keeps the author's literal text.
18
+ */
19
+ import type { Context } from '@deepseek-ai/cordis';
20
+ /** How long one injected command may run; the executor caps a larger request. */
21
+ export declare const DYNAMIC_CONTEXT_TIMEOUT_MS = 120000;
22
+ /** The requested forward cap for one injected command's stdout, in bytes. */
23
+ export declare const DYNAMIC_CONTEXT_MAX_OUTPUT_BYTES: number;
24
+ /** The slice of the host shell service this module uses. */
25
+ export interface ShellSeam {
26
+ resolve(request: {
27
+ command: string;
28
+ workdir?: string;
29
+ timeoutMs?: number;
30
+ stdoutMaxBytes?: number;
31
+ signal?: AbortSignal;
32
+ }): unknown;
33
+ run(spec: unknown): Promise<ShellOutcome>;
34
+ }
35
+ /** The fields of one shell run this module reads. */
36
+ export interface ShellOutcome {
37
+ exitCode: number | null;
38
+ timedOut: boolean;
39
+ aborted: boolean;
40
+ stdout: {
41
+ text: string;
42
+ truncated: boolean;
43
+ spillPath?: string;
44
+ };
45
+ stderr: {
46
+ text: string;
47
+ truncated: boolean;
48
+ spillPath?: string;
49
+ };
50
+ }
51
+ /**
52
+ * Resolve the host shell service from any context, whether or not the reading
53
+ * fiber injects `shell`.
54
+ *
55
+ * Cordis resolves `ctx.shell` by walking the reading fiber's ancestors, so a
56
+ * scope that does not inject the service throws `cannot get property "shell"
57
+ * without inject` even when a sibling fiber provides it. `ctx.get` reads the
58
+ * global service store instead and answers `undefined` in a profile that has
59
+ * no shell, which is what keeps the seam optional.
60
+ *
61
+ * @param ctx - the context the dynamic-context pass runs under.
62
+ * @returns the shell seam, or `undefined` when the profile provides none.
63
+ */
64
+ export declare function shellSeamOf(ctx: Context): ShellSeam | undefined;
65
+ export interface DynamicContextOptions {
66
+ shell: ShellSeam;
67
+ /** Session directory every injected command runs in. */
68
+ workdir?: string;
69
+ signal?: AbortSignal;
70
+ }
71
+ /**
72
+ * Run every placeholder's command and return the text the model receives.
73
+ *
74
+ * @param text - author text whose `${...}` variables and arguments are already resolved.
75
+ * @param options - the resolved shell seam, session directory and cancellation signal.
76
+ * @returns the text with each placeholder replaced by its command's output.
77
+ * @throws when a command fails, times out or is aborted, carrying the command and its output.
78
+ */
79
+ export declare function injectDynamicContext(text: string, options: DynamicContextOptions): Promise<string>;
80
+ /** Whether this command's exit status is a result rather than a failure. */
81
+ export declare function benignExit(exitCode: number | null, command: string): boolean;
@@ -1,13 +1,31 @@
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;
6
6
  }
7
7
  /** Resolve the active host language from settings; unknown values default to zh. */
8
8
  export declare function bindHostLocale(preference: string | undefined): HostTranslate;
9
- /** Read `locale.preference` from `$DSH_HOME/settings.yaml` (best effort). */
9
+ /**
10
+ * Wire the host settings service as the primary locale source, replacing the
11
+ * `settings.yaml` fallback.
12
+ * @param read - reads `locale.preference` from the settings service.
13
+ */
14
+ export declare function setHostLocaleSource(read: () => string | undefined): void;
15
+ /**
16
+ * The persisted locale preference: the host settings document when the service
17
+ * is composed, else `$DSH_HOME/settings.yaml` (best effort).
18
+ */
10
19
  export declare function readLocalePreference(): Promise<string | undefined>;
11
20
  /** Bind a host translator against the persisted locale preference. */
12
21
  export declare function loadHostLocale(): Promise<ResolvedLocale>;
22
+ /**
23
+ * Read `locale.preference` from the host settings service.
24
+ *
25
+ * The locale namespace is registered by the host's own client-locale plugin, so
26
+ * this reads `undefined` until that plugin mounts — which is why the caller
27
+ * re-binds when the service arrives rather than capturing the value once.
28
+ * @param settingsCtx - a context carrying the `settings` service.
29
+ */
30
+ export declare function readHostLocalePreference(settingsCtx: unknown): string | undefined;
13
31
  export {};
@@ -29,6 +29,7 @@
29
29
  */
30
30
  import type { Context } from '@deepseek-ai/cordis';
31
31
  import { type LegacyLspSeam } from './profile-seam.js';
32
+ import { type PluginPathContext } from '../catalog/plugin-variables.js';
32
33
  import { type Suite } from '../model/types.js';
33
34
  export interface LspMountDiagnostic {
34
35
  suiteId: string;
@@ -54,6 +55,8 @@ export declare function toLspServerConfig(spec: {
54
55
  initializationOptions?: unknown;
55
56
  configuration?: unknown;
56
57
  }): LspStdioServerConfig;
58
+ /** Resolve author-written paths in one declaration before the host spawns the server. */
59
+ export declare function expandLspServerConfig(config: LspStdioServerConfig, context: PluginPathContext): LspStdioServerConfig;
57
60
  /** Minimal structural shape of a dynamically imported host plugin module. */
58
61
  interface HostModule {
59
62
  default?: unknown;
@@ -87,6 +90,8 @@ export declare class LspMountRegistry {
87
90
  private capabilityFailure;
88
91
  /** Latest diagnostic per suite id; cleared when its suite mounts or leaves the wanted set. */
89
92
  private readonly lastDiagnostics;
93
+ /** Plugin storage root holding each suite's `${PLUGIN_DATA}` directory; unset leaves the variable verbatim. */
94
+ private pluginDataRoot?;
90
95
  /** Direct (user-configured) server provider; defaults to none. */
91
96
  private directProvider;
92
97
  private disabledProvider;
@@ -119,6 +124,8 @@ export declare class LspMountRegistry {
119
124
  private seamConflictReason;
120
125
  /** Dispose the capability seam this registry mounted, once no wanted server needs it. */
121
126
  private releaseCapability;
127
+ /** Install the plugin storage root per-suite data directories resolve against. */
128
+ setPluginDataRoot(root: string): void;
122
129
  /** Install the direct (user-configured) server provider used at reconcile time. */
123
130
  setDirectProvider(provider: () => Promise<Record<string, import('../model/types.js').LspServerSpec>>): void;
124
131
  setDisabledProvider(provider: () => Promise<Set<string>>): void;
@@ -4,8 +4,8 @@
4
4
  * and legacy SSE) or through the host's `@deepseek-ai/dsh-mcp-client`
5
5
  * (compatibility mode: no OAuth, no SSE, but the host-native implementation).
6
6
  *
7
- * The choice is a host settings namespace (`dsh-agent-plugins-market`,
8
- * `mcpEnhanced: boolean`, default true) registered by the plugin's node half:
7
+ * The choice is the `mcpEnhanced` field of the market's host settings
8
+ * namespace (see `contracts/settings.ts`) registered by the plugin's node half:
9
9
  * the registration is what makes the host 插件配置 tab serve our card, the
10
10
  * client card binds it for state, and the node half watches it to remount
11
11
  * servers when the switch flips. `readMcpBackend` remains only as the
@@ -16,30 +16,23 @@
16
16
  import z from '@deepseek-ai/schemastery';
17
17
  /** The MCP mount backend the market uses for suite servers. */
18
18
  export type McpBackend = 'builtin' | 'host';
19
- /** Settings namespace this plugin registers; the key the plugin-config tab pairs our card by. */
20
- export declare const MCP_SETTINGS_NAMESPACE = "dsh-agent-plugins-market";
21
- /** Schema of the market settings namespace: the switches this plugin's config card serves. */
19
+ /**
20
+ * Schema of the market settings namespace: the switches this plugin's config
21
+ * card serves, with the defaults declared to the host. The values themselves
22
+ * belong to {@link MARKET_SETTINGS_DEFAULTS}; this schema states them, it does
23
+ * not own them.
24
+ */
22
25
  export declare const MarketSettingsSchema: z<Schemastery.ObjectS<{
23
- /** ON (default) = the built-in bridge with OAuth and SSE; OFF = host client compat mode. */
24
26
  mcpEnhanced: z<boolean, boolean>;
25
- /** Read native Agent layouts under the project root; OFF (default) scans configured sources only. */
26
27
  scanProjectLayouts: z<boolean, boolean>;
27
- /** Download region for GitHub acquisition; `auto` follows the interface language. */
28
28
  downloadRegion: z<"auto" | "global" | "china", "auto" | "global" | "china">;
29
- /** ON (default) = the `report_market_issue` model tool is registered; OFF = unregistered. */
30
29
  feedbackEnabled: z<boolean, boolean>;
31
- /** ON = refresh every configured source in the background; OFF (default) = never. */
32
30
  autoUpdateSources: z<boolean, boolean>;
33
31
  }>, Schemastery.ObjectT<{
34
- /** ON (default) = the built-in bridge with OAuth and SSE; OFF = host client compat mode. */
35
32
  mcpEnhanced: z<boolean, boolean>;
36
- /** Read native Agent layouts under the project root; OFF (default) scans configured sources only. */
37
33
  scanProjectLayouts: z<boolean, boolean>;
38
- /** Download region for GitHub acquisition; `auto` follows the interface language. */
39
34
  downloadRegion: z<"auto" | "global" | "china", "auto" | "global" | "china">;
40
- /** ON (default) = the `report_market_issue` model tool is registered; OFF = unregistered. */
41
35
  feedbackEnabled: z<boolean, boolean>;
42
- /** ON = refresh every configured source in the background; OFF (default) = never. */
43
36
  autoUpdateSources: z<boolean, boolean>;
44
37
  }>>;
45
38
  /** Path of the legacy persisted settings file under the plugin data root. */
@@ -12,6 +12,14 @@ import type { ReconnectConfig } from './connection.js';
12
12
  import type { McpServerPolicy } from '../../model/types.js';
13
13
  /** Default timeout for individual MCP tool calls (ms). */
14
14
  export declare const DEFAULT_TOOL_CALL_TIMEOUT_MS = 60000;
15
+ /**
16
+ * How long one connection attempt may spend initializing (ms). A server that
17
+ * never answers would otherwise hold its process, transport and browser leg
18
+ * until the SDK's own 60-second request default expired; a working server
19
+ * handshakes well under a second, and a genuinely slow one can declare its own
20
+ * `startupTimeoutMs`.
21
+ */
22
+ export declare const DEFAULT_STARTUP_TIMEOUT_MS = 10000;
15
23
  /** Valid `serverName`, kept below the public tool-name budget. */
16
24
  export declare const SERVER_NAME_PATTERN: RegExp;
17
25
  /**
@@ -1,55 +1,25 @@
1
1
  /**
2
- * Local ports of the tiny host seams the self-built MCP client needs.
2
+ * The host seams the self-built MCP client consumes, re-exported from the
3
+ * packages that own them.
3
4
  *
4
- * The market plugin must stay self-contained at runtime: it cannot import
5
- * host-internal packages that are not published at compatible versions, and
6
- * every one of these seams is a small pure function or constant. Each port
7
- * below is copied verbatim (semantics, not prose) from the harness source at
8
- * `0.1.1-rc.2` and carries the upstream reference it came from, so a future
9
- * host change can be re-diffed against `~/workspace/deepseek-harness`.
5
+ * These are small pure functions and constants, but each one encodes a rule
6
+ * this plugin must obey rather than a choice it gets to make: which credential
7
+ * keys the host accepts, how long a timer may be, which environment names never
8
+ * reach a child process, and which image failures a caller can correct. Reading
9
+ * them from the host keeps one owner per rule, so a host change reaches this
10
+ * plugin instead of leaving a copy behind.
10
11
  *
11
- * Anything larger than a handful of lines (the JSON Schema subset validator)
12
- * lives in its own module.
12
+ * The OAuth provider and attachment admission reach their services through the
13
+ * optional `credentials` / `attachments` seams at runtime, so the service types
14
+ * here stay structural — only the rules are imported.
13
15
  *
14
16
  * @module runtime/mcp-client/host-seams
15
17
  */
16
- /**
17
- * The largest delay `setTimeout` accepts without overflowing to a 1ms clamp
18
- * (2^31 - 1). Shared guard for reconnect and callback timers.
19
- */
20
- export declare const MAX_TIMER_DELAY_MS = 2147483647;
21
- /** `DSH_*` environment namespace owned by the harness. */
22
- export declare const DSH_ENV_PREFIX: "DSH_";
23
- /**
24
- * Credential-shaped environment names are NOT forwarded to MCP server child
25
- * processes (the harness's own `DEEPSEEK_API_KEY`/secrets must not leak into a
26
- * spawned server implicitly). Deliberately supplied env entries survive
27
- * because the config's explicit env merges after the scrub.
28
- */
29
- export declare const SENSITIVE_ENV_PATTERN: RegExp;
30
- /**
31
- * The ambient parent environment minus credential-shaped names and minus all
32
- * `DSH_*` names — the canonical base every harness child starts from. `PATH`,
33
- * `HOME`, locale, and proxy variables survive, so child CLIs run normally;
34
- * harness identity never leaks implicitly. Both scrubs match case-insensitively:
35
- * Windows environment names are case-insensitive, so a parent `dsh_*` entry
36
- * would otherwise survive and read back as `$env:DSH_*` in the child.
37
- * @returns a fresh environment object safe to hand to a child spawn.
38
- */
39
- export declare function scrubbedParentEnv(): Record<string, string>;
40
- /** A credential record key: `<scope>/<id>` with both segments in the grammar below. */
41
- declare const credentialKeyBrand: unique symbol;
42
- export type CredentialKey = string & {
43
- readonly [credentialKeyBrand]: true;
44
- };
45
- /**
46
- * Brand a scope and an id as a {@link CredentialKey}.
47
- * @param scope - the owning plugin's registered name (here: the `mcp-auth` record scope).
48
- * @param id - the plugin's own addressing unit (here: the folded serverName).
49
- * @returns the branded key.
50
- * @throws TypeError when either segment is not a lowercase hyphenated identifier.
51
- */
52
- export declare function credentialKey(scope: string, id: string): CredentialKey;
18
+ import type { CredentialKey } from '@deepseek-ai/dsh-credentials';
19
+ import type { SaveImageAttachment } from '@deepseek-ai/dsh-attachment';
20
+ export { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout';
21
+ export { scrubbedParentEnv } from '@deepseek-ai/dsh-subprocess';
22
+ export { credentialKey, type CredentialKey } from '@deepseek-ai/dsh-credentials';
53
23
  /**
54
24
  * Structural mirror of the host `CredentialProvider` record surface the OAuth
55
25
  * provider needs. Typed structurally because the store arrives via the
@@ -64,26 +34,12 @@ export interface CredentialRecordStore {
64
34
  readRecord(key: CredentialKey): Promise<unknown>;
65
35
  modifyRecord(key: CredentialKey, mutate: (current: unknown) => Promise<unknown>): Promise<unknown>;
66
36
  }
37
+ export { isImageAdmissionError, type ImageMediaType, type SaveImageAttachment } from '@deepseek-ai/dsh-attachment';
67
38
  /**
68
- * Distinguish caller-correctable image admission failures from storage faults,
69
- * so an admission refusal projects text diagnostics while a storage fault is
70
- * reported as such.
71
- */
72
- export declare function isImageAdmissionError(error: unknown): boolean;
73
- /** Raster formats supported by the durable attachment vocabulary. */
74
- export type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';
75
- /** One decoded image handed to the host attachment store. */
76
- export interface SaveImageAttachment {
77
- data: Buffer;
78
- mediaType: ImageMediaType;
79
- }
80
- /**
81
- * Structural mirror of the host `AttachmentStore.saveImages` surface. The
82
- * returned refs are opaque host values that ride inside `ContentBlock`
83
- * image blocks; typed `unknown` here and narrowed by the model content
84
- * contract at the projection site.
39
+ * Structural mirror of the host attachment store surface this plugin writes
40
+ * through. The service is resolved off the tool host at call time, so its
41
+ * concrete class is deliberately not imported.
85
42
  */
86
43
  export interface AttachmentStoreLike {
87
44
  saveImages(images: readonly SaveImageAttachment[]): Promise<readonly unknown[]>;
88
45
  }
89
- export {};
@@ -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>;