@zhihand/mcp 0.32.4 → 0.32.5
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/bin/zhihand +28 -27
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/bin/zhihand
CHANGED
|
@@ -30,7 +30,7 @@ import { fetchUserCredentials } from "../dist/core/ws.js";
|
|
|
30
30
|
import { configureMCP, displayName } from "../dist/cli/mcp-config.js";
|
|
31
31
|
|
|
32
32
|
const DEFAULT_ENDPOINT = "https://api.zhihand.com";
|
|
33
|
-
const VERSION = "0.32.
|
|
33
|
+
const VERSION = "0.32.5";
|
|
34
34
|
|
|
35
35
|
const CLI_TOOL_MAP = {
|
|
36
36
|
claude: "claudecode",
|
|
@@ -652,7 +652,7 @@ switch (command) {
|
|
|
652
652
|
}
|
|
653
653
|
}
|
|
654
654
|
|
|
655
|
-
console.log("ZhiHand Device Test");
|
|
655
|
+
console.log("🔧 ZhiHand Device Test");
|
|
656
656
|
console.log(` Device: ${testConfig.credentialId}`);
|
|
657
657
|
console.log(` Endpoint: ${testConfig.controlPlaneEndpoint}\n`);
|
|
658
658
|
|
|
@@ -672,18 +672,18 @@ switch (command) {
|
|
|
672
672
|
} catch { /* non-fatal */ }
|
|
673
673
|
const getDevicePlatform = () => currentProfile?.platform ?? "unknown";
|
|
674
674
|
|
|
675
|
-
console.log("
|
|
675
|
+
console.log(" ── Capability readiness ──");
|
|
676
676
|
if (!currentCaps) {
|
|
677
|
-
console.log("
|
|
677
|
+
console.log(" ⚠️ Device profile not loaded — all capability gates will allow tests through.");
|
|
678
678
|
} else {
|
|
679
|
-
const fmt = (name, cap) => ` ${cap.ready ? "
|
|
679
|
+
const fmt = (name, cap) => ` ${cap.ready ? "✅" : "⚠️"} ${name.padEnd(16)} ${cap.ready ? "ready" : "NOT ready"} — ${cap.reason}`;
|
|
680
680
|
console.log(fmt("screen_sharing", currentCaps.screen_sharing));
|
|
681
681
|
console.log(fmt("hid", currentCaps.hid));
|
|
682
682
|
console.log(fmt("live_session", currentCaps.live_session));
|
|
683
683
|
const ageStr = currentCaps.profile.age_ms >= 0 ? `${(currentCaps.profile.age_ms / 1000).toFixed(1)}s` : "unknown";
|
|
684
|
-
console.log(` ${currentCaps.profile.stale ? "
|
|
684
|
+
console.log(` ${currentCaps.profile.stale ? "⚠️" : "✅"} profile age=${ageStr}${currentCaps.profile.stale ? " (STALE)" : ""}`);
|
|
685
685
|
if (forceRun) {
|
|
686
|
-
console.log(" --force passed: capability gates disabled.");
|
|
686
|
+
console.log(" ⚡ --force passed: capability gates disabled.");
|
|
687
687
|
}
|
|
688
688
|
}
|
|
689
689
|
console.log("");
|
|
@@ -719,18 +719,18 @@ switch (command) {
|
|
|
719
719
|
const ackStatus = ack.command?.ack_status ?? "ok";
|
|
720
720
|
const resultInfo = ack.command?.ack_result ? ` ${JSON.stringify(ack.command.ack_result)}` : "";
|
|
721
721
|
if (ackStatus === "ok") {
|
|
722
|
-
console.log(
|
|
722
|
+
console.log(`✅ (${ms}ms)${resultInfo}`);
|
|
723
723
|
passed++;
|
|
724
724
|
} else {
|
|
725
|
-
console.log(
|
|
725
|
+
console.log(`❌ [${ackStatus}] (${ms}ms)${resultInfo}`);
|
|
726
726
|
failed++;
|
|
727
727
|
}
|
|
728
728
|
} else {
|
|
729
|
-
console.log(
|
|
729
|
+
console.log(`⏱️ timeout (${ms}ms)`);
|
|
730
730
|
failed++;
|
|
731
731
|
}
|
|
732
732
|
} catch (err) {
|
|
733
|
-
console.log(
|
|
733
|
+
console.log(`❌ ${err.message} (${Date.now() - t0}ms)`);
|
|
734
734
|
failed++;
|
|
735
735
|
}
|
|
736
736
|
}
|
|
@@ -739,7 +739,7 @@ switch (command) {
|
|
|
739
739
|
const currentPlatform = getDevicePlatform();
|
|
740
740
|
if (t.platform && t.platform !== currentPlatform) {
|
|
741
741
|
totalSteps++; skipped++;
|
|
742
|
-
console.log(` ${String(t.id).padStart(2)}. ${t.label}...
|
|
742
|
+
console.log(` ${String(t.id).padStart(2)}. ${t.label}... ⏭️ (${t.platform}-only, device is ${currentPlatform})`);
|
|
743
743
|
return;
|
|
744
744
|
}
|
|
745
745
|
if (!forceRun && currentCaps) {
|
|
@@ -748,7 +748,7 @@ switch (command) {
|
|
|
748
748
|
const gate = requiredCap === "screen" ? currentCaps.screen_sharing : currentCaps.hid;
|
|
749
749
|
if (!gate.ready) {
|
|
750
750
|
totalSteps++; skipped++;
|
|
751
|
-
console.log(` ${String(t.id).padStart(2)}. ${t.label}...
|
|
751
|
+
console.log(` ${String(t.id).padStart(2)}. ${t.label}... ⏭️ (${requiredCap} not ready: ${gate.reason})`);
|
|
752
752
|
return;
|
|
753
753
|
}
|
|
754
754
|
}
|
|
@@ -768,14 +768,14 @@ switch (command) {
|
|
|
768
768
|
currentProfile = extractStatic(currentRawAttrs);
|
|
769
769
|
currentCaps = computeCapabilities(currentRawAttrs, profileReceivedAtMs);
|
|
770
770
|
const s = currentProfile;
|
|
771
|
-
console.log(
|
|
771
|
+
console.log(`✅ ${s.platform} ${s.model}, ${s.osVersion}, ${s.screenWidthPx}x${s.screenHeightPx} (${ms}ms)`);
|
|
772
772
|
passed++;
|
|
773
773
|
} else {
|
|
774
|
-
console.log(
|
|
774
|
+
console.log(`⚠️ loaded but empty (${ms}ms)`);
|
|
775
775
|
failed++;
|
|
776
776
|
}
|
|
777
777
|
} catch (err) {
|
|
778
|
-
console.log(
|
|
778
|
+
console.log(`❌ ${err.message} (${Date.now() - t0}ms)`);
|
|
779
779
|
failed++;
|
|
780
780
|
}
|
|
781
781
|
break;
|
|
@@ -805,12 +805,12 @@ switch (command) {
|
|
|
805
805
|
const capReadySummary = ["screen_sharing", "hid", "live_session"]
|
|
806
806
|
.map((k) => `${k}=${caps[k]?.ready ? "ready" : "not-ready"}`)
|
|
807
807
|
.join(", ");
|
|
808
|
-
console.log(
|
|
808
|
+
console.log(`✅ ${topLevel.length} curated + ${rawKeys.length} raw attributes; ${capReadySummary}`);
|
|
809
809
|
console.log(` curated: ${topLevel.join(", ")}`);
|
|
810
810
|
console.log(` raw: ${rawKeys.join(", ")}`);
|
|
811
811
|
passed++;
|
|
812
812
|
} catch (err) {
|
|
813
|
-
console.log(
|
|
813
|
+
console.log(`❌ ${err.message}`);
|
|
814
814
|
failed++;
|
|
815
815
|
}
|
|
816
816
|
break;
|
|
@@ -824,7 +824,7 @@ switch (command) {
|
|
|
824
824
|
const queued = await enqueueCommand(testConfig, cmd);
|
|
825
825
|
const ack = await waitForCommandAck(testConfig, { commandId: queued.id, timeoutMs: 10_000 });
|
|
826
826
|
if (!ack.acked) {
|
|
827
|
-
console.log(
|
|
827
|
+
console.log(`⏱️ timeout (${Date.now() - t0}ms)`);
|
|
828
828
|
failed++;
|
|
829
829
|
break;
|
|
830
830
|
}
|
|
@@ -833,14 +833,14 @@ switch (command) {
|
|
|
833
833
|
const ms = Date.now() - t0;
|
|
834
834
|
if (shot.stale) {
|
|
835
835
|
const threshold = getSnapshotStaleThresholdMs();
|
|
836
|
-
console.log(
|
|
836
|
+
console.log(`❌ stale (${kb}KB, age=${(shot.ageMs / 1000).toFixed(1)}s > ${(threshold / 1000).toFixed(1)}s) ${shot.width}x${shot.height} seq=${shot.sequence} — phone may not be screen-sharing (${ms}ms)`);
|
|
837
837
|
failed++;
|
|
838
838
|
} else {
|
|
839
|
-
console.log(
|
|
839
|
+
console.log(`✅ ${kb}KB, ${shot.width}x${shot.height}, age=${shot.ageMs >= 0 ? `${shot.ageMs}ms` : "?"}, seq=${shot.sequence} (${ms}ms)`);
|
|
840
840
|
passed++;
|
|
841
841
|
}
|
|
842
842
|
} catch (err) {
|
|
843
|
-
console.log(
|
|
843
|
+
console.log(`❌ ${err.message} (${Date.now() - t0}ms)`);
|
|
844
844
|
failed++;
|
|
845
845
|
}
|
|
846
846
|
break;
|
|
@@ -873,23 +873,24 @@ switch (command) {
|
|
|
873
873
|
if (selectedIds) {
|
|
874
874
|
const foundIds = new Set(toRun.map((t) => t.id));
|
|
875
875
|
const missing = [...selectedIds].filter((id) => !foundIds.has(id));
|
|
876
|
-
if (missing.length) console.warn(`
|
|
876
|
+
if (missing.length) console.warn(` ⚠️ Unknown test IDs: ${missing.join(", ")}`);
|
|
877
877
|
}
|
|
878
878
|
|
|
879
879
|
let currentPhase = "";
|
|
880
880
|
for (let i = 0; i < toRun.length; i++) {
|
|
881
881
|
const t = toRun[i];
|
|
882
882
|
if (t.phase !== currentPhase) {
|
|
883
|
-
console.log(
|
|
883
|
+
console.log(`\n ── ${t.phase} ──`);
|
|
884
884
|
currentPhase = t.phase;
|
|
885
885
|
}
|
|
886
886
|
await runSingleTest(t);
|
|
887
887
|
if (i < toRun.length - 1) await pause();
|
|
888
888
|
}
|
|
889
889
|
|
|
890
|
-
console.log(`\n Result
|
|
891
|
-
|
|
892
|
-
|
|
890
|
+
console.log(`\n ── Result ──`);
|
|
891
|
+
console.log(` ${passed}/${totalSteps} passed, ${failed} failed, ${skipped} skipped`);
|
|
892
|
+
if (failed === 0) console.log(" 🎉 All tests passed! Device is fully responsive.");
|
|
893
|
+
else console.log(` ⚠️ ${failed} test(s) failed. Check phone connectivity.`);
|
|
893
894
|
process.exit(failed > 0 ? 1 : 0);
|
|
894
895
|
}
|
|
895
896
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.32.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.32.5";
|
|
3
3
|
export declare function createServer(): McpServer;
|
|
4
4
|
export declare function startStdioServer(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { handlePair } from "./tools/pair.js";
|
|
|
8
8
|
import { resolveTargetDevice } from "./tools/resolve.js";
|
|
9
9
|
import { buildControlToolDescription, buildSystemToolDescription, buildScreenshotToolDescription, formatDeviceStatus, extractDynamic, } from "./core/device.js";
|
|
10
10
|
import { registry } from "./core/registry.js";
|
|
11
|
-
export const PACKAGE_VERSION = "0.32.
|
|
11
|
+
export const PACKAGE_VERSION = "0.32.5";
|
|
12
12
|
function errorResult(message) {
|
|
13
13
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
14
14
|
}
|