dsh-agent-plugins-market 0.8.1 → 0.8.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 (157) hide show
  1. package/README.md +2 -2
  2. package/README.zh.md +2 -2
  3. package/client/client.js +1591 -1726
  4. package/client/client.js.map +1 -1
  5. package/lib/application/agent-roles.js +53 -0
  6. package/lib/application/catalog-context.js +2 -2
  7. package/lib/application/catalog.js +4 -8
  8. package/lib/{runtime → application}/deadline.js +1 -1
  9. package/lib/application/details.js +3 -3
  10. package/lib/application/json-file.js +43 -0
  11. package/lib/{runtime → application/lsp}/lsp-direct-config.js +9 -7
  12. package/lib/application/lsp/lsp-server-state.js +17 -0
  13. package/lib/{runtime → application/lsp}/lsp-status.js +22 -7
  14. package/lib/{runtime → application/lsp}/profile-seam.js +1 -1
  15. package/lib/application/lsp-service.js +5 -5
  16. package/lib/{runtime → application/mcp}/mcp-backend.js +3 -19
  17. package/lib/{runtime → application/mcp}/mcp-config.js +4 -4
  18. package/lib/{runtime → application/mcp}/mcp-direct-config.js +8 -49
  19. package/lib/{runtime → application/mcp}/mcp-overrides.js +3 -5
  20. package/lib/{runtime → application/mcp}/mcp-status.js +13 -7
  21. package/lib/application/mcp-service.js +11 -35
  22. package/lib/application/panel-resources.js +48 -11
  23. package/lib/{runtime → application/panels}/user-hooks.js +2 -2
  24. package/lib/{runtime → application/panels}/user-store.js +2 -2
  25. package/lib/application/ports.js +1 -0
  26. package/lib/application/project-agent-roles.js +1 -1
  27. package/lib/{runtime → application}/server-config.js +7 -17
  28. package/lib/application/snapshot-cache.js +1 -1
  29. package/lib/application/source-store.js +3 -4
  30. package/lib/{runtime → application/state}/state-store.js +5 -7
  31. package/lib/{runtime → application/state}/storage-migration.js +4 -4
  32. package/lib/catalog/source-catalog.js +0 -4
  33. package/lib/contracts/lsp.js +1 -0
  34. package/lib/contracts/market.js +0 -1
  35. package/lib/contracts/mcp.js +1 -0
  36. package/lib/index.js +42 -33
  37. package/lib/routes.js +2 -9
  38. package/lib/runtime/{agent-role-router.js → agents/agent-role-router.js} +7 -53
  39. package/lib/runtime/{subagent-catalog.js → agents/subagent-catalog.js} +24 -16
  40. package/lib/runtime/core/context.js +31 -0
  41. package/lib/runtime/{reconciler.js → core/reconciler.js} +5 -5
  42. package/lib/runtime/host/failure-detail.js +58 -0
  43. package/lib/runtime/{feedback-tool.js → host/feedback-tool.js} +1 -1
  44. package/lib/runtime/host/host-locale.js +83 -0
  45. package/lib/runtime/{settings-namespace.js → host/settings-namespace.js} +1 -1
  46. package/lib/runtime/host/shell-path.js +196 -0
  47. package/lib/runtime/{tool-registry-observer.js → host/tool-registry-observer.js} +2 -1
  48. package/lib/runtime/{lsp-mounts.js → lsp/lsp-mounts.js} +69 -20
  49. package/lib/runtime/{mcp-client → mcp/bridge}/bridge.js +52 -22
  50. package/lib/runtime/{mcp-client → mcp/bridge}/connection.js +2 -2
  51. package/lib/runtime/{mcp-client → mcp/bridge}/oauth.js +1 -1
  52. package/lib/runtime/{mcp-client → mcp/bridge}/tools.js +2 -2
  53. package/lib/runtime/{mcp-auth-record.js → mcp/mcp-auth-record.js} +1 -1
  54. package/lib/runtime/{mcp-mounts.js → mcp/mcp-mounts.js} +14 -7
  55. package/lib/runtime/{user-commands.js → panels/user-commands.js} +3 -3
  56. package/lib/runtime/{user-panels.js → panels/user-panels.js} +2 -2
  57. package/lib/runtime/{commands-mounts.js → surfaces/commands-mounts.js} +7 -7
  58. package/lib/runtime/{hooks-mounts.js → surfaces/hooks-mounts.js} +2 -2
  59. package/lib/runtime/{project-runtime.js → surfaces/project-runtime.js} +5 -5
  60. package/lib/runtime/{skills-provider.js → surfaces/skills-provider.js} +4 -4
  61. package/lib/types/application/agent-roles.d.ts +30 -0
  62. package/lib/types/application/catalog.d.ts +4 -7
  63. package/lib/types/application/details.d.ts +1 -1
  64. package/lib/types/application/json-file.d.ts +12 -0
  65. package/lib/types/{runtime → application/lsp}/lsp-direct-config.d.ts +1 -1
  66. package/lib/types/{runtime → application/lsp}/lsp-status.d.ts +3 -3
  67. package/lib/types/{runtime → application/mcp}/mcp-backend.d.ts +4 -9
  68. package/lib/types/{runtime/mcp-client/config.d.ts → application/mcp/mcp-bridge-config.d.ts} +11 -1
  69. package/lib/types/{runtime → application/mcp}/mcp-config.d.ts +6 -7
  70. package/lib/types/application/mcp/mcp-direct-config.d.ts +17 -0
  71. package/lib/types/{runtime → application/mcp}/mcp-overrides.d.ts +1 -1
  72. package/lib/types/{runtime → application/mcp}/mcp-status.d.ts +7 -7
  73. package/lib/types/application/mcp-service.d.ts +4 -11
  74. package/lib/types/application/panel-resources.d.ts +9 -2
  75. package/lib/types/{runtime → application/panels}/user-hooks.d.ts +1 -1
  76. package/lib/types/{runtime → application/panels}/user-store.d.ts +1 -1
  77. package/lib/types/application/ports.d.ts +17 -3
  78. package/lib/types/application/project-agent-roles.d.ts +1 -1
  79. package/lib/types/application/queries.d.ts +3 -6
  80. package/lib/types/{runtime → application}/regions.d.ts +1 -1
  81. package/lib/types/{runtime → application/state}/state-store.d.ts +2 -2
  82. package/lib/types/catalog/source-catalog.d.ts +0 -2
  83. package/lib/types/contracts/lsp-status.d.ts +6 -0
  84. package/lib/types/contracts/lsp.d.ts +16 -0
  85. package/lib/types/contracts/market.d.ts +1 -4
  86. package/lib/types/contracts/mcp-status.d.ts +21 -2
  87. package/lib/types/contracts/mcp.d.ts +20 -0
  88. package/lib/types/model/types.d.ts +0 -14
  89. package/lib/types/runtime/{agent-role-router.d.ts → agents/agent-role-router.d.ts} +3 -28
  90. package/lib/types/runtime/{subagent-catalog.d.ts → agents/subagent-catalog.d.ts} +6 -6
  91. package/lib/types/runtime/core/context.d.ts +14 -0
  92. package/lib/types/runtime/{reconcile-scheduler.d.ts → core/reconcile-scheduler.d.ts} +2 -2
  93. package/lib/types/runtime/{reconciler.d.ts → core/reconciler.d.ts} +8 -8
  94. package/lib/types/runtime/host/failure-detail.d.ts +6 -0
  95. package/lib/types/runtime/host/host-locale.d.ts +66 -0
  96. package/lib/types/runtime/{model-catalog.d.ts → host/model-catalog.d.ts} +1 -1
  97. package/lib/types/runtime/{settings-namespace.d.ts → host/settings-namespace.d.ts} +2 -2
  98. package/lib/types/runtime/host/shell-path.d.ts +70 -0
  99. package/lib/types/runtime/{lsp-mounts.d.ts → lsp/lsp-mounts.d.ts} +17 -11
  100. package/lib/types/runtime/{mcp-client → mcp/bridge}/bridge.d.ts +1 -1
  101. package/lib/types/runtime/{mcp-client → mcp/bridge}/connection.d.ts +3 -11
  102. package/lib/types/runtime/{mcp-client → mcp/bridge}/host-contract.d.ts +1 -1
  103. package/lib/types/runtime/{mcp-client → mcp/bridge}/oauth.d.ts +1 -1
  104. package/lib/types/runtime/{mcp-client → mcp/bridge}/transport.d.ts +1 -1
  105. package/lib/types/runtime/{mcp-auth-record.d.ts → mcp/mcp-auth-record.d.ts} +1 -1
  106. package/lib/types/runtime/{mcp-credentials.d.ts → mcp/mcp-credentials.d.ts} +1 -1
  107. package/lib/types/runtime/{mcp-mounts.d.ts → mcp/mcp-mounts.d.ts} +5 -11
  108. package/lib/types/runtime/{user-commands.d.ts → panels/user-commands.d.ts} +1 -1
  109. package/lib/types/runtime/{user-panels.d.ts → panels/user-panels.d.ts} +1 -1
  110. package/lib/types/runtime/{commands-mounts.d.ts → surfaces/commands-mounts.d.ts} +2 -2
  111. package/lib/types/runtime/{hooks-mounts.d.ts → surfaces/hooks-mounts.d.ts} +1 -1
  112. package/lib/types/runtime/{project-runtime.d.ts → surfaces/project-runtime.d.ts} +3 -3
  113. package/lib/types/runtime/{skills-provider.d.ts → surfaces/skills-provider.d.ts} +1 -1
  114. package/package.json +35 -32
  115. package/lib/runtime/host-locale.js +0 -89
  116. package/lib/runtime/legacy-root-migration.js +0 -12
  117. package/lib/runtime/lsp-server-state.js +0 -19
  118. package/lib/runtime/mcp-client/json-schema-subset.js +0 -181
  119. package/lib/types/runtime/host-locale.d.ts +0 -31
  120. package/lib/types/runtime/legacy-root-migration.d.ts +0 -2
  121. package/lib/types/runtime/mcp-client/json-schema-subset.d.ts +0 -58
  122. package/lib/types/runtime/mcp-direct-config.d.ts +0 -39
  123. /package/lib/{runtime/mcp-client/config.js → application/mcp/mcp-bridge-config.js} +0 -0
  124. /package/lib/{runtime → application/mcp}/mcp-redaction.js +0 -0
  125. /package/lib/{runtime → application}/regions.js +0 -0
  126. /package/lib/runtime/{agent-role-names.js → agents/agent-role-names.js} +0 -0
  127. /package/lib/runtime/{mount-lifecycle.js → core/mount-lifecycle.js} +0 -0
  128. /package/lib/runtime/{reconcile-scheduler.js → core/reconcile-scheduler.js} +0 -0
  129. /package/lib/runtime/{source-auto-update.js → core/source-auto-update.js} +0 -0
  130. /package/lib/runtime/{timer-seat.js → core/timer-seat.js} +0 -0
  131. /package/lib/runtime/{model-catalog.js → host/model-catalog.js} +0 -0
  132. /package/lib/runtime/{plugin-message-source.js → host/plugin-message-source.js} +0 -0
  133. /package/lib/runtime/{mcp-client → mcp/bridge}/host-contract.js +0 -0
  134. /package/lib/runtime/{mcp-client → mcp/bridge}/host-seams.js +0 -0
  135. /package/lib/runtime/{mcp-client → mcp/bridge}/plugin-identity.js +0 -0
  136. /package/lib/runtime/{mcp-client → mcp/bridge}/projection.js +0 -0
  137. /package/lib/runtime/{mcp-client → mcp/bridge}/transport.js +0 -0
  138. /package/lib/runtime/{mcp-credentials.js → mcp/mcp-credentials.js} +0 -0
  139. /package/lib/runtime/{dynamic-context.js → surfaces/dynamic-context.js} +0 -0
  140. /package/lib/types/{runtime → application}/deadline.d.ts +0 -0
  141. /package/lib/types/{runtime → application/lsp}/lsp-server-state.d.ts +0 -0
  142. /package/lib/types/{runtime → application/lsp}/profile-seam.d.ts +0 -0
  143. /package/lib/types/{runtime → application/mcp}/mcp-redaction.d.ts +0 -0
  144. /package/lib/types/{runtime → application}/server-config.d.ts +0 -0
  145. /package/lib/types/{runtime → application/state}/storage-migration.d.ts +0 -0
  146. /package/lib/types/runtime/{agent-role-names.d.ts → agents/agent-role-names.d.ts} +0 -0
  147. /package/lib/types/runtime/{mount-lifecycle.d.ts → core/mount-lifecycle.d.ts} +0 -0
  148. /package/lib/types/runtime/{source-auto-update.d.ts → core/source-auto-update.d.ts} +0 -0
  149. /package/lib/types/runtime/{timer-seat.d.ts → core/timer-seat.d.ts} +0 -0
  150. /package/lib/types/runtime/{feedback-tool.d.ts → host/feedback-tool.d.ts} +0 -0
  151. /package/lib/types/runtime/{plugin-message-source.d.ts → host/plugin-message-source.d.ts} +0 -0
  152. /package/lib/types/runtime/{tool-registry-observer.d.ts → host/tool-registry-observer.d.ts} +0 -0
  153. /package/lib/types/runtime/{mcp-client → mcp/bridge}/host-seams.d.ts +0 -0
  154. /package/lib/types/runtime/{mcp-client → mcp/bridge}/plugin-identity.d.ts +0 -0
  155. /package/lib/types/runtime/{mcp-client → mcp/bridge}/projection.d.ts +0 -0
  156. /package/lib/types/runtime/{mcp-client → mcp/bridge}/tools.d.ts +0 -0
  157. /package/lib/types/runtime/{dynamic-context.d.ts → surfaces/dynamic-context.d.ts} +0 -0
