@midscene/visualizer 1.7.5-beta-20260421030751.0 → 1.7.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.
Files changed (28) hide show
  1. package/dist/es/component/config-selector/index.mjs +7 -1
  2. package/dist/es/component/history-selector/index.css +1 -3
  3. package/dist/es/component/history-selector/index.mjs +33 -5
  4. package/dist/es/component/playground/index.css +9 -1
  5. package/dist/es/component/prompt-input/index.css +9 -1
  6. package/dist/es/component/prompt-input/index.mjs +44 -45
  7. package/dist/es/component/universal-playground/index.css +129 -0
  8. package/dist/es/component/universal-playground/index.mjs +13 -8
  9. package/dist/es/hooks/useMinimalTypeGate.mjs +47 -0
  10. package/dist/es/hooks/usePlaygroundExecution.mjs +1 -0
  11. package/dist/es/utils/progress-action-icon.mjs +49 -0
  12. package/dist/lib/component/config-selector/index.js +7 -1
  13. package/dist/lib/component/history-selector/index.css +1 -3
  14. package/dist/lib/component/history-selector/index.js +33 -5
  15. package/dist/lib/component/playground/index.css +9 -1
  16. package/dist/lib/component/prompt-input/index.css +9 -1
  17. package/dist/lib/component/prompt-input/index.js +44 -46
  18. package/dist/lib/component/universal-playground/index.css +129 -0
  19. package/dist/lib/component/universal-playground/index.js +13 -8
  20. package/dist/lib/hooks/useMinimalTypeGate.js +81 -0
  21. package/dist/lib/hooks/usePlaygroundExecution.js +1 -0
  22. package/dist/lib/utils/progress-action-icon.js +86 -0
  23. package/dist/types/component/config-selector/index.d.ts +1 -0
  24. package/dist/types/component/history-selector/index.d.ts +1 -0
  25. package/dist/types/hooks/useMinimalTypeGate.d.ts +72 -0
  26. package/dist/types/types.d.ts +32 -9
  27. package/dist/types/utils/progress-action-icon.d.ts +16 -0
  28. package/package.json +5 -5
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ useMinimalTypeGate: ()=>useMinimalTypeGate
28
+ });
29
+ const external_react_namespaceObject = require("react");
30
+ function useMinimalTypeGate(options) {
31
+ const { enabled, form, selectedType, onAfterReset, defaultType = 'aiAct' } = options;
32
+ const [hasExplicitSelection, setHasExplicitSelection] = (0, external_react_namespaceObject.useState)(false);
33
+ const skipNextRestoreRef = (0, external_react_namespaceObject.useRef)(false);
34
+ (0, external_react_namespaceObject.useEffect)(()=>{
35
+ if (!enabled || hasExplicitSelection || !selectedType || selectedType === defaultType) return;
36
+ skipNextRestoreRef.current = false;
37
+ form.setFieldsValue({
38
+ type: defaultType,
39
+ prompt: '',
40
+ params: {}
41
+ });
42
+ null == onAfterReset || onAfterReset();
43
+ }, [
44
+ enabled,
45
+ hasExplicitSelection,
46
+ selectedType,
47
+ defaultType,
48
+ form,
49
+ onAfterReset
50
+ ]);
51
+ const markExplicitSelection = (0, external_react_namespaceObject.useCallback)(()=>{
52
+ if (!enabled) return;
53
+ setHasExplicitSelection(true);
54
+ }, [
55
+ enabled
56
+ ]);
57
+ const skipNextRestore = (0, external_react_namespaceObject.useCallback)(()=>{
58
+ skipNextRestoreRef.current = true;
59
+ }, []);
60
+ const shouldSkipRestoreOnce = (0, external_react_namespaceObject.useCallback)(()=>{
61
+ if (!skipNextRestoreRef.current) return false;
62
+ skipNextRestoreRef.current = false;
63
+ return true;
64
+ }, []);
65
+ return (0, external_react_namespaceObject.useMemo)(()=>({
66
+ markExplicitSelection,
67
+ skipNextRestore,
68
+ shouldSkipRestoreOnce
69
+ }), [
70
+ markExplicitSelection,
71
+ skipNextRestore,
72
+ shouldSkipRestoreOnce
73
+ ]);
74
+ }
75
+ exports.useMinimalTypeGate = __webpack_exports__.useMinimalTypeGate;
76
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
77
+ "useMinimalTypeGate"
78
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
79
+ Object.defineProperty(exports, '__esModule', {
80
+ value: true
81
+ });
@@ -171,6 +171,7 @@ function usePlaygroundExecution(options) {
171
171
  id: `progress-${thisRunningId}-task-${index}`,
172
172
  type: 'progress',
173
173
  content: buildProgressContent(task),
174
+ actionKind: (0, agent_namespaceObject.typeStr)(task),
174
175
  timestamp: new Date((null == (_task_timing = task.timing) ? void 0 : _task_timing.start) || Date.now()),
175
176
  result: task.error ? {
176
177
  error: formatError(task.error),
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ defaultProgressActionIcon: ()=>defaultProgressActionIcon,
28
+ resolveProgressActionIcon: ()=>resolveProgressActionIcon
29
+ });
30
+ const icons_namespaceObject = require("@ant-design/icons");
31
+ const external_react_namespaceObject = require("react");
32
+ function defaultProgressActionIcon(kind) {
33
+ switch(kind){
34
+ case 'Planning':
35
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.ExperimentOutlined);
36
+ case 'Locate':
37
+ case 'Insight':
38
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.SearchOutlined);
39
+ case 'Tap':
40
+ case 'Click':
41
+ case 'DoubleClick':
42
+ case 'RightClick':
43
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.AimOutlined);
44
+ case 'Hover':
45
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.SelectOutlined);
46
+ case 'Input':
47
+ case 'KeyboardPress':
48
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.EditOutlined);
49
+ case 'Scroll':
50
+ case 'Swipe':
51
+ case 'PullGesture':
52
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.SwapOutlined);
53
+ case 'WaitFor':
54
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.HourglassOutlined);
55
+ case 'Assert':
56
+ case 'Boolean':
57
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.CheckCircleOutlined);
58
+ case 'Query':
59
+ case 'Number':
60
+ case 'String':
61
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.FileSearchOutlined);
62
+ case 'Ask':
63
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.QuestionCircleOutlined);
64
+ case 'Act':
65
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.PlayCircleOutlined);
66
+ default:
67
+ return /*#__PURE__*/ (0, external_react_namespaceObject.createElement)(icons_namespaceObject.ThunderboltOutlined);
68
+ }
69
+ }
70
+ function resolveProgressActionIcon(kind, override) {
71
+ if (!kind) return null;
72
+ if (override) {
73
+ const custom = override(kind);
74
+ if (void 0 !== custom) return custom;
75
+ }
76
+ return defaultProgressActionIcon(kind);
77
+ }
78
+ exports.defaultProgressActionIcon = __webpack_exports__.defaultProgressActionIcon;
79
+ exports.resolveProgressActionIcon = __webpack_exports__.resolveProgressActionIcon;
80
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
81
+ "defaultProgressActionIcon",
82
+ "resolveProgressActionIcon"
83
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
84
+ Object.defineProperty(exports, '__esModule', {
85
+ value: true
86
+ });
@@ -9,6 +9,7 @@ interface ConfigSelectorProps {
9
9
  hideDomAndScreenshotOptions?: boolean;
10
10
  deviceType?: DeviceType;
11
11
  trigger?: ReactNode;
12
+ popupPlacement?: 'topRight' | 'bottomRight';
12
13
  }
