@hcu-lab.me/mcp-device 1.0.2 → 1.0.4
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.
- package/LICENSE +20 -20
- package/README.md +84 -51
- package/dist/bootstrap.js +0 -0
- package/dist/command-manager.js +0 -0
- package/dist/config-field-definitions.js +0 -0
- package/dist/config-manager.js +0 -0
- package/dist/config.js +0 -0
- package/dist/custom-stdio.js +0 -0
- package/dist/data/official-app-ca.pem +12 -12
- package/dist/data/onboarding-prompts.json +70 -70
- package/dist/device/gateway-pairing.d.ts +1 -0
- package/dist/device/gateway-pairing.js +0 -6
- package/dist/error-handlers.js +0 -0
- package/dist/handlers/filesystem-handlers.js +2 -2
- package/dist/index.js +0 -0
- package/dist/mcp-device.js +0 -0
- package/dist/search-manager.js +0 -0
- package/dist/server.js +656 -656
- package/dist/terminal-manager.js +0 -0
- package/dist/tools/edit.js +2 -2
- package/dist/tools/fuzzySearch.js +9 -9
- package/dist/tools/improved-process-tools.js +10 -10
- package/dist/tools/prompts.js +1 -1
- package/dist/types.js +0 -0
- package/dist/ui/config-editor/index.html +13 -13
- package/dist/ui/config-editor/src/app.js +30 -30
- package/dist/ui/config-editor/src/array-modal.js +32 -32
- package/dist/ui/config-editor/styles.css +586 -586
- package/dist/ui/file-preview/index.html +16 -16
- package/dist/ui/file-preview/src/app.js +8 -8
- package/dist/ui/file-preview/src/document-layout.js +31 -31
- package/dist/ui/file-preview/src/document-outline.js +8 -8
- package/dist/ui/file-preview/src/markdown/conflict-dialog.js +33 -33
- package/dist/ui/file-preview/src/markdown/controller.js +9 -9
- package/dist/ui/file-preview/src/markdown/editor.js +31 -31
- package/dist/ui/file-preview/styles.css +1630 -1630
- package/dist/utils/files/binary.js +4 -4
- package/dist/utils/files/excel.js +3 -3
- package/dist/utils/system-info.js +90 -90
- package/dist/utils/usageTracker.js +49 -49
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +135 -131
package/dist/terminal-manager.js
CHANGED
|
File without changes
|
package/dist/tools/edit.js
CHANGED
|
@@ -151,8 +151,8 @@ export async function performSearchReplace(filePath, block, expectedReplacements
|
|
|
151
151
|
let warningMessage = "";
|
|
152
152
|
if (maxLines > MAX_LINES) {
|
|
153
153
|
const problemText = searchLines > replaceLines ? 'search text' : 'replacement text';
|
|
154
|
-
warningMessage = `\n\nWARNING: The ${problemText} has ${maxLines} lines (maximum: ${MAX_LINES}).
|
|
155
|
-
|
|
154
|
+
warningMessage = `\n\nWARNING: The ${problemText} has ${maxLines} lines (maximum: ${MAX_LINES}).
|
|
155
|
+
|
|
156
156
|
RECOMMENDATION: For large search/replace operations, consider breaking them into smaller chunks with fewer lines.`;
|
|
157
157
|
}
|
|
158
158
|
await writeFile(filePath, newContent);
|
|
@@ -11,15 +11,15 @@ export const FUZZY_SEARCH_TIMEOUT_MS = 30000;
|
|
|
11
11
|
* worker would boot the whole server per search. Kept as an eval'd snippet so
|
|
12
12
|
* the worker needs no separate file to ship alongside the compiled output.
|
|
13
13
|
*/
|
|
14
|
-
const WORKER_CODE = `
|
|
15
|
-
const { workerData, parentPort } = require('worker_threads');
|
|
16
|
-
import(workerData.moduleUrl)
|
|
17
|
-
.then((m) => {
|
|
18
|
-
parentPort.postMessage({ ok: true, ...m.runFuzzySearch(workerData.text, workerData.query) });
|
|
19
|
-
})
|
|
20
|
-
.catch((err) => {
|
|
21
|
-
parentPort.postMessage({ ok: false, error: String(err && err.stack || err) });
|
|
22
|
-
});
|
|
14
|
+
const WORKER_CODE = `
|
|
15
|
+
const { workerData, parentPort } = require('worker_threads');
|
|
16
|
+
import(workerData.moduleUrl)
|
|
17
|
+
.then((m) => {
|
|
18
|
+
parentPort.postMessage({ ok: true, ...m.runFuzzySearch(workerData.text, workerData.query) });
|
|
19
|
+
})
|
|
20
|
+
.catch((err) => {
|
|
21
|
+
parentPort.postMessage({ ok: false, error: String(err && err.stack || err) });
|
|
22
|
+
});
|
|
23
23
|
`;
|
|
24
24
|
const CORE_MODULE_URL = new URL('./fuzzySearchCore.js', import.meta.url).href;
|
|
25
25
|
/**
|
|
@@ -119,16 +119,16 @@ export async function startProcess(args) {
|
|
|
119
119
|
return {
|
|
120
120
|
content: [{
|
|
121
121
|
type: "text",
|
|
122
|
-
text: `Node.js session started with PID ${virtualPid} (MCP server execution)
|
|
123
|
-
|
|
124
|
-
IMPORTANT: Each interact_with_process call runs as a FRESH script.
|
|
125
|
-
State is NOT preserved between calls. Include ALL code in ONE call:
|
|
126
|
-
- imports, file reading, processing, and output together.
|
|
127
|
-
|
|
128
|
-
Available libraries:
|
|
129
|
-
- ExcelJS for Excel files: import ExcelJS from 'exceljs'
|
|
130
|
-
- All Node.js built-ins: fs, path, http, crypto, etc.
|
|
131
|
-
|
|
122
|
+
text: `Node.js session started with PID ${virtualPid} (MCP server execution)
|
|
123
|
+
|
|
124
|
+
IMPORTANT: Each interact_with_process call runs as a FRESH script.
|
|
125
|
+
State is NOT preserved between calls. Include ALL code in ONE call:
|
|
126
|
+
- imports, file reading, processing, and output together.
|
|
127
|
+
|
|
128
|
+
Available libraries:
|
|
129
|
+
- ExcelJS for Excel files: import ExcelJS from 'exceljs'
|
|
130
|
+
- All Node.js built-ins: fs, path, http, crypto, etc.
|
|
131
|
+
|
|
132
132
|
🔄 Ready for code - send complete self-contained script via interact_with_process.`
|
|
133
133
|
}],
|
|
134
134
|
};
|
package/dist/tools/prompts.js
CHANGED
|
@@ -224,7 +224,7 @@ function formatPromptsListResponse(prompts, category) {
|
|
|
224
224
|
}
|
|
225
225
|
});
|
|
226
226
|
response += `Say "Try #3" or "Let's do #1" to start any example.\n\n`;
|
|
227
|
-
response += `<INSTRUCTION>Output options for user exactly as provided without missing numbers.
|
|
227
|
+
response += `<INSTRUCTION>Output options for user exactly as provided without missing numbers.
|
|
228
228
|
Its important so user can choose an options by entering number only. Also do not forget new lines between numbers for easy reading</INSTRUCTION>\n\n`;
|
|
229
229
|
// AI reference mapping (do not show to user):
|
|
230
230
|
response += `<!-- AI_PROMPT_MAP: `;
|
package/dist/types.js
CHANGED
|
File without changes
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>Desktop Commander Config Editor</title>
|
|
7
|
-
<link rel="stylesheet" href="./styles.css" />
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="app"></div>
|
|
11
|
-
<script src="./config-editor-runtime.js"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Desktop Commander Config Editor</title>
|
|
7
|
+
<link rel="stylesheet" href="./styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script src="./config-editor-runtime.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -444,14 +444,14 @@ function render(container, controller, chrome, hooks = {}) {
|
|
|
444
444
|
const options = shellOptions
|
|
445
445
|
.map((shell) => `<option value="${escapeHtml(shell)}" ${shell === currentShell ? 'selected' : ''}>${escapeHtml(shell)}</option>`)
|
|
446
446
|
.join('');
|
|
447
|
-
controlHtml = `
|
|
448
|
-
<div class="setting-shell-control">
|
|
449
|
-
<select class="setting-inline-select" data-action="shell-select" data-key-index="${index}">
|
|
450
|
-
${options}
|
|
451
|
-
<option value="__custom__" ${isCustomShell ? 'selected' : ''}>Custom...</option>
|
|
452
|
-
</select>
|
|
453
|
-
<input class="setting-inline-input setting-shell-custom${isCustomShell ? '' : ' hidden'}" data-action="shell-custom" data-key-index="${index}" type="text" value="${escapeHtml(currentShell)}" placeholder="Type custom shell path"/>
|
|
454
|
-
</div>
|
|
447
|
+
controlHtml = `
|
|
448
|
+
<div class="setting-shell-control">
|
|
449
|
+
<select class="setting-inline-select" data-action="shell-select" data-key-index="${index}">
|
|
450
|
+
${options}
|
|
451
|
+
<option value="__custom__" ${isCustomShell ? 'selected' : ''}>Custom...</option>
|
|
452
|
+
</select>
|
|
453
|
+
<input class="setting-inline-input setting-shell-custom${isCustomShell ? '' : ' hidden'}" data-action="shell-custom" data-key-index="${index}" type="text" value="${escapeHtml(currentShell)}" placeholder="Type custom shell path"/>
|
|
454
|
+
</div>
|
|
455
455
|
`;
|
|
456
456
|
}
|
|
457
457
|
else if (entry.valueType === 'boolean') {
|
|
@@ -470,30 +470,30 @@ function render(container, controller, chrome, hooks = {}) {
|
|
|
470
470
|
else {
|
|
471
471
|
controlHtml = `<input class="setting-inline-input" data-action="edit-string" data-key-index="${index}" type="text" value="${escapeHtml(String(entry.value ?? ''))}"/>`;
|
|
472
472
|
}
|
|
473
|
-
return `
|
|
474
|
-
<section class="setting-row">
|
|
475
|
-
<div class="setting-info">
|
|
476
|
-
<h3>${escapeHtml(keyTitle)}</h3>
|
|
477
|
-
${description ? `<p>${escapeHtml(description)}</p>` : ''}
|
|
478
|
-
<p class="setting-summary${summary ? '' : ' hidden'}" data-setting-summary-key="${escapeHtml(entry.key)}">${summary ? escapeHtml(summary) : ''}</p>
|
|
479
|
-
</div>
|
|
480
|
-
<div class="setting-control">${controlHtml}</div>
|
|
481
|
-
</section>
|
|
473
|
+
return `
|
|
474
|
+
<section class="setting-row">
|
|
475
|
+
<div class="setting-info">
|
|
476
|
+
<h3>${escapeHtml(keyTitle)}</h3>
|
|
477
|
+
${description ? `<p>${escapeHtml(description)}</p>` : ''}
|
|
478
|
+
<p class="setting-summary${summary ? '' : ' hidden'}" data-setting-summary-key="${escapeHtml(entry.key)}">${summary ? escapeHtml(summary) : ''}</p>
|
|
479
|
+
</div>
|
|
480
|
+
<div class="setting-control">${controlHtml}</div>
|
|
481
|
+
</section>
|
|
482
482
|
`;
|
|
483
483
|
}).join('');
|
|
484
|
-
container.innerHTML = `
|
|
485
|
-
<main id="tool-shell" class="${shellClasses}">
|
|
486
|
-
${renderCompactRow({ id: 'compact-toggle', label: 'View config', filename: 'MCP Device', variant: 'ready', expandable: true, expanded: chrome.expanded, interactive: true })}
|
|
487
|
-
|
|
488
|
-
<section class="panel config-card">
|
|
489
|
-
<div class="panel-content-wrapper">
|
|
490
|
-
<div class="settings-stack" aria-label="MCP Device settings">${settingsHtml}</div>
|
|
491
|
-
</div>
|
|
492
|
-
</section>
|
|
493
|
-
|
|
494
|
-
${renderArrayModalMarkup('List Setting')}
|
|
495
|
-
</main>
|
|
496
|
-
<div id="config-tooltip" class="config-tooltip" role="status" aria-live="polite" hidden></div>
|
|
484
|
+
container.innerHTML = `
|
|
485
|
+
<main id="tool-shell" class="${shellClasses}">
|
|
486
|
+
${renderCompactRow({ id: 'compact-toggle', label: 'View config', filename: 'MCP Device', variant: 'ready', expandable: true, expanded: chrome.expanded, interactive: true })}
|
|
487
|
+
|
|
488
|
+
<section class="panel config-card">
|
|
489
|
+
<div class="panel-content-wrapper">
|
|
490
|
+
<div class="settings-stack" aria-label="MCP Device settings">${settingsHtml}</div>
|
|
491
|
+
</div>
|
|
492
|
+
</section>
|
|
493
|
+
|
|
494
|
+
${renderArrayModalMarkup('List Setting')}
|
|
495
|
+
</main>
|
|
496
|
+
<div id="config-tooltip" class="config-tooltip" role="status" aria-live="polite" hidden></div>
|
|
497
497
|
`;
|
|
498
498
|
const toolShell = container.querySelector('#tool-shell');
|
|
499
499
|
const compactRow = container.querySelector('.compact-row--ready');
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { escapeHtml } from '../../shared/escape-html.js';
|
|
2
2
|
export function renderArrayModalMarkup(initialTitle) {
|
|
3
|
-
return `
|
|
4
|
-
<div class="array-modal" id="array-modal" hidden>
|
|
5
|
-
<div class="array-modal-card">
|
|
6
|
-
<header>
|
|
7
|
-
<h3 id="array-modal-title">${escapeHtml(initialTitle)}</h3>
|
|
8
|
-
<div class="array-modal-actions">
|
|
9
|
-
<button type="button" id="array-modal-save" aria-label="Save list changes">
|
|
10
|
-
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M5 13l4 4L19 7"></path></svg>
|
|
11
|
-
</button>
|
|
12
|
-
<button type="button" id="array-modal-close" aria-label="Close list editor">
|
|
13
|
-
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M7 7l10 10M17 7L7 17"></path></svg>
|
|
14
|
-
</button>
|
|
15
|
-
</div>
|
|
16
|
-
</header>
|
|
17
|
-
<p class="array-modal-description" id="array-modal-description"></p>
|
|
18
|
-
<p class="array-modal-hint">Type an item, then press Enter (or click away) to add it. A new empty row appears automatically.</p>
|
|
19
|
-
<p class="array-modal-error hidden" id="array-modal-error" role="status" aria-live="polite"></p>
|
|
20
|
-
<div class="array-modal-list" id="array-modal-list"></div>
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
3
|
+
return `
|
|
4
|
+
<div class="array-modal" id="array-modal" hidden>
|
|
5
|
+
<div class="array-modal-card">
|
|
6
|
+
<header>
|
|
7
|
+
<h3 id="array-modal-title">${escapeHtml(initialTitle)}</h3>
|
|
8
|
+
<div class="array-modal-actions">
|
|
9
|
+
<button type="button" id="array-modal-save" aria-label="Save list changes">
|
|
10
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M5 13l4 4L19 7"></path></svg>
|
|
11
|
+
</button>
|
|
12
|
+
<button type="button" id="array-modal-close" aria-label="Close list editor">
|
|
13
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M7 7l10 10M17 7L7 17"></path></svg>
|
|
14
|
+
</button>
|
|
15
|
+
</div>
|
|
16
|
+
</header>
|
|
17
|
+
<p class="array-modal-description" id="array-modal-description"></p>
|
|
18
|
+
<p class="array-modal-hint">Type an item, then press Enter (or click away) to add it. A new empty row appears automatically.</p>
|
|
19
|
+
<p class="array-modal-error hidden" id="array-modal-error" role="status" aria-live="polite"></p>
|
|
20
|
+
<div class="array-modal-list" id="array-modal-list"></div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
23
|
`;
|
|
24
24
|
}
|
|
25
25
|
export function createArrayModalController(options) {
|
|
@@ -65,18 +65,18 @@ export function createArrayModalController(options) {
|
|
|
65
65
|
if (!modalList) {
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
-
modalList.innerHTML = `
|
|
69
|
-
<div class="array-modal-row array-modal-row--new">
|
|
70
|
-
<input id="array-modal-new-item" type="text" placeholder="Add item" aria-label="Add new item" />
|
|
71
|
-
</div>
|
|
72
|
-
${modalItems.map((item, index) => `
|
|
73
|
-
<div class="array-modal-row" data-modal-index="${index}">
|
|
74
|
-
<input class="array-modal-item-input" type="text" value="${escapeHtml(item)}" aria-label="Item ${index + 1}" />
|
|
75
|
-
<button type="button" class="array-modal-item-remove" aria-label="Remove item ${index + 1}">
|
|
76
|
-
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14M10 10v7M14 10v7"></path></svg>
|
|
77
|
-
</button>
|
|
78
|
-
</div>
|
|
79
|
-
`).join('')}
|
|
68
|
+
modalList.innerHTML = `
|
|
69
|
+
<div class="array-modal-row array-modal-row--new">
|
|
70
|
+
<input id="array-modal-new-item" type="text" placeholder="Add item" aria-label="Add new item" />
|
|
71
|
+
</div>
|
|
72
|
+
${modalItems.map((item, index) => `
|
|
73
|
+
<div class="array-modal-row" data-modal-index="${index}">
|
|
74
|
+
<input class="array-modal-item-input" type="text" value="${escapeHtml(item)}" aria-label="Item ${index + 1}" />
|
|
75
|
+
<button type="button" class="array-modal-item-remove" aria-label="Remove item ${index + 1}">
|
|
76
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14M10 10v7M14 10v7"></path></svg>
|
|
77
|
+
</button>
|
|
78
|
+
</div>
|
|
79
|
+
`).join('')}
|
|
80
80
|
`;
|
|
81
81
|
const addModalItem = (value) => {
|
|
82
82
|
const normalized = value.trim();
|