@basein/runner 0.3.17 → 0.3.18

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 (38) hide show
  1. package/dist/bin/bir-scenario.d.ts +5 -1
  2. package/dist/bin/bir-scenario.js +155 -5
  3. package/dist/bin/bir.js +2 -2
  4. package/dist/bin/scenario-edit.d.ts +7 -0
  5. package/dist/bin/scenario-edit.js +9 -2
  6. package/dist/bin/scenario-liveness.d.ts +12 -1
  7. package/dist/bin/scenario-liveness.js +8 -4
  8. package/dist/bin/setup.js +3 -3
  9. package/dist/control/client.d.ts +5 -0
  10. package/dist/control/client.js +7 -0
  11. package/dist/control/ensure-hook.d.ts +14 -3
  12. package/dist/control/ensure-hook.js +18 -5
  13. package/dist/control/server.d.ts +165 -2
  14. package/dist/control/server.js +719 -21
  15. package/dist/control/transcript.d.ts +19 -0
  16. package/dist/control/transcript.js +57 -0
  17. package/dist/proxy/intercept.js +13 -0
  18. package/dist/proxy/session.d.ts +23 -0
  19. package/dist/proxy/session.js +71 -3
  20. package/dist/record/recorder.d.ts +146 -0
  21. package/dist/record/recorder.js +9 -0
  22. package/dist/record/remote-recorder.d.ts +59 -1
  23. package/dist/record/remote-recorder.js +297 -20
  24. package/dist/record/switchable-recorder.js +6 -0
  25. package/dist/replay/bundle.d.ts +8 -0
  26. package/dist/replay/bundle.js +20 -6
  27. package/dist/replay/controller.d.ts +33 -1
  28. package/dist/replay/controller.js +137 -12
  29. package/dist/replay/derive.d.ts +15 -0
  30. package/dist/replay/derive.js +5 -0
  31. package/dist/replay/plan.d.ts +90 -1
  32. package/dist/replay/plan.js +232 -10
  33. package/dist/replay/source-run.d.ts +2 -2
  34. package/dist/replay/source-run.js +3 -3
  35. package/dist/replay/targets.d.ts +40 -1
  36. package/dist/replay/targets.js +105 -3
  37. package/dist/replay/types.d.ts +6 -5
  38. package/package.json +1 -1
@@ -24,9 +24,26 @@
24
24
  * accepts unauthenticated step reports is a local exfiltration channel.
25
25
  */
26
26
  import { type IntentSource } from "./transcript.js";
27
- import { type Recorder } from "../record/recorder.js";
27
+ import { type AttentionPlan, type Recorder } from "../record/recorder.js";
28
28
  import { type ReplayOptions } from "../replay/controller.js";
29
29
  import { type ServiceHealth } from "../util/service-health.js";
30
+ /**
31
+ * The project a run or a tool list belongs to (the service's review of
32
+ * calcscenarioautocorrect.md, item 16): the first 16 hex characters of the
33
+ * sha256 of its folder, made absolute and — on Windows — lower-cased with
34
+ * forward slashes, as the discovery file's key is (paths.ts, `controlKey`).
35
+ * The service only compares it, so a plan's recording finds its own
36
+ * project's tools and never another project's server of the same name.
37
+ */
38
+ export declare function projectKey(dir: string): string;
39
+ /**
40
+ * The one line a session start shows the person (review item 8): which plan
41
+ * waits, for how long, why, and where to look —
42
+ * `bir: a plan needs you — "Check engaged users and reassign leads" held for 3 days, a correction is waiting: <url>`
43
+ * — and with more than one, how many, and the first one's page. A plan that
44
+ * is not held, whose correction waits, says only that.
45
+ */
46
+ export declare function attentionText(plans: readonly AttentionPlan[], now?: number): string | undefined;
30
47
  /**
31
48
  * The prompt match gate (see {@link ControlServer.armFromMatch}). A match that
32
49
  * answered slower than `slowMs` (`BIR_MATCH_SLOW_MS`), or not inside its
@@ -311,6 +328,20 @@ export declare class ControlServer {
311
328
  private readonly proxySessions;
312
329
  /** `run_scenario` pres not yet consumed by a `/scenario/run`, oldest first. */
313
330
  private directCalls;
331
+ /**
332
+ * `report_wrong_result` pres not yet consumed by a `/scenario/dispute`,
333
+ * oldest first (review item 19): how a report from `bir-scenario`, which is
334
+ * never told its session, finds the session — and so the plan — it is about.
335
+ */
336
+ private reportCalls;
337
+ /** Plans the agent said were wrong, and the service's answer — on its way, or in. */
338
+ private readonly disputed;
339
+ /**
340
+ * The plans that need their owner, by account, as the service last listed
341
+ * them (`GET /scenarios/attention`, review item 8), and the ask still on its
342
+ * way. Null is "nothing can be said": no service, an older one, a failure.
343
+ */
344
+ private readonly attention;
314
345
  /** Plans a `/scenario/run` is executing right now: one run per plan. */
315
346
  private readonly runningPlans;
