@windsland52/maafw-live 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -2
  3. package/bin/maafw-live.mjs +25 -0
  4. package/docs/daemon-protocol.md +116 -0
  5. package/docs/keyframe-evidence-contract-v0.md +61 -0
  6. package/docs/keyframe-retention-contract-v0.md +236 -0
  7. package/lib/client/daemon.js +234 -0
  8. package/lib/client/daemon.js.map +1 -0
  9. package/lib/commands/annotate.js +172 -0
  10. package/lib/commands/annotate.js.map +1 -0
  11. package/lib/commands/calibrate.js +61 -0
  12. package/lib/commands/calibrate.js.map +1 -0
  13. package/lib/commands/color.js +73 -0
  14. package/lib/commands/color.js.map +1 -0
  15. package/lib/commands/crop.js +228 -0
  16. package/lib/commands/crop.js.map +1 -0
  17. package/lib/commands/env.js +215 -0
  18. package/lib/commands/env.js.map +1 -0
  19. package/lib/commands/index.js +64 -0
  20. package/lib/commands/index.js.map +1 -0
  21. package/lib/commands/input.js +219 -0
  22. package/lib/commands/input.js.map +1 -0
  23. package/lib/commands/kf.js +131 -0
  24. package/lib/commands/kf.js.map +1 -0
  25. package/lib/commands/reco.js +211 -0
  26. package/lib/commands/reco.js.map +1 -0
  27. package/lib/commands/repl.js +698 -0
  28. package/lib/commands/repl.js.map +1 -0
  29. package/lib/commands/runtime.js +514 -0
  30. package/lib/commands/runtime.js.map +1 -0
  31. package/lib/commands/skill.js +169 -0
  32. package/lib/commands/skill.js.map +1 -0
  33. package/lib/commands/timing.js +229 -0
  34. package/lib/commands/timing.js.map +1 -0
  35. package/lib/commands/version.js +66 -0
  36. package/lib/commands/version.js.map +1 -0
  37. package/lib/daemon/framed.mjs +2850 -0
  38. package/lib/daemon/reco_child.mjs +146 -0
  39. package/lib/exec.js +96 -0
  40. package/lib/exec.js.map +1 -0
  41. package/lib/flags.js +42 -0
  42. package/lib/flags.js.map +1 -0
  43. package/lib/image.js +90 -0
  44. package/lib/image.js.map +1 -0
  45. package/lib/index.js +139 -0
  46. package/lib/index.js.map +1 -0
  47. package/lib/interface/index.js +12 -0
  48. package/lib/interface/index.js.map +1 -0
  49. package/lib/interface/jsonc.js +95 -0
  50. package/lib/interface/jsonc.js.map +1 -0
  51. package/lib/interface/load.js +307 -0
  52. package/lib/interface/load.js.map +1 -0
  53. package/lib/interface/override.js +103 -0
  54. package/lib/interface/override.js.map +1 -0
  55. package/lib/interface/plan.js +188 -0
  56. package/lib/interface/plan.js.map +1 -0
  57. package/lib/pkg.js +18 -0
  58. package/lib/pkg.js.map +1 -0
  59. package/lib/protocol.js +90 -0
  60. package/lib/protocol.js.map +1 -0
  61. package/lib/runtime/actions.js +110 -0
  62. package/lib/runtime/actions.js.map +1 -0
  63. package/lib/runtime/keyframes.js +73 -0
  64. package/lib/runtime/keyframes.js.map +1 -0
  65. package/lib/runtime/session.js +86 -0
  66. package/lib/runtime/session.js.map +1 -0
  67. package/lib/types/client/daemon.d.ts +86 -0
  68. package/lib/types/commands/annotate.d.ts +3 -0
  69. package/lib/types/commands/calibrate.d.ts +7 -0
  70. package/lib/types/commands/color.d.ts +9 -0
  71. package/lib/types/commands/crop.d.ts +3 -0
  72. package/lib/types/commands/env.d.ts +2 -0
  73. package/lib/types/commands/index.d.ts +13 -0
  74. package/lib/types/commands/input.d.ts +17 -0
  75. package/lib/types/commands/kf.d.ts +10 -0
  76. package/lib/types/commands/reco.d.ts +23 -0
  77. package/lib/types/commands/repl.d.ts +2 -0
  78. package/lib/types/commands/runtime.d.ts +48 -0
  79. package/lib/types/commands/skill.d.ts +17 -0
  80. package/lib/types/commands/timing.d.ts +64 -0
  81. package/lib/types/commands/version.d.ts +3 -0
  82. package/lib/types/exec.d.ts +31 -0
  83. package/lib/types/flags.d.ts +58 -0
  84. package/lib/types/image.d.ts +27 -0
  85. package/lib/types/index.d.ts +1 -0
  86. package/lib/types/interface/index.d.ts +11 -0
  87. package/lib/types/interface/jsonc.d.ts +9 -0
  88. package/lib/types/interface/load.d.ts +113 -0
  89. package/lib/types/interface/override.d.ts +33 -0
  90. package/lib/types/interface/plan.d.ts +47 -0
  91. package/lib/types/pkg.d.ts +6 -0
  92. package/lib/types/protocol.d.ts +108 -0
  93. package/lib/types/runtime/actions.d.ts +166 -0
  94. package/lib/types/runtime/keyframes.d.ts +43 -0
  95. package/lib/types/runtime/session.d.ts +53 -0
  96. package/lib/types/update-check.d.ts +20 -0
  97. package/lib/types/usage.d.ts +3 -0
  98. package/lib/update-check.js +97 -0
  99. package/lib/update-check.js.map +1 -0
  100. package/lib/usage.js +50 -0
  101. package/lib/usage.js.map +1 -0
  102. package/package.json +81 -4
  103. package/skills/README.md +51 -0
  104. package/skills/maafw-live/SKILL.md +263 -0
  105. package/skills/maafw-live/references/examples.md +238 -0
  106. package/skills/maafw-live/references/pitfalls.md +118 -0
  107. package/skills/maafw-live/references/workflows.md +159 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * annotate(轻量 SoM):候选区域 + 编号回画。
