@wonderwhy-er/desktop-commander 0.2.41 → 0.2.43

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 (45) hide show
  1. package/README.md +0 -2
  2. package/dist/handlers/filesystem-handlers.js +24 -4
  3. package/dist/remote-device/remote-channel.d.ts +14 -0
  4. package/dist/remote-device/remote-channel.js +107 -28
  5. package/dist/server.d.ts +6 -1
  6. package/dist/server.js +112 -25
  7. package/dist/setup-claude-server.js +56 -50
  8. package/dist/terminal-manager.d.ts +18 -0
  9. package/dist/terminal-manager.js +130 -18
  10. package/dist/tools/edit.js +11 -4
  11. package/dist/tools/filesystem.d.ts +5 -0
  12. package/dist/tools/filesystem.js +43 -0
  13. package/dist/tools/fuzzySearch.d.ts +10 -20
  14. package/dist/tools/fuzzySearch.js +66 -105
  15. package/dist/tools/fuzzySearchCore.d.ts +52 -0
  16. package/dist/tools/fuzzySearchCore.js +125 -0
  17. package/dist/tools/improved-process-tools.js +8 -1
  18. package/dist/tools/pdf/markdown.d.ts +13 -0
  19. package/dist/tools/pdf/markdown.js +93 -29
  20. package/dist/tools/schemas.d.ts +20 -0
  21. package/dist/tools/schemas.js +45 -2
  22. package/dist/track-installation.js +57 -38
  23. package/dist/types.d.ts +6 -1
  24. package/dist/ui/contracts.d.ts +1 -1
  25. package/dist/ui/contracts.js +4 -1
  26. package/dist/ui/file-preview/preview-runtime.js +111 -113
  27. package/dist/ui/file-preview/src/app.js +19 -17
  28. package/dist/ui/file-preview/src/directory-controller.js +3 -3
  29. package/dist/ui/file-preview/src/file-type-handlers.js +2 -2
  30. package/dist/ui/file-preview/src/host/external-actions.d.ts +0 -11
  31. package/dist/ui/file-preview/src/host/external-actions.js +0 -39
  32. package/dist/ui/file-preview/src/markdown/controller.js +3 -1
  33. package/dist/ui/file-preview/src/panel-actions.js +2 -2
  34. package/dist/uninstall-claude-server.js +54 -47
  35. package/dist/utils/ab-test.d.ts +4 -0
  36. package/dist/utils/ab-test.js +6 -0
  37. package/dist/utils/capture.d.ts +10 -2
  38. package/dist/utils/capture.js +92 -60
  39. package/dist/utils/mcp-ui-ab-test.d.ts +13 -0
  40. package/dist/utils/mcp-ui-ab-test.js +62 -0
  41. package/dist/utils/unsupportedParams.d.ts +24 -0
  42. package/dist/utils/unsupportedParams.js +66 -0
  43. package/dist/version.d.ts +1 -1
  44. package/dist/version.js +1 -1
  45. package/package.json +6 -1
