@windsland52/maafw-live 0.3.0 → 0.4.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 (118) hide show
  1. package/README.md +24 -9
  2. package/docs/daemon-protocol.md +15 -10
  3. package/docs/keyframe-retention-contract-v0.md +23 -34
  4. package/docs/session-unify-v0.md +115 -0
  5. package/lib/client/daemon.js +45 -3
  6. package/lib/commands/annotate.js +15 -8
  7. package/lib/commands/calibrate.js +3 -3
  8. package/lib/commands/color.js +3 -3
  9. package/lib/commands/crop.js +8 -8
  10. package/lib/commands/dispatch.js +121 -0
  11. package/lib/commands/env.js +200 -6
  12. package/lib/commands/index.js +7 -1
  13. package/lib/commands/input.js +71 -33
  14. package/lib/commands/kf.js +49 -13
  15. package/lib/commands/probe.js +70 -0
  16. package/lib/commands/reco.js +285 -56
  17. package/lib/commands/repl.js +1305 -502
  18. package/lib/commands/roi-check.js +273 -0
  19. package/lib/commands/roi-compare.js +388 -0
  20. package/lib/commands/runtime.js +295 -91
  21. package/lib/commands/timing.js +28 -10
  22. package/lib/daemon/framed.mjs +1014 -184
  23. package/lib/daemon/reco_child.mjs +150 -9
  24. package/lib/flags.js +2 -0
  25. package/lib/index.js +24 -20
  26. package/lib/interface/hotkey.js +142 -0
  27. package/lib/interface/index.js +1 -1
  28. package/lib/interface/load.js +107 -17
  29. package/lib/interface/override.js +218 -34
  30. package/lib/interface/plan.js +108 -17
  31. package/lib/option-args.js +29 -0
  32. package/lib/pkg.js +36 -0
  33. package/lib/protocol.js +4 -0
  34. package/lib/runtime/actions.js +127 -12
  35. package/lib/runtime/log-watch.js +160 -0
  36. package/lib/runtime/node-source.js +100 -0
  37. package/lib/runtime/ocr-model.js +45 -0
  38. package/lib/runtime/pi-env.js +34 -0
  39. package/lib/runtime/pretask.js +217 -0
  40. package/lib/runtime/prune.js +28 -0
  41. package/lib/runtime/receipts.js +57 -0
  42. package/lib/runtime/reco-args.js +38 -0
  43. package/lib/runtime/reco-verdict.js +82 -0
  44. package/lib/runtime/roi-compare.js +198 -0
  45. package/lib/runtime/session-forward.js +79 -0
  46. package/lib/runtime/session-ipc.js +471 -0
  47. package/lib/runtime/session.js +57 -8
  48. package/lib/runtime/signal-guard.js +35 -0
  49. package/lib/types/commands/dispatch.d.ts +22 -0
  50. package/lib/types/commands/env.d.ts +19 -0
  51. package/lib/types/commands/index.d.ts +1 -1
  52. package/lib/types/commands/probe.d.ts +15 -0
  53. package/lib/types/commands/reco.d.ts +11 -7
  54. package/lib/types/commands/repl.d.ts +8 -0
  55. package/lib/types/commands/roi-check.d.ts +3 -0
  56. package/lib/types/commands/roi-compare.d.ts +3 -0
  57. package/lib/types/commands/runtime.d.ts +20 -2
  58. package/lib/types/flags.d.ts +4 -0
  59. package/lib/types/interface/hotkey.d.ts +36 -0
  60. package/lib/types/interface/index.d.ts +1 -1
  61. package/lib/types/interface/load.d.ts +84 -7
  62. package/lib/types/interface/override.d.ts +58 -13
  63. package/lib/types/interface/plan.d.ts +23 -2
  64. package/lib/types/option-args.d.ts +19 -0
  65. package/lib/types/pkg.d.ts +8 -0
  66. package/lib/types/protocol.d.ts +16 -0
  67. package/lib/types/runtime/actions.d.ts +89 -7
  68. package/lib/types/runtime/log-watch.d.ts +28 -0
  69. package/lib/types/runtime/node-source.d.ts +25 -0
  70. package/lib/types/runtime/ocr-model.d.ts +8 -0
  71. package/lib/types/runtime/pi-env.d.ts +24 -0
  72. package/lib/types/runtime/pretask.d.ts +53 -0
  73. package/lib/types/runtime/prune.d.ts +4 -0
  74. package/lib/types/runtime/receipts.d.ts +7 -0
  75. package/lib/types/runtime/reco-args.d.ts +18 -0
  76. package/lib/types/runtime/reco-verdict.d.ts +50 -0
  77. package/lib/types/runtime/roi-compare.d.ts +117 -0
  78. package/lib/types/runtime/session-forward.d.ts +10 -0
  79. package/lib/types/runtime/session-ipc.d.ts +117 -0
  80. package/lib/types/runtime/session.d.ts +26 -2
  81. package/lib/types/runtime/signal-guard.d.ts +19 -0
  82. package/lib/usage.js +3 -3
  83. package/package.json +17 -4
  84. package/skills/maafw-live/SKILL.md +32 -2
  85. package/skills/maafw-live/references/pitfalls.md +97 -4
  86. package/skills/maafw-live/references/workflows.md +5 -0
  87. package/docs/keyframe-evidence-contract-v0.md +0 -61
  88. package/lib/client/daemon.js.map +0 -1
  89. package/lib/commands/annotate.js.map +0 -1
  90. package/lib/commands/calibrate.js.map +0 -1
  91. package/lib/commands/color.js.map +0 -1
  92. package/lib/commands/crop.js.map +0 -1
  93. package/lib/commands/env.js.map +0 -1
  94. package/lib/commands/index.js.map +0 -1
  95. package/lib/commands/input.js.map +0 -1
  96. package/lib/commands/kf.js.map +0 -1
  97. package/lib/commands/reco.js.map +0 -1
  98. package/lib/commands/repl.js.map +0 -1
  99. package/lib/commands/runtime.js.map +0 -1
  100. package/lib/commands/skill.js.map +0 -1
  101. package/lib/commands/timing.js.map +0 -1
  102. package/lib/commands/version.js.map +0 -1
  103. package/lib/exec.js.map +0 -1
  104. package/lib/flags.js.map +0 -1
  105. package/lib/image.js.map +0 -1
  106. package/lib/index.js.map +0 -1
  107. package/lib/interface/index.js.map +0 -1
  108. package/lib/interface/jsonc.js.map +0 -1
  109. package/lib/interface/load.js.map +0 -1
  110. package/lib/interface/override.js.map +0 -1
  111. package/lib/interface/plan.js.map +0 -1
  112. package/lib/pkg.js.map +0 -1
  113. package/lib/protocol.js.map +0 -1
  114. package/lib/runtime/actions.js.map +0 -1
  115. package/lib/runtime/keyframes.js.map +0 -1
  116. package/lib/runtime/session.js.map +0 -1
  117. package/lib/update-check.js.map +0 -1
  118. package/lib/usage.js.map +0 -1
