antechamber 1.0.22 → 1.0.24

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,23 @@ and this project uses [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.24] - 2026-10-27
11
+
12
+ ### Fixed
13
+
14
+ - Keep each reply in its own turn in OpenChamber 2.x after history is reloaded. A reply's request can start a few
15
+ milliseconds before OmO writes its prompt, so a restored reply sorted ahead of its prompt: the first turn's replies
16
+ vanished and each later turn's first reply was drawn in the turn before.
17
+
18
+ ## [1.0.23] - 2026-10-27
19
+
20
+ ### Fixed
21
+
22
+ - Draw shell and eval cards in OpenChamber 2.x as shell cards: the command as code, then its live output. OpenCode
23
+ 2.x renamed `bash` to `shell`, and OpenChamber 2.x drew `bash` cards with its generic body, listing `Command:` and
24
+ `Description:`. The v2 API now reports these cards as `shell`, and the OmO Compatibility extension heads `shell`
25
+ cards too.
26
+
10
27
  ## [1.0.22] - 2026-10-26
11
28
 
12
29
  ### Fixed
@@ -142,6 +142,8 @@ export function parsePiSessionText(s, agentName, raw) {
142
142
  let currentModel = { providerID: "unknown", modelID: "unknown" };
143
143
  let currentThinkingLevel;
144
144
  let lastUserId = "";
145
+ // When the newest user-role record (prompt, context, compaction, user shell) was created. A reply must sort after it.
146
+ let userAt = Number.NEGATIVE_INFINITY;
145
147
  // Like live agent_end, a new user turn closes the previous run: its own
146
148
  // unresolved provider cards end with that run's stop reason.
147
149
  let runAssistant;
@@ -166,6 +168,7 @@ export function parsePiSessionText(s, agentName, raw) {
166
168
  const compaction = compactionMessages(s, e.id ?? `r${indexOf.get(e) ?? 0}`, e.summary, entryTime(e), currentModel, currentThinkingLevel);
167
169
  out.push(...compaction);
168
170
  lastUserId = compaction[0].info.id;
171
+ userAt = compaction[0].info.time.created;
169
172
  continue;
170
173
  }
171
174
  if (e.type === "custom_message") {
@@ -193,6 +196,7 @@ export function parsePiSessionText(s, agentName, raw) {
193
196
  ? [{ type: "text", text: e.content }]
194
197
  : [];
195
198
  const time = entryTime(e);
199
+ userAt = time;
196
200
  if (e.id)
197
201
  s.tree.messageEntries[contextID] = e.id;
198
202
  out.push({
@@ -236,6 +240,7 @@ export function parsePiSessionText(s, agentName, raw) {
236
240
  if (e.id)
237
241
  s.tree.messageEntries[msgId] = e.id;
238
242
  lastUserId = msgId;
243
+ userAt = created;
239
244
  const info = {
240
245
  id: msgId,
241
246
  sessionID,
@@ -263,6 +268,7 @@ export function parsePiSessionText(s, agentName, raw) {
263
268
  const stem = userId?.slice(0, -1) ?? mappedIds[0] ?? `msg_${sessionID}_r${idx}`;
264
269
  const msgId = `${stem}z`;
265
270
  lastUserId = `${stem}u`;
271
+ userAt = created;
266
272
  if (e.id) {
267
273
  s.tree.messageEntries[msgId] = e.id;
268
274
  s.tree.messageEntries[lastUserId] = e.id;
@@ -320,16 +326,17 @@ export function parsePiSessionText(s, agentName, raw) {
320
326
  `msg_${sessionID}_r${idx}`;
321
327
  if (e.id)
322
328
  s.tree.messageEntries[msgId] = e.id;
329
+ // The reply starts when its request starts (`m.timestamp`), which can be a few ms before pi writes the prompt
330
+ // entry that `userAt` comes from. OpenChamber 2.x groups turns by creation time, so a reply created before its
331
+ // prompt would move into the previous turn, or vanish before the first one.
332
+ const started = Math.max(typeof m.timestamp === "number" && Number.isFinite(m.timestamp) && m.timestamp <= created
333
+ ? m.timestamp
334
+ : created, userAt + 1);
323
335
  const info = {
324
336
  id: msgId,
325
337
  sessionID,
326
338
  role: "assistant",
327
- time: {
328
- created: typeof m.timestamp === "number" && Number.isFinite(m.timestamp) && m.timestamp <= created
329
- ? m.timestamp
330
- : created,
331
- completed: created,
332
- },
339
+ time: { created: started, completed: Math.max(created, started) },
333
340
  parentID: lastUserId,
334
341
  modelID: currentModel.modelID,
335
342
  providerID: currentModel.providerID,
package/dist/v2.js CHANGED
@@ -180,17 +180,22 @@ export function toV2AssistantMessage(info) {
180
180
  msg.error = i.error;
181
181
  return msg;
182
182
  }
183
+ /** OpenCode 2.x renamed `bash` to `shell`; OpenChamber 2.x draws a shell card (command, live output) only for `shell`. */
184
+ function v2ToolName(tool) {
185
+ return tool === "bash" ? "shell" : tool;
186
+ }
183
187
  function toolContent(part) {
184
188
  const st = part.state;
189
+ const name = v2ToolName(part.tool);
185
190
  const start = st.status === "pending" ? undefined : st.time.start;
186
191
  const end = st.status === "pending" || st.status === "running" ? undefined : st.time.end;
187
192
  const base = {
188
193
  type: "tool",
189
194
  id: part.callID,
190
- name: part.tool,
195
+ name,
191
196
  // keep the SDK v1 spellings too — harmless and tolerates older readers
192
197
  callID: part.callID,
193
- tool: part.tool,
198
+ tool: name,
194
199
  executed: false,
195
200
  time: {
196
201
  ...(start !== undefined ? { created: start, ran: start } : {}),
@@ -555,11 +560,12 @@ export class V2EventTranslator {
555
560
  }
556
561
  onToolPart(directory, part) {
557
562
  const st = this.state(part.sessionID);
563
+ const name = v2ToolName(part.tool);
558
564
  let ts = st.tools.get(part.id);
559
565
  if (!ts) {
560
566
  ts = {
561
567
  callID: part.callID,
562
- name: part.tool,
568
+ name,
563
569
  started: false,
564
570
  inputEnded: false,
565
571
  called: false,
@@ -576,7 +582,7 @@ export class V2EventTranslator {
576
582
  if (state.status === "pending") {
577
583
  if (!ts.started) {
578
584
  ts.started = true;
579
- frames.push(this.frame(directory, "session.tool.input.started", { ...base, name: part.tool }));
585
+ frames.push(this.frame(directory, "session.tool.input.started", { ...base, name }));
580
586
  }
581
587
  const raw = state.raw ?? "";
582
588
  if (raw.length > ts.raw.length) {
@@ -586,13 +592,13 @@ export class V2EventTranslator {
586
592
  }
587
593
  return frames;
588
594
  }
589
- // mapTool renames a call when it leaves pending (eval -> bash). OpenChamber 2.x takes the tool name only from
595
+ // mapTool renames a call when it leaves pending (eval -> shell). OpenChamber 2.x takes the tool name only from
590
596
  // input.started, so announce the card again under its new name before its input ends.
591
- if (!ts.started || (ts.name !== part.tool && !ts.inputEnded)) {
597
+ if (!ts.started || (ts.name !== name && !ts.inputEnded)) {
592
598
  ts.started = true;
593
- frames.push(this.frame(directory, "session.tool.input.started", { ...base, name: part.tool }));
599
+ frames.push(this.frame(directory, "session.tool.input.started", { ...base, name }));
594
600
  }
595
- ts.name = part.tool;
601
+ ts.name = name;
596
602
  if (!ts.inputEnded) {
597
603
  ts.inputEnded = true;
598
604
  frames.push(this.frame(directory, "session.tool.input.ended", {
@@ -11,10 +11,10 @@ What it does today:
11
11
  instead of the generic "Agent Task".
12
12
 
13
13
  - **Eval cell headers.** OpenChamber 1.24 streams live output only for shell
14
- cards, so antechamber shows OmO eval cells as shell cards. With this extension
15
- their header reads `JS Eval` (or `Python Eval`) and the cell's summary instead
16
- of "Shell Command" and the first line of code. Other shell cards keep their
17
- normal header.
14
+ cards, so antechamber shows OmO eval cells as shell cards (`bash` in OpenChamber
15
+ 1.x, `shell` in 2.x). With this extension their header reads `JS Eval` (or
16
+ `Python Eval`) and the cell's summary instead of "Shell Command" and the first
17
+ line of code. Other shell cards keep their normal header.
18
18
 
19
19
  ## Requirements
20
20
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-compat",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
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",
@@ -22,6 +22,11 @@
22
22
  "title": "{metadata.evalTitle}",
23
23
  "subtitle": "{metadata.evalSubtitle}"
24
24
  },
25
+ {
26
+ "match": "shell",
27
+ "title": "{metadata.evalTitle}",
28
+ "subtitle": "{metadata.evalSubtitle}"
29
+ },
25
30
  {
26
31
  "match": "task",
27
32
  "title": "{metadata.agentTitle}",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-graph",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
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",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-work",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "OpenChamber 2.x Work Status section: OmO todo phases, monitors, eval cells and background work of 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": "1.0.22",
3
+ "version": "1.0.24",
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",