3
+ *
4
+ * 模型消费方式:看回画图选编号 → 查候选表 ctrl 坐标 → click / reco / crop。
5
+ * 候选源:OCR 框(语义最强)、变化 diff 区域、连通域、边缘密度;半透明/粒子/渐变场景
6
+ * 候选质量降级——那时走点选路径(crop --point),两条路径互为降级。
7
+ *
8
+ * 源帧两条路:会话内 L1 小图(缺省,一次性命令自动截一帧)或**关键帧库留存帧**(`--from-kf`,
9
+ * 控制器分辨率、离线、不需要设备)。库帧路径下 diff 源不可用(没有会话事件),工具如实报出,
10
+ * 不拿别的区域顶替——所以它适合"事后在旧帧上重跑候选",不适合替代实时变化检测。
11
+ */
12
+ import { defaultFramesDir, resolveFrame } from '../runtime/keyframes.js';
13
+ import { EXIT, fail } from '../protocol.js';
14
+ import { annotate, seedObservation, withDaemon } from '../runtime/actions.js';
15
+ import { describeSession, ensureSession, offlineResource } from '../runtime/session.js';
16
+ import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
17
+ export const annotateCommand = {
18
+ name: 'annotate',
19
+ summary: '轻量 SoM:OCR/diff/连通域/边缘密度候选区域 + 编号回画(源可为会话内帧或关键帧库留存帧)',
20
+ usage: 'maafw-live annotate [--seq n] [--out <png>] [--resource-dir <dir>] [--project <dir>|--kind ...]\n' +
21
+ ' maafw-live annotate --from-kf <kf:库UUID:序号> [--frames-dir <dir>] [--out <png>] [--resource-dir <dir>|--project <dir>]\n' +
22
+ ' OCR 候选需要资源目录(OCR 模型);一次性命令自动截一帧;其余候选源无依赖\n' +
23
+ ' --from-kf 在库里留存帧上离线跑(不需要设备;该路径没有会话事件,diff 源不可用)\n' +
24
+ ' --som-limit n 放开候选上限(缺省 30;网格/表格类界面必给)\n' +
25
+ ' --som-max-area-ratio r 巨框剔除阈值(缺省 0.12,按画面面积比;OCR 框不参与)\n' +
26
+ ' 回画优先落在 L0 全分辨率原图上;回执带 availability(截断/剔除/分带),别把"30 条"读成"画面就这些"',
27
+ options: {
28
+ ...CONNECT_OPTIONS,
29
+ seq: { type: 'string' },
30
+ out: { type: 'string' },
31
+ 'resource-dir': { type: 'string' },
32
+ 'from-kf': { type: 'string' },
33
+ 'frames-dir': { type: 'string' },
34
+ 'som-limit': { type: 'string' },
35
+ 'som-max-area-ratio': { type: 'string' },
36
+ roi: { type: 'string' },
37
+ },
38
+ async run(ctx) {
39
+ const o = sessionOptions(ctx.values);
40
+ const seq = typeof ctx.values.seq === 'string' ? Number(ctx.values.seq) : undefined;
41
+ if (ctx.values.seq !== undefined && !Number.isFinite(seq)) {
42
+ return fail('BAD_ARGUMENTS', '--seq 必须是数字', undefined, EXIT.USAGE);
43
+ }
44
+ const out = typeof ctx.values.out === 'string' ? ctx.values.out : undefined;
45
+ const roi = typeof ctx.values.roi === 'string'
46
+ ? ctx.values.roi.split(',').map((x) => Number(String(x).trim()))
47
+ : undefined;
48
+ if (roi && (roi.length !== 4 || roi.some((n) => !Number.isFinite(n)))) {
49
+ return fail('BAD_ARGUMENTS', '--roi 需要 4 个数字:x,y,w,h(控制器分辨率坐标)', undefined, EXIT.USAGE);
50
+ }
51
+ /* 上限/阈值必须**显式拒绝**非法值,不能靠 daemon 的 `> 0` 守卫悄悄换回默认——
52
+ * `--som-limit 0` 被静默当成 30 时,调用方以为"不限量",拿到的是截断表。 */
53
+ const somLimitRaw = ctx.values['som-limit'];
54
+ const somLimit = typeof somLimitRaw === 'string' ? Number(somLimitRaw) : undefined;
55
+ if (somLimitRaw !== undefined && (!Number.isFinite(somLimit) || somLimit <= 0)) {
56
+ return fail('BAD_ARGUMENTS', '--som-limit 必须是正整数(收到 ' + JSON.stringify(somLimitRaw) + ')'
57
+ + ';0 不等于"不限量"', undefined, EXIT.USAGE);
58
+ }
59
+ const ratioRaw = ctx.values['som-max-area-ratio'];
60
+ const ratio = typeof ratioRaw === 'string' ? Number(ratioRaw) : undefined;
61
+ if (ratioRaw !== undefined && (!Number.isFinite(ratio) || ratio <= 0 || ratio >= 1)) {
62
+ return fail('BAD_ARGUMENTS', '--som-max-area-ratio 要在 (0,1) 之间(画面面积比,收到 ' + JSON.stringify(ratioRaw) + ')'
63
+ + ';0 不等于"关闭剔除"', undefined, EXIT.USAGE);
64
+ }
65
+ const fromKf = typeof ctx.values['from-kf'] === 'string' ? ctx.values['from-kf'] : undefined;
66
+ if (fromKf !== undefined && seq !== undefined) {
67
+ return fail('BAD_ARGUMENTS', '--from-kf 与 --seq 互斥:前者在库内留存帧上跑,后者在本会话缓冲帧上跑', '取库里有哪些帧:maafw-live kf list', EXIT.USAGE);
68
+ }
69
+ /* 库帧来源:先走离线读侧解析(契约 §4.1),daemon 只接身份与路径 */
70
+ let kfSource;
71
+ if (fromKf !== undefined) {
72
+ const dir = typeof ctx.values['frames-dir'] === 'string' ? ctx.values['frames-dir'] : defaultFramesDir();
73
+ const r = resolveFrame(dir, fromKf);
74
+ if (r.status !== 'available' || !r.path || !r.record) {
75
+ const code = r.status === 'corrupt' ? 'KF_CORRUPT' : (r.status === 'unsupported' ? 'KF_UNSUPPORTED' : 'KF_MISSING');
76
+ return fail(code, '库帧不可用(' + r.status + '):' + String(r.reason ?? '') + '(库 ' + dir + ')', 'kf list 看库内有哪些帧;missing 表示本机不可复核,不代表历史从未观测', EXIT.FINDINGS);
77
+ }
78
+ const rec = r.record;
79
+ kfSource = {
80
+ id: rec.id, path: r.path, sha256: rec.sha256, ctrlW: rec.ctrlW, ctrlH: rec.ctrlH,
81
+ captureSeq: rec.captureSeq, capturedAt: rec.capturedAt,
82
+ };
83
+ }
84
+ const offline = kfSource !== undefined;
85
+ try {
86
+ return await withDaemon(async (client) => {
87
+ const s = offline ? { connected: false } : await ensureSession(client, o);
88
+ let resourceDir = (typeof ctx.values['resource-dir'] === 'string' ? ctx.values['resource-dir'] : undefined)
89
+ ?? s.plan?.resource?.paths[0];
90
+ if (!resourceDir && offline && o.project) {
91
+ /* 离线:项目只作资源的来源(OCR 模型),不扫设备不连接 */
92
+ const off = offlineResource(o.project, o.controller, o.resource);
93
+ if (off.error) {
94
+ return fail('PLAN_FAILED', '离线解析项目资源失败:' + off.error, '也可以直接给 --resource-dir <dir>', EXIT.FINDINGS);
95
+ }
96
+ resourceDir = off.paths[0];
97
+ }
98
+ /* 一次性命令缓冲为空:先截一帧(用完即删,不留临时文件)。库帧路径不截帧——源已固定。 */
99
+ if (!offline && seq === undefined) {
100
+ await seedObservation(client, 'annotate');
101
+ }
102
+ const r = await annotate(client, {
103
+ ...(offline ? { kfSource } : {}),
104
+ ...(!offline && seq !== undefined ? { seq } : {}),
105
+ ...(out ? { out } : {}),
106
+ ...(resourceDir ? { resourceDir } : {}),
107
+ ...(roi ? { roi } : {}),
108
+ ...(somLimit !== undefined ? { somLimit } : {}),
109
+ ...(ratio !== undefined ? { somMaxAreaRatio: ratio } : {}),
110
+ });
111
+ if (r.ok === false) {
112
+ return fail('ANNOTATE', String(r.error ?? '候选生成失败'), offline
113
+ ? '库帧候选失败通常是文件被改动或库记录不一致;kf resolve 可复核'
114
+ : '需要观测:REPL 里先 screencap / stream start;一次性命令会自动截一帧', EXIT.FINDINGS);
115
+ }
116
+ const cands = r.candidates ?? [];
117
+ const sources = r.sources;
118
+ const src = r.source;
119
+ const unavailable = r.sourcesUnavailable;
120
+ const ctrl = Array.isArray(r.ctrl) ? r.ctrl : null;
121
+ const avail = r.availability;
122
+ const srcLine = src?.kind === 'kf'
123
+ ? '源帧 ' + String(src.id) + '(留存帧,捕获 seq=' + String(src.captureSeq) + ',' +
124
+ String(ctrl?.[0] ?? '?') + 'x' + String(ctrl?.[1] ?? '?') + ',离线)'
125
+ : '源帧 seq=' + String(r.seq) + '(小图 ' + JSON.stringify(r.small) + ' × ctrl ' + JSON.stringify(r.ctrl) + ')';
126
+ /* 可用性三列:**"看起来有结果"不等于"有结果"**。截断/剔除/分带一起读,
127
+ * 才分得清"这一带没东西"与"这一带的东西被上限或门槛拿掉了"。 */
128
+ const availLines = avail
129
+ ? [
130
+ ' 可用性:合并池 ' + String(avail.mergedTotal ?? '?') + ' → 进表 ' + String(r.count)
131
+ + '(上限 ' + String(avail.limit ?? '?') + ',截断 ' + String(avail.truncated ?? 0) + ')'
132
+ + ';剔除 太小 ' + String(avail.dropped?.tooSmall ?? 0) + ' / 巨框 ' + String(avail.dropped?.tooBig ?? 0)
133
+ + '(阈值 ' + String(avail.maxAreaRatio ?? '?') + ')/ 重复 ' + String(avail.dropped?.duplicated ?? 0),
134
+ ...(avail.byBand ? [' 分带(上/中/下):' + avail.byBand.map((b) => String(b.inTable) + '/' + String(b.inPool)).join(' ')] : []),
135
+ ...(avail.outResolution ? [' 回画分辨率:' + String(avail.outResolution.w) + 'x' + String(avail.outResolution.h)
136
+ + '(' + String(avail.outResolution.source) + ')'] : []),
137
+ ...(avail.detectionResolution ? [' 检测面分辨率:' + String(avail.detectionResolution.w) + 'x'
138
+ + String(avail.detectionResolution.h) + '(' + String(avail.detectionResolution.source)
139
+ + ')——检测面越小,小目标越可能探不到'] : []),
140
+ ]
141
+ : [];
142
+ return {
143
+ exitCode: EXIT.OK,
144
+ human: [
145
+ ...describeSession(s),
146
+ ...(offline ? ['离线候选:未连接设备(库帧是本机持久文件)'] : []),
147
+ 'SoM 候选 ' + String(r.count) + ' 个(ocr ' + String(sources?.ocr ?? 0) + ' / diff ' + String(sources?.diff ?? 0) +
148
+ ' / conn ' + String(sources?.conn ?? 0) + ' / edge ' + String(sources?.edge ?? 0) + ')→ ' + String(r.out),
149
+ ' ' + srcLine,
150
+ ...availLines,
151
+ ...(unavailable ? Object.entries(unavailable).map(([k, v]) => ' ' + k + ' 源不可用:' + v) : []),
152
+ ' 坐标为控制器分辨率(面积占比供排序:越小越像小按钮,越大越像面板/背景):',
153
+ ...cands.map((c) => ' #' + c.id + ' [' + c.source + '] ctrl=' + c.ctrl.join(',')
154
+ + (typeof c.areaRatio === 'number' ? ' 面积比=' + c.areaRatio : '')
155
+ + (typeof c.score === 'number' ? ' score=' + c.score : '')
156
+ + (c.text ? ' "' + c.text + '"' : '')),
157
+ ...(r.warn ? [' 警告:' + String(r.warn)] : []),
158
+ '选号后:click / reco --node(roi 用 ctrl 坐标)/ crop --roi(可再 crop --from-kf 于同一帧)',
159
+ ],
160
+ data: r,
161
+ warnings: r.warn ? [String(r.warn)] : [],
162
+ written: [String(r.out)],
163
+ };
164
+ });
165
+ }
166
+ catch (e) {
167
+ return daemonFail(e);
168
+ }
169
+ },
170
+ };
171
+ export const ANNOTATE_COMMANDS = [annotateCommand];
172
+ //# sourceMappingURL=annotate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotate.js","sourceRoot":"","sources":["../../src/commands/annotate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * 变化检测阈值校准:静止画面采帧,统计分块亮度差 / 全局位差率的噪声分布,
3
+ * 推荐 blockThresh / changeGlobal。校准期间画面必须静止(max≫p99 会警告重跑)。
4
+ */
5
+ import { EXIT, fail } from '../protocol.js';
6
+ import { calibrate, withDaemon } from '../runtime/actions.js';
7
+ import { describeSession, ensureSession } from '../runtime/session.js';
8
+ import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
9
+ export const calibrateCommand = {
10
+ name: 'calibrate',
11
+ summary: '变化检测阈值校准:静止画面采帧定噪声地板,推荐 blockThresh / changeGlobal',
12
+ usage: 'maafw-live calibrate [--frames n] [--interval ms] --project <dir>|--kind ...\n' +
13
+ ' 采集期间保持画面静止;结果给出可直接粘贴的 stream start 参数',
14
+ options: { ...CONNECT_OPTIONS, frames: { type: 'string' }, interval: { type: 'string' } },
15
+ async run(ctx) {
16
+ const o = sessionOptions(ctx.values);
17
+ if (!o.project && !o.kind) {
18
+ return fail('BAD_ARGUMENTS', '校准要设备:给 --project <dir>(推荐)或 --kind win32|adb|gamepad', undefined, EXIT.USAGE);
19
+ }
20
+ const frames = typeof ctx.values.frames === 'string' ? Number(ctx.values.frames) : undefined;
21
+ if (frames !== undefined && !Number.isFinite(frames)) {
22
+ return fail('BAD_ARGUMENTS', '--frames 必须是数字(6..60,默认 24)', undefined, EXIT.USAGE);
23
+ }
24
+ const interval = typeof ctx.values.interval === 'string' ? Number(ctx.values.interval) : undefined;
25
+ if (interval !== undefined && !Number.isFinite(interval)) {
26
+ return fail('BAD_ARGUMENTS', '--interval 必须是毫秒数(默认 300)', undefined, EXIT.USAGE);
27
+ }
28
+ try {
29
+ return await withDaemon(async (client) => {
30
+ const s = await ensureSession(client, o);
31
+ const r = await calibrate(client, {
32
+ ...(frames !== undefined ? { frames } : {}),
33
+ ...(interval !== undefined ? { interval } : {}),
34
+ });
35
+ if (r.ok === false) {
36
+ return fail('CALIBRATE', String(r.error ?? '校准失败'), undefined, EXIT.FINDINGS);
37
+ }
38
+ const block = r.block;
39
+ const global = r.global;
40
+ return {
41
+ exitCode: r.warn ? EXIT.FINDINGS : EXIT.OK,
42
+ human: [
43
+ ...describeSession(s),
44
+ '校准 ' + String(r.frames) + ' 帧(分块亮度差 / 全局位差率的噪声分布):',
45
+ ' 分块差 p50=' + block.p50 + ' p99=' + block.p99 + ' max=' + block.max,
46
+ ' 位差率 p50=' + global.p50 + ' p99=' + global.p99 + ' max=' + global.max,
47
+ ' 推荐:' + String(r.apply),
48
+ ...(r.warn ? [' 警告:' + String(r.warn)] : []),
49
+ ],
50
+ data: r,
51
+ ...(r.warn ? { warnings: [String(r.warn)] } : {}),
52
+ };
53
+ });
54
+ }
55
+ catch (e) {
56
+ return daemonFail(e);
57
+ }
58
+ },
59
+ };
60
+ export const CALIBRATE_COMMANDS = [calibrateCommand];
61
+ //# sourceMappingURL=calibrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calibrate.js","sourceRoot":"","sources":["../../src/commands/calibrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 探色命令:ROI 实测主色/均值(RGB/HSV/灰度)——模型只选色不报色值。
3
+ *
4
+ * 为什么不靠模型读像素:色值必须来自实测(降采样小图按该帧捕获尺寸换算后的 ROI),
5
+ * 模型选完色后用 reco ColorMatch 出框(走已修好的参数透传链),出框与否是事实不是判断。
6
+ */
7
+ import { EXIT, fail } from '../protocol.js';
8
+ import { colorProbe, seedObservation, withDaemon } from '../runtime/actions.js';
9
+ import { describeSession, ensureSession } from '../runtime/session.js';
10
+ import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
11
+ export const colorCommand = {
12
+ name: 'color',
13
+ summary: '探色:ROI 实测均值/HSV/主色(控制器分辨率坐标;选中后用 reco ColorMatch 出框)',
14
+ usage: 'maafw-live color [--roi x,y,w,h] [--seq n] --project <dir>|--kind ...\n' +
15
+ ' 一次性命令先自动截一帧再测;REPL 里测缓冲最新帧(先 screencap / stream)',
16
+ options: { ...CONNECT_OPTIONS, roi: { type: 'string' }, seq: { type: 'string' } },
17
+ async run(ctx) {
18
+ const o = sessionOptions(ctx.values);
19
+ if (!o.project && !o.kind) {
20
+ return fail('BAD_ARGUMENTS', '要设备才能探色:给 --project <dir>(推荐)或 --kind win32|adb|gamepad', '多步操作用 maafw-live repl(连接一次后连续观测)', EXIT.USAGE);
21
+ }
22
+ const roi = typeof ctx.values.roi === 'string'
23
+ ? ctx.values.roi.split(',').map((x) => Number(String(x).trim()))
24
+ : undefined;
25
+ if (roi && (roi.length !== 4 || roi.some((n) => !Number.isFinite(n)))) {
26
+ return fail('BAD_ARGUMENTS', '--roi 需要 4 个数字:x,y,w,h(控制器分辨率坐标,与 pipeline 的 roi 同空间)', undefined, EXIT.USAGE);
27
+ }
28
+ const seq = typeof ctx.values.seq === 'string' ? Number(ctx.values.seq) : undefined;
29
+ if (ctx.values.seq !== undefined && !Number.isFinite(seq)) {
30
+ return fail('BAD_ARGUMENTS', '--seq 必须是数字', undefined, EXIT.USAGE);
31
+ }
32
+ try {
33
+ return await withDaemon(async (client) => {
34
+ const s = await ensureSession(client, o);
35
+ /* 一次性命令缓冲为空:先截一帧产生观测(screencap 现在进环,有捕获身份)。
36
+ * 截帧文件用完即删——它只是观测载体,既不落用户 cwd,也不留在临时目录。 */
37
+ if (seq === undefined) {
38
+ await seedObservation(client, 'color');
39
+ }
40
+ const r = await colorProbe(client, {
41
+ ...(seq !== undefined ? { seq } : {}),
42
+ ...(roi ? { roi } : {}),
43
+ });
44
+ if (r.ok === false) {
45
+ return fail('COLOR_PROBE', String(r.error ?? '探色失败'), 'REPL 里先 screencap 或 stream start;一次性命令会自动截一帧', EXIT.FINDINGS);
46
+ }
47
+ const mean = r.mean;
48
+ const hsv = r.hsv;
49
+ const dom = r.dominant;
50
+ return {
51
+ exitCode: EXIT.OK,
52
+ human: [
53
+ ...describeSession(s),
54
+ '探色 seq=' + String(r.seq) + (roi ? ' roi=' + roi.join(',') : ' (整帧)'),
55
+ ' 均值 RGB ' + mean.r + ',' + mean.g + ',' + mean.b + ' 灰度 ' + mean.gray +
56
+ ' HSV ' + hsv.h + '°,' + hsv.s + '%,' + hsv.v + '%',
57
+ ' 主色 RGB ' + dom.rgb.join(',') + '(覆盖 ' + Math.round(dom.ratio * 100) + '%)',
58
+ '出框验证:maafw-live reco --type ColorMatch --param \'{"color":[' + dom.rgb.join(',') + '],"threshold":0.05}\' …',
59
+ ],
60
+ data: r,
61
+ suggestedCommands: [
62
+ 'maafw-live reco --type ColorMatch --param \'{"color":[' + dom.rgb.join(',') + '],"threshold":0.05}\' --image <png> --resource-dir <dir>',
63
+ ],
64
+ };
65
+ });
66
+ }
67
+ catch (e) {
68
+ return daemonFail(e);
69
+ }
70
+ },
71
+ };
72
+ export const COLOR_COMMANDS = [colorCommand];
73
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/commands/color.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * 模板裁剪:低精度输入(宽松框或点+外扩)→ snap 收紧 → 从源帧原图裁剪 →
3
+ * 同帧自匹配逐边重试取得分最高边界。
4
+ *
5
+ * 关键约束:模板尺寸必须与识别空间一致——只从控制器分辨率的完整原图裁,
6
+ * 不从降采样小图裁。点→ROI 派生与裁剪共享同一条 snap 链(roadmap 条目4/5)。
7
+ *
8
+ * 源帧两条路:
9
+ * - L0 热缓存(缺省):进程态,seq 或最新;跨帧验证缺省开(新帧再匹配一次)。
10
+ * - 关键帧库留存帧(--from-kf):库内 L0 文件,跨会话可用、**不需要设备**——
11
+ * 不可复现状态的动线正是这条(捕获它的那次会话早已结束)。跨帧验证缺省关:
12
+ * 留存帧对应的状态通常已不在画面上,拿当前帧比只会得到假警告。
13
+ *
14
+ * 裁出的 PNG 是 L2 派生图(契约 §2),旁边写 `<out>.prov.json` 出处记录
15
+ * (契约 §5:L2 记录来源及裁剪 / 缩放变换)——出处与模板同生共死,可一起提交进仓库。
16
+ */
17
+ import { defaultFramesDir, resolveFrame } from '../runtime/keyframes.js';
18
+ import { EXIT, fail } from '../protocol.js';
19
+ import { seedObservation, tplCrop, withDaemon } from '../runtime/actions.js';
20
+ import { describeSession, ensureSession, offlineResource } from '../runtime/session.js';
21
+ import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
22
+ function nums(raw, count, what) {
23
+ if (raw === undefined)
24
+ return undefined;
25
+ const v = raw.split(',').map((x) => Number(String(x).trim()));
26
+ if (v.length !== count || v.some((n) => !Number.isFinite(n))) {
27
+ throw new Error(what + ' 需要 ' + count + ' 个数字');
28
+ }
29
+ return v;
30
+ }
31
+ /** 库里解析出来的帧 → daemon 的裁剪源(身份与路径;daemon 会复核 sha256 与像素尺寸)。 */
32
+ function kfSourceOf(r) {
33
+ const rec = r.record;
34
+ return {
35
+ id: rec.id,
36
+ path: String(r.path),
37
+ sha256: rec.sha256,
38
+ ctrlW: rec.ctrlW,
39
+ ctrlH: rec.ctrlH,
40
+ captureSeq: rec.captureSeq,
41
+ capturedAt: rec.capturedAt,
42
+ };
43
+ }
44
+ export const cropCommand = {
45
+ name: 'crop',
46
+ summary: '模板裁剪:宽松框/点 → snap 收紧 → 原图裁剪 → 自匹配验证(源可为 L0 热缓存或关键帧库留存帧)',
47
+ usage: 'maafw-live crop --roi x,y,w,h | --point x,y [--pad n] [--seq n] [--out <png>] [--no-cross] --project <dir>|--kind ...\n' +
48
+ ' maafw-live crop --from-kf <kf:库UUID:序号> --roi x,y,w,h [--frames-dir <dir>] [--resource-dir <dir> | --project <dir>] [--cross]\n' +
49
+ ' 源帧缺省是 L0 最新原图(screencap/stream/输入都会产生);连接真机时自动做跨帧验证(新帧再匹配一次)\n' +
50
+ ' --from-kf 改从关键帧库留存帧裁:离线可用(不需要设备),跨帧验证缺省关(留存帧对应的状态通常已不在画面上)\n' +
51
+ ' 裁出的 PNG 是 L2 派生图,旁边写 <out>.prov.json 出处记录(来源 + 裁剪变换;--no-prov 可关)\n' +
52
+ ' --keep-source 顺手把本次裁剪用的那一帧升格进关键帧库,出处随即带上可复核的 kf: 身份\n' +
53
+ ' (契约的模型是 L0 缓存 → 选择性升格 → 从库帧裁;少了这步,出处只剩一个随进程消失的 seq)\n' +
54
+ ' --prov-out <dir> 把出处写到该目录下(同名),用于模板要进资源包、而资源包只装框架要加载的东西:\n' +
55
+ ' 约定不变量是"同一相对路径"(如 state-plan/provenance/ 与 image/ 同构)',
56
+ options: {
57
+ ...CONNECT_OPTIONS,
58
+ roi: { type: 'string' },
59
+ point: { type: 'string' },
60
+ pad: { type: 'string' },
61
+ seq: { type: 'string' },
62
+ out: { type: 'string' },
63
+ 'resource-dir': { type: 'string' },
64
+ 'no-cross': { type: 'boolean' },
65
+ 'from-kf': { type: 'string' },
66
+ 'frames-dir': { type: 'string' },
67
+ cross: { type: 'boolean' },
68
+ 'no-prov': { type: 'boolean' },
69
+ 'prov-out': { type: 'string' },
70
+ 'keep-source': { type: 'boolean' },
71
+ },
72
+ async run(ctx) {
73
+ const o = sessionOptions(ctx.values);
74
+ let roi;
75
+ let point;
76
+ try {
77
+ roi = nums(typeof ctx.values.roi === 'string' ? ctx.values.roi : undefined, 4, '--roi');
78
+ point = nums(typeof ctx.values.point === 'string' ? ctx.values.point : undefined, 2, '--point');
79
+ }
80
+ catch (e) {
81
+ return fail('BAD_ARGUMENTS', e.message, undefined, EXIT.USAGE);
82
+ }
83
+ if (!roi && !point) {
84
+ return fail('BAD_ARGUMENTS', '给 --roi x,y,w,h(宽松框)或 --point x,y(自动外扩成宽松框)', undefined, EXIT.USAGE);
85
+ }
86
+ const seq = typeof ctx.values.seq === 'string' ? Number(ctx.values.seq) : undefined;
87
+ if (ctx.values.seq !== undefined && !Number.isFinite(seq)) {
88
+ return fail('BAD_ARGUMENTS', '--seq 必须是数字', undefined, EXIT.USAGE);
89
+ }
90
+ const pad = typeof ctx.values.pad === 'string' ? Number(ctx.values.pad) : undefined;
91
+ if (pad !== undefined && !Number.isFinite(pad)) {
92
+ return fail('BAD_ARGUMENTS', '--pad 必须是数字(点→ROI 外扩半径,默认 24)', undefined, EXIT.USAGE);
93
+ }
94
+ const out = typeof ctx.values.out === 'string' ? ctx.values.out : undefined;
95
+ const fromKf = typeof ctx.values['from-kf'] === 'string' ? ctx.values['from-kf'] : undefined;
96
+ if (fromKf !== undefined && seq !== undefined) {
97
+ return fail('BAD_ARGUMENTS', '--from-kf 与 --seq 互斥:前者从库内留存帧裁,后者从本会话 L0 热缓存裁', '取库里有哪些帧:maafw-live kf list', EXIT.USAGE);
98
+ }
99
+ if (fromKf !== undefined && ctx.values.cross === true && ctx.values['no-cross'] === true) {
100
+ return fail('BAD_ARGUMENTS', '--cross 与 --no-cross 互斥', undefined, EXIT.USAGE);
101
+ }
102
+ /* 库帧来源:先走离线读侧解析(契约 §4.1),daemon 只接身份与路径——
103
+ * 解析失败就在这一层如实报,不把不可复核的帧送进裁剪。 */
104
+ let kfSource;
105
+ if (fromKf !== undefined) {
106
+ const dir = typeof ctx.values['frames-dir'] === 'string' ? ctx.values['frames-dir'] : defaultFramesDir();
107
+ const r = resolveFrame(dir, fromKf);
108
+ if (r.status !== 'available' || !r.path || !r.record) {
109
+ const code = r.status === 'corrupt' ? 'KF_CORRUPT' : (r.status === 'unsupported' ? 'KF_UNSUPPORTED' : 'KF_MISSING');
110
+ return fail(code, '库帧不可用(' + r.status + '):' + String(r.reason ?? '') + '(库 ' + dir + ')', 'kf list 看库内有哪些帧;missing 表示本机不可复核,不代表历史从未观测', EXIT.FINDINGS);
111
+ }
112
+ kfSource = kfSourceOf(r);
113
+ }
114
+ const wantCross = ctx.values.cross === true;
115
+ /* 库帧路径默认离线:留存帧是本机持久文件,裁剪不需要设备。要跨帧验证才连。 */
116
+ const offline = kfSource !== undefined && !wantCross;
117
+ if (kfSource !== undefined && wantCross && !o.project && !o.kind) {
118
+ return fail('BAD_ARGUMENTS', '--cross 需要连接设备:给 --project <dir> 或 --kind', '不留 --cross 就是纯离线裁剪(留存帧的价值所在)', EXIT.USAGE);
119
+ }
120
+ try {
121
+ return await withDaemon(async (client) => {
122
+ const s = offline ? { connected: false } : await ensureSession(client, o);
123
+ /* 自匹配要加载资源(模板走 override_image,不写项目目录);项目模式用规划出的资源 */
124
+ let resourceDir = (typeof ctx.values['resource-dir'] === 'string' ? ctx.values['resource-dir'] : undefined)
125
+ ?? s.plan?.resource?.paths[0];
126
+ if (!resourceDir && offline && o.project) {
127
+ /* 离线:项目只是资源的来源,不是连接的对象——只读 interface.json,不扫设备 */
128
+ const off = offlineResource(o.project, o.controller, o.resource);
129
+ if (off.error) {
130
+ return fail('PLAN_FAILED', '离线解析项目资源失败:' + off.error, '也可以直接给 --resource-dir <dir>', EXIT.FINDINGS);
131
+ }
132
+ resourceDir = off.paths[0];
133
+ }
134
+ if (!resourceDir) {
135
+ return fail('BAD_ARGUMENTS', '自匹配需要资源目录:给 --resource-dir <dir> 或 --project <dir>', undefined, EXIT.USAGE);
136
+ }
137
+ /* L0 是进程态:一次性命令先截一帧产生观测(截帧文件用完即删,不落用户 cwd、也不留在临时目录)。
138
+ * 库帧路径不截帧——源已经固定,重截只会拿到另一个时刻。 */
139
+ if (kfSource === undefined && seq === undefined) {
140
+ await seedObservation(client, 'crop');
141
+ }
142
+ const r = await tplCrop(client, {
143
+ ...(roi ? { roi } : {}),
144
+ ...(point ? { point } : {}),
145
+ ...(pad !== undefined ? { pad } : {}),
146
+ ...(kfSource === undefined && seq !== undefined ? { seq } : {}),
147
+ ...(kfSource ? { kfSource } : {}),
148
+ ...(out ? { out } : {}),
149
+ resourceDir,
150
+ /* 跨帧验证缺省:热缓存路径交给 daemon 判(连接着就做);库帧路径显式关,--cross 才做 */
151
+ ...(kfSource !== undefined && !wantCross ? { cross: false } : (wantCross ? { cross: true } : {})),
152
+ ...(ctx.values['no-cross'] === true ? { cross: false } : {}),
153
+ ...(ctx.values['no-prov'] === true ? { prov: false } : {}),
154
+ ...(typeof ctx.values['prov-out'] === 'string' && ctx.values['prov-out']
155
+ ? { provOut: ctx.values['prov-out'] }
156
+ : {}),
157
+ ...(ctx.values['keep-source'] === true ? { keepSource: true } : {}),
158
+ });
159
+ if (r.ok === false) {
160
+ return fail('TPL_CROP', String(r.error ?? '裁剪失败'), kfSource ? '库帧裁剪失败通常是文件被改动或库记录不一致;kf resolve 可复核' : '源帧取 L0 最新原图:先 screencap / stream / 输入产生观测', EXIT.FINDINGS);
161
+ }
162
+ const box = r.box;
163
+ const src = r.source;
164
+ const cross = r.cross;
165
+ /* 贴合度信号:宽松框 → 最终框的几何对比(得分那一路分辨不出贴合度:三种窗口自匹配都是 1.0) */
166
+ const tg = r.tighten;
167
+ const space = r.spaceCheck;
168
+ const srcLine = src && src.kind === 'kf'
169
+ ? '源帧 ' + String(src.id) + '(留存帧,捕获 seq=' + String(src.captureSeq) + ',' +
170
+ String(src.ctrlW) + 'x' + String(src.ctrlH) + ',sha ' + String(src.sha256).slice(0, 12) + ')'
171
+ : '源帧 seq=' + String(r.seq) + '(' + String(r.ctrlW) + 'x' + String(r.ctrlH) + ',L0 热缓存)';
172
+ const spaceLine = space && space.current
173
+ ? ' 空间核对:源 ' + String(r.ctrlW) + 'x' + String(r.ctrlH) + (space.match ? ' = ' : ' ≠ ') +
174
+ '当前控制器 ' + space.current.w + 'x' + space.current.h
175
+ : ' 空间核对:未连接设备,未与当前控制器尺寸比对(模板空间 = 源帧捕获时尺寸 ' +
176
+ String(r.ctrlW) + 'x' + String(r.ctrlH) + ')';
177
+ const human = [
178
+ ...describeSession(s),
179
+ ...(offline ? ['离线裁剪:未连接设备(留存帧是本机持久文件,裁剪不需要设备)'] : []),
180
+ '模板 ' + String(r.w) + 'x' + String(r.h) + ' → ' + String(r.path),
181
+ ' ' + srcLine,
182
+ ' 宽松框 ' + JSON.stringify(r.loose) + ' → 收紧 ' + JSON.stringify(box) +
183
+ (tg?.from && tg?.to
184
+ ? '(' + tg.from.join('×') + ' → ' + tg.to.join('×') +
185
+ (tg.areaRatio !== null && tg.areaRatio !== undefined ? ',面积 ' + tg.areaRatio + '×' : '') +
186
+ (tg.grew ? ',反而放大' : '') + ')'
187
+ : '') +
188
+ (tg?.looseMatch
189
+ ? ';宽松框自匹配 ' + tg.looseMatch.score + (tg.looseMatch.positionOk ? '(位置正确,说明得分分辨不出贴合度)' : '(位置漂移)')
190
+ : '') +
191
+ (r.snapped ? '' : '(snap 无内容收紧,用原框)'),
192
+ ' 自匹配 ' + (r.positionOk === false ? '位置错误(best 落在 ' + JSON.stringify(r.selfMatchBox ?? null) + ')' : '位置正确') +
193
+ ',得分 ' + String(r.score) + '(' + String(r.tries) + ' 次评估)',
194
+ ...(cross
195
+ ? [' 跨帧验证 seq=' + String(cross.seq) + ':得分 ' + String(cross.score) +
196
+ (cross.posOk ? ',位置正确' : ',位置漂移 ' + JSON.stringify(cross.box ?? null))]
197
+ : [kfSource
198
+ ? ' 跨帧验证:跳过(源为留存帧,它对应的状态通常已不在当前画面上;状态可复现时给 --cross)'
199
+ : (ctx.values['no-cross'] === true
200
+ ? ' 跨帧验证:已按 --no-cross 关闭'
201
+ : ' 跨帧验证:未做(未连接设备)')]),
202
+ spaceLine,
203
+ ...(r.provPath
204
+ ? ['L2 出处:' + String(r.provPath) + '(来源 + 裁剪变换;随模板一起提交进仓库)']
205
+ : ['L2 出处:未写(--no-prov)']),
206
+ ...(r.keptSource && r.keptSource.id
207
+ ? ['源帧已留档:' + String(r.keptSource.id) + '(出处随之升级为可复核的 kf: 身份)']
208
+ : []),
209
+ ...(r.warns ?? []).map((w) => ' 警告:' + w),
210
+ 'pipeline 用法:roi ' + box.join(',') + ' + template 该文件(同帧验证:maafw-live reco --node …)',
211
+ ];
212
+ const warns = r.warns ?? [];
213
+ return {
214
+ exitCode: warns.length ? EXIT.FINDINGS : EXIT.OK,
215
+ human,
216
+ data: r,
217
+ written: [String(r.path), ...(r.provPath ? [String(r.provPath)] : [])],
218
+ ...(warns.length ? { warnings: warns } : {}),
219
+ };
220
+ });
221
+ }
222
+ catch (e) {
223
+ return daemonFail(e);
224
+ }
225
+ },
226
+ };
227
+ export const CROP_COMMANDS = [cropCommand];
228
+ //# sourceMappingURL=crop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crop.js","sourceRoot":"","sources":["../../src/commands/crop.ts"],"names":[],"mappings":"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"}