@ouro.bot/cli 0.1.0-alpha.921 → 0.1.0-alpha.922

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.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.922",
6
+ "changes": [
7
+ "Make Shepherd overview read fresh bounded screens for every terminal, separate historical returns, and report individual read failures."
8
+ ]
9
+ },
4
10
  {
5
11
  "version": "0.1.0-alpha.921",
6
12
  "changes": [
@@ -1,5 +1,5 @@
1
1
  {
2
- "runtimeVersion": "0.1.0-alpha.921",
2
+ "runtimeVersion": "0.1.0-alpha.922",
3
3
  "bundleSchemaVersion": 3,
4
4
  "lastUpdated": "2026-09-03T00:00:00.000Z"
5
5
  }
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0"?>
2
2
  <Container version="2">
3
3
  <Name>ouro-butler</Name>
4
- <Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.921</Repository>
4
+ <Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.922</Repository>
5
5
  <Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
6
6
  <Network>host</Network>
7
7
  <Shell>sh</Shell>
@@ -45,13 +45,16 @@ const redact_1 = require("../senses/shepherd/redact");
45
45
  const returns_1 = require("../senses/shepherd/returns");
46
46
  const tools_base_1 = require("./tools-base");
47
47
  /**
48
- * Shepherd's tools: every coding-agent session on this machine's terminal host with what Shepherd
49
- * last decided about it (`shepherd_overview`), what a session shows (`shepherd_read`), a status
48
+ * Shepherd's tools: every coding-agent session on this machine's terminal host with a current screen
49
+ * and what Shepherd last decided about it (`shepherd_overview`), a deeper read (`shepherd_read`), a status
50
50
  * line or notification for the human (`shepherd_signal`), and a line or key typed for the human
51
51
  * who asked for it (`shepherd_send`).
52
52
  */
53
53
  const STATUS_MAX_CHARS = 120;
54
54
  const READ_MAX_CHARS = 16_000;
55
+ const OVERVIEW_READ_LINES = 80;
56
+ const OVERVIEW_SCREEN_MAX_CHARS = 4_000;
57
+ const OVERVIEW_TOTAL_SCREEN_MAX_CHARS = 64_000;
55
58
  exports.SEND_TEXT_MAX_CHARS = 2_000;
56
59
  exports.SEND_KEYS = ["enter", "escape", "up", "down", "tab", "ctrl-c", "1", "2", "3", "4", "5", "6", "7", "8", "9", "y", "n"];
57
60
  /** Keys that can approve or choose something on a prompt: pressed only on the screen the caller last read. */
@@ -91,12 +94,27 @@ async function withHost(tool, ctx, run) {
91
94
  return JSON.stringify({ error: error.message });
92
95
  }
93
96
  }
97
+ async function currentScreen(host, session, maxChars) {
98
+ try {
99
+ const raw = await host.read(session, OVERVIEW_READ_LINES);
100
+ // Frame glyphs and padded empty rows otherwise crowd actual work out of a multi-terminal snapshot.
101
+ const content = (0, redact_1.redactSecrets)(raw).split("\n")
102
+ .map(line => line.replace(/[\u2500-\u259f]/g, "").trimEnd())
103
+ .filter(line => line.trim().length > 0).join("\n");
104
+ return { at: new Date().toISOString(), text: content.slice(Math.max(0, content.length - maxChars)), truncated: content.length > maxChars };
105
+ }
106
+ catch (error) {
107
+ const message = (0, redact_1.redactSecrets)(error instanceof Error ? error.message : String(error));
108
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "repertoire", event: "repertoire.shepherd_overview_read_error", message: "could not read one terminal in the live Shepherd overview", meta: { session, error: message } });
109
+ return { at: new Date().toISOString(), error: message };
110
+ }
111
+ }
94
112
  exports.shepherdOverviewToolDefinition = {
95
113
  tool: {
96
114
  type: "function",
97
115
  function: {
98
116
  name: "shepherd_overview",
99
- description: "Every terminal session on this machine's terminal host (cmux), with the coding agent there when known, and the last time Shepherd judged a return of control in it: when, what kind (premature, gate, done, unclear, loop_guard, error), whether it answered, and why. Read-only.",
117
+ description: "A live, read-only snapshot of every terminal on this machine's host (cmux): agent, folder, workspace and tab, plus a freshly read, redacted, bounded currentScreen with its observation time. Use currentScreen to answer what agents are doing now in one reply; lastReturn is historical and must not be presented as current status. A currentScreen.error explicitly identifies a terminal that could not be read; explain it inline with the other sessions, not by asking for another turn. For deeper details use shepherd_read. terminalCount is authoritative; derive any category counts from the actual listed sessions. Historical lastReturn includes the prior judgment time, kind, action and reason.",
100
118
  parameters: { type: "object", properties: {}, additionalProperties: false },
101
119
  },
102
120
  },
@@ -104,12 +122,15 @@ exports.shepherdOverviewToolDefinition = {
104
122
  const last = new Map();
105
123
  for (const record of (0, returns_1.readReturns)(ctx.agentRoot))
106
124
  last.set(record.session, record);
125
+ const sessions = await host.list();
126
+ const screenLimit = Math.min(OVERVIEW_SCREEN_MAX_CHARS, Math.floor(OVERVIEW_TOTAL_SCREEN_MAX_CHARS / Math.max(1, sessions.length)));
107
127
  return {
108
128
  host: host.name,
109
- sessions: (await host.list()).map((session) => {
129
+ terminalCount: sessions.length,
130
+ sessions: await Promise.all(sessions.map(async (session) => {
110
131
  const record = last.get(session.id);
111
- return { ...session, ...(record ? { lastReturn: { at: record.at, kind: record.kind, action: record.action, reason: record.reason, reply: record.reply, task: record.task } } : {}) };
112
- }),
132
+ return { ...session, currentScreen: await currentScreen(host, session.id, screenLimit), ...(record ? { lastReturn: { at: record.at, kind: record.kind, action: record.action, reason: record.reason, reply: record.reply, task: record.task } } : {}) };
133
+ })),
113
134
  };
114
135
  }),
115
136
  summaryKeys: [],
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.921",
3
+ "version": "0.1.0-alpha.922",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@ouro.bot/cli",
9
- "version": "0.1.0-alpha.921",
9
+ "version": "0.1.0-alpha.922",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.78.0",
12
12
  "@azure/identity": "^4.13.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.921",
3
+ "version": "0.1.0-alpha.922",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },