agent-miniprogram 0.1.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +386 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/close.d.ts +3 -0
  7. package/dist/commands/close.js +6 -0
  8. package/dist/commands/close.js.map +1 -0
  9. package/dist/commands/connect.d.ts +4 -0
  10. package/dist/commands/connect.js +8 -0
  11. package/dist/commands/connect.js.map +1 -0
  12. package/dist/commands/data.d.ts +3 -0
  13. package/dist/commands/data.js +6 -0
  14. package/dist/commands/data.js.map +1 -0
  15. package/dist/commands/eval.d.ts +3 -0
  16. package/dist/commands/eval.js +6 -0
  17. package/dist/commands/eval.js.map +1 -0
  18. package/dist/commands/input.d.ts +3 -0
  19. package/dist/commands/input.js +6 -0
  20. package/dist/commands/input.js.map +1 -0
  21. package/dist/commands/launch.d.ts +4 -0
  22. package/dist/commands/launch.js +7 -0
  23. package/dist/commands/launch.js.map +1 -0
  24. package/dist/commands/mock.d.ts +3 -0
  25. package/dist/commands/mock.js +13 -0
  26. package/dist/commands/mock.js.map +1 -0
  27. package/dist/commands/navigate.d.ts +7 -0
  28. package/dist/commands/navigate.js +10 -0
  29. package/dist/commands/navigate.js.map +1 -0
  30. package/dist/commands/screenshot.d.ts +4 -0
  31. package/dist/commands/screenshot.js +6 -0
  32. package/dist/commands/screenshot.js.map +1 -0
  33. package/dist/commands/scroll.d.ts +5 -0
  34. package/dist/commands/scroll.js +6 -0
  35. package/dist/commands/scroll.js.map +1 -0
  36. package/dist/commands/snapshot.d.ts +4 -0
  37. package/dist/commands/snapshot.js +6 -0
  38. package/dist/commands/snapshot.js.map +1 -0
  39. package/dist/commands/tap.d.ts +3 -0
  40. package/dist/commands/tap.js +6 -0
  41. package/dist/commands/tap.js.map +1 -0
  42. package/dist/commands/wait.d.ts +5 -0
  43. package/dist/commands/wait.js +20 -0
  44. package/dist/commands/wait.js.map +1 -0
  45. package/dist/daemon/client.d.ts +6 -0
  46. package/dist/daemon/client.js +55 -0
  47. package/dist/daemon/client.js.map +1 -0
  48. package/dist/daemon/server.d.ts +1 -0
  49. package/dist/daemon/server.js +369 -0
  50. package/dist/daemon/server.js.map +1 -0
  51. package/dist/daemon/session.d.ts +14 -0
  52. package/dist/daemon/session.js +65 -0
  53. package/dist/daemon/session.js.map +1 -0
  54. package/dist/replay/player.d.ts +3 -0
  55. package/dist/replay/player.js +41 -0
  56. package/dist/replay/player.js.map +1 -0
  57. package/dist/replay/recorder.d.ts +15 -0
  58. package/dist/replay/recorder.js +39 -0
  59. package/dist/replay/recorder.js.map +1 -0
  60. package/dist/snapshot/builder.d.ts +16 -0
  61. package/dist/snapshot/builder.js +371 -0
  62. package/dist/snapshot/builder.js.map +1 -0
  63. package/dist/snapshot/refs.d.ts +17 -0
  64. package/dist/snapshot/refs.js +68 -0
  65. package/dist/snapshot/refs.js.map +1 -0
  66. package/package.json +44 -0
  67. package/skills/agent-miniprogram/SKILL.md +163 -0
