shennian 0.3.1 → 0.3.3
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/README.md +3 -1
- package/dist/publish-build-manifest.json +291 -341
- package/dist/src/agents/codex.js +1 -1
- package/dist/src/agents/command-spec.js +2 -2
- package/dist/src/agents/detect.js +1 -1
- package/dist/src/agents/model-registry/discovery.js +2 -2
- package/dist/src/agents/model-registry/parsers.d.ts +1 -0
- package/dist/src/agents/model-registry/parsers.js +4 -4
- package/dist/src/agents/model-registry/service.js +1 -1
- package/dist/src/agents/native-capabilities.d.ts +10 -0
- package/dist/src/agents/native-capabilities.js +1 -0
- package/dist/src/agents/platform-instructions.js +5 -5
- package/dist/src/agents/runtime-compatibility.d.ts +11 -0
- package/dist/src/agents/runtime-compatibility.js +1 -0
- package/dist/src/agents/workbuddy.d.ts +44 -0
- package/dist/src/agents/workbuddy.js +3 -0
- package/dist/src/commands/daemon.d.ts +1 -0
- package/dist/src/commands/daemon.js +9 -9
- package/dist/src/commands/integration.d.ts +2 -0
- package/dist/src/commands/integration.js +1 -0
- package/dist/src/commands/manager.js +1 -2
- package/dist/src/commands/pair-browser.d.ts +43 -0
- package/dist/src/commands/pair-browser.js +1 -0
- package/dist/src/commands/pair.d.ts +2 -0
- package/dist/src/commands/pair.js +11 -8
- package/dist/src/commands/room.d.ts +13 -0
- package/dist/src/commands/room.js +4 -0
- package/dist/src/commands/upgrade.d.ts +3 -0
- package/dist/src/commands/upgrade.js +1 -1
- package/dist/src/config/index.d.ts +3 -1
- package/dist/src/config/index.js +2 -1
- package/dist/src/daemon-ipc/client.d.ts +8 -0
- package/dist/src/daemon-ipc/client.js +3 -0
- package/dist/src/daemon-ipc/paths.d.ts +7 -0
- package/dist/src/daemon-ipc/paths.js +1 -0
- package/dist/src/daemon-ipc/protocol.d.ts +30 -0
- package/dist/src/daemon-ipc/protocol.js +1 -0
- package/dist/src/daemon-ipc/secret.d.ts +3 -0
- package/dist/src/daemon-ipc/secret.js +3 -0
- package/dist/src/daemon-ipc/server.d.ts +13 -0
- package/dist/src/daemon-ipc/server.js +3 -0
- package/dist/src/index.js +2 -2
- package/dist/src/integrations/claude-room-plugin-lifecycle.d.ts +47 -0
- package/dist/src/integrations/claude-room-plugin-lifecycle.js +1 -0
- package/dist/src/integrations/codex-room-plugin-lifecycle.d.ts +49 -0
- package/dist/src/integrations/codex-room-plugin-lifecycle.js +1 -0
- package/dist/src/integrations/room-plugin-bundles.d.ts +23 -0
- package/dist/src/integrations/room-plugin-bundles.js +1 -0
- package/dist/src/integrations/room-plugin-lifecycle-common.d.ts +17 -0
- package/dist/src/integrations/room-plugin-lifecycle-common.js +1 -0
- package/dist/src/integrations/room-plugin-shared.d.ts +24 -0
- package/dist/src/integrations/room-plugin-shared.js +2 -0
- package/dist/src/integrations/room-session-hook.d.ts +30 -0
- package/dist/src/integrations/room-session-hook.js +2 -0
- package/dist/src/integrations/workbuddy-plugin-bundle.d.ts +15 -0
- package/dist/src/integrations/workbuddy-plugin-bundle.js +1 -0
- package/dist/src/integrations/workbuddy-plugin-lifecycle.d.ts +52 -0
- package/dist/src/integrations/workbuddy-plugin-lifecycle.js +2 -0
- package/dist/src/integrations/workbuddy-session-hook.d.ts +22 -0
- package/dist/src/integrations/workbuddy-session-hook.js +1 -0
- package/dist/src/manager/prompt.d.ts +1 -1
- package/dist/src/manager/prompt.js +1 -1
- package/dist/src/manager/retired-external-channel-compat.d.ts +78 -0
- package/dist/src/manager/retired-external-channel-compat.js +1 -0
- package/dist/src/manager/runtime.d.ts +1 -3
- package/dist/src/manager/runtime.js +7 -7
- package/dist/src/relay/client.d.ts +2 -0
- package/dist/src/relay/client.js +1 -1
- package/dist/src/room/activation-audit.d.ts +15 -0
- package/dist/src/room/activation-audit.js +2 -0
- package/dist/src/room/activation-policy.d.ts +8 -0
- package/dist/src/room/activation-policy.js +1 -0
- package/dist/src/room/activation-service.d.ts +25 -0
- package/dist/src/room/activation-service.js +2 -0
- package/dist/src/room/agent-tool.d.ts +62 -0
- package/dist/src/room/agent-tool.js +1 -0
- package/dist/src/room/attachment-cache.d.ts +40 -0
- package/dist/src/room/attachment-cache.js +2 -0
- package/dist/src/room/attachment-upload.d.ts +20 -0
- package/dist/src/room/attachment-upload.js +1 -0
- package/dist/src/room/authorized-action-coordinator.d.ts +40 -0
- package/dist/src/room/authorized-action-coordinator.js +1 -0
- package/dist/src/room/authorized-action-ipc.d.ts +11 -0
- package/dist/src/room/authorized-action-ipc.js +1 -0
- package/dist/src/room/device-authorization-client.d.ts +49 -0
- package/dist/src/room/device-authorization-client.js +1 -0
- package/dist/src/room/host-session-observation-ipc.d.ts +9 -0
- package/dist/src/room/host-session-observation-ipc.js +1 -0
- package/dist/src/room/host-session-observations.d.ts +54 -0
- package/dist/src/room/host-session-observations.js +2 -0
- package/dist/src/room/invite-bootstrap.d.ts +35 -0
- package/dist/src/room/invite-bootstrap.js +1 -0
- package/dist/src/room/invocation-token-ipc.d.ts +9 -0
- package/dist/src/room/invocation-token-ipc.js +1 -0
- package/dist/src/room/invocation-token.d.ts +53 -0
- package/dist/src/room/invocation-token.js +1 -0
- package/dist/src/room/jsonl-mirror.d.ts +73 -0
- package/dist/src/room/jsonl-mirror.js +6 -0
- package/dist/src/room/managed-room-binding.d.ts +42 -0
- package/dist/src/room/managed-room-binding.js +1 -0
- package/dist/src/room/managed-room-session.d.ts +143 -0
- package/dist/src/room/managed-room-session.js +3 -0
- package/dist/src/room/mirror-sync-service.d.ts +33 -0
- package/dist/src/room/mirror-sync-service.js +1 -0
- package/dist/src/room/operator-ipc.d.ts +11 -0
- package/dist/src/room/operator-ipc.js +1 -0
- package/dist/src/room/pending-authorized-actions.d.ts +69 -0
- package/dist/src/room/pending-authorized-actions.js +3 -0
- package/dist/src/room/room-action-client.d.ts +210 -0
- package/dist/src/room/room-action-client.js +1 -0
- package/dist/src/room/room-action-ipc.d.ts +33 -0
- package/dist/src/room/room-action-ipc.js +1 -0
- package/dist/src/room/room-action-schema.d.ts +3 -0
- package/dist/src/room/room-action-schema.js +1 -0
- package/dist/src/room/room-authorized-action-executor.d.ts +23 -0
- package/dist/src/room/room-authorized-action-executor.js +1 -0
- package/dist/src/room/room-binding-client.d.ts +51 -0
- package/dist/src/room/room-binding-client.js +1 -0
- package/dist/src/room/room-binding-ipc.d.ts +29 -0
- package/dist/src/room/room-binding-ipc.js +1 -0
- package/dist/src/room/session-registry-ipc.d.ts +14 -0
- package/dist/src/room/session-registry-ipc.js +1 -0
- package/dist/src/room/session-registry.d.ts +128 -0
- package/dist/src/room/session-registry.js +2 -0
- package/dist/src/room/tool-schema.d.ts +118 -0
- package/dist/src/room/tool-schema.js +1 -0
- package/dist/src/room/tool-server.d.ts +5 -0
- package/dist/src/room/tool-server.js +3 -0
- package/dist/src/session/handlers/agent-capabilities.d.ts +3 -0
- package/dist/src/session/handlers/agent-capabilities.js +1 -0
- package/dist/src/session/handlers/agent-config.js +1 -1
- package/dist/src/session/handlers/chat.js +2 -2
- package/dist/src/session/handlers/control.js +1 -1
- package/dist/src/session/handlers/fs.d.ts +1 -0
- package/dist/src/session/handlers/fs.js +1 -1
- package/dist/src/session/handlers/room-managed.d.ts +4 -0
- package/dist/src/session/handlers/room-managed.js +1 -0
- package/dist/src/session/manager.d.ts +18 -6
- package/dist/src/session/manager.js +1 -1
- package/dist/src/session/types.d.ts +5 -0
- package/dist/src/upgrade/engine.d.ts +14 -1
- package/dist/src/upgrade/engine.js +2 -2
- package/dist/src/upgrade/scheduler.d.ts +45 -0
- package/dist/src/upgrade/scheduler.js +1 -0
- package/node_modules/@shennian/wire/dist/agent-capabilities.d.ts +17 -0
- package/node_modules/@shennian/wire/dist/agent-capabilities.d.ts.map +1 -0
- package/node_modules/@shennian/wire/dist/agent-capabilities.js +2 -0
- package/node_modules/@shennian/wire/dist/agent-capabilities.js.map +1 -0
- package/node_modules/@shennian/wire/dist/agent-workspace.d.ts +41 -0
- package/node_modules/@shennian/wire/dist/agent-workspace.d.ts.map +1 -0
- package/node_modules/@shennian/wire/dist/agent-workspace.js +3 -0
- package/node_modules/@shennian/wire/dist/agent-workspace.js.map +1 -0
- package/node_modules/@shennian/wire/dist/index.d.ts +3 -1
- package/node_modules/@shennian/wire/dist/index.d.ts.map +1 -1
- package/node_modules/@shennian/wire/dist/index.js +3 -1
- package/node_modules/@shennian/wire/dist/index.js.map +1 -1
- package/node_modules/@shennian/wire/dist/machine.d.ts +1 -0
- package/node_modules/@shennian/wire/dist/machine.d.ts.map +1 -1
- package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
- package/node_modules/@shennian/wire/dist/methods.d.ts.map +1 -1
- package/node_modules/@shennian/wire/dist/room.d.ts +112 -0
- package/node_modules/@shennian/wire/dist/room.d.ts.map +1 -0
- package/node_modules/@shennian/wire/dist/room.js +4 -0
- package/node_modules/@shennian/wire/dist/room.js.map +1 -0
- package/node_modules/@shennian/wire/dist/session.d.ts +15 -2
- package/node_modules/@shennian/wire/dist/session.d.ts.map +1 -1
- package/node_modules/@shennian/wire/dist/session.js +1 -1
- package/node_modules/@shennian/wire/dist/session.js.map +1 -1
- package/package.json +3 -5
- package/dist/scripts/wechat-rpa-confirmation.mjs +0 -5
- package/dist/src/agents/pi-context.d.ts +0 -42
- package/dist/src/agents/pi-context.js +0 -12
- package/dist/src/agents/pi.d.ts +0 -70
- package/dist/src/agents/pi.js +0 -17
- package/dist/src/channels/base.d.ts +0 -144
- package/dist/src/channels/base.js +0 -1
- package/dist/src/channels/registry.d.ts +0 -8
- package/dist/src/channels/registry.js +0 -1
- package/dist/src/channels/reply-split.d.ts +0 -1
- package/dist/src/channels/reply-split.js +0 -10
- package/dist/src/channels/runtime.d.ts +0 -138
- package/dist/src/channels/runtime.js +0 -5
- package/dist/src/channels/secret-registry.d.ts +0 -35
- package/dist/src/channels/secret-registry.js +0 -1
- package/dist/src/channels/websocket.d.ts +0 -55
- package/dist/src/channels/websocket.js +0 -8
- package/dist/src/channels/wechat-channel/anchor.d.ts +0 -10
- package/dist/src/channels/wechat-channel/anchor.js +0 -1
- package/dist/src/channels/wechat-channel/automation-lane.d.ts +0 -35
- package/dist/src/channels/wechat-channel/automation-lane.js +0 -2
- package/dist/src/channels/wechat-channel/client.d.ts +0 -283
- package/dist/src/channels/wechat-channel/client.js +0 -1
- package/dist/src/channels/wechat-channel/cooldown.d.ts +0 -21
- package/dist/src/channels/wechat-channel/cooldown.js +0 -1
- package/dist/src/channels/wechat-channel/core/fixture-compare.d.ts +0 -52
- package/dist/src/channels/wechat-channel/core/fixture-compare.js +0 -1
- package/dist/src/channels/wechat-channel/core/media-action-plan.d.ts +0 -3
- package/dist/src/channels/wechat-channel/core/media-action-plan.js +0 -1
- package/dist/src/channels/wechat-channel/core/schema.d.ts +0 -67
- package/dist/src/channels/wechat-channel/core/schema.js +0 -1
- package/dist/src/channels/wechat-channel/core/trace-comparator.d.ts +0 -28
- package/dist/src/channels/wechat-channel/core/trace-comparator.js +0 -1
- package/dist/src/channels/wechat-channel/fingerprint.d.ts +0 -31
- package/dist/src/channels/wechat-channel/fingerprint.js +0 -1
- package/dist/src/channels/wechat-channel/helper-assets.d.ts +0 -103
- package/dist/src/channels/wechat-channel/helper-assets.js +0 -1
- package/dist/src/channels/wechat-channel/helper-client.d.ts +0 -87
- package/dist/src/channels/wechat-channel/helper-client.js +0 -3
- package/dist/src/channels/wechat-channel/helper-protocol.d.ts +0 -122
- package/dist/src/channels/wechat-channel/helper-protocol.js +0 -1
- package/dist/src/channels/wechat-channel/human-coordination.d.ts +0 -25
- package/dist/src/channels/wechat-channel/human-coordination.js +0 -1
- package/dist/src/channels/wechat-channel/index.d.ts +0 -21
- package/dist/src/channels/wechat-channel/index.js +0 -1
- package/dist/src/channels/wechat-channel/ledger.d.ts +0 -48
- package/dist/src/channels/wechat-channel/ledger.js +0 -2
- package/dist/src/channels/wechat-channel/media-cache-resolver.d.ts +0 -42
- package/dist/src/channels/wechat-channel/media-cache-resolver.js +0 -1
- package/dist/src/channels/wechat-channel/media-resolver.d.ts +0 -186
- package/dist/src/channels/wechat-channel/media-resolver.js +0 -1
- package/dist/src/channels/wechat-channel/message-key.d.ts +0 -19
- package/dist/src/channels/wechat-channel/message-key.js +0 -1
- package/dist/src/channels/wechat-channel/observer.d.ts +0 -171
- package/dist/src/channels/wechat-channel/observer.js +0 -7
- package/dist/src/channels/wechat-channel/outbound-ledger.d.ts +0 -96
- package/dist/src/channels/wechat-channel/outbound-ledger.js +0 -2
- package/dist/src/channels/wechat-channel/outbound-sender.d.ts +0 -74
- package/dist/src/channels/wechat-channel/outbound-sender.js +0 -1
- package/dist/src/channels/wechat-channel/pacing.d.ts +0 -3
- package/dist/src/channels/wechat-channel/pacing.js +0 -1
- package/dist/src/channels/wechat-channel/preflight.d.ts +0 -46
- package/dist/src/channels/wechat-channel/preflight.js +0 -1
- package/dist/src/channels/wechat-channel/runner.d.ts +0 -43
- package/dist/src/channels/wechat-channel/runner.js +0 -1
- package/dist/src/channels/wechat-channel/runtime.d.ts +0 -50
- package/dist/src/channels/wechat-channel/runtime.js +0 -1
- package/dist/src/channels/wechat-channel/scheduler.d.ts +0 -74
- package/dist/src/channels/wechat-channel/scheduler.js +0 -1
- package/dist/src/channels/wechat-channel/vector-store.d.ts +0 -44
- package/dist/src/channels/wechat-channel/vector-store.js +0 -1
- package/dist/src/channels/wechat-rpa/macos-flow.d.ts +0 -55
- package/dist/src/channels/wechat-rpa/macos-flow.js +0 -1
- package/dist/src/channels/wechat-rpa/macos.d.ts +0 -11
- package/dist/src/channels/wechat-rpa/macos.js +0 -21
- package/dist/src/channels/wechat-rpa/normalizer.d.ts +0 -49
- package/dist/src/channels/wechat-rpa/normalizer.js +0 -7
- package/dist/src/channels/wechat-rpa/product-channel.d.ts +0 -76
- package/dist/src/channels/wechat-rpa/product-channel.js +0 -16
- package/dist/src/channels/wechat-rpa-session-sync.d.ts +0 -26
- package/dist/src/channels/wechat-rpa-session-sync.js +0 -1
- package/dist/src/channels/wechat-rpa.d.ts +0 -104
- package/dist/src/channels/wechat-rpa.js +0 -6
- package/dist/src/channels/wecom.d.ts +0 -51
- package/dist/src/channels/wecom.js +0 -4
- package/dist/src/commands/external-attachments.d.ts +0 -9
- package/dist/src/commands/external-attachments.js +0 -1
- package/dist/src/commands/external.d.ts +0 -2
- package/dist/src/commands/external.js +0 -1
- package/dist/src/commands/helper-runtime-official-download.d.ts +0 -80
- package/dist/src/commands/helper-runtime-official-download.js +0 -1
- package/dist/src/commands/runtime.d.ts +0 -120
- package/dist/src/commands/runtime.js +0 -1
- package/dist/src/commands/wechat/command.d.ts +0 -3
- package/dist/src/commands/wechat/command.js +0 -1
- package/dist/src/commands/wechat/direct.d.ts +0 -14
- package/dist/src/commands/wechat/direct.js +0 -2
- package/dist/src/commands/wechat/doctor.d.ts +0 -2
- package/dist/src/commands/wechat/doctor.js +0 -1
- package/dist/src/commands/wechat/ipc.d.ts +0 -9
- package/dist/src/commands/wechat/ipc.js +0 -1
- package/dist/src/commands/wechat/operations.d.ts +0 -3
- package/dist/src/commands/wechat/operations.js +0 -4
- package/dist/src/commands/wechat/output.d.ts +0 -7
- package/dist/src/commands/wechat/output.js +0 -4
- package/dist/src/commands/wechat/types.d.ts +0 -142
- package/dist/src/commands/wechat/types.js +0 -1
- package/dist/src/commands/wechat/utils.d.ts +0 -16
- package/dist/src/commands/wechat/utils.js +0 -1
- package/dist/src/commands/wechat.d.ts +0 -6
- package/dist/src/commands/wechat.js +0 -1
- package/dist/src/devtools/wechat-channel-action-smoke.d.ts +0 -105
- package/dist/src/devtools/wechat-channel-action-smoke.js +0 -10
- package/dist/src/devtools/wechat-channel-download-report.d.ts +0 -111
- package/dist/src/devtools/wechat-channel-download-report.js +0 -2
- package/dist/src/devtools/wechat-channel-markdown-report.d.ts +0 -6
- package/dist/src/devtools/wechat-channel-markdown-report.js +0 -5
- package/dist/src/devtools/wechat-channel-product-steps.d.ts +0 -9
- package/dist/src/devtools/wechat-channel-product-steps.js +0 -40
- package/dist/src/session/handlers/skills.d.ts +0 -7
- package/dist/src/session/handlers/skills.js +0 -1
- package/dist/src/session/handlers/wechat-helper-runtime.d.ts +0 -33
- package/dist/src/session/handlers/wechat-helper-runtime.js +0 -1
- package/dist/src/skills/registry.d.ts +0 -16
- package/dist/src/skills/registry.js +0 -15
- package/dist/src/skills/setup.d.ts +0 -11
- package/dist/src/skills/setup.js +0 -1
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { buildBottomPageReport, buildDownloadVisibleMediaReport } from './wechat-channel-download-report.js';
|
|
2
|
-
import { type WeChatChannelObserveActivityGuardOptions, type WeChatChannelOcrBlock } from '../channels/wechat-channel/observer.js';
|
|
3
|
-
import { type WeChatChannelRuntimePlatform } from '../channels/wechat-channel/runtime.js';
|
|
4
|
-
export type WeChatChannelActionSmokeStep = 'open-read' | 'send-text' | 'send-file' | 'send-image' | 'send-video' | 'structure-window' | 'server-observe' | 'read-bottom-page' | 'download-visible-media' | 'send-and-confirm' | 'human-send-preflight-busy' | 'human-send-preflight-busy-then-idle' | 'human-send-user-active-timeout' | 'human-send-takeover-during-run' | 'human-send-takeover-then-idle' | 'human-send-normal' | 'human-observe-deferred';
|
|
5
|
-
export type WeChatChannelActionSmokeOptions = {
|
|
6
|
-
conversation: string;
|
|
7
|
-
mode: 'open-read' | 'send' | 'observe' | 'all' | 'custom';
|
|
8
|
-
steps: WeChatChannelActionSmokeStep[];
|
|
9
|
-
outDir: string;
|
|
10
|
-
workDir: string;
|
|
11
|
-
traceId: string;
|
|
12
|
-
runtimeId: string;
|
|
13
|
-
machineId: string;
|
|
14
|
-
sessionId?: string;
|
|
15
|
-
serverUrl?: string;
|
|
16
|
-
platform?: WeChatChannelRuntimePlatform;
|
|
17
|
-
text?: string;
|
|
18
|
-
filePath?: string;
|
|
19
|
-
imagePath?: string;
|
|
20
|
-
videoPath?: string;
|
|
21
|
-
downloadAnchorText?: string;
|
|
22
|
-
allowEmptyMedia?: boolean;
|
|
23
|
-
activityGuard?: WeChatChannelObserveActivityGuardOptions;
|
|
24
|
-
skipRuntimeUpsert?: boolean;
|
|
25
|
-
requireServer: boolean;
|
|
26
|
-
};
|
|
27
|
-
export type WeChatChannelActionSmokeResult = {
|
|
28
|
-
ok: boolean;
|
|
29
|
-
conversation: string;
|
|
30
|
-
outDir: string;
|
|
31
|
-
helperTracePath: string;
|
|
32
|
-
traceId: string;
|
|
33
|
-
runtimeId: string;
|
|
34
|
-
machineId: string;
|
|
35
|
-
startedAt: string;
|
|
36
|
-
finishedAt: string;
|
|
37
|
-
durationMs: number;
|
|
38
|
-
steps: Array<{
|
|
39
|
-
step: WeChatChannelActionSmokeStep;
|
|
40
|
-
ok: boolean;
|
|
41
|
-
skipped?: boolean;
|
|
42
|
-
reasonCode?: string;
|
|
43
|
-
errorSummary?: string;
|
|
44
|
-
userAction?: string;
|
|
45
|
-
details?: Record<string, unknown>;
|
|
46
|
-
}>;
|
|
47
|
-
};
|
|
48
|
-
export type WeChatChannelSmokeObservePipeline = 'edge-structure' | 'server-observe';
|
|
49
|
-
export declare function resolveWeChatSmokeObserveSessionMode(input: {
|
|
50
|
-
sessionId?: string;
|
|
51
|
-
observePipeline?: WeChatChannelSmokeObservePipeline;
|
|
52
|
-
}): 'direct-edge-structure' | 'session-bound';
|
|
53
|
-
export { buildBottomPageReport, buildDownloadVisibleMediaReport };
|
|
54
|
-
export declare function parseWeChatChannelActionSmokeArgs(argv: string[]): WeChatChannelActionSmokeOptions;
|
|
55
|
-
export declare function stepsForMode(mode: WeChatChannelActionSmokeOptions['mode']): WeChatChannelActionSmokeStep[];
|
|
56
|
-
export declare function runWeChatChannelActionSmoke(options: WeChatChannelActionSmokeOptions): Promise<WeChatChannelActionSmokeResult>;
|
|
57
|
-
export declare function buildSendStepAcceptance(input: {
|
|
58
|
-
sendAccepted: boolean;
|
|
59
|
-
text?: string | null;
|
|
60
|
-
attachmentPath?: string | null;
|
|
61
|
-
beforeTextCount?: number | null;
|
|
62
|
-
afterTextCount?: number | null;
|
|
63
|
-
skipPostSendVerify?: boolean;
|
|
64
|
-
}): {
|
|
65
|
-
ok: boolean;
|
|
66
|
-
reasonCode?: string;
|
|
67
|
-
sendAccepted: boolean;
|
|
68
|
-
confirmationRequired: boolean;
|
|
69
|
-
};
|
|
70
|
-
export declare function nextSmokeDrainWaitMs(nextAttemptAt: string | undefined, startedAtMs: number, maxWaitMs: number): number;
|
|
71
|
-
export type WeChatChannelSendAndConfirmEvidenceInput = {
|
|
72
|
-
sendResults: Array<{
|
|
73
|
-
ok?: boolean;
|
|
74
|
-
skipped?: boolean;
|
|
75
|
-
reasonCode?: string;
|
|
76
|
-
errorSummary?: string;
|
|
77
|
-
details?: {
|
|
78
|
-
text?: unknown;
|
|
79
|
-
sendStatus?: unknown;
|
|
80
|
-
waitingRecords?: unknown;
|
|
81
|
-
failedRecords?: unknown;
|
|
82
|
-
manualReviewRecords?: unknown;
|
|
83
|
-
};
|
|
84
|
-
}>;
|
|
85
|
-
observedMessages: Array<{
|
|
86
|
-
normalizedText?: string | null;
|
|
87
|
-
anchorText?: string | null;
|
|
88
|
-
textExcerpt?: string | null;
|
|
89
|
-
}>;
|
|
90
|
-
};
|
|
91
|
-
export declare function buildSendAndConfirmEvidence(input: WeChatChannelSendAndConfirmEvidenceInput): {
|
|
92
|
-
ok: boolean;
|
|
93
|
-
reasonCode?: string;
|
|
94
|
-
sentTexts: string[];
|
|
95
|
-
confirmedTexts: string[];
|
|
96
|
-
outboundStatuses: string[];
|
|
97
|
-
skippedFixtureCount: number;
|
|
98
|
-
pendingOutboundCount: number;
|
|
99
|
-
failedOutboundCount: number;
|
|
100
|
-
manualReviewCount: number;
|
|
101
|
-
};
|
|
102
|
-
export declare function countMarkerOccurrencesInOcrBlocks(blocks: Array<{
|
|
103
|
-
text?: string | null;
|
|
104
|
-
}>, marker: string): number;
|
|
105
|
-
export declare function countMarkerOccurrencesInChatContentBlocks(blocks: Array<WeChatChannelOcrBlock>, marker: string): number;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import M from"node:crypto";import{spawnSync as ce}from"node:child_process";import p from"node:fs";import i from"node:path";import{fileURLToPath as le}from"node:url";import{buildBottomPageReport as T,buildDownloadVisibleMediaReport as G}from"./wechat-channel-download-report.js";import{buildWeChatMessagesMarkdown as k}from"./wechat-channel-markdown-report.js";import{loadConfig as ue}from"../config/index.js";import{createWeChatChannelApiClient as C}from"../channels/wechat-channel/client.js";import{resolveWeChatChannelHelperAsset as me,WECHAT_CHANNEL_HELPER_VERSION as he}from"../channels/wechat-channel/helper-assets.js";import{WeChatChannelHelperClient as fe}from"../channels/wechat-channel/helper-client.js";import{requiredWindowsWeChatChannelHelperCapabilitiesForProfile as O}from"../channels/wechat-channel/helper-protocol.js";import{classifyWeChatOutboundEchoes as ge,enqueueWeChatOutboundReply as z}from"../channels/wechat-channel/outbound-ledger.js";import{loadWeChatChannelLedger as we,saveWeChatChannelLedger as be,updateWeChatChannelBindingLedger as pe}from"../channels/wechat-channel/ledger.js";import{waitForWeChatChannelPacing as J}from"../channels/wechat-channel/pacing.js";import{WeChatChannelOutboundSender as Q,sendQueuedWeChatOutboundRecords as I}from"../channels/wechat-channel/outbound-sender.js";import{captureWeChatWindow as j,detectWeChatMessageInputPointByServerVision as ve,ensureWeChatWindowReady as S,focusKnownWeChatWindow as x,observeWeChatChannelBindingViaHelper as ye,openConversationBySearch as D,recognizeWeChatScreenshot as E}from"../channels/wechat-channel/observer.js";import{createWeChatChannelRuntime as Se}from"../channels/wechat-channel/runtime.js";function ke(e){const t=!e.sessionId&&e.observePipeline==="edge-structure";if(!e.sessionId&&!t)throw new Error("session_id_required: pass --session-id <existing Shennian session id> for server observe steps");return t?"direct-edge-structure":"session-bound"}const Ce="ABC",Ie="wechat-channel-action-smoke";function xe(e){const t=e.filter(l=>l!=="--"),n=ft(t),r=wt(t,"--step").map(gt).filter(l=>l!=null),o=ue(),s=b(t,"--trace-id")||`wechat-action-smoke-${Date.now().toString(36)}`,d=i.resolve(b(t,"--out")||b(t,"--output")||i.join(process.cwd(),".dev-runtime","wechat-channel","action-smoke",s)),a=r.length?bt(r):De(n);return{conversation:A(t,"--conversation")||A(t,"--group")||Ce,mode:r.length?"custom":n,steps:a,outDir:d,workDir:i.resolve(b(t,"--work-dir")||process.cwd()),traceId:s,runtimeId:b(t,"--runtime-id")||Ie,machineId:b(t,"--machine-id")||process.env.SHENNIAN_MACHINE_ID||o.machineId||"local",sessionId:b(t,"--session-id")||process.env.SHENNIAN_EXTERNAL_SESSION_ID||process.env.SHENNIAN_MANAGER_SESSION_ID,serverUrl:b(t,"--server-url")||o.serverUrl,platform:ut(b(t,"--platform")),text:A(t,"--text"),filePath:U(b(t,"--file")),imagePath:U(b(t,"--image")),videoPath:U(b(t,"--video")),downloadAnchorText:A(t,"--download-anchor-text")||A(t,"--media-anchor-text"),allowEmptyMedia:t.includes("--allow-empty-media"),requireServer:t.includes("--require-server")}}function De(e){return e==="send"?["open-read","send-text","send-file","send-image","send-video"]:e==="observe"?["structure-window"]:e==="all"?["open-read","send-text","send-file","send-image","send-video","structure-window"]:["open-read"]}async function Ae(e){const t=Date.now(),n=new Date(t).toISOString();p.mkdirSync(e.outDir,{recursive:!0});const r=i.join(e.outDir,"helper-trace.jsonl");p.writeFileSync(r,"");const o=st(e),s=o.bindings[0],d=at(e,r);await d.start();const a={ok:!1,conversation:e.conversation,outDir:e.outDir,helperTracePath:r,traceId:e.traceId,runtimeId:e.runtimeId,machineId:e.machineId,startedAt:n,finishedAt:n,durationMs:0,steps:[]};try{for(const l of e.steps){if(_e(l)&&a.steps.some(c=>c.step==="open-read"&&!c.ok&&!c.skipped)){a.steps.push({step:l,ok:!1,reasonCode:"open_read_required",errorSummary:"open-read failed; refusing to run send step against the current WeChat window"});continue}a.steps.push(await Re({step:l,options:e,runtime:o,binding:s,helper:d}))}}finally{await d.stop().catch(()=>{}),a.finishedAt=new Date().toISOString(),a.durationMs=Date.now()-t,a.ok=a.steps.every(l=>l.ok||l.skipped),m(i.join(e.outDir,"summary.json"),a)}return a}function _e(e){return e==="send-text"||e==="send-file"||e==="send-image"||e==="send-video"||e==="send-and-confirm"}async function Re(e){try{return e.step==="open-read"?await Ee(e):e.step==="structure-window"?await Ve(e):e.step==="server-observe"?await Ke(e):e.step==="read-bottom-page"?await Ue(e):e.step==="download-visible-media"?await qe(e):e.step==="send-and-confirm"?await Le(e):e.step.startsWith("human-")?await Te(e):await X(e)}catch(t){const n=Ct(t),r=await Pe(e,n,t);return{step:e.step,ok:!1,reasonCode:n,errorSummary:t instanceof Error?t.message:String(t),userAction:It(n),...r?{details:r}:{}}}}async function Pe(e,t,n){if(!Me(t))return;const r=i.join(e.options.outDir,`${e.step}-failure-diagnostics.json`),o={step:e.step,reasonCode:t,errorSummary:n instanceof Error?n.message:String(n),capturedAt:new Date().toISOString()};try{o.permissions=await e.helper.request("permissions.check",{},e.options.traceId)}catch(s){o.permissionsError=s instanceof Error?s.message:String(s)}try{o.windows=await e.helper.request("windows.list",{},e.options.traceId)}catch(s){o.windowsError=s instanceof Error?s.message:String(s)}return m(r,o),{failureDiagnosticsPath:r}}function Me(e){return e.startsWith("wechat_")||e.startsWith("permission_")||e.startsWith("user_active")}async function Te(e){if(e.step==="human-observe-deferred")return await je(e);const t=e.step,n=`human-${P(`${e.options.traceId}:${t}:${Date.now()}`)}`,r={version:1,runtimeId:e.runtime.runtimeId,records:[]},o=z({ledger:r,replyId:`human:${t}:${n}`,idempotencyKey:`human:${n}`,bindingId:e.binding.bindingId,runtimeId:e.runtime.runtimeId,sessionId:e.binding.sessionId,conversationName:e.binding.conversationDisplayName,replyBaseRevision:0,text:`${n} ${e.options.text||"Shennian WeChat human coordination smoke"}`}),s=ee(e.helper,te(t)),d=s.actionLog,a=C({serverUrl:e.options.serverUrl}),l=async y=>{d.push(`openConversation:${y}`);const N=await S(s,e.options.traceId),de=await x(s,N,e.options.traceId);return D({helper:s,window:de,settleToBottom:!1,binding:{...e.binding,conversationDisplayName:y},runtime:e.runtime,api:a,workDir:e.options.workDir,traceId:e.options.traceId})},c=new Q({helper:s,platform:e.runtime.policy.platform,openConversation:l,traceId:e.options.traceId,activityGatePolicy:e.step==="human-send-user-active-timeout"?{keyDownThresholdMs:3e4,mouseMovedThresholdMs:3e4,mouseClickThresholdMs:3e4,scrollWheelThresholdMs:3e4}:void 0});let h=await I({ledger:r,bindingId:e.binding.bindingId,currentLastInboundRevision:0,sender:c,now:new Date("2026-06-15T00:00:00.000Z"),maxUserActivityWaitMs:e.step==="human-send-user-active-timeout"?1e3:void 0});e.step==="human-send-user-active-timeout"&&(h=await I({ledger:r,bindingId:e.binding.bindingId,currentLastInboundRevision:0,sender:c,now:new Date("2026-06-15T00:00:02.000Z"),maxUserActivityWaitMs:1e3})),(e.step==="human-send-preflight-busy-then-idle"||e.step==="human-send-takeover-then-idle")&&(s.setScenario(Qe()),h=await I({ledger:r,bindingId:e.binding.bindingId,currentLastInboundRevision:0,sender:c,now:new Date("2026-06-15T00:00:06.000Z")}));const g=Xe(e.step,o)?await H({helper:s,runtime:e.runtime,binding:e.binding,api:a,workDir:e.options.workDir,marker:n,traceId:e.options.traceId,outDir:e.options.outDir,filePrefix:e.step}):0,u=g>0?ge({ledger:r,bindingId:e.binding.bindingId,messages:[{stableMessageKey:`human-echo:${n}`,senderRole:"self",kind:"text",anchorText:o.text,normalizedText:o.text,textExcerpt:o.text,observedAt:new Date().toISOString()}]}):{confirmedRecords:[],manualReviewRecords:[],remainingMessages:[]},w=r.records[0],B=rt(w,h,u.confirmedRecords),v={case:e.step,marker:n,runStatus:B,reasonCode:w.deferReason||w.failureCode||null,outboundStatus:w.sendStatus,attemptCount:w.attemptCount??0,nextAttemptAt:w.nextAttemptAt??null,observedMarkerCount:g,actionLog:d,clipboardRestore:d.includes("clipboard.restore")?"attempted":"not_needed",commitStage:w.commitStage??null};return m(i.join(e.options.outDir,`${e.step}-summary.json`),v),{step:e.step,ok:ot(e.step,v),reasonCode:v.reasonCode||void 0,details:v}}async function je(e){const t=ee(e.helper,te("human-observe-deferred")),n=await t.request("activity.snapshot",{},e.options.traceId),r=!!(n.ok&&n.result&&typeof n.result=="object"&&Number(n.result.keyDownSecondsAgo)<5),o={case:e.step,marker:null,runStatus:r?"observe_deferred_user_active":"baseline_or_no_change",reasonCode:r?"recent_keyboard_activity":null,outboundStatus:null,attemptCount:0,nextAttemptAt:null,observedMarkerCount:0,actionLog:t.actionLog,clipboardRestore:"not_needed"};return m(i.join(e.options.outDir,`${e.step}-summary.json`),o),{step:e.step,ok:r&&!t.actionLog.some(s=>s.startsWith("windows.")||s.startsWith("wechat.")||s.startsWith("clipboard.")),reasonCode:o.reasonCode||void 0,details:o}}async function Ee(e){const t=await S(e.helper,e.options.traceId),n=await x(e.helper,t,e.options.traceId),r=C({serverUrl:e.options.serverUrl}),o=await D({helper:e.helper,window:n,binding:e.binding,runtime:e.runtime,api:r,workDir:e.options.workDir,traceId:e.options.traceId});if(!o.opened)throw await We({helper:e.helper,window:n,outDir:e.options.outDir,traceId:e.options.traceId,reason:o.reason||"conversation_not_opened"}),new Error(o.reason||"conversation_not_opened");const s=await j(e.helper,n.windowId,e.options.traceId),d=_(e.options.outDir,"open-read-full-window",s),a=await E(e.helper,s,e.options.traceId);return m(i.join(e.options.outDir,"open-read-ocr.json"),a),{step:"open-read",ok:!0,details:{openedReason:o.reason,windowId:n.windowId,screenshotPath:d,screenshot:{width:s.width,height:s.height,mimeType:s.mimeType},ocrBlockCount:a.blocks?.length??0,visibleConversationFingerprintCount:a.visibleConversationFingerprints?.length??0}}}async function We(e){try{const t=await j(e.helper,e.window.windowId,e.traceId,e.window.bounds),n=_(e.outDir,"open-read-failure-window",t),r=await E(e.helper,t,e.traceId);m(i.join(e.outDir,"open-read-failure-ocr.json"),r),m(i.join(e.outDir,"open-read-failure-summary.json"),{reason:e.reason,windowId:e.window.windowId,screenshotPath:n,screenshot:{width:t.width,height:t.height,mimeType:t.mimeType},ocrBlockCount:r.blocks?.length??0,visibleConversationFingerprintCount:r.visibleConversationFingerprints?.length??0,topTexts:(r.blocks??[]).slice(0,30).map(o=>({text:o.text,bbox:o.bbox}))})}catch(t){m(i.join(e.outDir,"open-read-failure-summary.json"),{reason:e.reason,captureError:t instanceof Error?t.message:String(t)})}}async function X(e){return await $e(e,mt(e.step,e.options))}async function $e(e,t){if(t.skipped)return{step:e.step,ok:!0,skipped:!0,reasonCode:t.reasonCode};const n=C({serverUrl:e.options.serverUrl}),r={version:1,runtimeId:e.runtime.runtimeId,records:[]},o=`${e.options.traceId}:${e.step}:${t.text}:${t.attachmentPath||""}`,s=t.text?await H({helper:e.helper,runtime:e.runtime,binding:e.binding,api:n,workDir:e.options.workDir,marker:t.text,traceId:e.options.traceId,outDir:e.options.outDir,filePrefix:`${e.step}-before-send`,settleToBottom:!1}).catch(()=>null):null;z({ledger:r,replyId:`action-smoke:${e.step}:${P(o)}`,idempotencyKey:`action-smoke:${P(o)}`,bindingId:e.binding.bindingId,runtimeId:e.runtime.runtimeId,sessionId:e.binding.sessionId,conversationName:e.binding.conversationDisplayName,replyBaseRevision:0,text:t.text,attachmentLocalRefs:t.attachmentPath?[t.attachmentPath]:[]});const d=new Q({helper:e.helper,platform:e.runtime.policy.platform,traceId:e.options.traceId,activityGatePolicy:e.runtime.foregroundPolicy==="work"?{mouseMovedThresholdMs:0,mouseClickThresholdMs:0,scrollWheelThresholdMs:0,keyDownThresholdMs:0}:void 0,takeoverCheck:e.runtime.foregroundPolicy!=="work",onAfterPaste:async({kind:w})=>{await Ze({helper:e.helper,traceId:e.options.traceId,outDir:e.options.outDir,filePrefix:`${e.step}-after-paste-${w}`})},openConversation:async w=>{const B=await S(e.helper,e.options.traceId),v=await x(e.helper,B,e.options.traceId),y=await D({helper:e.helper,window:v,settleToBottom:!1,binding:{...e.binding,conversationDisplayName:w},runtime:e.runtime,api:n,workDir:e.options.workDir,traceId:e.options.traceId});if(!y.opened)return{...y,inputPoint:null};const N=await ve({runtime:e.runtime,binding:{...e.binding,conversationDisplayName:w},helper:e.helper,api:n,workDir:e.options.workDir,traceId:e.options.traceId,window:v});return{...y,inputPoint:N}}}),a=await Ne({ledger:r,bindingId:e.binding.bindingId,sender:d});await J("send-after-submit",`${e.options.traceId}:${e.step}:after-submit`);const l=r.records[0],c=a.failedRecords[0]?.failureCode||a.manualReviewRecords[0]?.failureCode||a.waitingRecords[0]?.deferReason||a.staleRecords[0]?.failureCode,f=a.sentRecords.length===1&&a.failedRecords.length===0&&a.waitingRecords.length===0&&a.manualReviewRecords.length===0&&a.staleRecords.length===0,h=e.step==="send-text",g=f&&t.text&&!h?await nt({helper:e.helper,runtime:e.runtime,binding:e.binding,api:n,workDir:e.options.workDir,marker:t.text,traceId:e.options.traceId,outDir:e.options.outDir,filePrefix:`${e.step}-after-send`,settleToBottom:!1,attempts:3,targetGreaterThan:s}):null,u=Be({sendAccepted:f,text:t.text,attachmentPath:t.attachmentPath,beforeTextCount:s,afterTextCount:g,skipPostSendVerify:h});return{step:e.step,ok:u.ok,reasonCode:c||u.reasonCode,errorSummary:a.failedRecords[0]?.lastErrorSummary||a.manualReviewRecords[0]?.lastErrorSummary,details:{text:t.text,attachmentPath:t.attachmentPath??null,helperTracePath:i.join(e.options.outDir,"helper-trace.jsonl"),confirmationRequired:u.confirmationRequired,sendAccepted:u.sendAccepted,beforeTextCount:s,afterTextCount:g,sentRecords:a.sentRecords.length,failedRecords:a.failedRecords.length,waitingRecords:a.waitingRecords.length,manualReviewRecords:a.manualReviewRecords.length,staleRecords:a.staleRecords.length,sendStatus:l?.sendStatus,failureCode:l?.failureCode??null,lastErrorSummary:l?.lastErrorSummary??null,deferReason:l?.deferReason,commitStage:l?.commitStage??null,attemptCount:l?.attemptCount??0,nextAttemptAt:l?.nextAttemptAt??null}}}function Be(e){const t=!!(e.text&&e.text.trim()&&!e.attachmentPath);if(!e.sendAccepted)return{ok:!1,reasonCode:void 0,sendAccepted:!1,confirmationRequired:t};if(e.skipPostSendVerify||!t)return{ok:!0,sendAccepted:!0,confirmationRequired:e.skipPostSendVerify?!1:t};const n=typeof e.beforeTextCount=="number"&&Number.isFinite(e.beforeTextCount)?e.beforeTextCount:null,r=typeof e.afterTextCount=="number"&&Number.isFinite(e.afterTextCount)?e.afterTextCount:0,o=n==null?r>0:r>n;return{ok:o,reasonCode:o?void 0:"sent_text_not_observed",sendAccepted:!0,confirmationRequired:t}}async function Ne(e){const t=e.maxAttempts??24,n=e.maxWaitMs??9e4,r=Date.now();let o=await I({ledger:e.ledger,bindingId:e.bindingId,currentLastInboundRevision:0,sender:e.sender,maxUserActivityWaitMs:n});for(let s=2;o.waitingRecords.length>0&&s<=t&&!(Date.now()-r>=n);s+=1){const d=Oe(o.waitingRecords[0]?.nextAttemptAt,r,n);await V(d),o=await I({ledger:e.ledger,bindingId:e.bindingId,currentLastInboundRevision:0,sender:e.sender,maxUserActivityWaitMs:n})}return o}function Oe(e,t,n){const r=Math.max(0,n-(Date.now()-t));if(r<=0)return 0;const o=e?new Date(e).getTime():Number.NaN,s=Number.isFinite(o)?o-Date.now():1e3;return Math.max(500,Math.min(Math.max(500,s),Math.min(5e3,r)))}function Fe(e){const t=e.sendResults.filter(u=>!Z(u)),n=e.sendResults.filter(u=>!u.skipped).map(u=>u.details?.text&&typeof u.details.text=="string"?u.details.text:"").filter(Boolean),r=e.observedMessages.map(u=>[u.normalizedText||"",u.anchorText||"",u.textExcerpt||""].join(`
|
|
2
|
-
`)).join(`
|
|
3
|
-
`),o=n.filter(u=>r.includes(u)),s=e.sendResults.map(u=>typeof u.details?.sendStatus=="string"?u.details.sendStatus:"").filter(Boolean),d=e.sendResults.filter(Z).length,a=F(t,"waitingRecords"),l=F(t,"failedRecords"),c=F(t,"manualReviewRecords"),f=t.find(u=>!u.ok||u.skipped),h=s.length===n.length&&s.every(u=>u==="sent_unconfirmed"||u==="confirmed_echo"),g=!f&&n.length>0&&o.length>0&&h&&a===0&&l===0&&c===0;return{ok:g,reasonCode:g?void 0:f?.reasonCode||(a>0?"outbound_send_waiting":void 0)||(l>0?"outbound_send_failed":void 0)||(c>0?"outbound_manual_review":void 0)||(h?void 0:"outbound_status_not_accepted")||(o.length?"partial_sent_messages_observed":"sent_messages_not_observed"),sentTexts:n,confirmedTexts:o,outboundStatuses:s,skippedFixtureCount:d,pendingOutboundCount:a,failedOutboundCount:l,manualReviewCount:c}}function Z(e){return e.skipped===!0&&e.reasonCode==="ffmpeg_unavailable_for_video_fixture"}function F(e,t){return e.reduce((n,r)=>{const o=r.details?.[t];return n+(typeof o=="number"&&Number.isFinite(o)?o:0)},0)}async function Le(e){const t=["send-text"],n=[];for(const c of t)n.push(await X({...e,step:c}));await V(1200);const r=await W(e,3,{observePipeline:"edge-structure"}),o=T(r.messages),s=i.join(e.options.outDir,"bottom-page.md"),d=k(r.messages,{conversation:e.options.conversation,attachmentsDirName:i.basename(r.attachmentsDir)});m(i.join(e.options.outDir,"bottom-page-summary.json"),o),m(i.join(e.options.outDir,"server-observe-messages.json"),r.messages),R(s,d);const a=Fe({sendResults:n,observedMessages:r.messages}),l=a.ok&&r.messages.length>0;return{step:"send-and-confirm",ok:l,reasonCode:l?void 0:a.reasonCode,errorSummary:n.find(c=>!c.ok||c.skipped)?.errorSummary,details:{sent:n.map(c=>({step:c.step,ok:c.ok,skipped:c.skipped,reasonCode:c.reasonCode,errorSummary:c.errorSummary,text:c.details?.text,attachmentPath:c.details?.attachmentPath,sendStatus:c.details?.sendStatus,deferReason:c.details?.deferReason,failureCode:c.details?.failureCode,commitStage:c.details?.commitStage,attemptCount:c.details?.attemptCount,nextAttemptAt:c.details?.nextAttemptAt,waitingRecords:c.details?.waitingRecords,failedRecords:c.details?.failedRecords,manualReviewRecords:c.details?.manualReviewRecords})),sentTexts:a.sentTexts,confirmedTexts:a.confirmedTexts,outboundStatuses:a.outboundStatuses,skippedFixtureCount:a.skippedFixtureCount,pendingOutboundCount:a.pendingOutboundCount,failedOutboundCount:a.failedOutboundCount,manualReviewCount:a.manualReviewCount,observedCount:r.messages.length,byKind:o.byKind,attachmentSummary:o.attachmentSummary,attachmentsDir:r.attachmentsDir,reportPath:i.join(e.options.outDir,"bottom-page-summary.json"),markdownPath:s,markdown:d}}}async function W(e,t,n={}){let r;const o=[];for(let s=1;s<=t;s+=1)try{const d=await Y(e,n);return o.length&&(o.push({phase:"observe",attempt:s,ok:!0,observedCount:d.messages.length,at:new Date().toISOString()}),m(i.join(e.options.outDir,"observe-retry-events.json"),o)),d}catch(d){if(r=d,o.push({phase:"observe",attempt:s,ok:!1,errorSummary:d instanceof Error?d.message:String(d||""),at:new Date().toISOString()}),s>=t||!He(d))break;try{const a=await S(e.helper,e.options.traceId),l=await x(e.helper,a,e.options.traceId),c=await D({helper:e.helper,window:l,binding:e.binding,runtime:e.runtime,api:C({serverUrl:e.options.serverUrl}),workDir:e.options.workDir,traceId:e.options.traceId});o.push({phase:"recover",attempt:s,ok:c.opened,reason:c.reason,windowId:l.windowId,at:new Date().toISOString()})}catch(a){o.push({phase:"recover",attempt:s,ok:!1,errorSummary:a instanceof Error?a.message:String(a||""),at:new Date().toISOString()})}m(i.join(e.options.outDir,"observe-retry-events.json"),o),await J("observe-retry",`${e.options.traceId}:observe-retry:${s}`,1500*s)}throw o.length&&m(i.join(e.options.outDir,"observe-retry-events.json"),o),r}function He(e){const t=e instanceof Error?e.message:String(e||"");return/conversation_not_visible|wechat_window_unavailable|wechat_window_not_found|title_not_confirmed|server_observe_failed|timeout/i.test(t)}async function Ue(e){const t=await W(e,3),n=T(t.messages),r=i.join(e.options.outDir,"bottom-page.md"),o=k(t.messages,{conversation:e.options.conversation,attachmentsDirName:i.basename(t.attachmentsDir)});return m(i.join(e.options.outDir,"bottom-page-summary.json"),n),m(i.join(e.options.outDir,"server-observe-messages.json"),t.messages),R(r,o),{step:"read-bottom-page",ok:n.messageCount>0,reasonCode:n.messageCount>0?void 0:"no_observed_messages",details:{messageCount:n.messageCount,byKind:n.byKind,attachmentSummary:n.attachmentSummary,attachmentsDir:t.attachmentsDir,reportPath:i.join(e.options.outDir,"bottom-page-summary.json"),markdownPath:r,markdown:o}}}async function qe(e){const t=await W(e,3,{observePipeline:"edge-structure",persistLocalLedger:!0});L(e.options.outDir,"download-visible",t.observationEvidence);const n=T(t.messages),r=i.join(e.options.outDir,"download-visible.md"),o=k(t.messages,{conversation:e.options.conversation,attachmentsDirName:i.basename(t.attachmentsDir)}),s=G(t.messages,t.attachmentsDir,{observePipeline:t.observePipeline,downloadAnchorText:e.options.downloadAnchorText,ledgerPath:t.ledgerPath,ledgerBinding:t.ledgerBinding,traceHashes:t.traceHashes});m(i.join(e.options.outDir,"bottom-page-summary.json"),n),m(i.join(e.options.outDir,"download-visible-summary.json"),s),m(i.join(e.options.outDir,"download-visible-messages.json"),t.messages),R(r,o);const d=!!(e.options.allowEmptyMedia&&s.reasonCode==="no_visible_media_candidates"&&t.messages.length>0),a=s.ok||d;return{step:"download-visible-media",ok:a,reasonCode:a?void 0:s.reasonCode,details:{mediaCandidateCount:s.mediaCandidateCount,localAttachmentCount:s.localAttachmentCount,originalLocalAttachmentCount:s.originalLocalAttachmentCount,previewAttachmentCount:s.previewAttachmentCount,missingLocalPathCount:s.missingLocalPathCount,pendingAttachmentCount:s.pendingAttachmentCount,byKind:s.byKind,byAvailability:s.byAvailability,reasonCodes:s.reasonCodes,mediaReasonCode:s.reasonCode,allowEmptyMediaRead:d,attachmentsDir:t.attachmentsDir,reportPath:i.join(e.options.outDir,"download-visible-summary.json"),markdownPath:r,markdown:o,phases:s.phases,observePipeline:s.observePipeline,ledgerPath:s.ledgerPath,ledgerRevision:s.ledger?.revision,traceHashes:s.traceHashes,traceEvents:s.traceEvents}}}async function Ke(e){const t=await W(e,3,{observePipeline:"server-observe"});L(e.options.outDir,"server-observe",t.observationEvidence),m(i.join(e.options.outDir,"server-observe-messages.json"),t.messages);const n=i.join(e.options.outDir,"server-observe.md"),r=k(t.messages,{conversation:e.options.conversation,attachmentsDirName:i.basename(t.attachmentsDir)});R(n,r);const o=oe(t.messages);return{step:"server-observe",ok:t.messages.length>0,reasonCode:t.messages.length>0?void 0:"no_observed_messages",details:{observedCount:t.messages.length,byKind:q(t.messages.map(s=>s.kind||"unknown")),attachmentSummary:o,attachmentsDir:t.attachmentsDir,markdownPath:n,markdown:r}}}async function Ve(e){const t=await Y(e,{observePipeline:"edge-structure",downloadMedia:!1});L(e.options.outDir,"structure-window",t.observationEvidence),m(i.join(e.options.outDir,"structure-window-messages.json"),t.messages);const n=i.join(e.options.outDir,"structure-window.md"),r=k(t.messages,{conversation:e.options.conversation,attachmentsDirName:i.basename(t.attachmentsDir)});R(n,r);const o=oe(t.messages);return{step:"structure-window",ok:t.messages.length>0,reasonCode:t.messages.length>0?void 0:"no_observed_messages",details:{observedCount:t.messages.length,byKind:q(t.messages.map(s=>s.kind||"unknown")),attachmentSummary:o,attachmentsDir:t.attachmentsDir,markdownPath:n,markdown:r}}}async function Y(e,t={}){const n=ke({sessionId:e.options.sessionId,observePipeline:t.observePipeline}),r=C({serverUrl:e.options.serverUrl});e.options.skipRuntimeUpsert||(n==="direct-edge-structure"?await r.upsertRuntime(e.runtime):await r.upsertRuntime(e.runtime,{...e.binding,enabled:!1,allowReply:!1}));const o=i.join(e.options.outDir,"inbound-attachments");p.mkdirSync(o,{recursive:!0});const s=t.persistLocalLedger?pt(e.options):void 0,d=s?we(s,e.runtime.runtimeId):void 0;let a,l,c;const f=await ye({runtime:e.runtime,binding:{...e.binding,downloadMedia:t.downloadMedia??e.binding.downloadMedia},helper:e.helper,api:r,workDir:e.options.workDir,attachmentsDir:o,traceId:e.options.traceId,mediaAnchorText:e.options.downloadAnchorText,activityGuard:e.options.activityGuard,observePipeline:t.observePipeline,localLedgerTailAnchors:d?vt(d.bindings[e.binding.bindingId]):void 0,onObservationEvidence:({capture:u,ocr:w})=>{a=ze(u),l=Je(w),c=Ge(u,w,{captureHash:a,ocrHash:l})}});let h,g;if(d&&s){const u=pe({ledger:d,bindingId:e.binding.bindingId,observedMessages:f});h=u.binding,g=ie({bindingId:e.binding.bindingId,revision:h.revision,messages:u.newMessages}),be(s,d)}return{messages:f,attachmentsDir:o,observePipeline:t.observePipeline,...s?{ledgerPath:s}:{},...h?{ledgerBinding:h}:{},traceHashes:{...a?{captureHash:a}:{},...l?{ocrHash:l}:{},...g?{ingestPayloadHash:g}:{}},...c?{observationEvidence:c}:{}}}function Ge(e,t,n){return{capture:e,report:{screenshot:{width:e.width,height:e.height,mimeType:e.mimeType,...e.windowId?{windowId:e.windowId}:{}},hashes:n,ocrBlockCount:t.blocks?.length??0,visibleConversationFingerprintCount:t.visibleConversationFingerprints?.length??0,topTexts:(t.blocks??[]).slice(0,40).map(r=>({text:r.text,...r.bbox?{bbox:r.bbox}:{},...typeof r.confidence=="number"?{confidence:r.confidence}:{}}))}}}function L(e,t,n){if(!n)return;const r=n.capture.dataBase64?_(e,`${t}-observation-window`,n.capture):void 0;m(i.join(e,`${t}-observation-evidence.json`),{...n.report,...r?{screenshotPath:r}:{}})}function ze(e){if(e.dataBase64)return`sha256:${M.createHash("sha256").update(Buffer.from(e.dataBase64,"base64")).digest("hex")}`}function Je(e){return ie({blocks:(e.blocks??[]).map(t=>({text:t.text??"",bbox:t.bbox??null,confidence:typeof t.confidence=="number"?Number(t.confidence.toFixed(4)):null})),visibleConversationFingerprints:e.visibleConversationFingerprints??[]})}function ee(e,t){let n=t,r=0,o=0,s="";const d=[];return{actionLog:d,setScenario(l){n=l,r=0,o=0},async request(l,c,f){if(d.push(l),l==="activity.snapshot"){if(r+=1,r<=n.preflightBusySnapshots)return{id:`human-${r}`,ok:!0,result:{keyDownSecondsAgo:.2,mouseMovedSecondsAgo:.2,scrollWheelSecondsAgo:.2,privacy:{capturesKeyContent:!1,capturesMousePath:!1}},latencyMs:0,traceId:f};if(n.forceIdleAfterBusy)return{id:`human-${r}`,ok:!0,result:{keyDownSecondsAgo:60,mouseMovedSecondsAgo:60,leftMouseDownSecondsAgo:60,rightMouseDownSecondsAgo:60,scrollWheelSecondsAgo:60,privacy:{capturesKeyContent:!1,capturesMousePath:!1}},latencyMs:0,traceId:f}}if(l==="automation.lease.acquire"){const h=await e.request(l,c,f),g=h.result&&typeof h.result=="object"?h.result:{};return s=typeof g.leaseId=="string"?g.leaseId:"",h}return l==="automation.lease.status"?(o+=1,n.simulateInterruptionAtLeaseStatus===o?(d.push("automation.lease.simulateInterruption"),{id:`human-lease-${o}`,ok:!0,result:{active:!0,leaseId:s,interrupted:!0,interruptReason:n.interruptionReason||"recent_mouse_activity"},latencyMs:0,traceId:f}):{id:`human-lease-${o}`,ok:!0,result:{active:!0,leaseId:s,interrupted:!1},latencyMs:0,traceId:f}):e.request(l,c,f)}}}function te(e){return e==="human-send-preflight-busy"||e==="human-send-preflight-busy-then-idle"||e==="human-send-user-active-timeout"||e==="human-observe-deferred"?{preflightBusySnapshots:100}:e==="human-send-takeover-during-run"||e==="human-send-takeover-then-idle"?{preflightBusySnapshots:0,forceIdleAfterBusy:!0,simulateInterruptionAtLeaseStatus:2,interruptionReason:"recent_mouse_activity"}:{preflightBusySnapshots:0,forceIdleAfterBusy:!0}}function Qe(){return{preflightBusySnapshots:0,forceIdleAfterBusy:!0}}function Xe(e,t){return t.sendStatus!=="sent_unconfirmed"?!1:e==="human-send-normal"||e==="human-send-preflight-busy-then-idle"||e==="human-send-takeover-then-idle"}async function Ze(e){try{const t=await S(e.helper,e.traceId),n=await j(e.helper,t.windowId,e.traceId,t.bounds),r=_(e.outDir,e.filePrefix,n),o=await E(e.helper,n,e.traceId);m(i.join(e.outDir,`${e.filePrefix}-ocr.json`),{screenshotPath:r,ocr:o})}catch(t){m(i.join(e.outDir,`${e.filePrefix}-error.json`),{errorSummary:t instanceof Error?t.message:String(t||"after paste evidence failed")})}}async function H(e){const t=await S(e.helper,e.traceId),n=await x(e.helper,t,e.traceId);if(!(await D({helper:e.helper,window:n,binding:e.binding,runtime:e.runtime,api:e.api,workDir:e.workDir,traceId:e.traceId,settleToBottom:e.settleToBottom})).opened)return 0;const o=await j(e.helper,n.windowId,e.traceId),s=_(e.outDir,`${e.filePrefix}-observe-marker`,o),d=await E(e.helper,o,e.traceId);return m(i.join(e.outDir,`${e.filePrefix}-observe-marker-ocr.json`),{screenshotPath:s,marker:e.marker,ocr:d}),et(d.blocks||[],e.marker)}function Ye(e,t){const n=t.trim();if(!n)return 0;const r=e.map(d=>d.text||"").join(`
|
|
4
|
-
`),o=re(r,n);if(o>0)return o;const s=ne(n);return s.length<8?0:re(ne(r),s)}function et(e,t){const n=e.filter(tt);return Ye(n,t)}function tt(e){const t=e.bbox;if(!t)return!0;const n=Number(t.x),r=Number(t.y),o=Number(t.width);return[n,r,o].every(Number.isFinite)?n+o/2>=560&&r>=100:!0}function ne(e){return e.normalize("NFKC").replace(/[\s\u200B-\u200D\uFEFF]+/g,"")}function re(e,t){if(!t)return 0;let n=0,r=0;for(;;){const o=e.indexOf(t,r);if(o<0)break;n+=1,r=o+t.length}return n}async function nt(e){const t=Math.max(1,e.attempts??3),n=typeof e.targetGreaterThan=="number"&&Number.isFinite(e.targetGreaterThan)?e.targetGreaterThan:null;let r=0;for(let o=0;o<t;o+=1){if(r=await H({helper:e.helper,runtime:e.runtime,binding:e.binding,api:e.api,workDir:e.workDir,marker:e.marker,traceId:e.traceId,outDir:e.outDir,filePrefix:`${e.filePrefix}-${o+1}`,settleToBottom:e.settleToBottom}),n==null?r>0:r>n)return r;o<t-1&&await V(800)}return r}function rt(e,t,n){return n.length>0||e.sendStatus==="confirmed_echo"?"confirmed_echo":t.waitingRecords.length>0?"send_waiting_user_idle":t.failedRecords.length>0?e.failureCode==="user_active_timeout"?"failed:user_active_timeout":"outbound_send_failed":t.manualReviewRecords.length>0||e.sendStatus==="manual_review"?"manual_review":e.sendStatus==="sent_unconfirmed"?"sent_unconfirmed":e.sendStatus}function ot(e,t){return e==="human-send-preflight-busy"?t.outboundStatus==="queued"&&t.observedMarkerCount===0&&!t.actionLog.includes("clipboard.setText")&&!t.actionLog.includes("keyboard.shortcut"):e==="human-send-user-active-timeout"?t.outboundStatus==="failed"&&t.runStatus==="failed:user_active_timeout"&&t.observedMarkerCount===0&&!t.actionLog.includes("clipboard.setText")&&!t.actionLog.includes("keyboard.shortcut"):e==="human-send-takeover-during-run"?(t.outboundStatus==="queued"||t.outboundStatus==="manual_review")&&t.observedMarkerCount===0:e==="human-send-preflight-busy-then-idle"||e==="human-send-takeover-then-idle"||e==="human-send-normal"?t.outboundStatus==="confirmed_echo"||t.outboundStatus==="sent_unconfirmed"&&t.observedMarkerCount===1:t.runStatus==="observe_deferred_user_active"}function st(e){return Se({runtimeId:e.runtimeId,machineId:e.machineId,pollIntervalMs:6e4,platform:e.platform,foregroundPolicy:"work",bindings:[{bindingId:`action-smoke:${P(e.conversation)}`,sessionId:e.sessionId||`action-smoke:${P(e.runtimeId)}`,conversationDisplayName:e.conversation,enabled:!0,allowReply:!0,downloadMedia:!0}]})}function at(e,t){const n=me({platform:e.platform});if(!n.ok)throw new Error(`${n.reasonCode}: ${n.message}`);return new fe({helperPath:n.helperPath,expectedHelperVersion:n.version||he,requiredCapabilities:lt(e),guardUnsafeWindowsCommands:(e.platform??process.platform)==="win32",skipUserActivityGuard:!0,cleanupWindowsOverlays:(e.platform??process.platform)==="win32",requestLogger:it(t)})}function it(e){return t=>{p.appendFileSync(e,`${JSON.stringify(dt(t))}
|
|
5
|
-
`)}}function dt(e){const t={phase:e.phase,at:e.at,id:e.id,command:e.command};return e.traceId&&(t.traceId=e.traceId),e.timeoutMs!=null&&(t.timeoutMs=e.timeoutMs),e.durationMs!=null&&(t.durationMs=e.durationMs),e.params!==void 0&&(t.params=$(e.params)),e.ok!==void 0&&(t.ok=e.ok),e.errorCode&&(t.errorCode=e.errorCode),e.errorSummary&&(t.errorSummary=e.errorSummary),e.latencyMs!=null&&(t.latencyMs=e.latencyMs),e.result!==void 0&&(t.result=$(e.result)),t}function $(e,t="",n=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string")return ct(t,e)?{type:"string",length:e.length,sha256:M.createHash("sha256").update(e).digest("hex").slice(0,16),preview:e.slice(0,120)}:e;if(Array.isArray(e)){const s=e.slice(0,10).map(d=>$(d,t,n+1));return e.length>s.length?{type:"array",length:e.length,items:s}:s}if(typeof e!="object")return String(e);if(n>=5)return{type:"object",truncated:!0};const r=e,o={};for(const[s,d]of Object.entries(r))o[s]=$(d,s,n+1);return o}function ct(e,t){return t.length>240?!0:/(base64|bytes|data|image|screenshot|png|jpeg|jpg|buffer)/i.test(e)&&t.length>48}function lt(e){if((e.platform??process.platform)==="win32")return e.steps.some(t=>t.startsWith("send")||t.startsWith("human-send"))?O("send"):e.steps.some(t=>t==="download-visible-media")?O("download"):O("observe")}function ut(e){const t=String(e||"").trim().toLowerCase();if(t){if(t==="windows"||t==="win32")return"win32";if(t==="macos"||t==="darwin")return"darwin";throw new Error(`unsupported_wechat_smoke_platform:${e}`)}}function mt(e,t){const n=i.join(t.outDir,"fixtures");p.mkdirSync(n,{recursive:!0});const r=new Date().toISOString().replace(/[-:.TZ]/g,"").slice(0,14);if(e==="send-text")return{text:t.text||`codex-product-action text ${r}`};if(e==="send-file"){const o=t.filePath||i.join(n,`wechat-action-smoke-${r}.txt`);return t.filePath||p.writeFileSync(o,`Shennian WeChat product action smoke
|
|
6
|
-
${r}
|
|
7
|
-
`,"utf8"),{text:t.text||"",attachmentPath:o}}if(e==="send-image"){const o=t.imagePath||i.join(n,`wechat-action-smoke-${r}.png`);return t.imagePath||yt(o),{text:t.text||"",attachmentPath:o}}if(e==="send-video"){const o=t.videoPath||i.join(n,`wechat-action-smoke-${r}.mp4`);return!t.videoPath&&!St(o)?{skipped:!0,reasonCode:"ffmpeg_unavailable_for_video_fixture"}:{text:t.text||"",attachmentPath:o}}throw new Error(`step ${e} is not a send step`)}function oe(e){const t=e.flatMap(n=>ht(n.mediaMetadata));return{count:t.length,byAvailability:q(t.map(n=>se(n,"availability")||"unknown")),localPaths:t.map(n=>se(n,"localPath")).filter(n=>!!n)}}function ht(e){if(!e||typeof e!="object")return[];const t=e;return Array.isArray(t.attachments)?t.attachments.filter(ae):ae(t.attachment)?[t.attachment]:t.localPath||t.url||t.availability||t.name||t.fileName?[t]:[]}function ft(e){const t=b(e,"--mode")||(e[0]?.startsWith("--")?"":e[0]);return t==="send"||t==="observe"||t==="all"||t==="open-read"?t:"open-read"}function gt(e){return e==="open-read"||e==="send-text"||e==="send-file"||e==="send-image"||e==="send-video"||e==="structure-window"||e==="server-observe"||e==="read-bottom-page"||e==="download-visible-media"||e==="send-and-confirm"||e==="human-send-preflight-busy"||e==="human-send-preflight-busy-then-idle"||e==="human-send-user-active-timeout"||e==="human-send-takeover-during-run"||e==="human-send-takeover-then-idle"||e==="human-send-normal"||e==="human-observe-deferred"?e:null}function wt(e,t){const n=[];for(let r=0;r<e.length;r+=1)e[r]===t&&e[r+1]&&n.push(e[r+1]);return n}function b(e,t){const n=e.indexOf(t),r=n>=0?e[n+1]:void 0;return r&&!r.startsWith("--")?r:void 0}function A(e,t){const n=b(e,`${t}-base64`);return n!==void 0?Buffer.from(n,"base64").toString("utf8"):b(e,t)}function U(e){return e?i.resolve(e):void 0}function bt(e){return Array.from(new Set(e))}function _(e,t,n){const r=n.mimeType.includes("jpeg")?".jpg":".png",o=i.join(e,`${t}${r}`);return p.writeFileSync(o,Buffer.from(n.dataBase64,"base64")),o}function m(e,t){p.mkdirSync(i.dirname(e),{recursive:!0}),p.writeFileSync(e,`${JSON.stringify(t,null,2)}
|
|
8
|
-
`,"utf8")}function R(e,t){p.mkdirSync(i.dirname(e),{recursive:!0}),p.writeFileSync(e,t,"utf8")}function pt(e){return i.join(e.outDir,"wechat-channel-ledger.json")}function vt(e,t=3){return(e?.recent??[]).slice(-t).map(n=>({stableMessageKey:n.stableMessageKey,senderRole:n.senderRole,kind:n.kind,anchorText:n.anchorText??n.normalizedText??n.textExcerpt??null,anchorMetadata:n.anchorMetadata??null}))}function yt(e){p.writeFileSync(e,Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAAVElEQVR4nO3PMQ0AMAgAMUTof2kOKWzo8mCqkmeX9waYtwOwG4DbANwG4DYAtwG4DcBtAG4DcBuA2wDcBuA2ALcBuA3AbQBuA3AbgNsA3AbgNgC3AbgNwG0AbgNwG8BPDyCqAzmh3yHRAAAAAElFTkSuQmCC","base64"))}function St(e){return ce("ffmpeg",["-y","-f","lavfi","-i","testsrc=size=160x120:rate=5","-t","1","-pix_fmt","yuv420p",e],{encoding:"utf8",stdio:"ignore",timeout:2e4}).status===0&&p.existsSync(e)}function q(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;return t}function se(e,t){return typeof e[t]=="string"?e[t].trim():""}function ae(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function P(e){return M.createHash("sha256").update(e).digest("hex").slice(0,16)}function ie(e){return`sha256:${M.createHash("sha256").update(kt(e)).digest("hex")}`}function kt(e){return JSON.stringify(K(e))}function K(e){if(Array.isArray(e))return e.map(K);if(!e||typeof e!="object")return e;const t=e;return Object.fromEntries(Object.keys(t).sort().map(n=>[n,K(t[n])]))}function Ct(e){const t=e instanceof Error?e.message:String(e),n=t.split(":",1)[0]?.trim();return n&&/^[a-z0-9_/-]+$/i.test(n)?n.replace(/\//g,"_"):/permission|accessibility|screen|automation/i.test(t)?"permission_missing":/wechat.*window|window.*unavailable/i.test(t)?"wechat_window_unavailable":/observe|VLM|server|api/i.test(t)?"server_observe_failed":"action_smoke_failed"}function It(e){if(e==="wechat_duplicate_instance")return"\u8BF7\u5173\u95ED\u91CD\u590D\u767B\u5F55\u3001\u5DF2\u767B\u5F55\u63D0\u793A\u6216\u7B2C\u4E8C\u4E2A\u5FAE\u4FE1\u4E3B\u7A97\u53E3\uFF0C\u53EA\u4FDD\u7559\u4E00\u4E2A\u5DF2\u767B\u5F55\u7684 Windows \u5FAE\u4FE1\u4E3B\u7A97\u53E3\u540E\u91CD\u8BD5\u3002"}function V(e){return new Promise(t=>setTimeout(t,e))}function xt(e){process.stdout.write(`${JSON.stringify({ok:e.ok,conversation:e.conversation,outDir:e.outDir,durationMs:e.durationMs,steps:e.steps.map(t=>({step:t.step,ok:t.ok,skipped:t.skipped,reasonCode:t.reasonCode,userAction:t.userAction,details:t.details,errorSummary:t.errorSummary}))},null,2)}
|
|
9
|
-
`)}async function Dt(){const e=xe(process.argv.slice(2)),t=await Ae(e);xt(t),(!t.ok||e.requireServer&&t.steps.some(n=>n.step==="server-observe"&&!n.ok))&&process.exit(1)}process.argv[1]&&i.resolve(process.argv[1])===le(import.meta.url)&&Dt().catch(e=>{process.stderr.write(`${e instanceof Error?e.stack||e.message:String(e)}
|
|
10
|
-
`),process.exit(1)});export{T as buildBottomPageReport,G as buildDownloadVisibleMediaReport,Fe as buildSendAndConfirmEvidence,Be as buildSendStepAcceptance,et as countMarkerOccurrencesInChatContentBlocks,Ye as countMarkerOccurrencesInOcrBlocks,Oe as nextSmokeDrainWaitMs,xe as parseWeChatChannelActionSmokeArgs,ke as resolveWeChatSmokeObserveSessionMode,Ae as runWeChatChannelActionSmoke,De as stepsForMode};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type { WeChatChannelObservedMessage } from '../channels/wechat-channel/client.js';
|
|
2
|
-
import type { WeChatChannelBindingLedger } from '../channels/wechat-channel/ledger.js';
|
|
3
|
-
import type { WeChatChannelTraceEvent } from '../channels/wechat-channel/core/schema.js';
|
|
4
|
-
export declare function buildBottomPageReport(messages: WeChatChannelObservedMessage[]): {
|
|
5
|
-
generatedAt: string;
|
|
6
|
-
messageCount: number;
|
|
7
|
-
byKind: Record<string, number>;
|
|
8
|
-
attachmentSummary: ReturnType<typeof summarizeObservedAttachments>;
|
|
9
|
-
messages: Array<Record<string, unknown>>;
|
|
10
|
-
};
|
|
11
|
-
export declare function buildDownloadVisibleMediaReport(messages: WeChatChannelObservedMessage[], attachmentsDir?: string, metadata?: {
|
|
12
|
-
observePipeline?: 'edge-structure' | 'server-observe';
|
|
13
|
-
downloadAnchorText?: string;
|
|
14
|
-
ledgerPath?: string;
|
|
15
|
-
ledgerBinding?: WeChatChannelBindingLedger;
|
|
16
|
-
traceHashes?: {
|
|
17
|
-
captureHash?: string;
|
|
18
|
-
ocrHash?: string;
|
|
19
|
-
ingestPayloadHash?: string;
|
|
20
|
-
};
|
|
21
|
-
}): {
|
|
22
|
-
generatedAt: string;
|
|
23
|
-
ok: boolean;
|
|
24
|
-
reasonCode?: string;
|
|
25
|
-
phases: string[];
|
|
26
|
-
observePipeline?: 'edge-structure' | 'server-observe';
|
|
27
|
-
mediaCandidateCount: number;
|
|
28
|
-
localAttachmentCount: number;
|
|
29
|
-
originalLocalAttachmentCount: number;
|
|
30
|
-
previewAttachmentCount: number;
|
|
31
|
-
pendingAttachmentCount: number;
|
|
32
|
-
missingLocalPathCount: number;
|
|
33
|
-
byKind: Record<string, number>;
|
|
34
|
-
byAvailability: Record<string, number>;
|
|
35
|
-
reasonCodes: Record<string, number>;
|
|
36
|
-
candidateEvidence: ReturnType<typeof summarizeCandidateEvidence>;
|
|
37
|
-
actionPlan: Array<Record<string, unknown>>;
|
|
38
|
-
resolverTrace: Array<Record<string, unknown>>;
|
|
39
|
-
attachmentValidation: Array<Record<string, unknown>>;
|
|
40
|
-
anchorScope?: {
|
|
41
|
-
anchorText: string;
|
|
42
|
-
anchorMatched: boolean;
|
|
43
|
-
anchorIndexes: number[];
|
|
44
|
-
fallbackReason?: string;
|
|
45
|
-
fallbackExpectedKind?: AnchorFallbackMediaKind;
|
|
46
|
-
windowBefore: number;
|
|
47
|
-
windowAfter: number;
|
|
48
|
-
sourceMessageCount: number;
|
|
49
|
-
scopedMessageCount: number;
|
|
50
|
-
globalMediaCandidateCount: number;
|
|
51
|
-
scopedMediaCandidateCount: number;
|
|
52
|
-
};
|
|
53
|
-
globalDiagnostics?: {
|
|
54
|
-
mediaCandidateCount: number;
|
|
55
|
-
pendingAttachmentCount: number;
|
|
56
|
-
byKind: Record<string, number>;
|
|
57
|
-
byAvailability: Record<string, number>;
|
|
58
|
-
reasonCodes: Record<string, number>;
|
|
59
|
-
};
|
|
60
|
-
attachmentsDir?: string;
|
|
61
|
-
ledgerPath?: string;
|
|
62
|
-
ledger?: {
|
|
63
|
-
bindingId: string;
|
|
64
|
-
baselineEstablished: boolean;
|
|
65
|
-
revision: number;
|
|
66
|
-
recentCount: number;
|
|
67
|
-
attachmentStateCount: number;
|
|
68
|
-
};
|
|
69
|
-
traceHashes: {
|
|
70
|
-
captureHash?: string;
|
|
71
|
-
ocrHash?: string;
|
|
72
|
-
structuredMessagesHash: string;
|
|
73
|
-
normalizedMessagesHash: string;
|
|
74
|
-
mediaCandidatesHash: string;
|
|
75
|
-
actionPlanHash: string;
|
|
76
|
-
ledgerDecisionHash?: string;
|
|
77
|
-
attachmentResultHash: string;
|
|
78
|
-
ingestPayloadHash?: string;
|
|
79
|
-
};
|
|
80
|
-
traceEvents: WeChatChannelTraceEvent[];
|
|
81
|
-
candidates: Array<Record<string, unknown>>;
|
|
82
|
-
};
|
|
83
|
-
type AnchorFallbackMediaKind = 'file' | 'image' | 'video';
|
|
84
|
-
declare function summarizeCandidateEvidence(candidates: Record<string, unknown>[]): {
|
|
85
|
-
candidateCount: number;
|
|
86
|
-
withBbox: number;
|
|
87
|
-
withDownloadActionBbox: number;
|
|
88
|
-
withActionPlan: number;
|
|
89
|
-
withResolverTrace: number;
|
|
90
|
-
withEdgeLocalPrevalidation: number;
|
|
91
|
-
withResolverOrPrevalidation: number;
|
|
92
|
-
withStabilityTrace: number;
|
|
93
|
-
withMenuOcrTrace: number;
|
|
94
|
-
withClipboardTrace: number;
|
|
95
|
-
withCacheScanTrace: number;
|
|
96
|
-
withAttachmentValidation: number;
|
|
97
|
-
originalPassCount: number;
|
|
98
|
-
previewOnlyCount: number;
|
|
99
|
-
pendingOrMetadataCount: number;
|
|
100
|
-
failedCount: number;
|
|
101
|
-
actionPlanReasonCodes: Record<string, number>;
|
|
102
|
-
resolverReasonCodes: Record<string, number>;
|
|
103
|
-
};
|
|
104
|
-
declare function summarizeObservedAttachments(messages: Array<{
|
|
105
|
-
mediaMetadata?: unknown;
|
|
106
|
-
}>): {
|
|
107
|
-
count: number;
|
|
108
|
-
byAvailability: Record<string, number>;
|
|
109
|
-
localPaths: string[];
|
|
110
|
-
};
|
|
111
|
-
export {};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import U from"node:crypto";import Q from"node:fs";import H from"node:path";import{buildWeChatChannelMediaActionPlan as X}from"../channels/wechat-channel/core/media-action-plan.js";import{normalizeWeChatChannelMessageKind as Y}from"../channels/wechat-channel/core/schema.js";function Me(e){return{generatedAt:new Date().toISOString(),messageCount:e.length,byKind:b(e.map(n=>n.kind||"unknown")),attachmentSummary:ye(e),messages:e.map((n,t)=>({index:t,stableMessageKey:n.stableMessageKey,senderRole:n.senderRole,senderName:n.senderName??null,kind:n.kind,text:n.normalizedText||n.anchorText||n.textExcerpt||null,normalizedText:n.normalizedText??null,anchorText:n.anchorText??null,textExcerpt:n.textExcerpt??null,bbox:n.bbox??null,observedAt:n.observedAt??null,attachments:C(n.mediaMetadata).map(E),mediaMetadata:n.mediaMetadata??null}))}}function Pe(e,n,t={}){const r=e.filter(M).map((c,u)=>S(c,u)),o=Z(e,t.downloadAnchorText,r.length),i=o?e.filter((c,u)=>o.indexes.has(u)):e,s=i.filter(M).map((c,u)=>S(c,u)),d=o?ie(r):null,h=s.map(se),w=s.reduce((c,u)=>{const m=Array.isArray(u.attachments)?u.attachments.filter(l):[];return c+m.filter(f=>f.availability==="edge-local"&&!!f.localPath).length},0),v=s.reduce((c,u)=>{const m=Array.isArray(u.attachments)?u.attachments.filter(l):[];return c+m.filter(f=>P(u,f)).length},0),p=s.reduce((c,u)=>{const m=Array.isArray(u.attachments)?u.attachments.filter(l):[];return c+m.filter(f=>R(f)).length},0),g=s.reduce((c,u)=>{const m=Array.isArray(u.attachments)?u.attachments.filter(l):[];return c+m.filter(f=>f.availability==="edge-local"&&f.localPathExists===!1).length},0),N=s.reduce((c,u)=>{const m=Array.isArray(u.attachments)?u.attachments.filter(l):[];return c+m.filter(f=>f.availability==="pending-download"||f.availability==="metadata-only").length},0),D=b(s.map(c=>a(c,"kind")||"unknown")),V=b(s.flatMap(c=>(Array.isArray(c.attachments)?c.attachments.filter(l):[]).map(m=>a(m,"availability")||"unknown"))),j=b(s.flatMap(c=>{const u=a(c,"edgeResolveReasonCode"),m=Array.isArray(c.attachments)?c.attachments.filter(l):[];return[u,...m.map(f=>a(f,"providerError"))].filter(f=>!!f)})),W=s.map(c=>c.actionPlan).filter(l),J=s.map(c=>c.resolverTrace).filter(l),$=s.flatMap(c=>L(c)),q=h.filter(c=>!c.pass).length,T=h.find(c=>!c.pass),G=T?a(T,"failureReason"):"",x=s.length===0?"no_visible_media_candidates":q>0?G||"media_candidate_original_missing":g>0?"local_attachment_missing":void 0,k={...t.traceHashes?.captureHash?{captureHash:t.traceHashes.captureHash}:{},...t.traceHashes?.ocrHash?{ocrHash:t.traceHashes.ocrHash}:{},structuredMessagesHash:A(i.map(O)),normalizedMessagesHash:A(i.map(O)),mediaCandidatesHash:A(s.map(fe)),actionPlanHash:A(s.map(me)),...t.ledgerBinding?{ledgerDecisionHash:A(I(t.ledgerBinding))}:{},attachmentResultHash:A(h.map(pe)),...t.traceHashes?.ingestPayloadHash?{ingestPayloadHash:t.traceHashes.ingestPayloadHash}:{}};return{generatedAt:new Date().toISOString(),ok:!x,...x?{reasonCode:x}:{},phases:["open-conversation","capture-window","structure-visible-window","normalize-validate-media","media-action-plan","media-resolver","local-attachment-validation"],...t.observePipeline?{observePipeline:t.observePipeline}:{},mediaCandidateCount:s.length,localAttachmentCount:w,originalLocalAttachmentCount:v,previewAttachmentCount:p,pendingAttachmentCount:N,missingLocalPathCount:g,byKind:D,byAvailability:V,reasonCodes:j,candidateEvidence:de(h),actionPlan:W,resolverTrace:J,attachmentValidation:$,...o?{anchorScope:ee(o,s.length)}:{},...d?{globalDiagnostics:d}:{},...n?{attachmentsDir:n}:{},...t.ledgerPath?{ledgerPath:t.ledgerPath}:{},...t.ledgerBinding?{ledger:I(t.ledgerBinding)}:{},traceHashes:k,traceEvents:ge({traceId:`download-visible:${k.attachmentResultHash.slice(0,16)}`,ok:!x,reasonCode:x,traceHashes:k}),candidates:h}}function Z(e,n,t){const r=z(n);if(!r)return null;const o=ne(r),i=e.map((p,g)=>z(oe(p)).includes(r)?g:-1).filter(p=>p>=0),s=1,d=8,h=new Set;for(const p of i){for(let g=p;g<=Math.min(e.length-1,p+d);g+=1)h.add(g);if(!e.slice(p+1,Math.min(e.length,p+d+1)).some(M))for(let g=Math.max(0,p-s);g<p;g+=1)h.add(g)}const w=te(e,o),v=i.length===0&&w>=0?"anchor_missing_latest_media_fallback":void 0;return v&&h.add(w),{anchorText:String(n||""),anchorMatched:i.length>0,anchorIndexes:i,windowBefore:s,windowAfter:d,sourceMessageCount:e.length,globalMediaCandidateCount:t,...v?{fallbackReason:v}:{},...v&&o?{fallbackExpectedKind:o}:{},indexes:h}}function ee(e,n){return{anchorText:e.anchorText,anchorMatched:e.anchorMatched,anchorIndexes:e.anchorIndexes,...e.fallbackReason?{fallbackReason:e.fallbackReason}:{},...e.fallbackExpectedKind?{fallbackExpectedKind:e.fallbackExpectedKind}:{},windowBefore:e.windowBefore,windowAfter:e.windowAfter,sourceMessageCount:e.sourceMessageCount,scopedMessageCount:e.indexes.size,globalMediaCandidateCount:e.globalMediaCandidateCount,scopedMediaCandidateCount:n}}function ne(e){return e.includes("video")||e.includes("vide0")?"video":e.includes("image")||e.includes("photo")||e.includes("ph0t0")||e.includes("picture")?"image":e.includes("file")||e.includes("document")?"file":null}function te(e,n=null){for(let t=e.length-1;t>=0;t-=1)if(M(e[t]))return ae(e[t],n)?t:-1;return-1}function ae(e,n){if(!e||!n)return!0;const t=String(e.kind||"").toLowerCase(),o=C(e.mediaMetadata).filter(l)[0]||{},i=String(a(o,"type")||"").toLowerCase(),s=String(a(o,"mimeType")||"").toLowerCase(),d=String(a(o,"name")||a(o,"localPath")||e.anchorText||e.textExcerpt||"").toLowerCase();return n==="video"?t.includes("video")||i==="video"||s.startsWith("video/")||/\.(mp4|mov|m4v|avi|mkv|webm)$/i.test(d):n==="image"?/image|photo|picture/.test(t)||i==="image"||s.startsWith("image/")||/\.(png|jpe?g|gif|webp|heic|tiff?|bmp)$/i.test(d):/file|document/.test(t)||i==="file"||!/image|photo|picture|video/.test(t)&&i!=="image"&&i!=="video"&&!s.startsWith("image/")&&!s.startsWith("video/")}function ie(e){return{mediaCandidateCount:e.length,pendingAttachmentCount:e.reduce((n,t)=>{const r=Array.isArray(t.attachments)?t.attachments.filter(l):[];return n+r.filter(o=>o.availability==="pending-download"||o.availability==="metadata-only").length},0),byKind:b(e.map(n=>a(n,"kind")||"unknown")),byAvailability:b(e.flatMap(n=>(Array.isArray(n.attachments)?n.attachments.filter(l):[]).map(r=>a(r,"availability")||"unknown"))),reasonCodes:b(e.flatMap(n=>{const t=a(n,"edgeResolveReasonCode"),r=Array.isArray(n.attachments)?n.attachments.filter(l):[];return[t,...r.map(o=>a(o,"providerError"))].filter(o=>!!o)}))}}function oe(e){if(!e)return"";const n=e;return[e.normalizedText,e.anchorText,e.textExcerpt,n.text].map(t=>String(t||"")).join(`
|
|
2
|
-
`)}function z(e){return String(e||"").normalize("NFKC").replace(/[o]/giu,"0").replace(/[^\p{L}\p{N}]/gu,"").toLowerCase()}function M(e){return C(e.mediaMetadata).length>0||/image|photo|video|file|document/i.test(e.kind||"")}function P(e,n){const t=a(n,"localPath");if(n.availability!=="edge-local"||!t||n.localPathExists===!1||R(n)||n.isOriginal===!1||a(n,"materializationKind")==="preview-crop")return!1;const r=String(a(e,"kind")||a(n,"type")||"").toLowerCase(),o=String(a(n,"type")||"").toLowerCase(),i=String(a(n,"mimeType")||"").toLowerCase(),s=String(a(n,"name")||t).toLowerCase(),d=String(a(n,"extension")||H.extname(s)).toLowerCase();return/video/.test(r)||o==="video"?i.startsWith("video/")||[".mp4",".mov",".m4v",".avi",".mkv",".webm"].includes(d):/image|photo/.test(r)||o==="image"?i.startsWith("image/")||[".png",".jpg",".jpeg",".gif",".webp",".heic",".tiff",".bmp"].includes(d):/file|document/.test(r)||o==="file"?o==="file"||!i.startsWith("image/")&&!i.startsWith("video/"):!0}function R(e){const n=a(e,"sourceAction"),t=a(e,"materializationKind"),r=a(e,"name"),o=a(e,"localPath");return n==="materialize-preview"||t==="preview-crop"||e.availability==="edge-preview"||/(^|-)preview\./i.test(r)||/(^|-)preview-[a-f0-9]{8,}\./i.test(H.basename(o))}function S(e,n){const t=l(e.mediaMetadata)?e.mediaMetadata:{},r=l(t.edgeResolveTrace)?t.edgeResolveTrace:null,o=re(e,t,r),i=C(e.mediaMetadata).map(E),s=ce(e,i);return{index:n,stableMessageKey:e.stableMessageKey,senderRole:e.senderRole,senderName:e.senderName??null,kind:e.kind,text:e.normalizedText||e.anchorText||e.textExcerpt||null,bbox:e.bbox??t.bbox??r?.bbox??null,downloadActionBbox:t.downloadActionBbox??r?.downloadActionBbox??null,confidence:y(t,"confidence"),mediaStatus:a(t,"mediaStatus")||null,edgeResolveReasonCode:a(t,"edgeResolveReasonCode")||null,edgeResolveAttempts:Array.isArray(t.edgeResolveAttempts)?t.edgeResolveAttempts:[],actionPlan:o,resolverTrace:le(r),edgeLocalPrevalidation:s,attachments:i}}function re(e,n,t){const r=l(t?.actionPlan)?t.actionPlan:null;if(r)return{source:"resolver-trace",reasonCode:a(r,"reasonCode")||null,actions:Array.isArray(r.actions)?r.actions.filter(l).map(_):[]};const o=l(n.attachment)?n.attachment:{},i=F(e.bbox??n.bbox),s=F(n.downloadActionBbox),d=X({messageKey:e.stableMessageKey,kind:Y(a(o,"type")||a(o,"kind")||a(n,"messageType")||e.kind),...i?{bbox:i}:{},...s?{downloadActionBbox:s}:{},fileName:a(o,"name")||a(o,"fileName")||a(n,"fileName")||null,mimeType:a(o,"mimeType")||a(n,"mimeType")||null,size:y(o,"size")??y(n,"size"),mediaStatus:a(n,"mediaStatus")||null});return{source:"shared-core",reasonCode:d.reasonCode,actions:d.actions.map(h=>_(h))}}function _(e){return{type:a(e,"type")||null,reasonCode:a(e,"reasonCode")||null,label:a(e,"label")||null,target:e.target??null}}function le(e){if(!e)return null;const n=Array.isArray(e.attempts)?e.attempts.filter(l):[];return{candidateKind:a(e,"candidateKind")||null,bbox:e.bbox??null,downloadActionBbox:e.downloadActionBbox??null,mediaStatus:a(e,"mediaStatus")||null,finalReasonCode:a(e,"finalReasonCode")||null,attemptCount:n.length,attempts:n.map(t=>({phase:a(t,"phase")||null,stage:a(t,"stage")||null,retry:t.retry===!0,ok:typeof t.ok=="boolean"?t.ok:null,reasonCode:a(t,"reasonCode")||null,rightClickPoint:t.rightClickPoint??null,menuSearchBounds:t.menuSearchBounds??null,pickedMethod:a(t,"pickedMethod")||null,pickedLabel:a(t,"pickedLabel")||null,pickedPoint:t.pickedPoint??null,ocrMenuCandidateCount:Array.isArray(t.ocrMenuCandidates)?t.ocrMenuCandidates.length:0,selectedOcrMenuCandidate:Array.isArray(t.ocrMenuCandidates)?t.ocrMenuCandidates.filter(l).find(r=>r.selected===!0)??null:null,clipboardPayload:t.clipboardPayload??null,downloadPoint:t.downloadPoint??null,cacheScan:t.cacheScan??null})),attachmentValidation:e.attachmentValidation??null}}function E(e){const n=a(e,"localPath"),t={type:a(e,"type")||a(e,"kind")||null,name:a(e,"name")||a(e,"fileName")||null,availability:a(e,"availability")||null,localPath:n||null,localPathExists:n?Q.existsSync(n):null,mimeType:a(e,"mimeType")||null,extension:a(e,"extension")||n&&H.extname(n)||null,sizeBytes:y(e,"sizeBytes")??y(e,"size"),sha256:a(e,"sha256")||a(e,"hash")||null,sourceAction:a(e,"sourceAction")||null,materializationKind:a(e,"materializationKind")||null,isOriginal:typeof e.isOriginal=="boolean"?e.isOriginal:null,mimeKindMatches:typeof e.mimeKindMatches=="boolean"?e.mimeKindMatches:null,providerError:a(e,"providerError")||null},r=typeof e.isOriginal=="boolean"?e.isOriginal:P(t,t),o=typeof e.mimeKindMatches=="boolean"?e.mimeKindMatches:r;return{...t,isOriginal:r,mimeKindMatches:o}}function se(e){const n=Array.isArray(e.attachments)?e.attachments.filter(l):[],t=n.filter(h=>P(e,h)),r=n.filter(R),o=n.some(h=>h.availability==="pending-download"||h.availability==="metadata-only"),i=l(e.edgeLocalPrevalidation)?e.edgeLocalPrevalidation:B(e,t),s=t.length>0,d=s?null:r.length>0?"only_preview_media_downloaded":o?"media_original_pending_or_metadata_only":"media_candidate_original_missing";return{...e,expectedKind:a(e,"kind")||"unknown",originalAttachmentCount:t.length,previewAttachmentCount:r.length,edgeLocalPrevalidation:i,isOriginal:s,pass:s,failureReason:d}}function ce(e,n){return B({stableMessageKey:e.stableMessageKey,kind:e.kind},n.filter(t=>P({kind:e.kind},t)))}function B(e,n){return n.length?{source:"edge-local-prevalidated",stableMessageKey:a(e,"stableMessageKey")||null,kind:a(e,"kind")||a(e,"expectedKind")||null,originalAttachmentCount:n.length,attachments:n.map(t=>ue(t))}:null}function ue(e){return{availability:a(e,"availability")||null,type:a(e,"type")||null,name:a(e,"name")||null,localPath:a(e,"localPath")||null,localPathExists:e.localPathExists===!0,mimeType:a(e,"mimeType")||null,extension:a(e,"extension")||null,sizeBytes:y(e,"sizeBytes"),sha256:a(e,"sha256")||null,sourceAction:a(e,"sourceAction")||null,materializationKind:a(e,"materializationKind")||null,isOriginal:e.isOriginal===!0,mimeKindMatches:e.mimeKindMatches===!0}}function L(e){const n=l(e.resolverTrace)?e.resolverTrace:null,t=n&&l(n.attachmentValidation)?[{source:"resolver-trace",stableMessageKey:a(e,"stableMessageKey")||null,...n.attachmentValidation}]:[],r=l(e.edgeLocalPrevalidation)?e.edgeLocalPrevalidation:null,o=Array.isArray(r?.attachments)?r.attachments.filter(l).map(i=>({source:"edge-local-prevalidated",stableMessageKey:a(e,"stableMessageKey")||null,...i})):[];return[...t,...o]}function de(e){const n=e.map(i=>i.resolverTrace).filter(l),t=e.map(i=>i.actionPlan).filter(l),r=e.map(i=>i.edgeLocalPrevalidation).filter(l),o=n.flatMap(i=>Array.isArray(i.attempts)?i.attempts.filter(l):[]);return{candidateCount:e.length,withBbox:e.filter(i=>!!i.bbox).length,withDownloadActionBbox:e.filter(i=>!!i.downloadActionBbox).length,withActionPlan:t.filter(i=>Array.isArray(i.actions)&&i.actions.length>0).length,withResolverTrace:n.length,withEdgeLocalPrevalidation:r.length,withResolverOrPrevalidation:e.filter(i=>l(i.resolverTrace)||l(i.edgeLocalPrevalidation)).length,withStabilityTrace:o.filter(i=>a(i,"phase")==="stability").length,withMenuOcrTrace:o.filter(i=>a(i,"pickedMethod")==="ocr-menu"||y(i,"ocrMenuCandidateCount")).length,withClipboardTrace:o.filter(i=>!!i.clipboardPayload).length,withCacheScanTrace:o.filter(i=>a(i,"phase")==="cache-scan"||!!i.cacheScan).length,withAttachmentValidation:e.filter(i=>L(i).length>0).length,originalPassCount:e.filter(i=>i.pass===!0).length,previewOnlyCount:e.filter(i=>a(i,"failureReason")==="only_preview_media_downloaded").length,pendingOrMetadataCount:e.filter(i=>a(i,"failureReason")==="media_original_pending_or_metadata_only").length,failedCount:e.filter(i=>i.pass!==!0).length,actionPlanReasonCodes:b(t.map(i=>a(i,"reasonCode")||"unknown")),resolverReasonCodes:b(e.map(i=>a(i,"edgeResolveReasonCode")||"unknown"))}}function O(e){return{stableMessageKey:e.stableMessageKey,senderRole:e.senderRole,kind:e.kind,text:e.normalizedText||e.anchorText||e.textExcerpt||null,bbox:e.bbox??null,mediaMetadata:he(e.mediaMetadata)}}function he(e){return l(e)?{mediaStatus:a(e,"mediaStatus")||null,availability:a(e,"availability")||null,edgeResolveReasonCode:a(e,"edgeResolveReasonCode")||null,attachments:C(e).map(n=>({type:a(n,"type")||a(n,"kind")||null,name:a(n,"name")||a(n,"fileName")||null,availability:a(n,"availability")||null,extension:a(n,"extension")||null,mimeType:a(n,"mimeType")||null,sourceAction:a(n,"sourceAction")||null,materializationKind:a(n,"materializationKind")||null,isOriginal:typeof n.isOriginal=="boolean"?n.isOriginal:null,mimeKindMatches:typeof n.mimeKindMatches=="boolean"?n.mimeKindMatches:null,providerError:a(n,"providerError")||null,hasLocalPath:!!a(n,"localPath"),sizeBytes:y(n,"sizeBytes")??y(n,"size")}))}:e??null}function fe(e){return{stableMessageKey:a(e,"stableMessageKey")||null,kind:a(e,"kind")||null,mediaStatus:a(e,"mediaStatus")||null,edgeResolveReasonCode:a(e,"edgeResolveReasonCode")||null,bbox:e.bbox??null,attachmentCount:Array.isArray(e.attachments)?e.attachments.length:0}}function me(e){const n=l(e.actionPlan)?e.actionPlan:{};return{stableMessageKey:a(e,"stableMessageKey")||null,kind:a(e,"kind")||null,reasonCode:a(n,"reasonCode")||null,actions:Array.isArray(n.actions)?n.actions.filter(l).map(t=>({type:a(t,"type")||null,reasonCode:a(t,"reasonCode")||null,label:a(t,"label")||null,hasTarget:!!t.target})):[],edgeResolveReasonCode:a(e,"edgeResolveReasonCode")||null}}function pe(e){const n=Array.isArray(e.attachments)?e.attachments.filter(l):[];return{stableMessageKey:a(e,"stableMessageKey")||null,kind:a(e,"kind")||null,pass:e.pass===!0,failureReason:a(e,"failureReason")||null,originalAttachmentCount:y(e,"originalAttachmentCount")??0,previewAttachmentCount:y(e,"previewAttachmentCount")??0,attachments:n.map(t=>({type:a(t,"type")||null,availability:a(t,"availability")||null,extension:a(t,"extension")||null,mimeType:a(t,"mimeType")||null,localPathExists:t.localPathExists===!0,sourceAction:a(t,"sourceAction")||null,materializationKind:a(t,"materializationKind")||null,isOriginal:t.isOriginal===!0,mimeKindMatches:t.mimeKindMatches===!0,providerError:a(t,"providerError")||null}))}}function I(e){return{bindingId:e.bindingId,baselineEstablished:e.baselineEstablished,revision:e.revision,recentCount:e.recent.length,attachmentStateCount:Object.keys(e.attachmentStates??{}).length}}function ge(e){return[...e.traceHashes.captureHash?[{traceId:e.traceId,phase:"capture_window",status:"ok",outputHash:e.traceHashes.captureHash}]:[],...e.traceHashes.ocrHash?[{traceId:e.traceId,phase:"structure_window_request",status:"ok",inputHash:e.traceHashes.captureHash,outputHash:e.traceHashes.ocrHash}]:[],{traceId:e.traceId,phase:"structure_window_response",status:"ok",outputHash:e.traceHashes.structuredMessagesHash},{traceId:e.traceId,phase:"normalize_messages",status:"ok",inputHash:e.traceHashes.structuredMessagesHash,outputHash:e.traceHashes.normalizedMessagesHash},{traceId:e.traceId,phase:"media_plan",status:"ok",inputHash:e.traceHashes.mediaCandidatesHash,outputHash:e.traceHashes.actionPlanHash},...e.traceHashes.ledgerDecisionHash?[{traceId:e.traceId,phase:"ledger_diff",status:"ok",inputHash:e.traceHashes.normalizedMessagesHash,outputHash:e.traceHashes.ledgerDecisionHash}]:[],{traceId:e.traceId,phase:"media_postprocess",status:e.ok?"ok":"failed",...e.reasonCode?{reasonCode:e.reasonCode}:{},inputHash:e.traceHashes.actionPlanHash,outputHash:e.traceHashes.attachmentResultHash},...e.traceHashes.ingestPayloadHash?[{traceId:e.traceId,phase:"session_ingest",status:e.ok?"ok":"pending",inputHash:e.traceHashes.attachmentResultHash,outputHash:e.traceHashes.ingestPayloadHash}]:[]]}function ye(e){const n=e.flatMap(t=>C(t.mediaMetadata));return{count:n.length,byAvailability:b(n.map(t=>a(t,"availability")||"unknown")),localPaths:n.map(t=>a(t,"localPath")).filter(t=>!!t)}}function C(e){if(!e||typeof e!="object")return[];const n=e;return Array.isArray(n.attachments)?n.attachments.filter(l):l(n.attachment)?[n.attachment]:n.localPath||n.url||n.availability||n.name||n.fileName?[n]:[]}function b(e){const n={};for(const t of e)n[t]=(n[t]??0)+1;return n}function a(e,n){return typeof e[n]=="string"?e[n].trim():""}function y(e,n){const t=Number(e[n]);return Number.isFinite(t)?t:null}function l(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function F(e){if(!l(e))return;const n=Number(e.x),t=Number(e.y),r=Number(e.width),o=Number(e.height);if([n,t,r,o].every(Number.isFinite))return{x:n,y:t,width:r,height:o,...typeof e.coordinateSpace=="string"?{coordinateSpace:e.coordinateSpace}:{}}}function A(e){return`sha256:${U.createHash("sha256").update(be(e)).digest("hex")}`}function be(e){return JSON.stringify(K(e))}function K(e){if(Array.isArray(e))return e.map(K);if(!e||typeof e!="object")return e;const n=e;return Object.fromEntries(Object.keys(n).sort().map(t=>[t,K(n[t])]))}export{Me as buildBottomPageReport,Pe as buildDownloadVisibleMediaReport};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { WeChatChannelObservedMessage } from '../channels/wechat-channel/client.js';
|
|
2
|
-
export type WeChatMessagesMarkdownOptions = {
|
|
3
|
-
conversation?: string;
|
|
4
|
-
attachmentsDirName?: string;
|
|
5
|
-
};
|
|
6
|
-
export declare function buildWeChatMessagesMarkdown(messages: WeChatChannelObservedMessage[], options?: WeChatMessagesMarkdownOptions): string;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import d from"node:path";function x(n,t={}){const e=[];if(t.conversation?.trim()&&e.push(`${i(t.conversation)}:`),n.length===0)return e.push("\u6D88\u606F: \uFF08\u6CA1\u6709\u8BFB\u5230\uFF09"),`${e.join(`
|
|
2
|
-
`)}
|
|
3
|
-
`;for(const r of n)e.push(`${l(r)}: ${m(r,t)}`);return`${e.join(`
|
|
4
|
-
`)}
|
|
5
|
-
`}function l(n){return n.senderName?.trim()?i(n.senderName):n.senderRole==="self"?"\u6211":n.senderRole==="system"?"\u7CFB\u7EDF":n.senderRole==="contact"?"\u5BF9\u65B9":"\u672A\u77E5"}function m(n,t){const e=$(n);if(e.length>0)return e.map(a=>h(a,n,t)).join("\u3001");const r=n.normalizedText||n.anchorText||n.textExcerpt;return r?.trim()?i(r):`\uFF08${s(n.kind)}\uFF09`}function h(n,t,e){const r=o(n,"localPath"),a=o(n,"name")||o(n,"fileName")||f(r)||s(o(n,"type")||t.kind),u=p(r,e);return u?`[${y(a)}](${k(u)})`:i(a)}function p(n,t){if(!n)return"";const e=f(n);return e&&t.attachmentsDirName?`${t.attachmentsDirName.replace(/\\/g,"/")}/${e}`:n.replace(/\\/g,"/")}function $(n){const t=c(n.mediaMetadata)?n.mediaMetadata:{},e=[];return c(t.attachment)&&e.push(t.attachment),Array.isArray(t.attachments)&&e.push(...t.attachments.filter(c)),e}function f(n){return n?d.posix.basename(n.replace(/\\/g,"/")):""}function s(n){const t=String(n||"").toLowerCase();return t.includes("image")||t.includes("photo")?"\u56FE\u7247":t.includes("video")?"\u89C6\u9891":t.includes("file")||t.includes("document")?"\u6587\u4EF6":"\u6D88\u606F"}function k(n){return/[\s()<>]/.test(n)?`<${n.replace(/[<>]/g,"")}>`:n}function y(n){return i(n).replace(/([\\\]])/g,"\\$1")}function i(n){return String(n||"").replace(/\s+/g," ").trim()}function o(n,t){const e=n[t];return typeof e=="string"?e:""}function c(n){return!!n&&typeof n=="object"&&!Array.isArray(n)}export{x as buildWeChatMessagesMarkdown};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { runWeChatChannelActionSmoke, type WeChatChannelActionSmokeOptions, type WeChatChannelActionSmokeStep } from './wechat-channel-action-smoke.js';
|
|
2
|
-
export type WeChatChannelProductStepName = 'open-conversation' | 'fingerprint' | 'visible-structure' | 'server-observe' | 'download-visible' | 'read-visible' | 'read-bottom-page' | 'send-message' | 'send-and-confirm' | 'send-text' | 'send-file' | 'send-image' | 'send-video' | 'observe' | 'human-coordination' | 'human-send-core' | 'human-send-preflight-busy' | 'human-send-preflight-busy-then-idle' | 'human-send-user-active-timeout' | 'human-send-takeover-during-run' | 'human-send-takeover-then-idle' | 'human-send-normal' | 'human-observe-deferred' | 'all';
|
|
3
|
-
export type WeChatChannelProductStepsOptions = WeChatChannelActionSmokeOptions & {
|
|
4
|
-
productStep: WeChatChannelProductStepName;
|
|
5
|
-
};
|
|
6
|
-
export declare function parseWeChatChannelProductStepsArgs(argv: string[]): WeChatChannelProductStepsOptions;
|
|
7
|
-
export declare function stepsForProductStep(step: WeChatChannelProductStepName): WeChatChannelActionSmokeStep[];
|
|
8
|
-
export declare function collectWeChatProductStepMarkdown(result: Awaited<ReturnType<typeof runWeChatChannelActionSmoke>>): string;
|
|
9
|
-
export declare function isWeChatChannelProductStepsEntrypoint(metaUrl: string, argvPath?: string): boolean;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import u from"node:path";import{fileURLToPath as l}from"node:url";import{parseWeChatChannelActionSmokeArgs as m,runWeChatChannelActionSmoke as c}from"./wechat-channel-action-smoke.js";const h={open:"open-conversation","open-read":"open-conversation","open-conversation":"open-conversation",fingerprint:"fingerprint","visible-structure":"visible-structure",structure:"visible-structure","structure-window":"visible-structure","server-observe":"server-observe","legacy-observe":"server-observe","download-visible":"download-visible",download:"download-visible",read:"read-visible","read-visible":"read-visible","read-messages":"read-visible",messages:"read-visible","read-bottom-page":"read-bottom-page","bottom-page":"read-bottom-page","read-bottom":"read-bottom-page","send-message":"send-message",send:"send-message","send-and-confirm":"send-and-confirm","send-confirm":"send-and-confirm","send-text":"send-text","send-file":"send-file","send-image":"send-image","send-video":"send-video",observe:"observe","human-coordination":"human-coordination","human-send-core":"human-send-core","human-send-preflight-busy":"human-send-preflight-busy","human-send-preflight-busy-then-idle":"human-send-preflight-busy-then-idle","human-send-user-active-timeout":"human-send-user-active-timeout","human-send-takeover-during-run":"human-send-takeover-during-run","human-send-takeover-then-idle":"human-send-takeover-then-idle","human-send-normal":"human-send-normal","human-observe-deferred":"human-observe-deferred",all:"all"};function p(e){const n=e.filter(o=>o!=="--"),r=v(n),t=n.filter((o,d)=>!(d===0&&!o.startsWith("--"))),s=m(["--mode",r==="all"?"all":"custom",...t,...f(r)]);return{...s,allowEmptyMedia:s.allowEmptyMedia||r==="read-visible",productStep:r,mode:r==="all"?"all":"custom",steps:i(r)}}function i(e){return e==="open-conversation"||e==="fingerprint"?["open-read"]:e==="visible-structure"||e==="observe"?["structure-window"]:e==="server-observe"?["server-observe"]:e==="download-visible"?["download-visible-media"]:e==="read-visible"?["download-visible-media"]:e==="read-bottom-page"?["read-bottom-page"]:e==="send-text"?["open-read","send-text"]:e==="send-file"?["open-read","send-file"]:e==="send-image"?["open-read","send-image"]:e==="send-video"?["open-read","send-video"]:e==="send-message"?["open-read","send-text","send-file","send-image","send-video"]:e==="send-and-confirm"?["open-read","send-and-confirm"]:e==="human-send-preflight-busy"?["human-send-preflight-busy"]:e==="human-send-preflight-busy-then-idle"?["human-send-preflight-busy-then-idle"]:e==="human-send-user-active-timeout"?["human-send-user-active-timeout"]:e==="human-send-takeover-during-run"?["human-send-takeover-during-run"]:e==="human-send-takeover-then-idle"?["human-send-takeover-then-idle"]:e==="human-send-normal"?["human-send-normal"]:e==="human-observe-deferred"?["human-observe-deferred"]:e==="human-send-core"||e==="human-coordination"?["human-send-preflight-busy","human-send-preflight-busy-then-idle","human-send-user-active-timeout","human-send-takeover-during-run","human-send-takeover-then-idle","human-send-normal","human-observe-deferred"]:["open-read","send-text","send-file","send-image","send-video","structure-window"]}function f(e){return i(e).flatMap(n=>["--step",n])}function v(e){const n=a(e,"--product-step")||a(e,"--step-name"),r=e[0]&&!e[0].startsWith("--")?e[0]:"",t=String(n||r||"open-conversation").trim(),s=t.toLowerCase().replace(/_/g,"-"),o=h[s];if(!o)throw new Error(`unknown_product_step: ${t}`);return o}function a(e,n){const r=e.indexOf(n),t=r>=0?e[r+1]:void 0;return t&&!t.startsWith("--")?t:void 0}function b(){process.stdout.write(`Usage:
|
|
2
|
-
pnpm wechat:rpa:product-steps -- <step> [options]
|
|
3
|
-
|
|
4
|
-
Product steps:
|
|
5
|
-
open-conversation Open a WeChat conversation and capture full-window OCR/fingerprints.
|
|
6
|
-
fingerprint Alias of open-conversation; reports visible-list fingerprints.
|
|
7
|
-
visible-structure Run structure-window on the full WeChat window.
|
|
8
|
-
server-observe Run the legacy /observe compatibility path for debug only.
|
|
9
|
-
download-visible Run the full visible-media edge flow and validate local attachments.
|
|
10
|
-
read-visible Default read: structure recent messages and download visible attachments when present.
|
|
11
|
-
read-bottom-page Observe the current bottom page and write bottom-page-summary.json.
|
|
12
|
-
send-message Send text, file, image and video fixtures.
|
|
13
|
-
send-and-confirm Send fixtures, observe bottom page, and confirm at least one sent text is visible.
|
|
14
|
-
send-text|send-file|send-image|send-video
|
|
15
|
-
human-coordination Run the standard human/RPA coordination product smoke cases.
|
|
16
|
-
human-send-core Alias of human-coordination.
|
|
17
|
-
human-send-preflight-busy
|
|
18
|
-
human-send-preflight-busy-then-idle
|
|
19
|
-
human-send-user-active-timeout
|
|
20
|
-
human-send-takeover-during-run
|
|
21
|
-
human-send-takeover-then-idle
|
|
22
|
-
human-send-normal
|
|
23
|
-
human-observe-deferred
|
|
24
|
-
observe Alias of visible-structure.
|
|
25
|
-
all Run open/read, send fixtures and structure-window.
|
|
26
|
-
|
|
27
|
-
Common options:
|
|
28
|
-
--conversation ABC
|
|
29
|
-
--session-id <existing Shennian session id> Required for observe/download-visible/all server-backed steps.
|
|
30
|
-
--out <dir>
|
|
31
|
-
--trace-id <id>
|
|
32
|
-
|
|
33
|
-
This devtool runs the product helper/runtime from the workspace. It does not enable
|
|
34
|
-
the long-running WeChat channel and does not require changing the global shennian CLI.
|
|
35
|
-
`)}async function g(){if(process.argv.includes("--help")||process.argv.includes("-h")){b();return}const e=p(process.argv.slice(2)),n=await c(e),r=w(n);r&&process.stdout.write(`${r}
|
|
36
|
-
`),process.stdout.write(`${JSON.stringify({ok:n.ok,productStep:e.productStep,conversation:n.conversation,outDir:n.outDir,helperTracePath:n.helperTracePath,durationMs:n.durationMs,steps:n.steps},null,2)}
|
|
37
|
-
`),n.ok||(process.exitCode=1)}function w(e){return e.steps.map(n=>typeof n.details?.markdown=="string"?n.details.markdown.trim():"").filter(Boolean).join(`
|
|
38
|
-
|
|
39
|
-
`)}function k(e,n=process.argv[1]){if(!n)return!1;try{return u.resolve(n)===l(e)}catch{return!1}}k(import.meta.url)&&g().catch(e=>{process.stderr.write(`${e.stack||e.message||String(e)}
|
|
40
|
-
`),process.exit(1)});export{w as collectWeChatProductStepMarkdown,k as isWeChatChannelProductStepsEntrypoint,p as parseWeChatChannelProductStepsArgs,i as stepsForProductStep};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ReqFrame } from '@shennian/wire';
|
|
2
|
-
import type { SessionManagerRuntime } from '../types.js';
|
|
3
|
-
export declare function handleSkillList(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
|
|
4
|
-
export declare function handleSkillInstall(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
|
|
5
|
-
export declare function handleSkillDoctor(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
|
|
6
|
-
export declare function handleSkillSetup(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
|
|
7
|
-
export declare function handleSkillUse(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{buildSkillUsePrompt as k,getInstalledSkill as n,installSkillFromUrl as y,listInstalledSkills as u,updateInstalledSkillSetup as p}from"../../skills/registry.js";import{runSkillDoctor as f,runSkillSetup as m,summarizeSetupStatus as I}from"../../skills/setup.js";async function g(e,s){e.client.sendRes({type:"res",id:s.id,ok:!0,payload:{skills:u()}})}async function h(e,s){const t=typeof s.params.installUrl=="string"?s.params.installUrl:"";if(!t){e.client.sendRes({type:"res",id:s.id,ok:!1,error:"installUrl is required"});return}const i=await y(t);e.client.sendRes({type:"res",id:s.id,ok:!0,payload:{skill:i}})}async function w(e,s){const t=typeof s.params.skillId=="string"?s.params.skillId:"",i=typeof s.params.doctorId=="string"?s.params.doctorId:void 0;if(!t){e.client.sendRes({type:"res",id:s.id,ok:!1,error:"skillId is required"});return}if(!n(t)){e.client.sendRes({type:"res",id:s.id,ok:!1,error:`Skill not installed: ${t}`});return}const l=await f(t,i),r=I(l);p(t,{setupStatus:r,doctorResults:l}),e.client.sendRes({type:"res",id:s.id,ok:!0,payload:{skill:n(t),setupStatus:r,doctorResults:l}})}async function U(e,s){const t=typeof s.params.skillId=="string"?s.params.skillId:"",i=typeof s.params.repairActionId=="string"?s.params.repairActionId:"";if(!t||!i){e.client.sendRes({type:"res",id:s.id,ok:!1,error:"skillId and repairActionId are required"});return}if(!n(t)){e.client.sendRes({type:"res",id:s.id,ok:!1,error:`Skill not installed: ${t}`});return}try{const l=await m(t,i);p(t,{setupStatus:l.status,doctorResults:l.doctorResults}),e.client.sendRes({type:"res",id:s.id,ok:l.status==="ready",payload:{skill:n(t),...l},error:l.status==="ready"?void 0:l.message})}catch(l){e.client.sendRes({type:"res",id:s.id,ok:!1,error:l instanceof Error?l.message:String(l)})}}async function A(e,s){const t=typeof s.params.skillId=="string"?s.params.skillId:"",i=typeof s.params.workDir=="string"?s.params.workDir:process.cwd(),l=Array.isArray(s.params.attachments)?s.params.attachments.map(r=>{const a=r,o=typeof a.path=="string"?a.path:"",d=typeof a.name=="string"?a.name:"",c=typeof a.mimeType=="string"?a.mimeType:"";return o&&d?{path:o,name:d,mimeType:c}:null}).filter(r=>r!=null):void 0;if(!t){e.client.sendRes({type:"res",id:s.id,ok:!1,error:"skillId is required"});return}e.client.sendRes({type:"res",id:s.id,ok:!0,payload:{prompt:k(t,i,l)}})}export{w as handleSkillDoctor,h as handleSkillInstall,g as handleSkillList,U as handleSkillSetup,A as handleSkillUse};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { ReqFrame } from '@shennian/wire';
|
|
2
|
-
import { type HelperRuntimeInstallResult, type HelperRuntimeStatusResult } from '../../commands/runtime.js';
|
|
3
|
-
import { type WeChatChannelRuntimePreflightInput } from '../../channels/wechat-channel/client.js';
|
|
4
|
-
import type { SessionManagerRuntime } from '../types.js';
|
|
5
|
-
type HelperRuntimeAction = 'status' | 'install' | 'upgrade' | 'repair';
|
|
6
|
-
type HelperRuntimeActionResult = {
|
|
7
|
-
action: HelperRuntimeAction;
|
|
8
|
-
status: HelperRuntimeStatusResult;
|
|
9
|
-
install?: HelperRuntimeInstallResult;
|
|
10
|
-
permissions?: HelperRuntimePermissionSnapshot;
|
|
11
|
-
projection?: {
|
|
12
|
-
ok: boolean;
|
|
13
|
-
error?: string;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
type HelperRuntimePermissionSnapshot = NonNullable<WeChatChannelRuntimePreflightInput> & {
|
|
17
|
-
platform?: string;
|
|
18
|
-
wechatWindowAvailable?: boolean;
|
|
19
|
-
helperVersion?: string | null;
|
|
20
|
-
protocolVersion?: number | null;
|
|
21
|
-
};
|
|
22
|
-
export declare function handleWeChatHelperRuntime(runtime: SessionManagerRuntime, req: ReqFrame): Promise<void>;
|
|
23
|
-
export declare function runHelperRuntimeAction(input: {
|
|
24
|
-
action: HelperRuntimeAction;
|
|
25
|
-
platform?: string;
|
|
26
|
-
source?: string;
|
|
27
|
-
channel?: string;
|
|
28
|
-
manifestUrl?: string;
|
|
29
|
-
probePermissions?: boolean;
|
|
30
|
-
env?: NodeJS.ProcessEnv;
|
|
31
|
-
homedir?: string;
|
|
32
|
-
}): Promise<HelperRuntimeActionResult>;
|
|
33
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{loadConfig as h}from"../../config/index.js";import{getHelperRuntimeStatus as f,installHelperRuntimeWithOfficialDownload as u}from"../../commands/runtime.js";import{createWeChatChannelApiClient as w}from"../../channels/wechat-channel/client.js";import{WECHAT_CHANNEL_HELPER_VERSION as g}from"../../channels/wechat-channel/helper-assets.js";import{WeChatChannelHelperClient as y}from"../../channels/wechat-channel/helper-client.js";import{requiredWeChatChannelHelperCapabilitiesForProfile as R}from"../../channels/wechat-channel/helper-protocol.js";import{createWeChatChannelRuntime as V}from"../../channels/wechat-channel/runtime.js";import{getCurrentVersion as b}from"../../upgrade/engine.js";async function I(e,o){const r=o.params??{},t=k(r.action);if(!t){e.client.sendRes({type:"res",id:o.id,ok:!1,error:'action must be "status", "install", "upgrade", or "repair"'});return}const n=typeof r.platform=="string"?r.platform:void 0,i=typeof r.source=="string"&&r.source.trim()?r.source:void 0,a=typeof r.channel=="string"&&r.channel.trim()?r.channel:void 0,c=typeof r.manifestUrl=="string"&&r.manifestUrl.trim()?r.manifestUrl:void 0,d=await C({action:t,platform:n,source:i,channel:a,manifestUrl:c});e.client.sendRes({type:"res",id:o.id,ok:!0,payload:d})}async function C(e){if(e.action==="status"){const i=f({platform:e.platform,env:e.env,homedir:e.homedir}),a=e.probePermissions===!1?void 0:await m(i),c=await p(i,a);return{action:e.action,status:i,permissions:a,projection:c}}const o=await u({source:e.source,platform:e.platform,env:e.env,homedir:e.homedir,force:e.action==="upgrade"||e.action==="repair",preferOfficialDownload:(e.action==="upgrade"||e.action==="repair")&&!e.source,officialDownload:{channel:e.channel,manifestUrl:e.manifestUrl}}),r=f({platform:e.platform,env:e.env,homedir:e.homedir}),t=e.probePermissions===!1?void 0:await m(r),n=await p(r,t);return{action:e.action,install:o,status:r,permissions:t,projection:n}}function k(e){return e==="status"||e==="install"||e==="upgrade"||e==="repair"?e:null}async function m(e){const o=new Date().toISOString();if(!e.ok||!e.helperPath)return{checkedAt:o,helperReady:!1,helperVersion:e.helperVersion??null,protocolVersion:e.protocolVersion??null,platform:e.platform};const r=new y({helperPath:e.helperPath,expectedHelperVersion:e.helperVersion||g,requiredCapabilities:R("send")});try{await r.start();const t=await r.request("permissions.check",{},`helper-runtime-status-${Date.now()}`),n=t.ok&&t.result&&typeof t.result=="object"?t.result:{};return{checkedAt:o,helperReady:t.ok,helperVersion:e.helperVersion??H(n.helperVersion),protocolVersion:e.protocolVersion??A(n.protocolVersion),platform:e.platform,screenRecording:l(n.screenRecording),accessibility:l(n.accessibility),inputMonitoring:l(n.inputMonitoring),automation:l(n.automation),wechatRunning:s(n.wechatRunning),wechatAppDetected:s(n.wechatAppDetected??n.wechatRunning),wechatWindowAvailable:s(n.wechatWindowAvailable)}}catch{return{checkedAt:o,helperReady:!1,helperVersion:e.helperVersion??null,protocolVersion:e.protocolVersion??null,platform:e.platform}}finally{await r.stop().catch(()=>{})}}async function p(e,o){if(!o||e.platform!=="darwin"&&e.platform!=="win32")return;const r=h(),t=r.machineId?.trim(),n=r.machineToken?.trim();if(!t||!n)return{ok:!1,error:"machine_not_paired"};try{const i=V({runtimeId:`wechat-machine:${t}`,machineId:t,platform:e.platform,bindings:[]});return await w({serverUrl:r.serverUrl,machineToken:n}).upsertRuntime(i,void 0,{helperVersion:e.helperVersion??void 0,clientRuntimeVersion:b(),preflight:o}),{ok:!0}}catch(i){return{ok:!1,error:i instanceof Error?i.message:String(i)}}}function l(e){return typeof e=="boolean"?e:"unknown"}function s(e){return typeof e=="boolean"?e:void 0}function H(e){return(typeof e=="string"?e.trim():"")||null}function A(e){const o=Number(e);return Number.isFinite(o)?o:null}export{I as handleWeChatHelperRuntime,C as runHelperRuntimeAction};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { InstalledShennianSkill, SkillDoctorResult, SkillSetupStatus } from '@shennian/wire';
|
|
2
|
-
export declare function getSkillsDir(): string;
|
|
3
|
-
export declare function getSkillDir(skillId: string): string;
|
|
4
|
-
export declare function listInstalledSkills(): InstalledShennianSkill[];
|
|
5
|
-
export declare function getInstalledSkill(skillId: string): InstalledShennianSkill | null;
|
|
6
|
-
export declare function updateInstalledSkillSetup(skillId: string, update: {
|
|
7
|
-
setupStatus?: SkillSetupStatus;
|
|
8
|
-
doctorResults?: SkillDoctorResult[];
|
|
9
|
-
}): void;
|
|
10
|
-
export declare function installSkillFromUrl(installUrl: string): Promise<InstalledShennianSkill>;
|
|
11
|
-
export declare function buildSkillUsePrompt(skillId: string, workDir: string, attachments?: Array<{
|
|
12
|
-
path: string;
|
|
13
|
-
name: string;
|
|
14
|
-
mimeType: string;
|
|
15
|
-
}>): string;
|
|
16
|
-
export declare function buildInstalledSkillInstructions(): string;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import o from"node:fs";import s from"node:path";import{resolveShennianPath as p}from"../config/index.js";import{runSkillDoctor as S,summarizeSetupStatus as h}from"./setup.js";function k(n){const t=n.trim();if(!/^[a-z0-9][a-z0-9._-]{1,80}$/i.test(t))throw new Error("Invalid skill id");return t}function w(n){const t=n.replace(/\\/g,"/");if(!t||t.startsWith("/")||t.includes("\0"))throw new Error(`Unsafe bundle path: ${n}`);if(t.split("/").some(i=>!i||i==="."||i===".."))throw new Error(`Unsafe bundle path: ${n}`);return t}function a(n){try{return JSON.parse(o.readFileSync(n,"utf8"))}catch{return null}}function c(){const n=p("skills");return o.mkdirSync(n,{recursive:!0}),n}function d(n){return s.join(c(),k(n))}function f(){const n=c();return o.readdirSync(n,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>{const e=s.join(n,t.name),i=a(s.join(e,"skill.json")),r=a(s.join(e,".shennian-install.json"));if(!i?.id||!i.name)return null;const l={...i,installedAt:r?.installedAt??new Date(0).toISOString(),path:e};return r?.setupStatus&&(l.setupStatus=r.setupStatus),r?.doctorResults&&(l.doctorResults=r.doctorResults),l}).filter(t=>t!=null).sort((t,e)=>t.name.localeCompare(e.name))}function m(n){return f().find(t=>t.id===n)??null}function x(n,t){const e=d(n),i=s.join(e,".shennian-install.json"),r=a(i)??{};o.writeFileSync(i,JSON.stringify({...r,...t,updatedAt:new Date().toISOString()},null,2)+`
|
|
2
|
-
`,"utf8")}async function y(n){if(!n.startsWith("http://")&&!n.startsWith("https://"))return a(s.resolve(n))??(()=>{throw new Error("Invalid skill bundle")})();const t=await fetch(n);if(!t.ok)throw new Error(`Skill download failed: ${t.status} ${t.statusText}`);return await t.json()}function j(n,t){const e=w(t.path),i=s.join(n,e);o.mkdirSync(s.dirname(i),{recursive:!0}),o.writeFileSync(i,t.content,"utf8"),t.executable&&process.platform!=="win32"&&o.chmodSync(i,493)}async function D(n){const t=await y(n);if(!t?.manifest?.id||!Array.isArray(t.files))throw new Error("Invalid skill bundle");const e=d(t.manifest.id);o.rmSync(e,{recursive:!0,force:!0}),o.mkdirSync(e,{recursive:!0}),o.writeFileSync(s.join(e,"skill.json"),JSON.stringify(t.manifest,null,2)+`
|
|
3
|
-
`,"utf8");for(const u of t.files)j(e,u);const i=t.manifest.setup?.doctors?.length?(await Promise.all(t.manifest.setup.doctors.map(u=>S(t.manifest.id,u)))).flat():[],r=h(i);o.writeFileSync(s.join(e,".shennian-install.json"),JSON.stringify({installedAt:new Date().toISOString(),installUrl:n,setupStatus:r,doctorResults:i},null,2)+`
|
|
4
|
-
`,"utf8");const l=m(t.manifest.id);if(!l)throw new Error("Skill installation did not complete");return l}function F(n,t,e){const i=m(n);if(!i)throw new Error(`Skill not installed: ${n}`);const r=(e??[]).map(l=>`- ${l.name} (${l.mimeType}): ${l.path}`).join(`
|
|
5
|
-
`);return[`Use the Shennian skill "${i.name}".`,"",`Skill folder: ${i.path}`,`Before using it, read: ${s.join(i.path,"SKILL.md")}`,`Working directory: ${t}`,r?`
|
|
6
|
-
Current attachments:
|
|
7
|
-
${r}`:"","","Follow the skill output contract. Prefer local deterministic extraction first, then use agent document or vision capability only when needed."].filter(Boolean).join(`
|
|
8
|
-
`)}function v(){const n=f();if(n.length===0)return"";const t=n.map(e=>[`- ${e.id}: ${e.description}`,` Skill folder: ${e.path}`,` Read ${s.join(e.path,"SKILL.md")} before using this skill.`].join(`
|
|
9
|
-
`));return`## Shennian Skills
|
|
10
|
-
|
|
11
|
-
Installed skills are file-based capabilities managed by Shennian under ${c()}.
|
|
12
|
-
When a user asks to use one, read its SKILL.md and follow its output contract.
|
|
13
|
-
|
|
14
|
-
${t.join(`
|
|
15
|
-
`)}`}export{v as buildInstalledSkillInstructions,F as buildSkillUsePrompt,m as getInstalledSkill,d as getSkillDir,c as getSkillsDir,D as installSkillFromUrl,f as listInstalledSkills,x as updateInstalledSkillSetup};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { SkillDoctorResult, SkillRepairAction, SkillSetupStatus } from '@shennian/wire';
|
|
2
|
-
export declare const MARKDOWN_PDF_REPAIR_ACTION: SkillRepairAction;
|
|
3
|
-
export declare function markdownPdfRepairActions(): SkillRepairAction[];
|
|
4
|
-
export declare function runMarkdownPdfBrowserDoctor(): Promise<SkillDoctorResult>;
|
|
5
|
-
export declare function runSkillDoctor(skillId: string, doctorId?: string): Promise<SkillDoctorResult[]>;
|
|
6
|
-
export declare function runSkillSetup(skillId: string, repairActionId: string): Promise<{
|
|
7
|
-
status: SkillSetupStatus;
|
|
8
|
-
doctorResults: SkillDoctorResult[];
|
|
9
|
-
message: string;
|
|
10
|
-
}>;
|
|
11
|
-
export declare function summarizeSetupStatus(doctorResults: SkillDoctorResult[]): SkillSetupStatus | undefined;
|
package/dist/src/skills/setup.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{findChromiumExecutable as d,installManagedChromium as c,MARKDOWN_PDF_BROWSER_DOCTOR_ID as s,MARKDOWN_PDF_MANAGED_CHROMIUM_ACTION_ID as t,MARKDOWN_PDF_SKILL_ID as n,managedChromiumBrowsersPath as l}from"../tools/markdown-to-pdf.js";const m={id:t,label:"Install PDF export component",description:"Download a Shennian-managed Chromium browser into ~/.shennian/browsers without using sudo.",requiresNetwork:!0,requiresSudo:!1,downloadSizeMb:180};function D(){return[m]}function i(e){return{skillId:n,doctorId:s,status:e.status,issues:e.issues,checkedAt:e.checkedAt??new Date().toISOString(),recommendedRepairActionId:t,repairActions:D()}}async function _(){try{const e=await d();return i({status:"ready",issues:[{code:"MARKDOWN_PDF_BROWSER_READY",severity:"info",message:`PDF export browser is ready: ${e}`}]})}catch{return i({status:"needs_setup",issues:[{code:"MARKDOWN_PDF_BROWSER_MISSING",severity:"error",message:"This machine needs a headless browser before Markdown files can be exported to PDF.",repairActionId:t}]})}}async function p(e,r){return e===n&&(!r||r===s)?[await _()]:[{skillId:e,doctorId:r||"unknown",status:"ready",issues:[{code:"SKILL_DOCTOR_NOT_REQUIRED",severity:"info",message:"This skill does not declare a local environment doctor."}],checkedAt:new Date().toISOString()}]}async function w(e,r){if(e!==n||r!==t)throw new Error("Unsupported skill repair action");await c();const o=await p(e,s),a=o.every(u=>u.status==="ready")?"ready":"setup_failed";return{status:a,doctorResults:o,message:a==="ready"?`PDF export component installed in ${l()}`:"PDF export component was installed, but the browser is still not ready. The system may need additional Linux libraries."}}function h(e){if(e.length!==0)return e.every(r=>r.status==="ready")?"ready":e.some(r=>r.status==="blocked")?"blocked":e.some(r=>r.status==="setup_failed")?"setup_failed":"needs_setup"}export{m as MARKDOWN_PDF_REPAIR_ACTION,D as markdownPdfRepairActions,_ as runMarkdownPdfBrowserDoctor,p as runSkillDoctor,w as runSkillSetup,h as summarizeSetupStatus};
|