@@ -20,7 +20,9 @@
20
20
  * @module runtime/mcp-client/bridge
21
21
  */
22
22
  import { resolveReconnectPolicy, startConnection } from './connection.js';
23
- import { validateConfig } from './config.js';
23
+ import { validateConfig } from '../../../application/mcp/mcp-bridge-config.js';
24
+ import { resolveDeclaredCommand } from '../../host/shell-path.js';
25
+ import { optionalService } from '../../core/context.js';
24
26
  /** Cordis plugin name used by loader diagnostics. */
25
27
  export const name = 'market-mcp-client';
26
28
  /** Services required by this plugin. */
@@ -33,19 +35,6 @@ export const inject = ['tools'];
33
35
  * defense for direct programmatic loads.
34
36
  */
35
37
  const activeServerNames = new WeakMap();
36
- /** Tolerantly read an optional service from the cordis context. */
37
- function optionalService(ctx, serviceName) {
38
- try {
39
- const reader = ctx;
40
- const service = reader.get?.(serviceName);
41
- // A missing service either reads as undefined or throws (cordis strict
42
- // mode); both mean "not mounted".
43
- return service === null ? undefined : service;
44
- }
45
- catch {
46
- return undefined;
47
- }
48
- }
49
38
  /** Adapt the cordis context onto the structural host the bridge modules use. */