@@ -0,0 +1,13 @@
1
+ export declare const MCP_UI_EXPERIMENT_NAME = "McpUiPreviews";
2
+ export declare const MCP_UI_SHOW_VARIANT = "showMCPUi";
3
+ export declare const MCP_UI_HIDE_VARIANT = "notShowMCPUi";
4
+ export interface McpUiPreviewDecisionDeps {
5
+ getExistingAssignment: () => Promise<unknown>;
6
+ isFirstRun: () => boolean;
7
+ wasLoadedFromCache: () => boolean;
8
+ waitForFreshFlags: () => Promise<void>;
9
+ getABTestVariant: (experimentName: string) => Promise<string | null>;
10
+ capture: (event: string, properties?: Record<string, unknown>) => Promise<unknown> | unknown;
11
+ }
12
+ export declare function resolveMcpUiPreviewDecision(deps: McpUiPreviewDecisionDeps): Promise<boolean>;
13
+ export declare function shouldShowMcpUiPreviews(): Promise<boolean>;
@@ -0,0 +1,62 @@
1
+ import { configManager } from '../config-manager.js';
2
+ import { getABTestVariant } from './ab-test.js';
3
+ import { capture } from './capture.js';
4
+ import { featureFlagManager } from './feature-flags.js';
5
+ export const MCP_UI_EXPERIMENT_NAME = 'McpUiPreviews';
6
+ export const MCP_UI_SHOW_VARIANT = 'showMCPUi';
7
+ export const MCP_UI_HIDE_VARIANT = 'notShowMCPUi';
8
+ function variantEnablesMcpUi(variant) {
9
+ if (variant === MCP_UI_HIDE_VARIANT)
10
+ return false;
11
+ if (variant === MCP_UI_SHOW_VARIANT)
12
+ return true;
13
+ return null;
14
+ }
15
+ export async function resolveMcpUiPreviewDecision(deps) {
16
+ try {
17
+ const existingAssignment = await deps.getExistingAssignment();
18
+ const existingDecision = variantEnablesMcpUi(existingAssignment);
19
+ if (existingDecision !== null) {
20
+ if (!deps.wasLoadedFromCache()) {
21
+ await deps.waitForFreshFlags();
22
+ }
23
+ const currentVariant = await deps.getABTestVariant(MCP_UI_EXPERIMENT_NAME);
24
+ return variantEnablesMcpUi(currentVariant) ?? existingDecision;
25
+ }
26
+ if (!deps.isFirstRun()) {
27
+ return true;
28
+ }
29
+ if (!deps.wasLoadedFromCache()) {
30
+ await deps.waitForFreshFlags();
31
+ }
32
+ const variant = await deps.getABTestVariant(MCP_UI_EXPERIMENT_NAME);
33
+ const decision = variantEnablesMcpUi(variant);
34
+ if (decision === null) {
35
+ return true;
36
+ }
37
+ try {
38
+ await deps.capture('server_mcp_ui_ab_decision', {
39
+ experiment: MCP_UI_EXPERIMENT_NAME,
40
+ variant,
41
+ mcp_ui_enabled: decision,
42
+ });
43
+ }
44
+ catch {
45
+ // Telemetry must not change the assigned product experience.
46
+ }
47
+ return decision;
48
+ }
49
+ catch {
50
+ return true;
51
+ }
52
+ }
53
+ export async function shouldShowMcpUiPreviews() {
54
+ return resolveMcpUiPreviewDecision({
55
+ getExistingAssignment: () => configManager.getValue(`abTest_${MCP_UI_EXPERIMENT_NAME}`),
56
+ isFirstRun: () => configManager.isFirstRun(),
57
+ wasLoadedFromCache: () => featureFlagManager.wasLoadedFromCache(),
58
+ waitForFreshFlags: () => featureFlagManager.waitForFreshFlags(),
59
+ getABTestVariant,
60
+ capture,
61
+ });
62
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Utility for detecting parameters a caller sent that a tool's Zod schema does
3
+ * not accept.
4
+ *
5
+ * Zod's default `z.object()` silently strips unknown keys, so a model that
6
+ * invents a parameter (e.g. `view_range`) gets a normal-looking response with no
7
+ * signal that its input was ignored. These helpers let the dispatcher surface a
8
+ * corrective warning instead.
9
+ *
10
+ * Detection is top-level only. That is sufficient here because none of the tool
11
+ * arg schemas use a top-level `.passthrough()`/catchall — free-form fields
12
+ * (`options`, `params`, `pdfOptions`) are named keys whose contents are
13
+ * intentionally unvalidated.
14
+ */
15
+ /** List the parameter names a tool schema accepts (empty array if it takes none). */
16
+ export declare function getSupportedParams(schema: unknown): string[];
17
+ /**
18
+ * Return the names of top-level keys in `args` that the schema does not accept.
19
+ * Returns [] when args is not a plain object or the schema's params can't be
20
+ * determined (so we never warn on something we can't reason about).
21
+ */
22
+ export declare function detectUnsupportedParams(args: unknown, schema: unknown): string[];
23
+ /** Build the corrective warning string shown to the model. */
24
+ export declare function buildUnsupportedParamsWarning(toolName: string, unsupported: string[], supported: string[]): string;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Utility for detecting parameters a caller sent that a tool's Zod schema does
3
+ * not accept.
4
+ *
5
+ * Zod's default `z.object()` silently strips unknown keys, so a model that
6
+ * invents a parameter (e.g. `view_range`) gets a normal-looking response with no
7
+ * signal that its input was ignored. These helpers let the dispatcher surface a
8
+ * corrective warning instead.
9
+ *
10
+ * Detection is top-level only. That is sufficient here because none of the tool
11
+ * arg schemas use a top-level `.passthrough()`/catchall — free-form fields
12
+ * (`options`, `params`, `pdfOptions`) are named keys whose contents are
13
+ * intentionally unvalidated.
14
+ */
15
+ /**
16
+ * Resolve a Zod schema down to the field map of its underlying object schema,
17
+ * unwrapping wrappers (effects/optional/default/nullable/branded) defensively.
18
+ * Returns null when the schema is not (and does not wrap) a plain object schema,
19
+ * in which case we cannot determine the supported parameters and must not warn.
20
+ */
21
+ function getObjectShape(schema) {
22
+ let current = schema;
23
+ for (let i = 0; current && current._def && i < 10; i++) {
24
+ const typeName = current._def.typeName;
25
+ if (typeName === 'ZodObject') {
26
+ const shape = typeof current.shape === 'function' ? current.shape() : current.shape;
27
+ return shape ?? null;
28
+ }
29
+ if (typeName === 'ZodEffects')
30
+ current = current._def.schema;
31
+ else if (typeName === 'ZodOptional' || typeName === 'ZodNullable' || typeName === 'ZodDefault') {
32
+ current = typeof current._def.innerType === 'function' ? current._def.innerType() : current._def.innerType;
33
+ }
34
+ else if (typeName === 'ZodBranded')
35
+ current = current._def.type;
36
+ else
37
+ return null;
38
+ }
39
+ return null;
40
+ }
41
+ /** List the parameter names a tool schema accepts (empty array if it takes none). */
42
+ export function getSupportedParams(schema) {
43
+ const shape = getObjectShape(schema);
44
+ return shape ? Object.keys(shape) : [];
45
+ }
46
+ /**
47
+ * Return the names of top-level keys in `args` that the schema does not accept.
48
+ * Returns [] when args is not a plain object or the schema's params can't be
49
+ * determined (so we never warn on something we can't reason about).
50
+ */
51
+ export function detectUnsupportedParams(args, schema) {
52
+ if (!args || typeof args !== 'object' || Array.isArray(args))
53
+ return [];
54
+ const shape = getObjectShape(schema);
55
+ if (shape === null)
56
+ return [];
57
+ const supported = new Set(Object.keys(shape));
58
+ return Object.keys(args).filter((k) => !supported.has(k));
59
+ }
60
+ /** Build the corrective warning string shown to the model. */
61
+ export function buildUnsupportedParamsWarning(toolName, unsupported, supported) {
62
+ const ignored = unsupported.join(', ');
63
+ const supportedList = supported.length > 0 ? supported.join(', ') : '(none)';
64
+ return `You sent parameters not supported by this tool, which were ignored: ${ignored}. `
65
+ + `Supported parameters for ${toolName}: ${supportedList}.`;
66
+ }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.2.41";
1
+ export declare const VERSION = "0.2.43";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.2.41';
1
+ export const VERSION = '0.2.43';
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@wonderwhy-er/desktop-commander",
3
- "version": "0.2.41",
3
+ "version": "0.2.43",
4
4
  "description": "MCP server for terminal operations and file editing",
5
5
  "mcpName": "io.github.wonderwhy-er/desktop-commander",
6
6
  "license": "MIT",
7
7
  "author": "Eduards Ruzga",
8
8
  "homepage": "https://github.com/wonderwhy-er/DesktopCommanderMCP",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/wonderwhy-er/DesktopCommanderMCP.git"
12
+ },
9
13
  "bugs": "https://github.com/wonderwhy-er/DesktopCommanderMCP/issues",
10
14
  "type": "module",
11
15
  "engines": {
@@ -41,6 +45,7 @@
41
45
  "prepare": "npm run build",
42
46
  "clean": "shx rm -rf dist",
43
47
  "test": "npm run build && node test/run-all-tests.js",
48
+ "test:integration": "npm run build && node test/integration/run-all-integration-tests.js",
44
49
  "test:debug": "node --inspect test/run-all-tests.js",
45
50
  "validate:tools": "npm run build && node scripts/validate-tools-sync.js",
46
51
  "link:local": "npm run build && npm link",