@@ -9,11 +9,13 @@
9
9
  * 单次采样退化为 P50=P95=该值,与历史单次行为逐字段一致。
10
10
  */
11
11
  import { EXIT, fail } from '../protocol.js';
12
- import { computePipelineOverride, mergeOverride } from '../interface/index.js';
12
+ import { computePipelineOverride, appendOverride } from '../interface/index.js';
13
+ import { buildAgentEnv } from '../runtime/pi-env.js';
14
+ import { parseOptionArgs } from '../option-args.js';
13
15
  import * as act from '../runtime/actions.js';
14
16
  import { withDaemon } from '../runtime/actions.js';
15
17
  import { describeSession, ensureSession } from '../runtime/session.js';
16
- import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
18
+ import { CONNECT_OPTIONS, daemonFail, argPath, sessionOptions } from './runtime.js';
17
19
  /** 最近邻秩百分位:sorted 升序;n=1 时任意 p 返回该值,n 小时偏保守端(P95 取最大) */
18
20
  export function percentile(values, p) {
19
21
  if (!values.length)
@@ -79,11 +81,14 @@ export const timingCommand = {
79
81
  runs: { type: 'string' },
80
82
  override: { type: 'string' },
81
83
  preset: { type: 'string' },
84
+ /* 与 run 同一取值通道:timing 测的就是 run 那条路,option 进不去会让
85
+ * "时长分布"测的是一个根本不该跑的配置(P1-#4)。 */
86
+ option: { type: 'string', multiple: true },
82
87
  },
83
88
  async run(ctx) {
84
- const o = sessionOptions(ctx.values);
89
+ const o = sessionOptions(ctx);
85
90
  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;
91
+ const resourceDir = argPath(ctx, typeof ctx.values['resource-dir'] === 'string' ? ctx.values['resource-dir'] : undefined);
87
92
  if (!entry)
88
93
  return fail('BAD_ARGUMENTS', '缺少入口任务名:--entry <task>', undefined, EXIT.USAGE);
89
94
  if (!o.project && !resourceDir) {
@@ -105,8 +110,13 @@ export const timingCommand = {
105
110
  return fail('BAD_ARGUMENTS', '--override 不是合法 JSON', undefined, EXIT.USAGE);
106
111
  }
107
112
  }
113
+ /* --option 与 run 同一取值通道(CLI > preset > default_case 由 computePipelineOverride 判) */
114
+ const parsedOptions = parseOptionArgs(ctx.values.option);
115
+ if (parsedOptions.error) {
116
+ return fail('BAD_ARGUMENTS', parsedOptions.error, '例:--option taskOpt=b --option 章节数.章节号=4', EXIT.USAGE);
117
+ }
108
118
  try {
109
- return await withDaemon(async (client) => {
119
+ return await withDaemon(ctx, async (client) => {
110
120
  const s = await ensureSession(client, o);
111
121
  let args;
112
122
  if (o.project) {
@@ -121,16 +131,24 @@ export const timingCommand = {
121
131
  resourceName: s.plan?.resource?.selected ?? null,
122
132
  taskName: task?.name ?? null,
123
133
  presetName: typeof ctx.values.preset === 'string' ? ctx.values.preset : null,
134
+ ...(Object.keys(parsedOptions.cases).length ? { optionCases: parsedOptions.cases } : {}),
135
+ ...(Object.keys(parsedOptions.fields).length ? { optionFields: parsedOptions.fields } : {}),
124
136
  });
125
- /* 用户 --override 最后覆盖合成结果:**与 run 共用同一份合并实现**。
126
- * 这里曾经自己展开 fields——字符串会被摊成 {0:'a',1:'b'}、null / 数字静默变空对象,
127
- * 于是同一个 --override 在 timing 与 run 下结果不同。 */
128
- mergeOverride(chain.override, override);
137
+ /* 用户 --override 追加到链尾 = 最高优先级:**与 run 共用同一份追加实现**。
138
+ * 分层数组交给框架逐层继承;不在这里预合并(层间 type 边界会被摊平毁掉)。 */
139
+ appendOverride(chain.override, override);
129
140
  args = {
130
141
  resourceDirs: paths, entry: task?.entry ?? entry,
131
142
  override: chain.override, timeoutMs,
132
143
  agents: s.plan.loaded.agents.map((a) => ({ exec: a.exec, args: a.args })),
133
144
  agentCwd: s.plan.loaded.dir ?? undefined,
145
+ /* agent 子进程的环境变量声明按"当前 controller/resource 选择"生成——
146
+ * 此前 timing 不带 env,agent 拿到的配置与 run 跑的不是同一套(P1-#4)。 */
147
+ agentEnv: buildAgentEnv({
148
+ loaded: s.plan.loaded,
149
+ controllerName: s.plan?.controllerName ?? null,
150
+ resourceName: s.plan?.resource?.selected ?? null,
151
+ }),
134
152
  };
135
153
  }
136
154
  else {
@@ -180,7 +198,7 @@ export const timingCommand = {
180
198
  const unsettled = agg.nodeStats.filter((n) => n.nextBeforeStable);
181
199
  const last = samples.at(-1);
182
200
  const human = [
183
- ...describeSession(s),
201
+ ...describeSession(s, ctx.flags.verbose),
184
202
  'timing 采样 x' + runs + '(' + agg.successful + ' 成功' + (agg.failed ? ' / ' + agg.failed + ' 失败' : '') + '):',
185
203
  ...samples.map((smp) => ' #' + smp.index + ' ' + (smp.ok ? '成功' : '失败(不计入建议)') + ' ' + smp.durationMs + 'ms ' + smp.nodes.length + ' 节点'),
186
204
  '节点时长分布(成功样本,P50 / P95):',