@midscene/harmony 1.7.6 → 1.7.7-beta-20260428102047.0

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/dist/es/bin.mjs CHANGED
@@ -823,6 +823,8 @@ const createPlatformActions = (device)=>({
823
823
  description: 'Terminate (force-stop) a HarmonyOS app by bundle name or mapped app name',
824
824
  interfaceAlias: 'terminate',
825
825
  paramSchema: terminateParamSchema,
826
+ delayBeforeRunner: 0,
827
+ delayAfterRunner: 0,
826
828
  call: async (param)=>{
827
829
  if (!param.uri || '' === param.uri.trim()) throw new Error('Terminate requires a non-empty uri parameter');
828
830
  await device.terminate(param.uri);
@@ -831,6 +833,8 @@ const createPlatformActions = (device)=>({
831
833
  HarmonyBackButton: defineAction({
832
834
  name: 'HarmonyBackButton',
833
835
  description: 'Trigger the system "back" operation on HarmonyOS devices',
836
+ delayBeforeRunner: 0,
837
+ delayAfterRunner: 0,
834
838
  call: async ()=>{
835
839
  await device.back();
836
840
  }
@@ -838,6 +842,8 @@ const createPlatformActions = (device)=>({
838
842
  HarmonyHomeButton: defineAction({
839
843
  name: 'HarmonyHomeButton',
840
844
  description: 'Trigger the system "home" operation on HarmonyOS devices',
845
+ delayBeforeRunner: 0,
846
+ delayAfterRunner: 0,
841
847
  call: async ()=>{
842
848
  await device.home();
843
849
  }
@@ -912,26 +918,48 @@ class HarmonyAgent extends Agent {
912
918
  this.recentApps = this.createActionWrapper('HarmonyRecentAppsButton');
913
919
  }
914
920
  }
915
- async function selectDevice() {
916
- console.log('🔍 Scanning for HarmonyOS devices...');
921
+ const HARMONY_NO_DEVICE_MESSAGE = 'No HarmonyOS devices found. Connect a device via USB, ensure HDC is configured, and run `hdc list targets` to verify.';
922
+ function createNoDeviceError() {
923
+ return new Error(HARMONY_NO_DEVICE_MESSAGE);
924
+ }
925
+ async function getHdcTargets() {
917
926
  const devices = await utils_getConnectedDevices();
918
- if (0 === devices.length) {
919
- console.error('❌ No HarmonyOS devices found!');
920
- console.log('📱 Please ensure:');
921
- console.log(' • Your device is connected via USB');
922
- console.log(' • HDC is properly configured');
923
- console.log(' • Run `hdc list targets` to verify');
924
- process.exit(1);
927
+ return devices.map((device, index)=>({
928
+ id: device.deviceId,
929
+ label: device.deviceId,
930
+ isDefault: 0 === index,
931
+ status: 'device'
932
+ }));
933
+ }
934
+ async function getHdcTargetsSafe() {
935
+ try {
936
+ const targets = await getHdcTargets();
937
+ return {
938
+ targets,
939
+ ...0 === targets.length ? {
940
+ error: HARMONY_NO_DEVICE_MESSAGE
941
+ } : {}
942
+ };
943
+ } catch (error) {
944
+ return {
945
+ targets: [],
946
+ error: error instanceof Error ? error.message : String(error)
947
+ };
925
948
  }
926
- if (1 === devices.length) {
927
- console.log(`📱 Found device: ${devices[0].deviceId}`);
928
- return devices[0].deviceId;
949
+ }
950
+ async function selectDevice() {
951
+ console.log('🔍 Scanning for HarmonyOS devices...');
952
+ const targets = await getHdcTargets();
953
+ if (0 === targets.length) throw createNoDeviceError();
954
+ if (1 === targets.length) {
955
+ console.log(`📱 Found device: ${targets[0].id}`);
956
+ return targets[0].id;
929
957
  }
930
958
  return prompts_select({
931
959
  message: '📱 Multiple devices found. Please select one:',
932
- choices: devices.map((device)=>({
933
- name: device.deviceId,
934
- value: device.deviceId
960
+ choices: targets.map((target)=>({
961
+ name: target.label,
962
+ value: target.id
935
963
  }))
936
964
  });
937
965
  }
@@ -940,10 +968,114 @@ const harmonyPlaygroundPlatform = definePlaygroundPlatform({
940
968
  title: 'Midscene HarmonyOS Playground',
941
969
  description: "HarmonyOS playground platform descriptor",
942
970
  async prepare (options) {
943
- const selectedDeviceId = options?.deviceId || await selectDevice();
944
971
  const staticDir = options?.staticDir || node_path.join(__dirname, '../../static');
945
972
  const availablePort = await findAvailablePort(PLAYGROUND_SERVER_PORT);
946
973
  if (availablePort !== PLAYGROUND_SERVER_PORT) console.log(`⚠️ Port ${PLAYGROUND_SERVER_PORT} is busy, using port ${availablePort} instead`);
974
+ const createSessionManager = ()=>({
975
+ async getSetupSchema () {
976
+ const explicitDeviceId = options?.deviceId;
977
+ const discovery = explicitDeviceId ? {
978
+ targets: [
979
+ {
980
+ id: explicitDeviceId,
981
+ label: explicitDeviceId,
982
+ isDefault: true,
983
+ status: 'device'
984
+ }
985
+ ]
986
+ } : await getHdcTargetsSafe();
987
+ const { error, targets } = discovery;
988
+ return {
989
+ title: 'Welcome to\nMidscene.js Playground!',
990
+ description: 'Select an available HDC device to create the current HarmonyOS Agent',
991
+ primaryActionLabel: 'Create Agent',
992
+ autoSubmitWhenReady: 1 === targets.length,
993
+ notice: error ? {
994
+ type: 'warning',
995
+ message: 'HarmonyOS device discovery failed',
996
+ description: error
997
+ } : void 0,
998
+ fields: [
999
+ {
1000
+ key: 'deviceId',
1001
+ label: 'HDC device',
1002
+ type: 'select',
1003
+ required: true,
1004
+ options: targets.map((target)=>({
1005
+ label: target.label,
1006
+ value: target.id,
1007
+ description: target.description
1008
+ })),
1009
+ defaultValue: targets.find((target)=>target.isDefault)?.id,
1010
+ placeholder: 'Select a connected HarmonyOS device'
1011
+ }
1012
+ ],
1013
+ targets
1014
+ };
1015
+ },
1016
+ async listTargets () {
1017
+ if (options?.deviceId) return [
1018
+ {
1019
+ id: options.deviceId,
1020
+ label: options.deviceId,
1021
+ isDefault: true,
1022
+ status: 'device'
1023
+ }
1024
+ ];
1025
+ return (await getHdcTargetsSafe()).targets;
1026
+ },
1027
+ async createSession (input) {
1028
+ const targets = options?.deviceId ? [
1029
+ {
1030
+ id: options.deviceId,
1031
+ label: options.deviceId,
1032
+ isDefault: true,
1033
+ status: 'device'
1034
+ }
1035
+ ] : await getHdcTargets();
1036
+ const deviceId = options?.deviceId || ('string' == typeof input?.deviceId && input.deviceId ? input.deviceId : targets.find((target)=>target.isDefault)?.id);
1037
+ if (!deviceId) throw createNoDeviceError();
1038
+ const connectAgent = async ()=>{
1039
+ const device = new device_HarmonyDevice(deviceId);
1040
+ await device.connect();
1041
+ return new HarmonyAgent(device);
1042
+ };
1043
+ const agent = await connectAgent();
1044
+ return {
1045
+ agent,
1046
+ agentFactory: connectAgent,
1047
+ preview: createScreenshotPreviewDescriptor({
1048
+ title: 'HarmonyOS device preview'
1049
+ }),
1050
+ displayName: deviceId,
1051
+ metadata: {
1052
+ deviceId
1053
+ }
1054
+ };
1055
+ }
1056
+ });
1057
+ if (options?.deferConnection) return {
1058
+ platformId: 'harmony',
1059
+ title: 'Midscene HarmonyOS Playground',
1060
+ sessionManager: createSessionManager(),
1061
+ launchOptions: {
1062
+ port: availablePort,
1063
+ openBrowser: false,
1064
+ verbose: false,
1065
+ staticPath: staticDir
1066
+ },
1067
+ preview: createScreenshotPreviewDescriptor({
1068
+ title: 'HarmonyOS device preview'
1069
+ }),
1070
+ metadata: {
1071
+ ...options.deviceId ? {
1072
+ deviceId: options.deviceId
1073
+ } : {},
1074
+ sessionConnected: false,
1075
+ setupState: 'required'
1076
+ }
1077
+ };
1078
+ const selectedDeviceId = options?.deviceId || await selectDevice();
947
1079
  return {
948
1080
  platformId: 'harmony',
949
1081
  title: 'Midscene HarmonyOS Playground',
package/dist/es/cli.mjs CHANGED
@@ -820,6 +820,8 @@ const createPlatformActions = (device)=>({
820
820
  description: 'Terminate (force-stop) a HarmonyOS app by bundle name or mapped app name',
821
821
  interfaceAlias: 'terminate',
822
822
  paramSchema: terminateParamSchema,
823
+ delayBeforeRunner: 0,
824
+ delayAfterRunner: 0,
823
825
  call: async (param)=>{
824
826
  if (!param.uri || '' === param.uri.trim()) throw new Error('Terminate requires a non-empty uri parameter');
825
827
  await device.terminate(param.uri);
@@ -828,6 +830,8 @@ const createPlatformActions = (device)=>({
828
830
  HarmonyBackButton: defineAction({
829
831
  name: 'HarmonyBackButton',
830
832
  description: 'Trigger the system "back" operation on HarmonyOS devices',
833
+ delayBeforeRunner: 0,
834
+ delayAfterRunner: 0,
831
835
  call: async ()=>{
832
836
  await device.back();
833
837
  }
@@ -835,6 +839,8 @@ const createPlatformActions = (device)=>({
835
839
  HarmonyHomeButton: defineAction({
836
840
  name: 'HarmonyHomeButton',
837
841
  description: 'Trigger the system "home" operation on HarmonyOS devices',
842
+ delayBeforeRunner: 0,
843
+ delayAfterRunner: 0,
838
844
  call: async ()=>{
839
845
  await device.home();
840
846
  }
@@ -1014,7 +1020,7 @@ class HarmonyMidsceneTools extends BaseMidsceneTools {
1014
1020
  const tools = new HarmonyMidsceneTools();
1015
1021
  runToolsCLI(tools, 'midscene-harmony', {
1016
1022
  stripPrefix: 'harmony_',
1017
- version: "1.7.6",
1023
+ version: "1.7.7-beta-20260428102047.0",
1018
1024
  extraCommands: createReportCliCommands()
1019
1025
  }).catch((e)=>{
1020
1026
  process.exit(reportCLIError(e));
package/dist/es/index.mjs CHANGED
@@ -791,6 +791,8 @@ const createPlatformActions = (device)=>({
791
791
  description: 'Terminate (force-stop) a HarmonyOS app by bundle name or mapped app name',
792
792
  interfaceAlias: 'terminate',
793
793
  paramSchema: terminateParamSchema,
794
+ delayBeforeRunner: 0,
795
+ delayAfterRunner: 0,
794
796
  call: async (param)=>{
795
797
  if (!param.uri || '' === param.uri.trim()) throw new Error('Terminate requires a non-empty uri parameter');
796
798
  await device.terminate(param.uri);
@@ -799,6 +801,8 @@ const createPlatformActions = (device)=>({
799
801
  HarmonyBackButton: defineAction({
800
802
  name: 'HarmonyBackButton',
801
803
  description: 'Trigger the system "back" operation on HarmonyOS devices',
804
+ delayBeforeRunner: 0,
805
+ delayAfterRunner: 0,
802
806
  call: async ()=>{
803
807
  await device.back();
804
808
  }
@@ -806,6 +810,8 @@ const createPlatformActions = (device)=>({
806
810
  HarmonyHomeButton: defineAction({
807
811
  name: 'HarmonyHomeButton',
808
812
  description: 'Trigger the system "home" operation on HarmonyOS devices',
813
+ delayBeforeRunner: 0,
814
+ delayAfterRunner: 0,
809
815
  call: async ()=>{
810
816
  await device.home();
811
817
  }
@@ -1016,26 +1022,48 @@ class HarmonyMidsceneTools extends BaseMidsceneTools {
1016
1022
  });
1017
1023
  }
1018
1024
  }
1025
+ const HARMONY_NO_DEVICE_MESSAGE = 'No HarmonyOS devices found. Connect a device via USB, ensure HDC is configured, and run `hdc list targets` to verify.';
1026
+ function createNoDeviceError() {
1027
+ return new Error(HARMONY_NO_DEVICE_MESSAGE);
1028
+ }
1029
+ async function getHdcTargets() {
1030
+ const devices = await getConnectedDevices();
1031
+ return devices.map((device, index)=>({
1032
+ id: device.deviceId,
1033
+ label: device.deviceId,
1034
+ isDefault: 0 === index,
1035
+ status: 'device'
1036
+ }));
1037
+ }
1038
+ async function getHdcTargetsSafe() {
1039
+ try {
1040
+ const targets = await getHdcTargets();
1041
+ return {
1042
+ targets,
1043
+ ...0 === targets.length ? {
1044
+ error: HARMONY_NO_DEVICE_MESSAGE
1045
+ } : {}
1046
+ };
1047
+ } catch (error) {
1048
+ return {
1049
+ targets: [],
1050
+ error: error instanceof Error ? error.message : String(error)
1051
+ };
1052
+ }
1053
+ }
1019
1054
  async function selectDevice() {
1020
1055
  console.log('🔍 Scanning for HarmonyOS devices...');
1021
- const devices = await getConnectedDevices();
1022
- if (0 === devices.length) {
1023
- console.error('❌ No HarmonyOS devices found!');
1024
- console.log('📱 Please ensure:');
1025
- console.log(' • Your device is connected via USB');
1026
- console.log(' • HDC is properly configured');
1027
- console.log(' • Run `hdc list targets` to verify');
1028
- process.exit(1);
1029
- }
1030
- if (1 === devices.length) {
1031
- console.log(`📱 Found device: ${devices[0].deviceId}`);
1032
- return devices[0].deviceId;
1056
+ const targets = await getHdcTargets();
1057
+ if (0 === targets.length) throw createNoDeviceError();
1058
+ if (1 === targets.length) {
1059
+ console.log(`📱 Found device: ${targets[0].id}`);
1060
+ return targets[0].id;
1033
1061
  }
1034
1062
  return prompts_select({
1035
1063
  message: '📱 Multiple devices found. Please select one:',
1036
- choices: devices.map((device)=>({
1037
- name: device.deviceId,
1038
- value: device.deviceId
1064
+ choices: targets.map((target)=>({
1065
+ name: target.label,
1066
+ value: target.id
1039
1067
  }))
1040
1068
  });
1041
1069
  }
@@ -1044,10 +1072,114 @@ const harmonyPlaygroundPlatform = definePlaygroundPlatform({
1044
1072
  title: 'Midscene HarmonyOS Playground',
1045
1073
  description: "HarmonyOS playground platform descriptor",
1046
1074
  async prepare (options) {
1047
- const selectedDeviceId = options?.deviceId || await selectDevice();
1048
1075
  const staticDir = options?.staticDir || node_path.join(__dirname, '../../static');
1049
1076
  const availablePort = await findAvailablePort(PLAYGROUND_SERVER_PORT);
1050
1077
  if (availablePort !== PLAYGROUND_SERVER_PORT) console.log(`⚠️ Port ${PLAYGROUND_SERVER_PORT} is busy, using port ${availablePort} instead`);
1078
+ const createSessionManager = ()=>({
1079
+ async getSetupSchema () {
1080
+ const explicitDeviceId = options?.deviceId;
1081
+ const discovery = explicitDeviceId ? {
1082
+ targets: [
1083
+ {
1084
+ id: explicitDeviceId,
1085
+ label: explicitDeviceId,
1086
+ isDefault: true,
1087
+ status: 'device'
1088
+ }
1089
+ ]
1090
+ } : await getHdcTargetsSafe();
1091
+ const { error, targets } = discovery;
1092
+ return {
1093
+ title: 'Welcome to\nMidscene.js Playground!',
1094
+ description: 'Select an available HDC device to create the current HarmonyOS Agent',
1095
+ primaryActionLabel: 'Create Agent',
1096
+ autoSubmitWhenReady: 1 === targets.length,
1097
+ notice: error ? {
1098
+ type: 'warning',
1099
+ message: 'HarmonyOS device discovery failed',
1100
+ description: error
1101
+ } : void 0,
1102
+ fields: [
1103
+ {
1104
+ key: 'deviceId',
1105
+ label: 'HDC device',
1106
+ type: 'select',
1107
+ required: true,
1108
+ options: targets.map((target)=>({
1109
+ label: target.label,
1110
+ value: target.id,
1111
+ description: target.description
1112
+ })),
1113
+ defaultValue: targets.find((target)=>target.isDefault)?.id,
1114
+ placeholder: 'Select a connected HarmonyOS device'
1115
+ }
1116
+ ],
1117
+ targets
1118
+ };
1119
+ },
1120
+ async listTargets () {
1121
+ if (options?.deviceId) return [
1122
+ {
1123
+ id: options.deviceId,
1124
+ label: options.deviceId,
1125
+ isDefault: true,
1126
+ status: 'device'
1127
+ }
1128
+ ];
1129
+ return (await getHdcTargetsSafe()).targets;
1130
+ },
1131
+ async createSession (input) {
1132
+ const targets = options?.deviceId ? [
1133
+ {
1134
+ id: options.deviceId,
1135
+ label: options.deviceId,
1136
+ isDefault: true,
1137
+ status: 'device'
1138
+ }
1139
+ ] : await getHdcTargets();
1140
+ const deviceId = options?.deviceId || ('string' == typeof input?.deviceId && input.deviceId ? input.deviceId : targets.find((target)=>target.isDefault)?.id);
1141
+ if (!deviceId) throw createNoDeviceError();
1142
+ const connectAgent = async ()=>{
1143
+ const device = new HarmonyDevice(deviceId);
1144
+ await device.connect();
1145
+ return new HarmonyAgent(device);
1146
+ };
1147
+ const agent = await connectAgent();
1148
+ return {
1149
+ agent,
1150
+ agentFactory: connectAgent,
1151
+ preview: createScreenshotPreviewDescriptor({
1152
+ title: 'HarmonyOS device preview'
1153
+ }),
1154
+ displayName: deviceId,
1155
+ metadata: {
1156
+ deviceId
1157
+ }
1158
+ };
1159
+ }
1160
+ });
1161
+ if (options?.deferConnection) return {
1162
+ platformId: 'harmony',
1163
+ title: 'Midscene HarmonyOS Playground',
1164
+ sessionManager: createSessionManager(),
1165
+ launchOptions: {
1166
+ port: availablePort,
1167
+ openBrowser: false,
1168
+ verbose: false,
1169
+ staticPath: staticDir
1170
+ },
1171
+ preview: createScreenshotPreviewDescriptor({
1172
+ title: 'HarmonyOS device preview'
1173
+ }),
1174
+ metadata: {
1175
+ ...options.deviceId ? {
1176
+ deviceId: options.deviceId
1177
+ } : {},
1178
+ sessionConnected: false,
1179
+ setupState: 'required'
1180
+ }
1181
+ };
1182
+ const selectedDeviceId = options?.deviceId || await selectDevice();
1051
1183
  return {
1052
1184
  platformId: 'harmony',
1053
1185
  title: 'Midscene HarmonyOS Playground',
@@ -820,6 +820,8 @@ const createPlatformActions = (device)=>({
820
820
  description: 'Terminate (force-stop) a HarmonyOS app by bundle name or mapped app name',
821
821
  interfaceAlias: 'terminate',
822
822
  paramSchema: terminateParamSchema,
823
+ delayBeforeRunner: 0,
824
+ delayAfterRunner: 0,
823
825
  call: async (param)=>{
824
826
  if (!param.uri || '' === param.uri.trim()) throw new Error('Terminate requires a non-empty uri parameter');
825
827
  await device.terminate(param.uri);
@@ -828,6 +830,8 @@ const createPlatformActions = (device)=>({
828
830
  HarmonyBackButton: defineAction({
829
831
  name: 'HarmonyBackButton',
830
832
  description: 'Trigger the system "back" operation on HarmonyOS devices',
833
+ delayBeforeRunner: 0,
834
+ delayAfterRunner: 0,
831
835
  call: async ()=>{
832
836
  await device.back();
833
837
  }
@@ -835,6 +839,8 @@ const createPlatformActions = (device)=>({
835
839
  HarmonyHomeButton: defineAction({
836
840
  name: 'HarmonyHomeButton',
837
841
  description: 'Trigger the system "home" operation on HarmonyOS devices',
842
+ delayBeforeRunner: 0,
843
+ delayAfterRunner: 0,
838
844
  call: async ()=>{
839
845
  await device.home();
840
846
  }
@@ -1018,7 +1024,7 @@ class HarmonyMCPServer extends BaseMCPServer {
1018
1024
  constructor(toolsManager){
1019
1025
  super({
1020
1026
  name: '@midscene/harmony-mcp',
1021
- version: "1.7.6",
1027
+ version: "1.7.7-beta-20260428102047.0",
1022
1028
  description: 'Control the HarmonyOS device using natural language commands'
1023
1029
  }, toolsManager);
1024
1030
  }