316
347
  /**
@@ -572,6 +603,16 @@ export declare class ControlServer {
572
603
  */
573
604
  private ensureRun;
574
605
  private runMetadata;
606
+ /**
607
+ * The project key of everything this recorder sends (review item 16): its
608
+ * runs and its tool lists. The folder this recorder serves — the one its
609
+ * discovery file is keyed by and its hooks are installed in — and not a
610
+ * session's `cwd`: that follows the agent's `cd` from turn to turn, and a
611
+ * tool list is sent when its proxy starts, before any of its calls ties it
612
+ * to a session. The service matches a plan's recording to its tools by
613
+ * equality, so both sides must hash the same folder.
614
+ */
615
+ private projectKeyHere;
575
616
  /**
576
617
  * A similar-prompt hit means the service created no run, so every later step
577
618
  * post would 404. Stop recording it — that half is v1 and is mandatory, and
@@ -668,6 +709,16 @@ export declare class ControlServer {
668
709
  * is none, and a `bir-scenario` must have proved it serves the tool.
669
710
  */
670
711
  private deliveryToolAvailable;
712
+ /**
713
+ * Whether a running `bir-scenario` here serves `report_wrong_result` right
714
+ * now (review item 19): one that is not off said so in its hello. What a
715
+ * bundle delivered beside a call of the agent's own (a divergence) is laid
716
+ * out by: such a bundle forbids every tool call but this one. A direct
717
+ * plan's bundle goes by its own `bir-scenario`'s word instead, which came
718
+ * with its `/scenario/run` (see {@link onScenarioRun}). Configured is not
719
+ * connected, as for the delivery tool.
720
+ */
721
+ private reportToolServed;
671
722
  /**
672
723
  * Whether this project's configuration has the `bir` server, as far as
673
724
  * anything here knows: a hook that named one of its tools, the caller's
@@ -681,6 +732,25 @@ export declare class ControlServer {
681
732
  * only — no other I/O.
682
733
  */
683
734
  private liveHellos;
735
+ /**
736
+ * The tool list of each wrapped server last sent to the service, by
737
+ * account, project and server (AC12; review item 16): its hash, when, and
738
+ * whether the service took it (null while the send is on its way).
739
+ */
740
+ private readonly toolListsSent;
741
+ /**
742
+ * `POST /proxy/tools` — a proxy's server listed its tools (`tools/list`;
743
+ * the service's autocorrect.md AC12). Its names, descriptions, input
744
+ * schemas and what it says of each tool (`annotations`) go to the service —
745
+ * secret-shaped text taken out, and within what the service keeps — with
746
+ * the project they are of ({@link projectKeyHere}, the key every run here
747
+ * carries). Sent when the list changed since that server's last one for
748
+ * this account and project, when the last send failed ten minutes ago, or
749
+ * six hours after the last one the service took. `bir off`, and a session
750
+ * started with BIR_OFF=1, send nothing, as for a step. Always `{ ok: true }`;
751
+ * never slow.
752
+ */
753
+ private onProxyTools;
684
754
  /**
685
755
  * `POST /scenario/hello` — a running `bir-scenario` saying what it serves
686
756
  * (K3): on `initialize`, on `tools/list`, when its off state flips and every
@@ -689,6 +759,42 @@ export declare class ControlServer {
689
759
  * and is not off still runs. Always `{ ok: true }`; never slow.
690
760
  */
691
761
  private onScenarioHello;
762
+ /** Remember a `report_wrong_result` pre (see {@link reportCalls}): a few, and only for a while. */
763
+ private noteReportCall;
764
+ /**
765
+ * `POST /scenario/dispute` — the agent said, through `bir`'s
766
+ * `report_wrong_result`, that a replay's results do not answer its request
767
+ * (the service's review of calcscenarioautocorrect.md, item 19): the plan
768
+ * took the wrong half of an "if … otherwise", or acted on the wrong item. A
769
+ * wrong half is caught only when the agent says so, and until now there was
770
+ * no way to say it but in an answer nobody might read.
771
+ *
772
+ * WHOSE PLAN. The session is the one whose `PreToolUse` for the tool carried
773
+ * the request's `toolUseId` (`bir-scenario` forwards the host's id for the
774
+ * call, as for `run_scenario`); without one, the one session where such a
775
+ * call is waiting; without that either, the one session whose plan ran in
776
+ * the last half hour. Never a guess between two. The plan is the newest one
777
+ * that ran in that session's latest turn with a plan: this turn's, or the
778
+ * one before it.
779
+ *
780
+ * WHAT GOES. `POST /scenarios/:scenarioId/dispute` with the reason, `by:
781
+ * "agent"`, and the turn's execution ticket as `executionId` — the id its
782
+ * report books under when the turn ends, so the service may well have the
783
+ * ticket and not yet the row. Once per plan and turn: a second report of the
784
+ * same plan is answered from the first. Nothing here undoes anything.
785
+ *
786
+ * Answers `{ ok, held?, why? }` for `bir-scenario` to put in one sentence.
787
+ * Never throws, and is never slow beyond the service's own bound.
788
+ */
789
+ private onScenarioDispute;
790
+ /** The session a `/scenario/dispute` is about (see {@link onScenarioDispute}), or undefined. */
791
+ private sessionForDispute;
792
+ /**
793
+ * The plan a report of a wrong replay is about: the newest that ran — a
794
+ * step of it did its work — in the session's latest turn with one, this
795
+ * turn or the one before it.
796
+ */
797
+ private disputedPlan;
692
798
  /**
693
799
  * Re-read whether this project configures the `bir` server — only when
694
800
  * ~/.claude.json or .mcp.json changed since the last read. A file the host is
@@ -713,6 +819,20 @@ export declare class ControlServer {
713
819
  * not Claude Code, and undefined when it is.
714
820
  */
