humanish 0.89.1 → 0.90.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 (89) hide show
  1. package/README.md +15 -0
  2. package/dist/automatic-analysis-completion.d.ts +25 -0
  3. package/dist/automatic-analysis-completion.js +54 -0
  4. package/dist/automatic-analysis-completion.js.map +1 -0
  5. package/dist/automatic-analysis-config.d.ts +17 -0
  6. package/dist/automatic-analysis-config.js +31 -0
  7. package/dist/automatic-analysis-config.js.map +1 -0
  8. package/dist/automatic-study-analysis.d.ts +12 -0
  9. package/dist/automatic-study-analysis.js +168 -0
  10. package/dist/automatic-study-analysis.js.map +1 -0
  11. package/dist/concurrent-shared-world-lab.d.ts +4 -2
  12. package/dist/concurrent-shared-world-lab.js +10 -3
  13. package/dist/concurrent-shared-world-lab.js.map +1 -1
  14. package/dist/cua-actor-lab.d.ts +4 -2
  15. package/dist/cua-actor-lab.js +10 -5
  16. package/dist/cua-actor-lab.js.map +1 -1
  17. package/dist/e2b-terminal-lab.d.ts +4 -2
  18. package/dist/e2b-terminal-lab.js +10 -3
  19. package/dist/e2b-terminal-lab.js.map +1 -1
  20. package/dist/export-bundle.js +2 -0
  21. package/dist/export-bundle.js.map +1 -1
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +1 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/lab-config.d.ts +5 -0
  26. package/dist/lab-config.js +21 -2
  27. package/dist/lab-config.js.map +1 -1
  28. package/dist/lab-engine.d.ts +2 -0
  29. package/dist/lab-engine.js +12 -3
  30. package/dist/lab-engine.js.map +1 -1
  31. package/dist/lab-summary.d.ts +4 -0
  32. package/dist/lab-summary.js +3 -0
  33. package/dist/lab-summary.js.map +1 -1
  34. package/dist/observer-app.html +9 -9
  35. package/dist/observer.d.ts +3 -0
  36. package/dist/observer.js +23 -6
  37. package/dist/observer.js.map +1 -1
  38. package/dist/oss-lab.d.ts +1 -1
  39. package/dist/oss-lab.js.map +1 -1
  40. package/dist/oss-meta-lab.d.ts +1 -1
  41. package/dist/oss-meta-lab.js.map +1 -1
  42. package/dist/program.d.ts +5 -0
  43. package/dist/program.js +42 -7
  44. package/dist/program.js.map +1 -1
  45. package/dist/run-detail.d.ts +2 -0
  46. package/dist/run-detail.js +3 -0
  47. package/dist/run-detail.js.map +1 -1
  48. package/dist/run.d.ts +1 -1
  49. package/dist/run.js.map +1 -1
  50. package/dist/scripted-browser-lab.d.ts +4 -2
  51. package/dist/scripted-browser-lab.js +10 -5
  52. package/dist/scripted-browser-lab.js.map +1 -1
  53. package/dist/shared-world-lab.d.ts +4 -2
  54. package/dist/shared-world-lab.js +10 -3
  55. package/dist/shared-world-lab.js.map +1 -1
  56. package/dist/study-analysis-engine.d.ts +6 -1
  57. package/dist/study-analysis-engine.js +17 -3
  58. package/dist/study-analysis-engine.js.map +1 -1
  59. package/dist/study-analysis-evidence.js +45 -17
  60. package/dist/study-analysis-evidence.js.map +1 -1
  61. package/dist/study-analysis-job.d.ts +87 -0
  62. package/dist/study-analysis-job.js +197 -0
  63. package/dist/study-analysis-job.js.map +1 -0
  64. package/dist/study-analysis-service.d.ts +10 -1
  65. package/dist/study-analysis-service.js +31 -8
  66. package/dist/study-analysis-service.js.map +1 -1
  67. package/dist/study-analysis-sharing.js +13 -5
  68. package/dist/study-analysis-sharing.js.map +1 -1
  69. package/dist/study-analysis-store.d.ts +4 -0
  70. package/dist/study-analysis-store.js +40 -1
  71. package/dist/study-analysis-store.js.map +1 -1
  72. package/dist/study-analysis-validation.d.ts +2 -1
  73. package/dist/study-analysis-validation.js +12 -5
  74. package/dist/study-analysis-validation.js.map +1 -1
  75. package/dist/study-analysis.d.ts +6 -0
  76. package/dist/study-analysis.js.map +1 -1
  77. package/dist/tui-actions.d.ts +1 -1
  78. package/dist/tui-actions.js +15 -1
  79. package/dist/tui-actions.js.map +1 -1
  80. package/dist/tui-app.js +116 -116
  81. package/dist/tui-contract.d.ts +3 -2
  82. package/dist/tui-contract.js.map +1 -1
  83. package/docs/contracts/schemas.md +1 -1
  84. package/docs/contracts/study-analysis.md +18 -0
  85. package/docs/goals/current.md +4 -4
  86. package/docs/product/automatic-analysis.md +63 -0
  87. package/docs/ramp/README.md +5 -1
  88. package/docs/release/0.90.0-automatic-analysis.md +21 -0
  89. package/package.json +1 -1
package/dist/program.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type AutomaticAnalysisHooks } from "./automatic-analysis-completion.js";
1
2
  import { Command } from "commander";
2
3
  import { discoverProviderKeys } from "./key-resolution.js";
3
4
  import { type TelemetryProperties } from "./telemetry.js";
@@ -84,4 +85,8 @@ export declare function shouldServeOssMetaLabObserver(output: OssMetaLabResult,
84
85
  };
85
86
  };
86
87
  export declare function exitCodeForOssMetaLab(output: OssMetaLabResult): number;
88
+ /** Listeners exist only while post-run analysis is active; actor signal behavior is unchanged. */
89
+ export declare function cliAutomaticAnalysisHooks(io: Pick<CliIo, "writeErr">): AutomaticAnalysisHooks;
90
+ /** Preserve the run's own result while making requested post-processing failures machine-visible. */
91
+ export declare function automaticAnalysisEnvelope<T>(result: T): T;
87
92
  export {};
package/dist/program.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { automaticAnalysisSucceeded } from "./automatic-analysis-completion.js";
1
2
  import { formatCuaDiagnostics, formatCuaStopCause } from "./cua-diagnostics.js";
2
3
  import { existsSync, readFileSync } from "node:fs";
3
4
  import { formatOrientationHuman, readOrientation } from "./orientation.js";
@@ -2597,6 +2598,7 @@ async function runCuaBackend(args) {
2597
2598
  let outcome;
2598
2599
  try {
2599
2600
  outcome = await runLab(args.config, {
2601
+ automaticAnalysis: cliAutomaticAnalysisHooks(args.io),
2600
2602
  cwd: args.options.cwd,
2601
2603
  ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
2602
2604
  // Watch mode opens the served Observer below (or prints the phone target under --expose)
@@ -2695,7 +2697,7 @@ async function runCuaBackend(args) {
2695
2697
  };
2696
2698
  }
2697
2699
  writeResult(args.command, args.io, output, formatCuaLabHuman);
2698
- args.io.setExitCode(result.ok ? 0 : 2);
2700
+ args.io.setExitCode(result.ok && automaticAnalysisSucceeded(result) ? 0 : 2);
2699
2701
  if (server && (result.observer?.ok || attachedObserver)) {
2700
2702
  const activeServer = server;
2701
2703
  const followResult = output.observer?.ok ? output.observer : withObserverServer(attachedObserver, activeServer);
@@ -2733,6 +2735,7 @@ async function runScriptedBackend(args) {
2733
2735
  wantsMachine
2734
2736
  });
2735
2737
  const outcome = await runLab(args.config, {
2738
+ automaticAnalysis: cliAutomaticAnalysisHooks(args.io),
2736
2739
  cwd: args.options.cwd,
2737
2740
  ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
2738
2741
  // Watch mode opens the served Observer below instead of the static render.
@@ -2745,7 +2748,7 @@ async function runScriptedBackend(args) {
2745
2748
  }
2746
2749
  const result = outcome.result;
2747
2750
  writeResult(args.command, args.io, result, formatScriptedLabHuman);
2748
- args.io.setExitCode(result.ok ? 0 : 2);
2751
+ args.io.setExitCode(result.ok && automaticAnalysisSucceeded(result) ? 0 : 2);
2749
2752
  // Watch mode serves the freshly rendered Observer (and opens it unless told not to).
2750
2753
  if (args.mode === "watch" && result.ok && !wantsMachine) {
2751
2754
  await renderAndMaybeFollowObserver({
@@ -2770,6 +2773,7 @@ async function runTerminalBackend(args) {
2770
2773
  wantsMachine
2771
2774
  });
2772
2775
  const outcome = await runLab(args.config, {
2776
+ automaticAnalysis: cliAutomaticAnalysisHooks(args.io),
2773
2777
  cwd: args.options.cwd,
2774
2778
  ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
2775
2779
  open: args.mode === "watch" ? false : shouldOpen,
@@ -2782,7 +2786,7 @@ async function runTerminalBackend(args) {
2782
2786
  }
2783
2787
  const result = outcome.result;
2784
2788
  writeResult(args.command, args.io, result, formatTerminalLabHuman);
2785
- args.io.setExitCode(result.ok ? 0 : 2);
2789
+ args.io.setExitCode(result.ok && automaticAnalysisSucceeded(result) ? 0 : 2);
2786
2790
  if (args.mode === "watch" && result.ok && !wantsMachine) {
2787
2791
  await renderAndMaybeFollowObserver({
2788
2792
  command: args.command,
@@ -2804,6 +2808,7 @@ async function runSharedWorldBackend(args) {
2804
2808
  wantsMachine
2805
2809
  });
2806
2810
  const outcome = await runLab(args.config, {
2811
+ automaticAnalysis: cliAutomaticAnalysisHooks(args.io),
2807
2812
  cwd: args.options.cwd,
2808
2813
  ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
2809
2814
  open: args.mode === "watch" ? false : shouldOpen,
@@ -2816,7 +2821,7 @@ async function runSharedWorldBackend(args) {
2816
2821
  }
2817
2822
  const result = outcome.result;
2818
2823
  writeResult(args.command, args.io, result, formatSharedWorldLabHuman);
2819
- args.io.setExitCode(result.ok ? 0 : 2);
2824
+ args.io.setExitCode(result.ok && automaticAnalysisSucceeded(result) ? 0 : 2);
2820
2825
  if (args.mode === "watch" && result.ok && !wantsMachine) {
2821
2826
  await renderAndMaybeFollowObserver({
2822
2827
  command: args.command,
@@ -2886,6 +2891,7 @@ async function runConcurrentSharedWorldBackend(args) {
2886
2891
  let outcome;
2887
2892
  try {
2888
2893
  outcome = await runLab(args.config, {
2894
+ automaticAnalysis: cliAutomaticAnalysisHooks(args.io),
2889
2895
  cwd: args.options.cwd,
2890
2896
  ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
2891
2897
  open: wantsFollow ? false : shouldOpen,
@@ -2932,7 +2938,7 @@ async function runConcurrentSharedWorldBackend(args) {
2932
2938
  };
2933
2939
  }
2934
2940
  writeResult(args.command, args.io, output, formatConcurrentSharedWorldLabHuman);
2935
- args.io.setExitCode(result.ok ? 0 : 2);
2941
+ args.io.setExitCode(result.ok && automaticAnalysisSucceeded(result) ? 0 : 2);
2936
2942
  if (server && output.observer?.ok) {
2937
2943
  await followObserver(args.io, output.observer, server);
2938
2944
  }
@@ -3306,11 +3312,17 @@ function withOssMetaLabServer(result, server) {
3306
3312
  // funnel every real command uses, without duplicating its stdout-vs-formatHuman
3307
3313
  // branching. Not re-exported from src/index.ts; this stays an internal seam.
3308
3314
  export function writeResult(command, io, result, formatHuman) {
3315
+ const output = automaticAnalysisEnvelope(result);
3309
3316
  if (wantsJson(command)) {
3310
- io.writeOut(`${JSON.stringify(result, null, 2)}\n`);
3317
+ io.writeOut(`${JSON.stringify(output, null, 2)}\n`);
3311
3318
  }
3312
3319
  else {
3313
- io.writeOut(formatHuman(result));
3320
+ io.writeOut(formatHuman(output));
3321
+ if (output !== null && typeof output === "object" && "automaticAnalysis" in output) {
3322
+ const analysis = output.automaticAnalysis;
3323
+ if (analysis)
3324
+ io.writeOut(`analysis: ${analysis.state}${analysis.reason ? ` (${analysis.reason})` : ""}\n`);
3325
+ }
3314
3326
  }
3315
3327
  markInvocationEnvelopeWritten(command);
3316
3328
  // Every backend's result passes through here, so this is where a study's facts get read for
@@ -3757,4 +3769,27 @@ function wantsJson(command) {
3757
3769
  }
3758
3770
  return false;
3759
3771
  }
3772
+ /** Listeners exist only while post-run analysis is active; actor signal behavior is unchanged. */
3773
+ export function cliAutomaticAnalysisHooks(io) {
3774
+ const controller = new AbortController();
3775
+ return {
3776
+ deps: { signal: controller.signal },
3777
+ onStart: () => {
3778
+ const cancel = () => { controller.abort(); };
3779
+ const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
3780
+ io.writeErr("Participants finished; preparing analysis…\n");
3781
+ for (const signal of signals)
3782
+ process.on(signal, cancel);
3783
+ return () => { for (const signal of signals)
3784
+ process.off(signal, cancel); };
3785
+ }
3786
+ };
3787
+ }
3788
+ /** Preserve the run's own result while making requested post-processing failures machine-visible. */
3789
+ export function automaticAnalysisEnvelope(result) {
3790
+ if (result === null || typeof result !== "object" || !("automaticAnalysis" in result) || !("ok" in result))
3791
+ return result;
3792
+ const run = result;
3793
+ return { ...run, runOk: run.ok, ok: run.ok && automaticAnalysisSucceeded(run) };
3794
+ }
3760
3795
  //# sourceMappingURL=program.js.map