antechamber 1.0.21 → 1.0.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,22 @@ and this project uses [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.23] - 2026-10-27
11
+
12
+ ### Fixed
13
+
14
+ - Draw shell and eval cards in OpenChamber 2.x as shell cards: the command as code, then its live output. OpenCode
15
+ 2.x renamed `bash` to `shell`, and OpenChamber 2.x drew `bash` cards with its generic body, listing `Command:` and
16
+ `Description:`. The v2 API now reports these cards as `shell`, and the OmO Compatibility extension heads `shell`
17
+ cards too.
18
+
19
+ ## [1.0.22] - 2026-10-26
20
+
21
+ ### Fixed
22
+
23
+ - Show terminal turns appended to a session that the adapter last saved while empty, instead of keeping its
24
+ transcript blank. Empty forks and active reverts keep their hidden history.
25
+
10
26
  ## [1.0.21] - 2026-10-26
11
27
 
12
28
  ### Fixed
@@ -64,7 +64,7 @@ export declare function getEntries(pi: PiRpcClient, signal?: AbortSignal): Promi
64
64
  * those carry no conversation, so they do not undo the navigation.
65
65
  */
66
66
  export declare function restoredLeaf(tree: Entries, leaf: string | null): boolean;
67
- export declare function readSessionTree(piPath: string): Entries;
67
+ export declare function readSessionTree(piPath: string, offset?: number): Entries;
68
68
  /** Checkpoint persisted progress after agent_end, successful compaction, or process exit. */
69
69
  export declare function recordTurn(s: ManagedSession): void;
70
70
  /**
@@ -52,8 +52,8 @@ export function restoredLeaf(tree, leaf) {
52
52
  }
53
53
  return true;
54
54
  }
55
- export function readSessionTree(piPath) {
56
- const lines = readFileSync(piPath, "utf8").trimEnd().split("\n");
55
+ export function readSessionTree(piPath, offset = 0) {
56
+ const lines = readFileSync(piPath).subarray(offset).toString("utf8").trimEnd().split("\n");
57
57
  const entries = [];
58
58
  for (const [index, line] of lines.entries()) {
59
59
  if (line.trim().length === 0)
@@ -102,7 +102,10 @@ export function recordTurn(s) {
102
102
  */
103
103
  export function followExternalAppends(s, piPath) {
104
104
  const saved = s.tree.leafId;
105
- if (s.tree.revert || saved === undefined || saved === null)
105
+ if (s.tree.revert || saved === undefined)
106
+ return;
107
+ // A null selection can hide an abandoned branch; require a known append boundary.
108
+ if (saved === null && s.tree.fileSize === undefined)
106
109
  return;
107
110
  const size = statSync(piPath, { throwIfNoEntry: false })?.size;
108
111
  if (size === undefined || (s.tree.fileSize !== undefined && size <= s.tree.fileSize))
@@ -110,6 +113,11 @@ export function followExternalAppends(s, piPath) {
110
113
  let tree;
111
114
  try {
112
115
  tree = readSessionTree(piPath);
116
+ if (saved === null) {
117
+ const appended = new Set(readSessionTree(piPath, s.tree.fileSize).entries.map((entry) => entry.id));
118
+ if (!branchEntries(tree).some((entry) => entry.type === "message" && appended.has(entry.id)))
119
+ return;
120
+ }
113
121
  }
114
122
  catch (error) {
115
123
  // History parsing skips malformed lines; keep the saved selection rather than guess a tail.
@@ -117,7 +125,7 @@ export function followExternalAppends(s, piPath) {
117
125
  return;
118
126
  throw error;
119
127
  }
120
- if (tree.leafId === saved || !branchEntries(tree).some((entry) => entry.id === saved))
128
+ if (tree.leafId === saved || (saved !== null && !branchEntries(tree).some((entry) => entry.id === saved)))
121
129
  return;
122
130
  s.tree.leafId = tree.leafId;
123
131
  }
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.21",
3
+ "version": "1.0.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",
@@ -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.21",
3
+ "version": "1.0.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",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antechamber-omo-work",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
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.21",
3
+ "version": "1.0.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",