@@ -0,0 +1,65 @@
1
+ import { createRequire } from 'module';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as os from 'os';
5
+ const require = createRequire(import.meta.url);
6
+ const automator = require('miniprogram-automator');
7
+ const STATE_DIR = path.join(os.homedir(), '.agent-miniprogram');
8
+ const STATE_FILE = path.join(STATE_DIR, 'daemon.json');
9
+ let miniProgram = null;
10
+ function ensureStateDir() {
11
+ if (!fs.existsSync(STATE_DIR)) {
12
+ fs.mkdirSync(STATE_DIR, { recursive: true });
13
+ }
14
+ }
15
+ export function saveState(state) {
16
+ ensureStateDir();
17
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
18
+ }
19
+ export function loadState() {
20
+ if (!fs.existsSync(STATE_FILE)) {
21
+ return { connected: false };
22
+ }
23
+ try {
24
+ return JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
25
+ }
26
+ catch {
27
+ return { connected: false };
28
+ }
29
+ }
30
+ export function getMiniProgram() {
31
+ return miniProgram;
32
+ }
33
+ export async function launch(projectPath, wsEndpoint) {
34
+ const opts = { projectPath };
35
+ if (wsEndpoint)
36
+ opts.wsEndpoint = wsEndpoint;
37
+ miniProgram = await automator.launch(opts);
38
+ saveState({ connected: true, projectPath, wsEndpoint, currentPage: await getCurrentPage() });
39
+ }
40
+ export async function connect(wsEndpoint) {
41
+ miniProgram = await automator.connect({ wsEndpoint });
42
+ saveState({ connected: true, wsEndpoint, currentPage: await getCurrentPage() });
43
+ }
44
+ export async function closeSession() {
45
+ if (miniProgram) {
46
+ await miniProgram.close();
47
+ miniProgram = null;
48
+ }
49
+ saveState({ connected: false });
50
+ }
51
+ export async function getCurrentPage() {
52
+ if (!miniProgram)
53
+ return undefined;
54
+ try {
55
+ const page = await miniProgram.currentPage();
56
+ return page?.path;
57
+ }
58
+ catch {
59
+ return undefined;
60
+ }
61
+ }
62
+ export function isConnected() {
63
+ return miniProgram !== null;
64
+ }
65
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/daemon/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function replay(filePath: string, opts?: {
2
+ port?: number;
3
+ }): Promise<void>;
@@ -0,0 +1,41 @@
1
+ import * as fs from 'fs';
2
+ import { rpc } from '../daemon/client.js';
3
+ const REF_METHODS = new Set(['tap', 'input', 'scroll', 'longPress', 'swipe']);
4
+ function usesRef(params) {
5
+ return typeof params?.ref === 'string' && params.ref.startsWith('@');
6
+ }
7
+ export async function replay(filePath, opts = {}) {
8
+ const port = opts.port || 9430;
9
+ if (!fs.existsSync(filePath)) {
10
+ throw new Error(`File not found: ${filePath}`);
11
+ }
12
+ const amp = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
13
+ if (amp.version !== '1')
14
+ throw new Error(`Unsupported .amp version: ${amp.version}`);
15
+ console.log(`Replaying ${amp.actions.length} actions from ${filePath}`);
16
+ for (let i = 0; i < amp.actions.length; i++) {
17
+ const action = amp.actions[i];
18
+ // Wait the appropriate time between actions (capped at 3s)
19
+ if (i > 0) {
20
+ const prevAction = amp.actions[i - 1];
21
+ const delay = Math.min(action.timestamp - prevAction.timestamp, 3000);
22
+ if (delay > 50) {
23
+ await new Promise(r => setTimeout(r, delay));
24
+ }
25
+ }
26
+ // Auto-snapshot before ref-based actions to rebuild ref registry
27
+ if (REF_METHODS.has(action.method) && usesRef(action.params)) {
28
+ await rpc('snapshot', {}, port);
29
+ }
30
+ console.log(` [${i + 1}/${amp.actions.length}] ${action.method}`);
31
+ try {
32
+ await rpc(action.method, action.params, port);
33
+ }
34
+ catch (err) {
35
+ console.error(` Error: ${err.message}`);
36
+ throw err;
37
+ }
38
+ }
39
+ console.log('Replay complete.');
40
+ }
41
+ //# sourceMappingURL=player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.js","sourceRoot":"","sources":["../../src/replay/player.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAG1C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9E,SAAS,OAAO,CAAC,MAAW;IAC1B,OAAO,OAAO,MAAM,EAAE,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,QAAgB,EAAE,OAA0B,EAAE;IACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IAE/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACpE,IAAI,GAAG,CAAC,OAAO,KAAK,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAErF,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,OAAO,CAAC,MAAM,iBAAiB,QAAQ,EAAE,CAAC,CAAC;IAExE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9B,2DAA2D;QAC3D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtE,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,iEAAiE;QACjE,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,MAAM,GAAG,CAAC,UAAU,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface AmpAction {
2
+ method: string;
3
+ params: any;
4
+ timestamp: number;
5
+ }
6
+ export interface AmpFile {
7
+ version: '1';
8
+ createdAt: string;
9
+ actions: AmpAction[];
10
+ }
11
+ export declare function startRecording(): void;
12
+ export declare function recordAction(method: string, params: any): void;
13
+ export declare function stopRecording(outputPath?: string): string;
14
+ export declare function isRecording(): boolean;
15
+ export declare function loadRecording(): AmpAction[] | null;
@@ -0,0 +1,39 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ const STATE_DIR = path.join(os.homedir(), '.agent-miniprogram');
5
+ const RECORDING_FILE = path.join(STATE_DIR, 'recording.json');
6
+ let recording = null;
7
+ let recordingStartTime = 0;
8
+ export function startRecording() {
9
+ recording = [];
10
+ recordingStartTime = Date.now();
11
+ fs.writeFileSync(RECORDING_FILE, JSON.stringify({ active: true, startTime: recordingStartTime }));
12
+ }
13
+ export function recordAction(method, params) {
14
+ if (!recording)
15
+ return;
16
+ recording.push({ method, params, timestamp: Date.now() - recordingStartTime });
17
+ }
18
+ export function stopRecording(outputPath) {
19
+ if (!recording)
20
+ throw new Error('Not recording');
21
+ const amp = {
22
+ version: '1',
23
+ createdAt: new Date().toISOString(),
24
+ actions: recording,
25
+ };
26
+ const outFile = outputPath || path.join(process.cwd(), `recording-${Date.now()}.amp`);
27
+ fs.writeFileSync(outFile, JSON.stringify(amp, null, 2));
28
+ recording = null;
29
+ if (fs.existsSync(RECORDING_FILE))
30
+ fs.unlinkSync(RECORDING_FILE);
31
+ return outFile;
32
+ }
33
+ export function isRecording() {
34
+ return recording !== null;
35
+ }
36
+ export function loadRecording() {
37
+ return recording;
38
+ }
39
+ //# sourceMappingURL=recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;AAChE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAc9D,IAAI,SAAS,GAAuB,IAAI,CAAC;AACzC,IAAI,kBAAkB,GAAW,CAAC,CAAC;AAEnC,MAAM,UAAU,cAAc;IAC5B,SAAS,GAAG,EAAE,CAAC;IACf,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,MAAW;IACtD,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,kBAAkB,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAmB;IAC/C,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,GAAG,GAAY;QACnB,OAAO,EAAE,GAAG;QACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO,EAAE,SAAS;KACnB,CAAC;IACF,MAAM,OAAO,GAAG,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtF,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,SAAS,GAAG,IAAI,CAAC;IACjB,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IACjE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,SAAS,KAAK,IAAI,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface SnapshotOptions {
2
+ includeData?: boolean;
3
+ }
4
+ export interface SnapshotResult {
5
+ snapshot: string;
6
+ page: string;
7
+ }
8
+ interface WxmlNode {
9
+ tag: string;
10
+ attrs: Record<string, string>;
11
+ children: WxmlNode[];
12
+ text: string;
13
+ }
14
+ export declare function parseWxml(wxml: string): WxmlNode;
15
+ export declare function buildSnapshot(page: any, opts: SnapshotOptions): Promise<SnapshotResult>;
16
+ export {};
@@ -0,0 +1,371 @@
1
+ import { clearRefs, registerRef, saveRefs, loadRefs } from './refs.js';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as os from 'os';
5
+ const STATE_DIR = path.join(os.homedir(), '.agent-miniprogram');
6
+ const LAST_SNAPSHOT_FILE = path.join(STATE_DIR, 'last-snapshot.txt');
7
+ const LAYOUT_TAGS = new Set(['view', 'block', 'cover-view']);
8
+ // Built-in WXML tags — anything else is a custom component.
9
+ // Custom components get plain tag-name selectors (no :nth-child) because
10
+ // the WeChat automator does not support :nth-child on custom component tags.
11
+ const BUILT_IN_WXML_TAGS = new Set([
12
+ 'view', 'scroll-view', 'swiper', 'swiper-item', 'movable-view', 'movable-area',
13
+ 'cover-view', 'cover-image', 'icon', 'text', 'rich-text', 'progress',
14
+ 'button', 'checkbox-group', 'checkbox', 'form', 'input', 'label',
15
+ 'picker', 'picker-view', 'picker-view-column', 'radio-group', 'radio',
16
+ 'slider', 'switch', 'textarea', 'navigator', 'functional-page-navigator',
17
+ 'audio', 'camera', 'image', 'live-player', 'live-pusher', 'video',
18
+ 'map', 'canvas', 'open-data', 'web-view', 'ad', 'official-account',
19
+ 'block', 'page', 'template', 'slot', 'wxs',
20
+ 'svg', 'path', 'circle', 'rect', 'line', 'polygon', 'polyline',
21
+ 'ellipse', 'g', 'defs', 'use', 'symbol',
22
+ ]);
23
+ const EVENT_PREFIXES = [
24
+ 'bindtap', 'bind:tap', 'catchtap', 'catch:tap',
25
+ 'bindinput', 'bind:input', 'bindchange', 'bind:change',
26
+ 'bindsubmit', 'bind:submit', 'bindscroll', 'bind:scroll',
27
+ 'bindconfirm', 'bind:confirm', 'bindfocus', 'bind:focus',
28
+ 'bindblur', 'bind:blur', 'bindlongpress', 'bind:longpress',
29
+ 'bindgetuserinfo', 'bindgetphonenumber',
30
+ ];
31
+ // ─── WXML parser ─────────────────────────────────────────────────────────────
32
+ function findTagEnd(s, start) {
33
+ let i = start + 1;
34
+ let inStr = false;
35
+ let strChar = '';
36
+ while (i < s.length) {
37
+ const c = s[i];
38
+ if (inStr) {
39
+ if (c === strChar)
40
+ inStr = false;
41
+ }
42
+ else {
43
+ if (c === '"' || c === "'") {
44
+ inStr = true;
45
+ strChar = c;
46
+ }
47
+ else if (c === '>')
48
+ return i;
49
+ }
50
+ i++;
51
+ }
52
+ return s.length - 1;
53
+ }
54
+ function parseAttrs(str) {
55
+ const attrs = {};
56
+ let i = 0;
57
+ while (i < str.length) {
58
+ while (i < str.length && /\s/.test(str[i]))
59
+ i++;
60
+ if (i >= str.length)
61
+ break;
62
+ let nameStart = i;
63
+ while (i < str.length && !/[\s=/>]/.test(str[i]))
64
+ i++;
65
+ const name = str.slice(nameStart, i).trim();
66
+ if (!name) {
67
+ i++;
68
+ continue;
69
+ }
70
+ while (i < str.length && /\s/.test(str[i]))
71
+ i++;
72
+ if (str[i] !== '=') {
73
+ attrs[name] = '';
74
+ continue;
75
+ }
76
+ i++;
77
+ while (i < str.length && /\s/.test(str[i]))
78
+ i++;
79
+ if (str[i] === '"' || str[i] === "'") {
80
+ const q = str[i++];
81
+ let val = '';
82
+ while (i < str.length && str[i] !== q)
83
+ val += str[i++];
84
+ i++;
85
+ attrs[name] = val;
86
+ }
87
+ else {
88
+ let val = '';
89
+ while (i < str.length && !/[\s/>]/.test(str[i]))
90
+ val += str[i++];
91
+ attrs[name] = val;
92
+ }
93
+ }
94
+ return attrs;
95
+ }
96
+ // Self-closing WXML tags that never have children
97
+ const VOID_TAGS = new Set([
98
+ 'image', 'input', 'textarea', 'progress', 'slider', 'switch',
99
+ 'icon', 'radio', 'checkbox', 'editor', 'map', 'canvas', 'camera',
100
+ 'live-player', 'live-pusher', 'official-account', 'open-data', 'web-view',
101
+ ]);
102
+ function tokenize(wxml) {
103
+ const tokens = [];
104
+ let i = 0;
105
+ while (i < wxml.length) {
106
+ if (wxml[i] !== '<') {
107
+ let end = wxml.indexOf('<', i);
108
+ if (end === -1)
109
+ end = wxml.length;
110
+ const text = wxml.slice(i, end);
111
+ if (text.trim())
112
+ tokens.push({ type: 'text', content: text.trim() });
113
+ i = end;
114
+ continue;
115
+ }
116
+ if (wxml[i + 1] === '!' || wxml[i + 1] === '?') {
117
+ const end = wxml.indexOf('>', i);
118
+ i = end === -1 ? wxml.length : end + 1;
119
+ continue;
120
+ }
121
+ const tagEnd = findTagEnd(wxml, i);
122
+ const raw = wxml.slice(i + 1, tagEnd).trim();
123
+ if (raw.startsWith('/')) {
124
+ tokens.push({ type: 'close', tag: raw.slice(1).trim().toLowerCase() });
125
+ }
126
+ else {
127
+ const selfCloseSlash = raw.endsWith('/');
128
+ const content = selfCloseSlash ? raw.slice(0, -1).trim() : raw;
129
+ const spaceIdx = content.search(/\s/);
130
+ const tag = (spaceIdx === -1 ? content : content.slice(0, spaceIdx)).toLowerCase();
131
+ const attrStr = spaceIdx === -1 ? '' : content.slice(spaceIdx);
132
+ const attrs = parseAttrs(attrStr);
133
+ const selfClose = selfCloseSlash || VOID_TAGS.has(tag);
134
+ tokens.push({ type: 'open', tag, attrs, selfClose });
135
+ }
136
+ i = tagEnd + 1;
137
+ }
138
+ return tokens;
139
+ }
140
+ function buildTree(tokens) {
141
+ const root = { tag: '__root__', attrs: {}, children: [], text: '' };
142
+ const stack = [root];
143
+ for (const tok of tokens) {
144
+ const parent = stack[stack.length - 1];
145
+ if (tok.type === 'text') {
146
+ if (parent.children.length > 0) {
147
+ parent.children[parent.children.length - 1].text += ' ' + tok.content;
148
+ }
149
+ else {
150
+ parent.text += tok.content;
151
+ }
152
+ }
153
+ else if (tok.type === 'open') {
154
+ const node = { tag: tok.tag, attrs: tok.attrs, children: [], text: '' };
155
+ parent.children.push(node);
156
+ if (!tok.selfClose)
157
+ stack.push(node);
158
+ }
159
+ else {
160
+ // close: pop to matching open
161
+ for (let j = stack.length - 1; j >= 1; j--) {
162
+ if (stack[j].tag === tok.tag) {
163
+ stack.splice(j);
164
+ break;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ return root;
170
+ }
171
+ export function parseWxml(wxml) {
172
+ return buildTree(tokenize(wxml));
173
+ }
174
+ // ─── Snapshot rendering ───────────────────────────────────────────────────────
175
+ function getEventBindings(attrs) {
176
+ const seen = new Set();
177
+ return Object.keys(attrs)
178
+ .filter(k => EVENT_PREFIXES.some(p => k === p || k.startsWith(p + '=')))
179
+ .map(k => {
180
+ const handler = attrs[k];
181
+ let label;
182
+ if (k.includes('tap'))
183
+ label = `bindtap=${handler}`;
184
+ else if (k.includes('input'))
185
+ label = `bindinput=${handler}`;
186
+ else if (k.includes('change'))
187
+ label = `bindchange=${handler}`;
188
+ else if (k.includes('submit'))
189
+ label = `bindsubmit=${handler}`;
190
+ else if (k.includes('longpress'))
191
+ label = `bindlongpress=${handler}`;
192
+ else
193
+ label = `${k.replace('bind:', 'bind')}=${handler}`;
194
+ if (seen.has(label))
195
+ return '';
196
+ seen.add(label);
197
+ return label;
198
+ })
199
+ .filter(Boolean);
200
+ }
201
+ function getImportantAttrs(tag, attrs) {
202
+ const out = [];
203
+ if (tag === 'navigator') {
204
+ if (attrs.url) {
205
+ out.push(`→ ${attrs.url}`);
206
+ return out;
207
+ }
208
+ }
209
+ if (attrs.src)
210
+ out.push(`src="${attrs.src}"`);
211
+ if (attrs.url)
212
+ out.push(`url="${attrs.url}"`);
213
+ if (attrs.href)
214
+ out.push(`href="${attrs.href}"`);
215
+ if (attrs.placeholder)
216
+ out.push(`placeholder="${attrs.placeholder}"`);
217
+ if (attrs.value)
218
+ out.push(`value="${attrs.value}"`);
219
+ if ((tag === 'input' || tag === 'textarea') && attrs.type)
220
+ out.push(`type="${attrs.type}"`);
221
+ if (tag === 'scroll-view') {
222
+ if ('scroll-y' in attrs)
223
+ out.push('scroll-y');
224
+ if ('scroll-x' in attrs)
225
+ out.push('scroll-x');
226
+ }
227
+ if (attrs['open-type'])
228
+ out.push(`open-type="${attrs['open-type']}"`);
229
+ return out;
230
+ }
231
+ function isInteresting(node) {
232
+ const tag = node.tag;
233
+ if (!tag || tag === '__root__' || tag === 'wxs')
234
+ return false;
235
+ if (!LAYOUT_TAGS.has(tag))
236
+ return true;
237
+ if (node.text.trim())
238
+ return true;
239
+ if (getEventBindings(node.attrs).length > 0)
240
+ return true;
241
+ if (getImportantAttrs(tag, node.attrs).length > 0)
242
+ return true;
243
+ return node.children.some(c => isInteresting(c));
244
+ }
245
+ /**
246
+ * Build a CSS selector segment for this element.
247
+ *
248
+ * Priority:
249
+ * 1. #id — globally unique, always preferred
250
+ * 2. tag.class1.class2 — up to 2 classes; reliable across component boundaries
251
+ * 3. tag:nth-child(n) — for built-in tags with no class
252
+ * 4. tag — for custom components (no :nth-child; unsupported by WeChat automator)
253
+ *
254
+ * Selectors are stored in refs.json. Resolution in the daemon uses page.$() /
255
+ * element.$(), splitting at component boundaries as needed (see server.ts).
256
+ */
257
+ function buildCssSelector(tag, attrs, childIndex, // 0-based index among ALL parent's children
258
+ parentCss) {
259
+ if (attrs.id)
260
+ return `#${attrs.id}`;
261
+ let segment;
262
+ if (attrs.class) {
263
+ const classes = attrs.class.trim().split(/\s+/).slice(0, 2).map(c => `.${c}`).join('');
264
+ segment = `${tag}${classes}`;
265
+ }
266
+ else if (BUILT_IN_WXML_TAGS.has(tag)) {
267
+ segment = `${tag}:nth-child(${childIndex + 1})`;
268
+ }
269
+ else {
270
+ // Custom component: :nth-child is unsupported by the WeChat automator; use tag name only.
271
+ segment = tag;
272
+ }
273
+ return parentCss ? `${parentCss} > ${segment}` : segment;
274
+ }
275
+ function renderNode(node, indent, childIndex, parentCss, lines) {
276
+ const tag = node.tag;
277
+ const text = node.text.trim();
278
+ const events = getEventBindings(node.attrs);
279
+ const importantAttrs = getImportantAttrs(tag, node.attrs);
280
+ const css = buildCssSelector(tag, node.attrs, childIndex, parentCss);
281
+ const ref = registerRef(css, tag, text || undefined);
282
+ let line = `${' '.repeat(indent)}[${tag} ${ref}]`;
283
+ if (importantAttrs.length)
284
+ line += ' ' + importantAttrs.join(' ');
285
+ if (text)
286
+ line += ` "${text}"`;
287
+ if (events.length)
288
+ line += ' (' + events.join(', ') + ')';
289
+ lines.push(line);
290
+ node.children.forEach((child, i) => {
291
+ if (isInteresting(child)) {
292
+ renderNode(child, indent + 1, i, css, lines);
293
+ }
294
+ });
295
+ }
296
+ // ─── Main export ──────────────────────────────────────────────────────────────
297
+ export async function buildSnapshot(page, opts) {
298
+ loadRefs();
299
+ clearRefs();
300
+ const pagePath = (page.path || 'unknown').replace(/^\//, '');
301
+ const lines = [`Page: /${pagePath}`, ''];
302
+ let wxmlStr = '';
303
+ try {
304
+ wxmlStr = await fetchPageWxml(page);
305
+ }
306
+ catch (err) {
307
+ lines.push(`(snapshot error: ${err.message})`);
308
+ return finalize(lines, pagePath);
309
+ }
310
+ if (!wxmlStr.trim()) {
311
+ lines.push('(empty page)');
312
+ return finalize(lines, pagePath);
313
+ }
314
+ const tree = parseWxml(wxmlStr);
315
+ // The WXML from `page.$('page').outerWxml()` wraps content in <page>.
316
+ // Skip that root wrapper so we render its children at indent 0.
317
+ const topNodes = tree.tag === '__root__'
318
+ ? (tree.children[0]?.tag === 'page' ? tree.children[0].children : tree.children)
319
+ : tree.tag === 'page'
320
+ ? tree.children
321
+ : [tree];
322
+ topNodes.forEach((child, i) => {
323
+ if (isInteresting(child)) {
324
+ // top-level children of <page> — use "page > tag:nth-child(n)" as root selector
325
+ renderNode(child, 0, i, 'page', lines);
326
+ }
327
+ });
328
+ if (opts.includeData) {
329
+ try {
330
+ const data = await page.data();
331
+ lines.push('');
332
+ lines.push(`data: ${JSON.stringify(data).slice(0, 500)}`);
333
+ }
334
+ catch { /* ignore */ }
335
+ }
336
+ saveRefs();
337
+ return finalize(lines, pagePath);
338
+ }
339
+ async function fetchPageWxml(page) {
340
+ // Strategy 1: page.$('page') – standard miniprogram root
341
+ try {
342
+ const rootEl = await page.$('page');
343
+ if (rootEl)
344
+ return await rootEl.outerWxml();
345
+ }
346
+ catch { /* fall through */ }
347
+ // Strategy 2: direct children of page
348
+ try {
349
+ const children = await page.$$('page > *');
350
+ if (children?.length) {
351
+ const parts = await Promise.all(children.map((el) => el.outerWxml().catch(() => '')));
352
+ return parts.join('\n');
353
+ }
354
+ }
355
+ catch { /* fall through */ }
356
+ // Strategy 3: first element on page
357
+ try {
358
+ const all = await page.$$('*');
359
+ if (all?.length)
360
+ return await all[0].outerWxml();
361
+ }
362
+ catch { /* fall through */ }
363
+ return '';
364
+ }
365
+ function finalize(lines, pagePath) {
366
+ const snapshot = lines.join('\n');
367
+ fs.mkdirSync(path.dirname(LAST_SNAPSHOT_FILE), { recursive: true });
368
+ fs.writeFileSync(LAST_SNAPSHOT_FILE, snapshot);
369
+ return { snapshot, page: pagePath };
370
+ }
371
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/snapshot/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ interface RefEntry {
2
+ selector: string;
3
+ tag: string;
4
+ text?: string;
5
+ matchIndex?: number;
6
+ }
7
+ export declare function loadRefs(): void;
8
+ export declare function saveRefs(): void;
9
+ export declare function clearRefs(): void;
10
+ export declare function registerRef(selector: string, tag: string, text?: string): string;
11
+ export declare function resolveRef(ref: string): string | undefined;
12
+ export declare function resolveRefFull(ref: string): {
13
+ selector: string;
14
+ matchIndex: number;
15
+ } | undefined;
16
+ export declare function getRefInfo(ref: string): RefEntry | undefined;
17
+ export {};