antechamber 0.2.22 → 0.2.23

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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project uses [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.23] - 2026-10-17
11
+
12
+ - feat(monitors): show matched lines in monitor sessions (#32)
13
+
10
14
  ## [0.2.22] - 2026-10-17
11
15
 
12
16
  - fix(tools): stream live bash and eval output into OpenChamber cards (#29)
@@ -41,6 +45,10 @@ and this project uses [Semantic Versioning](https://semver.org/).
41
45
  - OmO Compatibility, a second bundled OpenChamber extension (1.24 or newer) with no code or permissions. It heads
42
46
  eval cards with `JS Eval` or `Python Eval` and the cell's summary.
43
47
 
48
+ ### Added
49
+
50
+ - Show the lines an OmO monitor matched in its monitor session, as they fire.
51
+
44
52
  ## [0.2.18] - 2026-10-17
45
53
 
46
54
  - test(endpoints): await the abort_bash dispatch instead of reading a flag (#27)
@@ -3,6 +3,8 @@ import type { OCEvent, OCMessageWithParts } from "./types.js";
3
3
  /** Names OmO's terminal extension passes to `pi.rpc.emit` (core/extensions/builtin/monitor-state-event.js). */
4
4
  export declare const MONITOR_STATE_EVENT = "terminal_monitor_state";
5
5
  export declare const MONITOR_ENDED_EVENT = "terminal_monitor_ended";
6
+ /** customType of the custom message OmO sends with a watch's matched lines (raw RPC capture of installed omo-ai 5.1.33, 2026-10-17). */
7
+ export declare const MONITOR_NOTIFICATION = "senpi-monitor:notification";
6
8
  export interface MonitorSnapshot {
7
9
  id: string;
8
10
  description: string;
@@ -33,6 +35,8 @@ export declare class MonitorSessions {
33
35
  owns(id: string): boolean;
34
36
  messages(id: string): OCMessageWithParts[];
35
37
  observe(parent: ManagedSession, ev: Record<string, unknown>): void;
38
+ /** A hidden `senpi-monitor:notification` custom message: append its lines to each watch it names. */
39
+ notify(parent: ManagedSession, message: Record<string, unknown>): void;
36
40
  /** The agent process is gone: OmO's in-process watches died with it. */
37
41
  stopParent(parentID: string): void;
38
42
  /** Forget a deleted child, or every child of a deleted parent. */
@@ -8,6 +8,10 @@ import { ocIdFor } from "./session-store.js";
8
8
  /** Names OmO's terminal extension passes to `pi.rpc.emit` (core/extensions/builtin/monitor-state-event.js). */
9
9
  export const MONITOR_STATE_EVENT = "terminal_monitor_state";
10
10
  export const MONITOR_ENDED_EVENT = "terminal_monitor_ended";
11
+ /** customType of the custom message OmO sends with a watch's matched lines (raw RPC capture of installed omo-ai 5.1.33, 2026-10-17). */
12
+ export const MONITOR_NOTIFICATION = "senpi-monitor:notification";
13
+ /** Matched lines kept per watch; older lines are dropped. */
14
+ const MAX_EVENT_LINES = 200;
11
15
  function record(value) {
12
16
  return value !== null && typeof value === "object" && !Array.isArray(value);
13
17
  }
@@ -95,6 +99,27 @@ export class MonitorSessions {
95
99
  else if (ev.name === MONITOR_ENDED_EVENT)
96
100
  this.applyEnded(parent, ev.data);
97
101
  }
102
+ /** A hidden `senpi-monitor:notification` custom message: append its lines to each watch it names. */
103
+ notify(parent, message) {
104
+ if (typeof message.content !== "string" || !record(message.details) || !Array.isArray(message.details.monitors))
105
+ return;
106
+ const lines = message.content
107
+ .replaceAll(/<\/?system-reminder>/g, "")
108
+ .replace(/^Monitor event\([^\n]*?\):\s?/, "")
109
+ .split("\n")
110
+ .filter((line) => line.trim() !== "");
111
+ if (lines.length === 0)
112
+ return;
113
+ for (const entry of message.details.monitors) {
114
+ if (!record(entry) || typeof entry.id !== "string")
115
+ continue;
116
+ const watch = this.watches.get(this.childID(parent, entry.id));
117
+ if (!watch)
118
+ continue;
119
+ watch.lines = [...watch.lines, ...lines].slice(-MAX_EVENT_LINES);
120
+ this.publish(watch);
121
+ }
122
+ }
98
123
  /** The agent process is gone: OmO's in-process watches died with it. */
99
124
  stopParent(parentID) {
100
125
  for (const watch of this.watches.values()) {
@@ -193,14 +218,14 @@ export class MonitorSessions {
193
218
  hasPendingInteraction: () => false,
194
219
  hasRunningChildren: () => false,
195
220
  };
196
- const watch = { session, monitor };
221
+ const watch = { session, monitor, lines: [] };
197
222
  this.watches.set(id, watch);
198
223
  this.sessions.set(id, session);
199
224
  this.emit(session.info.directory, { type: "session.created", properties: { info: session.info } });
200
225
  this.publish(watch);
201
226
  }
202
227
  publish(watch) {
203
- const { session, monitor, ending } = watch;
228
+ const { session, monitor, ending, lines } = watch;
204
229
  const directory = session.info.directory;
205
230
  const sessionID = session.info.id;
206
231
  const base = sessionID.replace(/^ses_/, "");
@@ -208,7 +233,8 @@ export class MonitorSessions {
208
233
  const started = monitor.startedAtMs;
209
234
  const command = monitor.command ?? monitor.description;
210
235
  const input = { command, description: monitor.description };
211
- const output = monitorSummary(monitor, ending);
236
+ const summary = monitorSummary(monitor, ending);
237
+ const output = lines.length > 0 ? `${summary}\n\n${lines.join("\n")}` : summary;
212
238
  const tool = {
213
239
  id: `prt_${base}_tool`,
214
240
  sessionID,
@@ -3,7 +3,7 @@ import type { OCAssistantMessage, OCMessageWithParts, OCModelRef, OCEvent, OCSes
3
3
  import type { ManagedSession } from "./sessions.js";
4
4
  import type { SessionStore } from "./session-store.js";
5
5
  import type { SubagentBridge } from "./subagents.js";
6
- import type { MonitorSessions } from "./monitor-sessions.js";
6
+ import { type MonitorSessions } from "./monitor-sessions.js";
7
7
  import { type TodoUpdated } from "./todo-bridge.js";
8
8
  export interface PiUsage {
9
9
  input?: number;
@@ -1,5 +1,6 @@
1
1
  /** Pi message/part translation and the live event bridge, with explicit manager services. */
2
2
  import { randomUUID } from "node:crypto";
3
+ import { MONITOR_NOTIFICATION } from "./monitor-sessions.js";
3
4
  import { applyProviderToolResults, finishProviderToolParts, mapTool, providerToolParts, resultMetadata, resultText, toolFailed, } from "./tool-map.js";
4
5
  import { TodoBridge } from "./todo-bridge.js";
5
6
  import { readSessionTree, recordTurn } from "./session-tree.js";
@@ -443,6 +444,11 @@ export class PiEventTranslator {
443
444
  case "message_start": {
444
445
  if (this.reconcileUser(s, ev))
445
446
  return;
447
+ const custom = ev.message;
448
+ if (custom?.role === "custom" && custom.customType === MONITOR_NOTIFICATION) {
449
+ this.services.monitors.notify(s, custom);
450
+ return;
451
+ }
446
452
  const msg = ev.message;
447
453
  if (msg?.role !== "assistant")
448
454
  return; // user message already recorded at prompt()
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-compat",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "description": "OpenChamber extension: displays OmO tool calls the way OmO means them when OpenChamber runs on antechamber",
5
5
  "private": true,
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-graph",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "description": "OpenChamber extension: live, interactive graph of the OmO sub-agents behind the current session",
5
5
  "private": true,
6
6
  "type": "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "description": "OpenCode-compatible HTTP/SSE server that lets OpenChamber drive the pi coding agent (and OmO) over RPC",
5
5
  "type": "module",
6
6
  "license": "MIT",