@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,169 @@
1
+ /**
2
+ * `maafw-live skill` —— 随包发布的 agent skill 与"装在 agent 里的那一份"如何对齐。
3
+ *
4
+ * 为什么不写版本号:skill 讲的是本工具的命令与判据,跟包走才不会各说各话;但写进文件的版本号
5
+ * 每次发版都要改,而且从仓库装的副本仍然对不上。所以对齐用**比字节**:逐文件 same / different /
6
+ * missing / extra(extra 是目标目录多出来的文件,例如 skills CLI 放进来的 agent 元数据,不算漂移)。
7
+ *
8
+ * 与本仓 docs/ 的分工:docs/ 是字段与协议的唯一出处,skill 只写动线与判据——两者都随包发布,
9
+ * 区别在消费者(人读 docs,agent 装 skill),因此这里只做"是不是同一份字节",不解释内容。
10
+ */
11
+ import { createHash } from 'node:crypto';
12
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
13
+ import { dirname, join, relative, sep } from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
15
+ import { EXIT, fail } from '../protocol.js';
16
+ const SKILL_NAME = 'maafw-live';
17
+ /** 包内 skill 目录:lib/commands/ → <包根>/skills/maafw-live(本地 checkout 同构) */
18
+ export function skillPayloadDir() {
19
+ return join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'skills', SKILL_NAME);
20
+ }
21
+ const sha256 = (buf) => createHash('sha256').update(buf).digest('hex');
22
+ /** 目录内全部文件的相对路径('/' 分隔、排序稳定),供比对与安装共用。 */
23
+ function listFiles(dir) {
24
+ const out = [];
25
+ const walk = (cur) => {
26
+ for (const e of readdirSync(cur, { withFileTypes: true })) {
27
+ const abs = join(cur, e.name);
28
+ if (e.isDirectory())
29
+ walk(abs);
30
+ else if (e.isFile())
31
+ out.push(relative(dir, abs).split(sep).join('/'));
32
+ }
33
+ };
34
+ walk(dir);
35
+ return out.sort();
36
+ }
37
+ /**
38
+ * 逐文件比对(纯函数,单测直接喂两个目录)。只比字节:任何不同都是 different,
39
+ * 但在**仅行尾不同**(CRLF ↔ LF)时补一条 note——那不是内容分叉,是工具改写。
40
+ */
41
+ export function compareSkillTrees(payload, target) {
42
+ const files = listFiles(payload);
43
+ const rows = [];
44
+ for (const rel of files) {
45
+ const pb = readFileSync(join(payload, ...rel.split('/')));
46
+ const ta = join(target, ...rel.split('/'));
47
+ const base = { path: rel, bytes: pb.length, sha256: sha256(pb) };
48
+ if (!existsSync(ta)) {
49
+ rows.push({ ...base, status: 'missing' });
50
+ continue;
51
+ }
52
+ const tb = readFileSync(ta);
53
+ if (pb.equals(tb)) {
54
+ rows.push({ ...base, status: 'same' });
55
+ continue;
56
+ }
57
+ const eolOnly = pb.toString('utf8').replace(/\r\n/g, '\n') === tb.toString('utf8').replace(/\r\n/g, '\n');
58
+ rows.push({ ...base, status: 'different', ...(eolOnly ? { note: '仅行尾不同(CRLF/LF)' } : {}) });
59
+ }
60
+ for (const rel of listFiles(target)) {
61
+ if (!files.includes(rel))
62
+ rows.push({ path: rel, status: 'extra' });
63
+ }
64
+ return rows;
65
+ }
66
+ const driftOf = (rows) => rows.some((r) => r.status !== 'same' && r.status !== 'extra');
67
+ function readPayload(dir) {
68
+ return listFiles(dir).map((rel) => {
69
+ const buf = readFileSync(join(dir, ...rel.split('/')));
70
+ return { path: rel, bytes: buf.length, sha256: sha256(buf), text: buf.toString('utf8') };
71
+ });
72
+ }
73
+ export const skillCommand = {
74
+ name: 'skill',
75
+ summary: '随包 skill:看包内副本与文件指纹、比对已装副本(same/different/missing/extra)、字节精确安装',
76
+ usage: 'maafw-live skill 包内 skill 位置与文件指纹\n' +
77
+ ' maafw-live skill --check <dir> 比对 <dir>/maafw-live 与包内副本(有漂移退出 3)\n' +
78
+ ' maafw-live skill --install <dir> 把包内副本逐字节写到 <dir>/maafw-live\n' +
79
+ ' maafw-live skill --print [--format json] 输出包内副本内容(harness 自取)',
80
+ options: {
81
+ check: { type: 'string' },
82
+ install: { type: 'string' },
83
+ print: { type: 'boolean' },
84
+ format: { type: 'string' },
85
+ },
86
+ async run(ctx) {
87
+ const payload = skillPayloadDir();
88
+ if (!existsSync(payload)) {
89
+ return fail('SKILL_NOT_FOUND', '包内未找到 skill 目录:' + payload, '本版本应随包发布 skills/maafw-live;从仓库运行时确认 skills/ 没有被删', EXIT.ENV);
90
+ }
91
+ const files = listFiles(payload);
92
+ const checkDir = typeof ctx.values.check === 'string' ? ctx.values.check : undefined;
93
+ if (checkDir !== undefined) {
94
+ const target = join(checkDir, SKILL_NAME);
95
+ if (!existsSync(target)) {
96
+ return fail('SKILL_DIR_NOT_FOUND', '目标目录下没有 ' + SKILL_NAME + ' skill:' + target, '给的是**安装根目录**(里面应当有 ' + SKILL_NAME + '/SKILL.md),例如 --global 装的 ~/.claude/skills', EXIT.ENV);
97
+ }
98
+ const rows = compareSkillTrees(payload, target);
99
+ const drifted = driftOf(rows);
100
+ const extra = rows.filter((r) => r.status === 'extra');
101
+ const mark = (s) => s === 'same' ? 'same ' : (s === 'different' ? 'different' : (s === 'missing' ? 'missing ' : 'extra '));
102
+ const human = [
103
+ '包内副本 ' + payload,
104
+ '已装副本 ' + target,
105
+ ...rows.map((r) => ' ' + mark(r.status) + ' ' + r.path + (r.note ? '(' + r.note + ')' : '')),
106
+ drifted
107
+ ? '结论:有漂移——用 --install <dir> 覆盖,或用 skills CLI 重新安装'
108
+ : '结论:逐字节一致' + (extra.length ? '(' + extra.length + ' 个多余文件不计漂移)' : ''),
109
+ ];
110
+ return {
111
+ exitCode: drifted ? EXIT.FINDINGS : EXIT.OK,
112
+ human,
113
+ data: { payload, target, drift: drifted, files: rows },
114
+ ...(drifted ? { warnings: ['skill 与包内副本不一致:已装副本可能对应旧版本 CLI'] } : {}),
115
+ };
116
+ }
117
+ const installDir = typeof ctx.values.install === 'string' ? ctx.values.install : undefined;
118
+ if (installDir !== undefined) {
119
+ const target = join(installDir, SKILL_NAME);
120
+ const written = [];
121
+ for (const rel of files) {
122
+ const dst = join(target, ...rel.split('/'));
123
+ mkdirSync(dirname(dst), { recursive: true });
124
+ writeFileSync(dst, readFileSync(join(payload, ...rel.split('/'))));
125
+ written.push(dst);
126
+ }
127
+ return {
128
+ exitCode: EXIT.OK,
129
+ human: [
130
+ '已写出 ' + files.length + ' 个文件 → ' + target,
131
+ ...written.map((w) => ' ' + w),
132
+ '注:本命令只做逐字节复制;要 agent 自动更新请用 skills CLI(npx skills add …)',
133
+ ],
134
+ data: { payload, target, files: written },
135
+ written,
136
+ };
137
+ }
138
+ if (ctx.values.print === true) {
139
+ const rows = readPayload(payload);
140
+ const asJson = ctx.values.format === 'json';
141
+ if (asJson) {
142
+ return {
143
+ exitCode: EXIT.OK,
144
+ data: { payload, files: rows },
145
+ };
146
+ }
147
+ const human = [];
148
+ for (const f of rows) {
149
+ human.push('===== ' + f.path + ' =====');
150
+ human.push(...f.text.replace(/\r\n/g, '\n').replace(/\n$/, '').split('\n'));
151
+ human.push('');
152
+ }
153
+ return { exitCode: EXIT.OK, human, data: { payload, files: rows.map(({ text, ...rest }) => rest) } };
154
+ }
155
+ const rows = readPayload(payload);
156
+ const total = rows.reduce((a, f) => a + f.bytes, 0);
157
+ return {
158
+ exitCode: EXIT.OK,
159
+ human: [
160
+ '包内 skill:' + payload,
161
+ '文件 ' + rows.length + ' 个,共 ' + total + ' 字节(skill 不写自己的版本号——对齐用比字节)',
162
+ ...rows.map((f) => ' ' + f.sha256.slice(0, 12) + ' ' + String(f.bytes).padStart(6) + ' ' + f.path),
163
+ '下一步:maafw-live skill --check <安装根目录> 比对已装副本;--install <目录> 逐字节写出',
164
+ ],
165
+ data: { payload, files: rows.map(({ text, ...rest }) => rest) },
166
+ };
167
+ },
168
+ };
169
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * timing:从帧流与节点事件反推 pipeline 的 delay / timeout 建议值。
3
+ *
4
+ * 做法:自动开流 → 跑任务(--runs n 次采样)→ 对齐两类时间线——
5
+ * - 节点时长(record.nodes)→ 节点级 timeout 建议(P95 × 1.5 余量)
6
+ * - 节点完成后的画面稳定时间(完成事件到下一个 stable 事件的时距)→ post-delay /
7
+ * wait_freezes 建议;下一节点先于 stable 开始则标"未稳定"(连续动画/识别窗口过紧)。
8
+ * 分布口径:建议值只取成功 run(失败 run 的时长是提前终止的,对 timeout 建议是误导);
9
+ * 单次采样退化为 P50=P95=该值,与历史单次行为逐字段一致。
10
+ */
11
+ import { EXIT, fail } from '../protocol.js';
12
+ import { computePipelineOverride, mergeOverride } from '../interface/index.js';
13
+ import * as act from '../runtime/actions.js';
14
+ import { withDaemon } from '../runtime/actions.js';
15
+ import { describeSession, ensureSession } from '../runtime/session.js';
16
+ import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
17
+ /** 最近邻秩百分位:sorted 升序;n=1 时任意 p 返回该值,n 小时偏保守端(P95 取最大) */
18
+ export function percentile(values, p) {
19
+ if (!values.length)
20
+ return 0;
21
+ const sorted = [...values].sort((a, b) => a - b);
22
+ const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));
23
+ return sorted[idx];
24
+ }
25
+ /** 跨 run 聚合(纯函数,单测直断言):节点统计与建议值都只算成功样本 */
26
+ export function aggregateTiming(samples) {
27
+ const ok = samples.filter((s) => s.ok);
28
+ const failed = samples.length - ok.length;
29
+ const durations = ok.map((s) => s.durationMs);
30
+ const maxNodeP95 = ok.length ? percentile(ok.map((s) => Math.max(0, ...s.nodes.map((n) => n.ms))), 95) : 0;
31
+ const settleSamples = ok.map((s) => {
32
+ const ss = s.nodes.filter((n) => n.settle !== null).map((n) => n.settle);
33
+ return ss.length ? Math.max(...ss) : null;
34
+ });
35
+ const settles = settleSamples.filter((v) => v !== null);
36
+ const names = [...new Set(ok.flatMap((s) => s.nodes.map((n) => n.name)))];
37
+ const nodeStats = names.map((name) => {
38
+ /* 全部出现都算:同名节点 run 内重复执行时,慢的往往是第二次(首跑等动画) */
39
+ const per = ok.flatMap((s) => s.nodes.filter((n) => n.name === name));
40
+ const ms = per.map((n) => n.ms);
41
+ const st = per.filter((n) => n.settle !== null).map((n) => n.settle);
42
+ return {
43
+ name,
44
+ status: per.at(-1)?.status ?? 'unknown',
45
+ runs: ok.filter((s) => s.nodes.some((n) => n.name === name)).length,
46
+ occurrences: per.length,
47
+ msP50: percentile(ms, 50),
48
+ msP95: percentile(ms, 95),
49
+ settleP50: st.length ? percentile(st, 50) : null,
50
+ settleP95: st.length ? percentile(st, 95) : null,
51
+ settleSamples: st.length,
52
+ nextBeforeStable: per.some((n) => n.nextBeforeStable),
53
+ };
54
+ });
55
+ return {
56
+ successful: ok.length, failed,
57
+ durationP50: percentile(durations, 50),
58
+ durationP95: percentile(durations, 95),
59
+ maxNodeP95,
60
+ maxSettleP95: settles.length ? percentile(settles, 95) : null,
61
+ nodeStats,
62
+ suggest: {
63
+ nodeTimeoutMs: Math.ceil((maxNodeP95 * 1.5) / 100) * 100,
64
+ taskTimeoutMs: Math.ceil((percentile(durations, 95) * 2) / 1000) * 1000,
65
+ postDelayMs: settles.length ? Math.ceil((percentile(settles, 95) * 1.2) / 50) * 50 : null,
66
+ },
67
+ };
68
+ }
69
+ export const timingCommand = {
70
+ name: 'timing',
71
+ summary: '跑任务并反推 timing 建议:节点时长 → timeout,动作后稳定时间 → wait_freezes 兜底参考;--runs n 取 P50/P95 分布',
72
+ usage: 'maafw-live timing --entry <task> --project <dir> [--timeout <ms>] [--runs <n>] [--preset <name>] [--override <json>]\n' +
73
+ ' 自动开流(帧流与节点事件对齐是分析前提);单次采样是下界,--runs 3-5 取分布再定稿',
74
+ options: {
75
+ ...CONNECT_OPTIONS,
76
+ entry: { type: 'string' },
77
+ 'resource-dir': { type: 'string' },
78
+ timeout: { type: 'string' },
79
+ runs: { type: 'string' },
80
+ override: { type: 'string' },
81
+ preset: { type: 'string' },
82
+ },
83
+ async run(ctx) {
84
+ const o = sessionOptions(ctx.values);
85
+ const entry = (typeof ctx.values.entry === 'string' ? ctx.values.entry : ctx.positionals[0]) ?? undefined;
86
+ const resourceDir = typeof ctx.values['resource-dir'] === 'string' ? ctx.values['resource-dir'] : undefined;
87
+ if (!entry)
88
+ return fail('BAD_ARGUMENTS', '缺少入口任务名:--entry <task>', undefined, EXIT.USAGE);
89
+ if (!o.project && !resourceDir) {
90
+ return fail('BAD_ARGUMENTS', '要么给 --project <dir>,要么给 --resource-dir <dir>', undefined, EXIT.USAGE);
91
+ }
92
+ const timeoutMs = typeof ctx.values.timeout === 'string' ? Number(ctx.values.timeout) : 120000;
93
+ if (!Number.isFinite(timeoutMs))
94
+ return fail('BAD_ARGUMENTS', '--timeout 必须是毫秒数', undefined, EXIT.USAGE);
95
+ const runs = typeof ctx.values.runs === 'string' ? Number(ctx.values.runs) : 1;
96
+ if (!Number.isInteger(runs) || runs < 1 || runs > 10) {
97
+ return fail('BAD_ARGUMENTS', '--runs 需为 1-10 的整数(真机动作采样,别当压测跑)', undefined, EXIT.USAGE);
98
+ }
99
+ let override = {};
100
+ if (typeof ctx.values.override === 'string') {
101
+ try {
102
+ override = JSON.parse(ctx.values.override);
103
+ }
104
+ catch (e) {
105
+ return fail('BAD_ARGUMENTS', '--override 不是合法 JSON', undefined, EXIT.USAGE);
106
+ }
107
+ }
108
+ try {
109
+ return await withDaemon(async (client) => {
110
+ const s = await ensureSession(client, o);
111
+ let args;
112
+ if (o.project) {
113
+ const paths = s.plan?.resource?.paths ?? [];
114
+ if (!paths.length) {
115
+ return fail('RESOURCE_NOT_FOUND', '项目里没有解析出资源路径:检查 interface.json 的 resource[] 声明', undefined, EXIT.FINDINGS);
116
+ }
117
+ const task = s.plan?.loaded.tasks.find((t) => t.name === entry || t.entry === entry);
118
+ const chain = computePipelineOverride({
119
+ loaded: s.plan.loaded,
120
+ controllerName: s.plan?.controllerName ?? null,
121
+ resourceName: s.plan?.resource?.selected ?? null,
122
+ taskName: task?.name ?? null,
123
+ presetName: typeof ctx.values.preset === 'string' ? ctx.values.preset : null,
124
+ });
125
+ /* 用户 --override 最后覆盖合成结果:**与 run 共用同一份合并实现**。
126
+ * 这里曾经自己展开 fields——字符串会被摊成 {0:'a',1:'b'}、null / 数字静默变空对象,
127
+ * 于是同一个 --override 在 timing 与 run 下结果不同。 */
128
+ mergeOverride(chain.override, override);
129
+ args = {
130
+ resourceDirs: paths, entry: task?.entry ?? entry,
131
+ override: chain.override, timeoutMs,
132
+ agents: s.plan.loaded.agents.map((a) => ({ exec: a.exec, args: a.args })),
133
+ agentCwd: s.plan.loaded.dir ?? undefined,
134
+ };
135
+ }
136
+ else {
137
+ args = { resourceDir, entry, override, timeoutMs };
138
+ }
139
+ /* 帧流是分析前提:开流 → 跑 n 次 → 停流;每 run 切自己的事件区间对齐。
140
+ * 末节点可能把下一 run 开头的 stable 算作自己的稳定点——语义上仍是
141
+ * "该节点之后画面何时静默",可接受。 */
142
+ await act.streamStart(client, { fps: 8 }).catch(() => null);
143
+ const samples = [];
144
+ try {
145
+ for (let i = 1; i <= runs; i++) {
146
+ const eventsBefore = client.events.events.length;
147
+ const r = await act.run(client, args, timeoutMs);
148
+ const evs = client.events.events.slice(eventsBefore);
149
+ if (r.ok === false || !r.record) {
150
+ return fail('TIMING_RUN', '任务没跑起来:' + String(r.error ?? '?'), undefined, EXIT.FINDINGS);
151
+ }
152
+ const rec = r.record;
153
+ /* 时间线对齐:run 类事件带节点名与消息;stable 是画面静默点 */
154
+ const runEvs = evs.filter((e) => e.type === 'run' && e.node);
155
+ const stables = evs.filter((e) => e.type === 'stable').map((e) => Number(e.t));
156
+ const nodes = rec.nodes.map((n) => {
157
+ const done = runEvs.filter((e) => e.node === n.name && /Succeeded$/.test(e.msg)).at(-1)
158
+ ?? runEvs.filter((e) => e.node === n.name && /Failed$/.test(e.msg)).at(-1);
159
+ if (!done)
160
+ return { name: n.name, ms: n.ms, status: n.status, settle: null, nextBeforeStable: false };
161
+ const nextNode = runEvs.find((e) => e.t > done.t && e.node !== n.name);
162
+ const stable = stables.find((t) => t > done.t);
163
+ const settle = stable !== undefined ? stable - done.t : null;
164
+ return {
165
+ name: n.name, ms: n.ms, status: n.status,
166
+ settle,
167
+ nextBeforeStable: nextNode !== undefined && (stable === undefined || nextNode.t < stable),
168
+ };
169
+ });
170
+ samples.push({ index: i, ok: rec.ok, durationMs: rec.durationMs, nodes, events: evs.length });
171
+ }
172
+ }
173
+ finally {
174
+ await act.streamStop(client).catch(() => null);
175
+ }
176
+ const agg = aggregateTiming(samples);
177
+ if (!agg.successful) {
178
+ return fail('TIMING_RUN', runs + ' 次采样全部未成功——没有可用于建议的成功样本', undefined, EXIT.FINDINGS);
179
+ }
180
+ const unsettled = agg.nodeStats.filter((n) => n.nextBeforeStable);
181
+ const last = samples.at(-1);
182
+ const human = [
183
+ ...describeSession(s),
184
+ 'timing 采样 x' + runs + '(' + agg.successful + ' 成功' + (agg.failed ? ' / ' + agg.failed + ' 失败' : '') + '):',
185
+ ...samples.map((smp) => ' #' + smp.index + ' ' + (smp.ok ? '成功' : '失败(不计入建议)') + ' ' + smp.durationMs + 'ms ' + smp.nodes.length + ' 节点'),
186
+ '节点时长分布(成功样本,P50 / P95):',
187
+ ...agg.nodeStats.map((n) => ' [' + n.status + '] ' + n.name + ' ' + n.msP50 + ' / ' + n.msP95 + 'ms' +
188
+ (n.settleP50 !== null ? ' 稳定 +' + n.settleP50 + ' / +' + n.settleP95 + 'ms' : '') +
189
+ (n.occurrences > n.runs ? ' (重复执行 ' + n.occurrences + ' 次 / ' + n.runs + ' run——重试或 Next 环)' : '') +
190
+ (n.runs < agg.successful ? ' (' + n.runs + '/' + agg.successful + ' run 出现——分支或跳过)' : '') +
191
+ (n.nextBeforeStable ? ' (下一节点先于画面稳定开始——识别窗口紧或连续动画)' : '')),
192
+ '建议(P95 × 余量,n=' + agg.successful + ' 成功采样;界面切换优先用 next 等待节点表达,delay 尽量保持缺省):',
193
+ ' 节点 timeout ≥ ' + agg.suggest.nodeTimeoutMs + 'ms(各 run 最长节点 P95 ' + agg.maxNodeP95 + 'ms × 1.5)',
194
+ ' 任务 timeout ≥ ' + agg.suggest.taskTimeoutMs + 'ms(任务时长 P95 ' + agg.durationP95 + 'ms × 2)',
195
+ agg.suggest.postDelayMs !== null
196
+ ? ' 动作后稳定参考 ' + agg.suggest.postDelayMs + 'ms(各 run 最长稳定 P95 ' + agg.maxSettleP95 + 'ms × 1.2)——优先由 next 等待节点的 timeout 覆盖该时长;确需兜底用 post_wait_freezes,post_delay 是最后手段'
197
+ : ' 动作后稳定时间:无 stable 事件可参考(画面持续变化或流太短)',
198
+ ];
199
+ if (agg.failed)
200
+ human.push(' 注意:' + agg.failed + ' 个失败 run 未计入建议;失败原因与时长见 data.runs');
201
+ if (unsettled.length) {
202
+ human.push(' 注意:' + unsettled.map((n) => n.name).join(' , ') + ' 未等画面稳定就进入下一节点');
203
+ }
204
+ return {
205
+ exitCode: EXIT.OK,
206
+ human,
207
+ data: {
208
+ runs: samples, distribution: agg, suggest: agg.suggest,
209
+ /* 兼容字段:单次消费方读 record / nodes 的形状不变 */
210
+ record: { ok: last.ok, durationMs: last.durationMs, nodes: last.nodes },
211
+ nodes: last.nodes,
212
+ sampledEvents: samples.reduce((a, smp) => a + smp.events, 0),
213
+ },
214
+ warnings: [
215
+ ...(agg.failed ? [agg.failed + ' 个失败 run 未计入建议'] : []),
216
+ ...samples.filter((smp) => !smp.ok).map((smp) => 'run #' + smp.index + ' 未成功——该样本已排除'),
217
+ ...(unsettled.length ? [unsettled.length + ' 个节点未等画面稳定即进入下一节点:' + unsettled.map((n) => n.name).join(' , ')] : []),
218
+ ...(runs === 1 ? ['单次采样=下界:加 --runs 3-5 取分布再定稿'] : []),
219
+ ],
220
+ };
221
+ });
222
+ }
223
+ catch (e) {
224
+ return daemonFail(e);
225
+ }
226
+ },
227
+ };
228
+ export const TIMING_COMMANDS = [timingCommand];
229
+ //# sourceMappingURL=timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.js","sourceRoot":"","sources":["../../src/commands/timing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /** `maafw-live version` —— CLI 与运行环境版本。技能用它做版本对齐;`--check` 对 registry 查有没有新版。 */
2
+ import { EXIT, fail } from '../protocol.js';
3
+ import { cliPackage } from '../pkg.js';
4
+ import { compareVersions, fetchLatest, readState, shouldCheck, updateCheckDisabled, writeState, } from '../update-check.js';
5
+ export const versionCommand = {
6
+ name: 'version',
7
+ summary: '打印 maafw-live CLI 及依赖的版本;--check 顺带对 registry 查有没有新版',
8
+ usage: 'maafw-live version [--check]',
9
+ options: { check: { type: 'boolean' } },
10
+ async run(ctx) {
11
+ const pkg = cliPackage();
12
+ const human = [
13
+ `${pkg.name} ${pkg.version}`,
14
+ // 装的是带 scope 的包名,敲的是裸名——同一个词的两种形态,这里显式给出敲的那个
15
+ ` command maafw-live`,
16
+ ` node ${process.version}`,
17
+ ` platform ${process.platform} ${process.arch}`,
18
+ ];
19
+ const data = {
20
+ name: pkg.name,
21
+ version: pkg.version,
22
+ node: process.version,
23
+ platform: process.platform,
24
+ arch: process.arch,
25
+ };
26
+ const explicit = ctx.values.check === true;
27
+ /* 显式请求:不受 TTY/限频约束,查不到要如实说。自动路径:只在交互终端、限频、失败静默。 */
28
+ const auto = !explicit && !updateCheckDisabled() && process.stdout.isTTY === true;
29
+ if (explicit || auto) {
30
+ let latest = auto ? readState()?.latest ?? null : null;
31
+ let fresh = false;
32
+ const cached = readState();
33
+ if (explicit || shouldCheck(cached, Date.now())) {
34
+ const fetched = await fetchLatest(pkg.name);
35
+ if (fetched) {
36
+ latest = fetched;
37
+ writeState({ checkedAt: Date.now(), latest: fetched });
38
+ fresh = true;
39
+ }
40
+ else if (explicit) {
41
+ return fail('UPDATE_CHECK_FAILED', '查询 registry 失败(离线 / 代理 / registry 抖动)', '加 --check 才需要联网;不带它 version 完全离线可用', EXIT.ENV);
42
+ }
43
+ }
44
+ else if (cached) {
45
+ latest = cached.latest;
46
+ }
47
+ if (latest) {
48
+ const cmp = compareVersions(latest, pkg.version);
49
+ data.latest = latest;
50
+ data.updateAvailable = cmp > 0;
51
+ data.source = fresh ? 'registry' : 'cache';
52
+ if (cmp > 0) {
53
+ human.push(` 新版 ${latest}(当前 ${pkg.version})`, ` 升级 npm install --global ${pkg.name}@latest`);
54
+ /* 自动提示不改退出码:版本旧不是"这次调用发现的问题" */
55
+ return { exitCode: explicit ? EXIT.FINDINGS : EXIT.OK, human, data };
56
+ }
57
+ human.push(` 最新 ${latest}(已是最新)`);
58
+ }
59
+ else if (explicit) {
60
+ human.push(' 最新 查询不到(registry 不可达)');
61
+ }
62
+ }
63
+ return { exitCode: EXIT.OK, human, data };
64
+ },
65
+ };
66
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"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"}