50
39
  function toToolHost(ctx) {
51
40
  const logger = {
@@ -74,6 +63,32 @@ function toToolHost(ctx) {
74
63
  getService: serviceName => optionalService(ctx, serviceName)
75
64
  };
76
65
  }
66
+ /**
67
+ * Resolve one stdio command before the SDK spawns it, extending the child
68
+ * `PATH` from the login shell only when the current environment cannot find
69
+ * the command.
70
+ *
71
+ * An explicit `env.PATH` is the author's or user's declaration and is never
72
+ * touched: the bridge respects it verbatim and does not even probe. Without
73
+ * one, the child inherits the scrubbed parent `PATH`; when that cannot resolve
74
+ * the command (the desktop case, where `npx` is absent) the login shell's
75
+ * directories are appended, and the extension travels beside the config as
76
+ * `config.env.PATH`.
77
+ *
78
+ * Resolution never rejects: a command that stays unresolved keeps today's
79
+ * behavior (a spawn that fails with its own `ENOENT`), and the searched `PATH`
80
+ * is returned as a diagnostic so the failure can say what was tried.
81
+ */
82
+ async function resolveStdioCommand(ctx, config) {
83
+ if (config.transport !== 'stdio')
84
+ return { config };
85
+ const resolution = await resolveDeclaredCommand(ctx, config.command, config.env);
86
+ if (resolution === undefined)
87
+ return { config };
88
+ const { path, diagnostic } = resolution;
89
+ const resolved = path === undefined ? config : { ...config, env: { ...config.env, PATH: path } };
90
+ return { config: resolved, ...(diagnostic === undefined ? {} : { diagnostic }) };
91
+ }
77
92
  /**
78
93
  * Connect one MCP server and publish its initial tool generation before
79
94
  * activation. Remains explicitly `async`: Cordis treats a prototype-bearing
@@ -87,7 +102,9 @@ export async function apply(ctx, config) {
87
102
  // Fail loud at load: programmatic construction bypasses any schema layer,
88
103
  // so every invariant is re-judged here before any effect registers.
89
104
  validateConfig(config);
90
- const reconnect = resolveReconnectPolicy(config.reconnect, `mcp-client(${config.serverName}): reconnect`);
105
+ const resolution = await resolveStdioCommand(ctx, config);
106
+ const resolvedConfig = resolution.config;
107
+ const reconnect = resolveReconnectPolicy(resolvedConfig.reconnect, `mcp-client(${resolvedConfig.serverName}): reconnect`);
91
108
  // Reserve the namespace next: a duplicate `serverName` fails THIS instance
92
109
  // at load with an actionable error and leaves the earlier instance intact.
93
110
  ctx.effect(() => {
@@ -96,11 +113,11 @@ export async function apply(ctx, config) {
96
113
  names = new Set();
97
114
  activeServerNames.set(ctx.root, names);
98
115
  }
99
- if (names.has(config.serverName)) {
100
- throw new Error(`market-mcp-client: serverName "${config.serverName}" is already in use by another bridge instance — pick a unique serverName`);
116
+ if (names.has(resolvedConfig.serverName)) {
117
+ throw new Error(`market-mcp-client: serverName "${resolvedConfig.serverName}" is already in use by another bridge instance — pick a unique serverName`);
101
118
  }
102
- names.add(config.serverName);
103
- return () => void names.delete(config.serverName);
119
+ names.add(resolvedConfig.serverName);
120
+ return () => void names.delete(resolvedConfig.serverName);
104
121
  }, 'market-mcp-client.serverName');
105
122
  // The supervisor owns the client/transport generations, the reconnect
106
123
  // loop, and the live tool registrations; disposal stops reconnection,
@@ -110,7 +127,7 @@ export async function apply(ctx, config) {
110
127
  // no-persistence configuration.
111
128
  const host = toToolHost(ctx);
112
129
  const credentials = optionalService(ctx, 'credentials');
113
- const connection = startConnection(host, config, reconnect, credentials);
130
+ const connection = startConnection(host, resolvedConfig, reconnect, credentials);
114
131
  ctx.effect(() => {
115
132
  return () => connection.dispose();
116
133
  }, 'market-mcp-client.connection');
@@ -120,7 +137,20 @@ export async function apply(ctx, config) {
120
137
  // fiber (Cordis rolls it back); otherwise the error is logged and the
121
138
  // supervisor enters its reconnect loop.
122
139
  const outcome = await connection.ready;
123
- if (outcome.error !== undefined && config.failOnStartupError) {
124
- throw new Error(`mcp-client(${config.serverName}): initial connection or tool synchronization failed`, { cause: outcome.error });
140
+ if (outcome.error !== undefined && resolvedConfig.failOnStartupError) {
141
+ // The resolution fact explains why the spawn failed (or what was searched),
142
+ // so it rides the cause chain into the mount diagnostic ahead of the raw
143
+ // spawn error. On the happy path there is nothing to add and the chain is
144
+ // exactly today's.
145
+ const cause = resolution.diagnostic === undefined ? outcome.error : new Error(resolution.diagnostic, { cause: outcome.error });
146
+ throw new Error(`mcp-client(${resolvedConfig.serverName}): initial connection or tool synchronization failed`, { cause });
147
+ }
148
+ // A command that resolved only after the login shell extended PATH leaves a
149
+ // trace, so "why does this work now" is answerable from the log. With
150
+ // failOnStartupError=false a failed resolution reaches here too; the env.PATH
151
+ // guard excludes it, because PATH is only set on a successful extension —
152
+ // the transport check is the narrowing that makes env exist at all.
153
+ if (resolvedConfig.transport === 'stdio' && resolvedConfig.env.PATH !== undefined && resolution.diagnostic !== undefined) {
154
+ ctx.logger?.info?.(`market-mcp-client(${resolvedConfig.serverName}): ${resolution.diagnostic}`);
125
155
  }
126
156
  }
@@ -23,11 +23,11 @@
23
23
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
24
24
  import { ToolListChangedNotificationSchema } from '@modelcontextprotocol/sdk/types.js';
25
25
  import { MAX_TIMER_DELAY_MS } from './host-seams.js';
26
- import { redactErrorMessage } from '../mcp-redaction.js';
26
+ import { redactErrorMessage } from '../../../application/mcp/mcp-redaction.js';
27
27
  import { PLUGIN_NAME, PLUGIN_VERSION } from './plugin-identity.js';
28
28
  import { createTransport } from './transport.js';
29
29
  import { syncTools } from './tools.js';
30
- import { DEFAULT_STARTUP_TIMEOUT_MS } from './config.js';
30
+ import { DEFAULT_STARTUP_TIMEOUT_MS } from '../../../application/mcp/mcp-bridge-config.js';
31
31
  /** Defaults shared by the config and {@link resolveReconnectPolicy}. */
32
32
  export const RECONNECT_DEFAULTS = Object.freeze({
33
33
  enabled: true,
@@ -31,7 +31,7 @@ import { createServer } from 'node:http';
31
31
  import { randomBytes } from 'node:crypto';
32
32
  import { isDeepStrictEqual } from 'node:util';
33
33
  import { credentialKey, scrubbedParentEnv } from './host-seams.js';
34
- import { redactErrorMessage, redactUrl } from '../mcp-redaction.js';
34
+ import { redactErrorMessage, redactUrl } from '../../../application/mcp/mcp-redaction.js';
35
35
  import { PLUGIN_NAME, PLUGIN_VERSION } from './plugin-identity.js';
36
36
  /** OAuth client identity presented during dynamic registration. */
37
37
  const CLIENT_NAME = `DeepSeek Harness (${PLUGIN_NAME})`;
@@ -19,9 +19,9 @@ import { createHash } from 'node:crypto';
19
19
  import { isDeepStrictEqual } from 'node:util';
20
20
  import { ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js';
21
21
  import { z } from 'zod';
22
- import { assertSupportedJsonSchema } from './json-schema-subset.js';
22
+ import { assertSupportedJsonSchema } from '@deepseek-ai/dsh-tools';
23
23
  import { containsImage, extractText, prepareImageProjection } from './projection.js';
24
- import { redactErrorMessage } from '../mcp-redaction.js';
24
+ import { redactErrorMessage } from '../../../application/mcp/mcp-redaction.js';
25
25
  /**
26
26
  * DeepSeek function-name contract: at most 64 characters. Wire-protocol
27
27
  * constant, not configuration.
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @module runtime/mcp-auth-record
10
10
  */
11
- import { credentialKey } from './mcp-client/host-seams.js';
11
+ import { credentialKey } from './bridge/host-seams.js';
12
12
  /** Credential-record scope for MCP OAuth state; per-server ids follow it. */
13
13
  export const MCP_AUTH_RECORD_SCOPE = 'mcp-auth';
14
14
  /**
@@ -1,11 +1,12 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { mkdir } from 'node:fs/promises';
3
- import * as mcpBridge from './mcp-client/bridge.js';
4
- import { toMcpMounts } from './mcp-config.js';
3
+ import * as mcpBridge from './bridge/bridge.js';
4
+ import { toMcpMounts } from '../../application/mcp/mcp-config.js';
5
5
  import { mcpCredentialResolver } from './mcp-credentials.js';
6
- import { SerialPassQueue, RetryScheduler } from './mount-lifecycle.js';
7
- import { qualifiedSuiteId, suiteDataDir } from '../catalog/paths.js';
8
- import { redactErrorMessage } from './mcp-redaction.js';
6
+ import { SerialPassQueue, RetryScheduler } from '../core/mount-lifecycle.js';
7
+ import { qualifiedSuiteId, suiteDataDir } from '../../catalog/paths.js';
8
+ import { redactErrorMessage } from '../../application/mcp/mcp-redaction.js';
9
+ import { causeMessages } from '../host/failure-detail.js';
9
10
  export class McpMountRegistry {
10
11
  ctx;
11
12
  pluginDataRoot;
@@ -157,7 +158,13 @@ export class McpMountRegistry {
157
158
  // reported so a transient error does not shadow the final state.
158
159
  const failure = await this.mountWith(entry.request);
159
160
  if (failure !== undefined) {
160
- diagnostics.push({ suiteId: qualifiedSuiteId(entry.suite.sourceId, entry.suite.id), serverKey: entry.serverKey, reason: failure.reason, code: failure.code });
161
+ diagnostics.push({
162
+ suiteId: qualifiedSuiteId(entry.suite.sourceId, entry.suite.id),
163
+ serverKey: entry.serverKey,
164
+ reason: failure.reason,
165
+ code: failure.code,
166
+ ...(failure.causes === undefined || failure.causes.length === 0 ? {} : { causes: failure.causes })
167
+ });
161
168
  // Foreign and duplicate skips are deterministic, not transient:
162
169
  // retrying them just burns the attempt budget and log lines. The
163
170
  // next full reconcile re-checks them anyway, so the self-heal path
@@ -263,7 +270,7 @@ export class McpMountRegistry {
263
270
  // Ignore teardown errors: the startup failure is the real signal.
264
271
  }
265
272
  }
266
- return { reason: `mount failed: ${redactErrorMessage(error instanceof Error ? error.message : String(error))}`, code: 'mount-failed' };
273
+ return { reason: `mount failed: ${redactErrorMessage(error instanceof Error ? error.message : String(error))}`, code: 'mount-failed', causes: causeMessages(error) };
267
274
  }
268
275
  this.live.set(mountKey(request.suiteId, request.serverKey), {
269
276
  suiteId: request.suiteId,
@@ -10,9 +10,9 @@
10
10
  * @module runtime/user-commands
11
11
  */
12
12
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
13
- import { commandCallName } from '../model/command-names.js';
14
- import { USER_ENTRY_PATH } from './user-store.js';
15
- import { pluginMarketSource } from './plugin-message-source.js';
13
+ import { commandCallName } from '../../model/command-names.js';
14
+ import { USER_ENTRY_PATH } from '../../application/panels/user-store.js';
15
+ import { pluginMarketSource } from '../host/plugin-message-source.js';
16
16
  /** Register/unregister user-panel commands to match the panel's enabled entries. */
17
17
  export class UserCommandMountRegistry {
18
18
  ctx;
@@ -30,8 +30,8 @@
30
30
  * @module runtime/user-panels
31
31
  */
32
32
  import { dirname } from 'node:path';
33
- import { skillEntryRejection } from '../catalog/skills-parse.js';
34
- import { deleteEntryDocument, entryExists, listEntryDocuments, listEntryFiles, readEntryDocument, resolveEntryDocument, SKILL_ENTRY_SHAPES, USER_ENTRY_NAME, USER_ENTRY_PATH, userEntryDir, writeEntryDocument, writeEntryFile } from './user-store.js';
33
+ import { skillEntryRejection } from '../../catalog/skills-parse.js';
34
+ import { deleteEntryDocument, entryExists, listEntryDocuments, listEntryFiles, readEntryDocument, resolveEntryDocument, SKILL_ENTRY_SHAPES, USER_ENTRY_NAME, USER_ENTRY_PATH, userEntryDir, writeEntryDocument, writeEntryFile } from '../../application/panels/user-store.js';
35
35
  /** The skill-source label user-panel entries carry into the skill registry. */
36
36
  export const USER_PANEL_SKILL_SOURCE = 'user-panel';
37
37
  /**
@@ -1,13 +1,13 @@
1
1
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
2
2
  import { parse as parseYaml } from 'yaml';
3
- import { stripFrontmatter } from '../catalog/skills-parse.js';
4
- import { parseFrontmatterRecord } from './user-store.js';
5
- import { qualifiedSuiteId, suiteDataDir } from '../catalog/paths.js';
6
- import { expandPluginPaths, pluginRootOf } from '../catalog/plugin-variables.js';
7
- import { defaultMarkdownResources, resourceText, resourceCommandName } from '../catalog/component-files.js';
8
- import { bindHostLocale } from './host-locale.js';
3
+ import { stripFrontmatter } from '../../catalog/skills-parse.js';
4
+ import { parseFrontmatterRecord } from '../../application/panels/user-store.js';
5
+ import { qualifiedSuiteId, suiteDataDir } from '../../catalog/paths.js';
6
+ import { expandPluginPaths, pluginRootOf } from '../../catalog/plugin-variables.js';
7
+ import { defaultMarkdownResources, resourceText, resourceCommandName } from '../../catalog/component-files.js';
8
+ import { bindHostLocale } from '../host/host-locale.js';
9
9
  import { injectDynamicContext, shellSeamOf } from './dynamic-context.js';
10
- import { pluginMarketSource } from './plugin-message-source.js';
10
+ import { pluginMarketSource } from '../host/plugin-message-source.js';
11
11
  const COMMAND_NAME = /^[a-z][a-z0-9_-]*$/;
12
12
  export class CommandMountRegistry {
13
13
  ctx;
@@ -18,8 +18,8 @@ import { writeFileAtomic } from '@deepseek-ai/dsh-atomic-write';
18
18
  import { tmpdir } from 'node:os';
19
19
  import { createHash } from 'node:crypto';
20
20
  import { join } from 'node:path';
21
- import { SerialPassQueue } from './mount-lifecycle.js';
22
- import { qualifiedSuiteId } from '../catalog/paths.js';
21
+ import { SerialPassQueue } from '../core/mount-lifecycle.js';
22
+ import { qualifiedSuiteId } from '../../catalog/paths.js';
23
23
  export class HooksMountRegistry {
24
24
  ctx;
25
25
  live = new Map();
@@ -1,11 +1,11 @@
1
1
  import { CommandMountRegistry } from './commands-mounts.js';
2
- import { expandPluginPaths, pluginRootOf } from '../catalog/plugin-variables.js';
3
- import { suiteDataDir } from '../catalog/paths.js';
4
- import { McpMountRegistry } from './mcp-mounts.js';
2
+ import { expandPluginPaths, pluginRootOf } from '../../catalog/plugin-variables.js';
3
+ import { suiteDataDir } from '../../catalog/paths.js';
4
+ import { McpMountRegistry } from '../mcp/mcp-mounts.js';
5
5
  import { HooksMountRegistry } from './hooks-mounts.js';
6
6
  import { readFile } from 'node:fs/promises';
7
- import { stripFrontmatter } from '../catalog/skills-parse.js';
8
- import { parseFrontmatterRecord } from './user-store.js';
7
+ import { stripFrontmatter } from '../../catalog/skills-parse.js';
8
+ import { parseFrontmatterRecord } from '../../application/panels/user-store.js';
9
9
  /** Mount under existing and newly created agents; the caller owns refresh and teardown. */
10
10
  export function mountProjectCommands(ctx, catalog, t, dataRoot) {
11
11
  return mountProjectSurface(ctx, catalog, 'commands', scope => new CommandMountRegistry(scope, t, dataRoot));
@@ -14,10 +14,10 @@
14
14
  * directory, so CC-authored skills work verbatim under the harness.
15
15
  */
16
16
  import { readFile } from 'node:fs/promises';
17
- import { parseSkillFrontmatter, stripFrontmatter } from '../catalog/skills-parse.js';
18
- import { parseFrontmatterRecord } from './user-store.js';
19
- import { expandPluginPaths, pluginRootOf } from '../catalog/plugin-variables.js';
20
- import { suiteDataDir } from '../catalog/paths.js';
17
+ import { parseSkillFrontmatter, stripFrontmatter } from '../../catalog/skills-parse.js';
18
+ import { parseFrontmatterRecord } from '../../application/panels/user-store.js';
19
+ import { expandPluginPaths, pluginRootOf } from '../../catalog/plugin-variables.js';
20
+ import { suiteDataDir } from '../../catalog/paths.js';
21
21
  import { injectDynamicContext } from './dynamic-context.js';
22
22
  export const SUITE_PROJECT_SOURCE = 'agent-plugin-project';
23
23
  export const SUITE_USER_SOURCE = 'agent-plugin-user';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Panel identity is preserved so identically named cards from different suites remain addressable.
3
+ */
4
+ export interface AgentRoleEntry {
5
+ name: string;
6
+ path: string;
7
+ description: string;
8
+ disabled: boolean;
9
+ title?: string;
10
+ rawText?: string;
11
+ /** Suite checkout root the card's `${PLUGIN_ROOT}` variables resolve to; absent for project-native files. */
12
+ suiteRoot?: string;
13
+ /** The suite's `${PLUGIN_DATA}` directory; absent for project-native files. */
14
+ suiteData?: string;
15
+ }
16
+ /**
17
+ * The executable part of one card. `tools` / `disallowedTools` stay in the file
18
+ * and are preserved by the editors, but they are not applied.
19
+ */
20
+ export interface AgentRolePolicy {
21
+ content: string;
22
+ model?: string;
23
+ provider?: string;
24
+ reasoningEffort?: string;
25
+ title?: string;
26
+ description?: string;
27
+ disabled: boolean;
28
+ }
29
+ /** Strict YAML parsing prevents malformed routing metadata from silently inheriting wider privileges. */
30
+ export declare function parseAgentRole(text: string): AgentRolePolicy;
@@ -1,11 +1,10 @@
1
1
  import type { LspLegacySeamMigration, LspStatusPayload } from '../contracts/lsp-status.js';
2
2
  import type { OverviewPayload, ServerConfigPayload, SkillContent, SourceProgress, SuiteDetail } from '../contracts/market.js';
3
- import type { McpStatusPayload } from '../contracts/mcp-status.js';
3
+ import type { McpStatusPayload } from './mcp/mcp-status.js';
4
4
  import type { SourceRef, Suite, SuiteSurfaceKey } from '../model/types.js';
5
- import type { McpBackend } from '../runtime/mcp-backend.js';
6
- import { type McpImportResult } from '../runtime/mcp-direct-config.js';
7
- import type { McpMountDiagnostic } from '../runtime/mcp-mounts.js';
8
- import { type McpServerOverride, type McpSuiteOverrides } from '../runtime/mcp-overrides.js';
5
+ import type { McpBackend } from '../contracts/mcp.js';
6
+ import type { McpMountDiagnostic } from '../contracts/mcp.js';
7
+ import { type McpServerOverride, type McpSuiteOverrides } from './mcp/mcp-overrides.js';
9
8
  import { type CatalogGitOptions, type CatalogOptions } from './catalog-context.js';
10
9
  import { type LspServerTable, type McpBackendInfo, type SourceInput, type SourcePatch } from './ports.js';
11
10
  import { type CatalogSnapshot } from './snapshot-cache.js';
@@ -95,8 +94,6 @@ export declare class Catalog implements MarketService {
95
94
  mcpStatus(): Promise<McpStatusPayload>;
96
95
  /** Persist a user-owned MCP service and reconcile its bridge mount. */
97
96
  addMcpServer(name: string, server: unknown): Promise<void>;
98
- /** Import several pasted services in one write; each entry reports its own outcome. */
99
- importMcpServers(servers: unknown, overwrite: boolean): Promise<McpImportResult>;
100
97
  /** Read effective service configuration without exposing credential literals. */
101
98
  serverConfig(kind: 'mcp' | 'lsp', id: string): Promise<ServerConfigPayload>;
102
99
  /** Validate a complete replacement before writing; plugin checkouts remain untouched. */
@@ -1,6 +1,6 @@
1
1
  import type { SkillContent, SuiteDetail } from '../contracts/market.js';
2
2
  import { type InstalledEntry, type Suite } from '../model/types.js';
3
- import type { McpMountDiagnostic as McpDiagnostic } from '../runtime/mcp-mounts.js';
3
+ import type { McpMountDiagnostic as McpDiagnostic } from '../contracts/mcp.js';
4
4
  /** Build the detail response for one normalized suite. */
5
5
  export declare function buildSuiteDetail(suite: Suite, installed: InstalledEntry | undefined, diagnostics: readonly McpDiagnostic[], mcpOverrides?: Record<string, Record<string, unknown>>): Promise<SuiteDetail>;
6
6
  /** Read one skill body from a normalized suite. */
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Read one JSON document. Resolves `undefined` when the file is absent or its
3
+ * text is empty; a `parse` that wants an absent file to read as a default
4
+ * handles `undefined` itself.
5
+ */
6
+ export declare function readJsonFile(path: string): Promise<unknown>;
7
+ /**
8
+ * Write one JSON document atomically: two-space indent, trailing newline, and
9
+ * the private-file modes the plugin's state files carry (0o600 file, 0o700
10
+ * directory).
11
+ */
12
+ export declare function writeJsonDocument(path: string, document: unknown): Promise<void>;
@@ -1,4 +1,4 @@
1
- import type { LspServerSpec } from '../model/types.js';
1
+ import type { LspServerSpec } from '../../model/types.js';
2
2
  /** The direct LSP server configuration file path. */
3
3
  export declare function lspServersPath(agentsRoot: string): string;
4
4
  /** Load the user-configured LSP servers; unreadable or invalid files yield an empty table. */
@@ -12,9 +12,9 @@
12
12
  * Direct user-configured rows follow the same model under the sentinel suite
13
13
  * id `direct` (mirroring mcp-status's `plugin`/`direct` split).
14
14
  */
15
- import type { LspStatusPayload } from '../contracts/lsp-status.js';
16
- import type { LspMountDiagnostic } from './lsp-mounts.js';
17
- import type { LspServerSpec, Suite } from '../model/types.js';
15
+ import type { LspStatusPayload } from '../../contracts/lsp-status.js';
16
+ import type { LspMountDiagnostic } from '../../contracts/lsp.js';
17
+ import type { LspServerSpec, Suite } from '../../model/types.js';
18
18
  /** Sentinel suite id for user-configured (non-suite) LSP servers. */
19
19
  export declare const DIRECT_LSP_SUITE_ID = "direct";
20
20
  /** The subset of LspMountRegistry the aggregator consumes (structural, for tests). */
@@ -8,14 +8,13 @@
8
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
- * servers when the switch flips. `readMcpBackend` remains only as the
12
- * one-time migration from the earlier data-root `settings.json` choice.
11
+ * servers when the switch flips.
13
12
  *
14
- * @module runtime/mcp-backend
13
+ * @module application/mcp-backend
15
14
  */
16
15
  import z from '@deepseek-ai/schemastery';
17
- /** The MCP mount backend the market uses for suite servers. */
18
- export type McpBackend = 'builtin' | 'host';
16
+ import type { McpBackend } from '../../contracts/mcp.js';
17
+ export type { McpBackend };
19
18
  /**
20
19
  * Schema of the market settings namespace: the switches this plugin's config
21
20
  * card serves, with the defaults declared to the host. The values themselves
@@ -42,10 +41,6 @@ export declare const MarketSettingsSchema: z<Schemastery.ObjectS<NoInfer<{
42
41
  readonly feedbackEnabled: z<boolean, boolean, "defined">;
43
42
  readonly autoUpdateSources: z<boolean, boolean, "defined">;
44
43
  }>>, "plain">;
45
- /** Path of the legacy persisted settings file under the plugin data root. */
46
- export declare function marketSettingsPath(dataRoot: string): string;
47
- /** Read the legacy persisted backend; absent or invalid values read as the default. */
48
- export declare function readMcpBackend(dataRoot: string): Promise<McpBackend>;
49
44
  /** What the host client probe reports: resolvability plus its version. */
50
45
  export interface HostMcpClientProbe {
51
46
  available: boolean;
@@ -8,7 +8,17 @@
8
8
  *
9
9
  * @module runtime/mcp-client/config
10
10
  */
11
- import type { ReconnectConfig } from './connection.js';
11
+ /** Automatic-reconnect tuning the transport configs carry. */
12
+ export interface ReconnectConfig {
13
+ /** Reconnect automatically after a lost connection (default true). */
14
+ enabled?: boolean;
15
+ /** First reconnect delay in milliseconds; doubles per consecutive failed attempt (default 500). */
16
+ initialDelayMs?: number;
17
+ /** Backoff ceiling in milliseconds; also the uptime after which the attempt budget resets (default 30000). */
18
+ maxDelayMs?: number;
19
+ /** Consecutive failed attempts per outage before giving up for good (default 10). */
20
+ maxAttempts?: number;
21
+ }
12
22
  import type { McpServerPolicy } from '../../model/types.js';
13
23
  /** Default timeout for individual MCP tool calls (ms). */
14
24
  export declare const DEFAULT_TOOL_CALL_TIMEOUT_MS = 60000;
@@ -1,6 +1,7 @@
1
- import type { Config } from './mcp-client/config.js';
1
+ import type { Config } from './mcp-bridge-config.js';
2
2
  import { type McpServerOverride, type McpSuiteOverrides } from './mcp-overrides.js';
3
- import type { HarnessMcpPolicy, McpServer, McpServerPolicy, McpServerSse, McpServerStdio, McpServerStreamableHttp, Suite } from '../model/types.js';
3
+ import type { McpStatusCode } from '../../contracts/mcp-status.js';
4
+ import type { HarnessMcpPolicy, McpServer, McpServerPolicy, McpServerSse, McpServerStdio, McpServerStreamableHttp, Suite } from '../../model/types.js';
4
5
  export interface McpMountRequest {
5
6
  suiteId: string;
6
7
  serverKey: string;
@@ -43,15 +44,13 @@ export interface ResolvedMcpPolicy {
43
44
  /** Startup timeout. */
44
45
  startupTimeout: McpTimeoutResolution;
45
46
  }
46
- export type McpMountFailureCode = 'unsupported-transport' | 'missing-credential' | 'credential-error' | 'unmount-failed' | 'mount-failed'
47
- /** The derived serverName's namespace is already mounted by another MCP client — informational, not a failure. */
48
- | 'foreign-mount'
49
- /** Another source's identical suite/server pair mounted first — this copy is redundant, informational. */
50
- | 'duplicate-mount';
47
+ export type McpMountFailureCode = Extract<McpStatusCode, 'unsupported-transport' | 'missing-credential' | 'credential-error' | 'unmount-failed' | 'mount-failed' | 'foreign-mount' | 'duplicate-mount'>;
51
48
  export interface McpMountFailure {
52
49
  serverKey: string;
53
50
  reason: string;
54
51
  code?: McpMountFailureCode;
52
+ /** The messages under the failure's `cause` chain, outermost first. */
53
+ causes?: string[];
55
54
  credentialRefs?: string[];
56
55
  }
57
56
  /** Optional DSH credential resolver used while building an in-memory mount. */
@@ -0,0 +1,17 @@
1
+ import { type McpSuiteConfig, type Suite } from '../../model/types.js';
2
+ export declare const USER_MCP_SOURCE = "@user-mcp";
3
+ export declare const USER_MCP_SUITE = "user-mcp";
4
+ /**
5
+ * Load the user's own MCP declaration file.
6
+ *
7
+ * The suite always carries an `mcp` document — an absent or malformed
8
+ * `mcp.json` leaves an empty one — so callers read `.mcp.servers` directly
9
+ * instead of re-checking the optional field.
10
+ */
11
+ export declare function loadUserMcpSuite(agentsRoot: string): Promise<Suite & {
12
+ mcp: McpSuiteConfig;
13
+ }>;
14
+ /** Add one service atomically; reject collisions and malformed config before writing. */
15
+ export declare function addUserMcpServer(agentsRoot: string, name: string, server: unknown): Promise<void>;
16
+ /** The user's hand-written MCP declaration file: `<agentsRoot>/mcp.json`. */
17
+ export declare function userMcpPath(agentsRoot: string): string;
@@ -1,4 +1,4 @@
1
- import type { McpServerSse, McpServerStreamableHttp, McpServerStdio } from '../model/types.js';
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
4
  /** The largest timeout a bridge config and the host timer can hold. */
@@ -1,15 +1,15 @@
1
1
  import type { McpSuiteOverrides } from './mcp-overrides.js';
2
- import type { McpStatusPayload } from '../contracts/mcp-status.js';
3
- import { inspectToolRegistry, type McpToolSnapshot } from './tool-registry-observer.js';
4
- import type { Suite } from '../model/types.js';
5
- export type { McpStatusEntry, McpStatusPayload, McpStatusKind, McpStatusState } from '../contracts/mcp-status.js';
6
- export { inspectToolRegistry };
7
- export type { McpToolSnapshot } from './tool-registry-observer.js';
2
+ import type { McpStatusCode, McpStatusPayload } from '../../contracts/mcp-status.js';
3
+ import type { McpToolSnapshot } from '../ports.js';
4
+ import type { Suite } from '../../model/types.js';
5
+ export type { McpStatusEntry, McpStatusPayload, McpStatusKind, McpStatusState } from '../../contracts/mcp-status.js';
6
+ export type { McpToolSnapshot };
8
7
  export interface McpDiagnostic {
9
8
  suiteId: string;
10
9
  serverKey: string;
11
10
  reason: string;
12
- code?: 'unsupported-transport' | 'missing-credential' | 'credential-error' | 'unmount-failed' | 'mount-failed' | 'foreign-mount' | 'duplicate-mount';
11
+ code?: McpStatusCode;
12
+ causes?: string[];
13
13
  credentialRefs?: string[];
14
14
  }
15
15
  /** Build status rows from discovered plugin MCP definitions and observed tool names. */
@@ -1,10 +1,9 @@
1
- import type { McpStatusPayload } from '../contracts/mcp-status.js';
1
+ import type { McpStatusPayload } from './mcp/mcp-status.js';
2
2
  import type { ServerConfigPayload } from '../contracts/market.js';
3
3
  import type { Suite } from '../model/types.js';
4
- import { type McpBackend } from '../runtime/mcp-backend.js';
5
- import { type McpImportResult } from '../runtime/mcp-direct-config.js';
6
- import type { McpMountDiagnostic } from '../runtime/mcp-mounts.js';
7
- import { type McpServerOverride, type McpSuiteOverrides } from '../runtime/mcp-overrides.js';
4
+ import type { McpBackend } from '../contracts/mcp.js';
5
+ import type { McpMountDiagnostic } from '../contracts/mcp.js';
6
+ import { type McpServerOverride, type McpSuiteOverrides } from './mcp/mcp-overrides.js';
8
7
  import type { CatalogContext } from './catalog-context.js';
9
8
  import type { CatalogPorts, McpBackendInfo } from './ports.js';
10
9
  import type { SourceStore } from './source-store.js';
@@ -19,12 +18,6 @@ export declare class McpService {
19
18
  status(): Promise<McpStatusPayload>;
20
19
  /** Persist a user-owned MCP service and reconcile its bridge mount. */
21
20
  addServer(name: string, server: unknown): Promise<void>;
22
- /**
23
- * Import several pasted services in one write. Each entry is checked on its
24
- * own and reports back with its own outcome, so a paste of many services
25
- * never fails as a block.
26
- */
27
- importServers(servers: unknown, overwrite: boolean): Promise<McpImportResult>;
28
21
  /** Read effective service configuration without exposing credential literals. */
29
22
  serverConfig(kind: 'mcp' | 'lsp', id: string): Promise<ServerConfigPayload>;
30
23
  /**
@@ -1,5 +1,11 @@
1
1
  import type { UserPanelEntryWire, UserPanelKind } from '../contracts/market.js';
2
- import type { UserPanelStore } from '../runtime/user-panels.js';
2
+ /** The user-panel store surface the panel resources drive (structural). */
3
+ interface UserPanelEntries {
4
+ list(strict?: boolean): Promise<UserPanelEntryWire[]>;
5
+ create(name: string, text: string): Promise<UserPanelEntryWire>;
6
+ update(name: string, text: string): Promise<void>;
7
+ remove(name: string): Promise<void>;
8
+ }
3
9
  import type { Catalog } from './catalog.js';
4
10
  /** The routes consume this structural surface, also implemented by user-only stores in tests. */
5
11
  export interface PanelResourceStore {
@@ -18,4 +24,5 @@ export interface PanelResourceStore {
18
24
  export declare function pluginResourceId(sourceId: string, suiteId: string, kind: UserPanelKind, name: string): string;
19
25
  /** Whether a panel entry id addresses a file inside an installed suite. */
20
26
  export declare function isPluginResourceId(id: string): boolean;
21
- export declare function createPanelResources(catalog: Catalog, users: Record<UserPanelKind, UserPanelStore>): Record<UserPanelKind, PanelResourceStore>;
27
+ export declare function createPanelResources(catalog: Catalog, users: Record<UserPanelKind, UserPanelEntries>): Record<UserPanelKind, PanelResourceStore>;
28
+ export {};
@@ -1,4 +1,4 @@
1
- import { type Suite } from '../model/types.js';
1
+ import { type Suite } from '../../model/types.js';
2
2
  export declare const USER_HOOKS_SOURCE = "@user-hooks";
3
3
  export declare const USER_HOOKS_SUITE = "user-hooks";
4
4
  /**
@@ -11,7 +11,7 @@
11
11
  * to that directory. Skills also accept the cross-tool directory spelling
12
12
  * (`<name>/SKILL.md`) that other Agent tools and the harness's own reader of
13
13
  * `~/.agents/skills` author, and read it from the top level only.
14
- * @module runtime/user-store
14
+ * @module application/user-store
15
15
  */
16
16
  /** Where user panel entries persist: `<agentsRoot>/<kind>/`. */
17
17
  export declare function userEntryDir(agentsRoot: string, kind: 'skills' | 'commands' | 'agents'): string;