13
14
  export declare const ConfigSelector: React.FC<ConfigSelectorProps>;
14
15
  export {};
@@ -7,6 +7,7 @@ interface HistorySelectorProps {
7
7
  history: HistoryItem[];
8
8
  currentType: string;
9
9
  trigger?: ReactNode;
10
+ popupPlacement?: 'top' | 'bottom';
10
11
  }
11
12
  export declare const HistorySelector: React.FC<HistorySelectorProps>;
12
13
  export {};
@@ -0,0 +1,72 @@
1
+ import type { FormInstance } from 'antd';
2
+ /**
3
+ * Options for {@link useMinimalTypeGate}.
4
+ */
5
+ export interface UseMinimalTypeGateOptions {
6
+ /**
7
+ * Whether the gate is active. When `false`, the hook is a no-op and all
8
+ * returned callbacks become stable identity-only functions. Typically
9
+ * wired to `chrome?.variant === 'minimal'`.
10
+ */
11
+ enabled: boolean;
12
+ /** The antd form that owns `type` / `prompt` / `params` fields. */
13
+ form: FormInstance;
14
+ /** Currently selected action type (usually read via `Form.useWatch`). */
15
+ selectedType: string | undefined;
16
+ /**
17
+ * Called when the gate snaps `form.type` back to its default. Hosts use
18
+ * this hook to clear any sibling state (local `promptValue`, custom
19
+ * history refs, etc.) alongside the form reset.
20
+ */
21
+ onAfterReset?: () => void;
22
+ /**
23
+ * The default type to snap back to when the user has not made an
24
+ * explicit selection. Defaults to `'aiAct'`, matching the natural
25
+ * language action.
26
+ */
27
+ defaultType?: string;
28
+ }
29
+ export interface MinimalTypeGate {
30
+ /**
31
+ * Record that the user has explicitly chosen an action — disables the
32
+ * snap-back effect for the remainder of the component's lifecycle.
33
+ * Call this from every user-initiated selection path: action dropdown
34
+ * click, history replay, etc.
35
+ */
36
+ markExplicitSelection: () => void;
37
+ /**
38
+ * One-shot flag: request that the NEXT run of the caller's
39
+ * history-restore effect be skipped entirely. Used when a history
40
+ * replay is about to change `selectedType` and we don't want the
41
+ * effect to overwrite the fresh form values. The flag auto-clears
42
+ * after being read via {@link shouldSkipRestoreOnce}.
43
+ */
44
+ skipNextRestore: () => void;
45
+ /**
46
+ * Read-and-clear accessor for the one-shot flag set by
47
+ * {@link skipNextRestore}.
48
+ */
49
+ shouldSkipRestoreOnce: () => boolean;
50
+ }
51
+ /**
52
+ * Keeps a minimal-chrome prompt input pinned to its default type until
53
+ * the user makes an explicit selection. The minimal chrome hides the
54
+ * type radio row, so any background pathway that lands a non-default
55
+ * type in the form (e.g. `lastSelectedType` restored from local
56
+ * storage) would otherwise surface a type the user never asked for.
57
+ *
58
+ * Behaviour:
59
+ * 1. While `enabled` and the user has not called `markExplicitSelection`,
60
+ * any `selectedType !== defaultType` triggers a form reset back to
61
+ * the default, clearing `prompt` and `params` along with it.
62
+ * 2. Once the user explicitly picks something, the gate unlocks and
63
+ * stays unlocked for the rest of the component's life.
64
+ * 3. `skipNextRestore` plus `shouldSkipRestoreOnce` give the caller a
65
+ * one-tick bypass so its own history-restore effect can skip the
66
+ * iteration where the type just changed due to a history replay.
67
+ *
68
+ * This replaces the previously inline `minimalHasExplicitTypeSelection`
69
+ * state + `skipMinimalSyncRef` + reset effect that lived inside
70
+ * `PromptInput`.
71
+ */
72
+ export declare function useMinimalTypeGate(options: UseMinimalTypeGateOptions): MinimalTypeGate;
@@ -1,5 +1,5 @@
1
1
  import type { ConnectivityTestResult, DeviceAction, ModelBrief, UIContext } from '@midscene/core';