715
821
  private hostContext;
822
+ /**
823
+ * The day this session's agent was told it is (issue 1212), read from its
824
+ * transcript each time it is asked. A session of another host has none.
825
+ */
826
+ private agentDayFor;
827
+ /**
828
+ * What a run's finish says of its agent's day (the service's review of
829
+ * calcscenarioautocorrect.md, item 1): the line of the session's system
830
+ * prompt that gives the date — never Claude Code's own date reminder, which
831
+ * is only this machine's day — and this machine's day when the turn's prompt
832
+ * came. The service checks a corrected plan against this run, and reads its
833
+ * prompt with this day, as a replay would have. Undefined with neither.
834
+ */
835
+ private runAgentDay;
716
836
  /**
717
837
  * The earlier tool results the reading of new values may look at: this
718
838
  * prompt's own, from the transcript — and so none for a plan that is
@@ -801,6 +921,20 @@ export declare class ControlServer {
801
921
  /** Transcript cost since `mark`; unmeasured (and zero) without one, or with a model that has no price. */
802
922
  private costSince;
803
923
  private reportExecution;
924
+ /**
925
+ * The plan's own calls of the turn, whole, as an answered turn's report
926
+ * carries them (the service's review of calcscenarioautocorrect.md, item
927
+ * 12): what each step sent and what came back, as they were kept for the
928
+ * turn (replay/controller.ts, `TurnCall`) — in a recording's own form,
929
+ * redacted and capped at 64 KiB apiece, as a redo's copies are (AC2) —
930
+ * where the report's own copies have 3,800 bytes. The calls of a called sub-task are
931
+ * left out: their step numbers are the sub-task's own, and would read as the
932
+ * plan's steps of the same number. `kept` is what the turn kept, taken while
933
+ * the seal still had it; this runs after the answer's wait, off the hook's
934
+ * path. The recorder cuts them to what one report may carry when it sends
935
+ * them.
936
+ */
937
+ private answerCallsOf;
804
938
  /**
805
939
  * Seal the session's run now, and drain it to the service in the background.
806
940
  *
@@ -831,6 +965,26 @@ export declare class ControlServer {
831
965
  */
832
966
  private drainRun;
833
967
  private onSessionStart;
968
+ /**
969
+ * The line a session start shows the person when plans of this account
970
+ * wait for their owner (`GET /scenarios/attention`; the service's review of
971
+ * calcscenarioautocorrect.md, item 8), or undefined. A `systemMessage`:
972
+ * Claude Code shows it to the person and adds nothing to the model's
973
+ * context. Asked at most once in {@link ATTENTION_CACHE_MS} per account (in
974
+ * {@link ATTENTION_RETRY_MS} when it could say nothing), waited for at most
975
+ * {@link ATTENTION_WAIT_MS}, and never while the service is failing; any
976
+ * failure says nothing. Not after a compaction — the
977
+ * session is mid-work, and was told at its start — and never in a session
978
+ * of another host, whose adapter shows a person nothing.
979
+ */
980
+ private attentionLine;
981
+ /**
982
+ * This account's plans that need their owner: the cached answer while it is
983
+ * fresh, else the service's, waited for no longer than
984
+ * {@link ATTENTION_WAIT_MS}. An answer that comes later still fills the
985
+ * cache for the next session start. One ask at a time per account.
986
+ */
987
+ private attentionFor;
834
988
  private onPrompt;
835
989
  /**
836
990
  * `PreToolUse`. Two shapes of answer:
@@ -1353,7 +1507,16 @@ export declare class ControlServer {
1353
1507
  private soleCandidate;
1354
1508
  /** Record the merged pair for a correlation and latch it against re-entry. */
1355
1509
  private settle;
1356
- /** The one place a tool step pair is written. Redaction and caps live here. */
1510
+ /**
1511
+ * The one place a tool step pair is written. Redaction and caps live here.
1512
+ *
1513
+ * Both rows carry the call's id (`metadata.callId`, review item 7) — the
1514
+ * caller's, or one minted here for a call no hook named — and the answer
1515
+ * of a call that failed says so (`metadata.isError`). The service pairs a
1516
+ * call with its answer by that id, where it used to pair them by tool name
1517
+ * in the order they came: two calls of one tool at once, answered out of
1518
+ * order, took each other's answers.
1519
+ */
1357
1520
  private record;
1358
1521
  }
1359
1522
  /**