2
- import type { ComponentType } from 'react';
2
+ import type { ComponentType, ReactNode } from 'react';
3
3
  export interface ZodType {
4
4
  _def?: {
5
5
  typeName: 'ZodOptional' | 'ZodDefault' | 'ZodNullable' | 'ZodObject' | 'ZodEnum' | 'ZodNumber' | 'ZodString' | 'ZodBoolean';
@@ -154,6 +154,14 @@ export interface InfoListItem {
154
154
  loadingProgressText?: string;
155
155
  verticalMode?: boolean;
156
156
  actionType?: string;
157
+ /**
158
+ * Identifier for the ExecutionTask that produced this progress item —
159
+ * `task.subType || task.type`, e.g. `'Planning'`, `'Locate'`, `'Tap'`,
160
+ * `'Input'`, `'Scroll'`, `'RunAdbShell'`. Hosts can use this with
161
+ * {@link PromptInputChromeConfig.resolveProgressActionIcon} to render
162
+ * a domain-specific icon in the progress pill.
163
+ */
164
+ actionKind?: string;
157
165
  }
158
166
  export interface UniversalPlaygroundConfig {
159
167
  showContextPreview?: boolean;
@@ -180,17 +188,32 @@ export interface UniversalPlaygroundConfig {
180
188
  */
181
189
  showSystemMessageHeader?: boolean;
182
190
  /**
183
- * When `true`, consecutive progress items in the conversation log are
184
- * wrapped under a single collapsible group header. A "run" is bounded by
185
- * the first non-progress item before and after it. Defaults to `false`
186
- * (flat list, every progress item renders inline).
191
+ * Opt-in controls for how consecutive progress items render in the
192
+ * conversation log. Defaults flatten every progress step inline (no
193
+ * grouping, no connector) so existing hosts keep their behaviour.
194
+ */
195
+ executionFlow?: ExecutionFlowConfig;
196
+ }
197
+ export interface ExecutionFlowConfig {
198
+ /**
199
+ * When `true`, consecutive progress items are wrapped under a single
200
+ * collapsible "Execution Flow" header. A "run" is bounded by the first
201
+ * non-progress item before and after it.
202
+ */
203
+ collapsible?: boolean;
204
+ /**
205
+ * Label shown on the collapsible header. Defaults to `'Execution Flow'`.
187
206
  */
188
- collapsibleProgressGroup?: boolean;
207
+ label?: string;
189
208
  /**
190
- * Label shown on the collapsible progress group header when
191
- * `collapsibleProgressGroup` is enabled. Defaults to `'Execution Flow'`.
209
+ * Resolve a domain-specific icon for each progress step. Called with
210
+ * `InfoListItem.actionKind` (e.g. `'Planning'`, `'Locate'`, `'Tap'`,
211
+ * `'Input'`, `'RunAdbShell'`). Returning a React node renders it to
212
+ * the left of the status glyph inside the pill; returning `undefined`
213
+ * falls back to the default mapping shipped by the visualiser, and
214
+ * returning `null` hides the icon slot entirely.
192
215
  */
193
- progressGroupLabel?: string;
216
+ resolveActionIcon?: (kind: string) => ReactNode | null | undefined;
194
217
  }
195
218
  /**
196
219
  * Optional visual chrome overrides for the embedded prompt input.
@@ -0,0 +1,16 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Default icon mapping for an `InfoListItem.actionKind` (which is
4
+ * `ExecutionTask.subType || ExecutionTask.type` — see
5
+ * `packages/core/src/agent/ui-utils.ts`). Returns `null` to mean
6
+ * "no icon for this kind"; callers should render the status glyph only.
7
+ *
8
+ * Hosts can override this entirely via
9
+ * `ExecutionFlowConfig.resolveActionIcon`.
10
+ */
11
+ export declare function defaultProgressActionIcon(kind: string): ReactNode | null;
12
+ /**
13
+ * Resolve the icon for a progress action, applying the host's override
14
+ * (if any) before falling back to the default mapping.
15
+ */
16
+ export declare function resolveProgressActionIcon(kind: string | undefined, override?: (kind: string) => ReactNode | null | undefined): ReactNode | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/visualizer",
3
- "version": "1.7.5-beta-20260421030751.0",
3
+ "version": "1.7.5",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
@@ -58,10 +58,10 @@
58
58
  "antd": "^5.21.6",
59
59
  "buffer": "6.0.3",
60
60
  "dayjs": "^1.11.11",
61
- "@midscene/playground": "1.7.5-beta-20260421030751.0",
62
- "@midscene/core": "1.7.5-beta-20260421030751.0",
63
- "@midscene/shared": "1.7.5-beta-20260421030751.0",
64
- "@midscene/web": "1.7.5-beta-20260421030751.0"
61
+ "@midscene/core": "1.7.5",
62
+ "@midscene/shared": "1.7.5",
63
+ "@midscene/playground": "1.7.5",
64
+ "@midscene/web": "1.7.5"
65
65
  },
66
66
  "license": "MIT",
67
67
  "scripts": {