@ouro.bot/cli 0.1.0-alpha.95 → 0.1.0-alpha.97

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,19 @@
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.97",
6
+ "changes": [
7
+ "Obligation-bound coding sessions now wake inner dialog when they complete, fail, stall, or need input, so the agent can keep a self-fix loop moving without waiting for the human to nudge it after child work changes state.",
8
+ "That wake stays scoped to real return-loop work instead of every coding progress line, which keeps the live chat visible without turning normal coding chatter into constant reruns."
9
+ ]
10
+ },
11
+ {
12
+ "version": "0.1.0-alpha.96",
13
+ "changes": [
14
+ "ensureSafeRepoWorkspace now re-reads the live branch from the worktree on every call and updates the in-memory and persisted selection when it has drifted, preventing stale workspaceBranch after external branch switches between coding sessions."
15
+ ]
16
+ },
4
17
  {
5
18
  "version": "0.1.0-alpha.95",
6
19
  "changes": [
@@ -207,40 +207,59 @@ function resetSafeWorkspaceSelection(options = {}) {
207
207
  function getActiveSafeWorkspaceSelection() {
208
208
  return activeSelection;
209
209
  }
210
- function ensureSafeRepoWorkspace(options = {}) {
211
- if (activeSelection) {
212
- return activeSelection;
210
+ function refreshSelectionWorkspaceBranch(selection, spawnSync) {
211
+ try {
212
+ if (!isGitClone(selection.workspaceRoot, spawnSync)) {
213
+ return selection;
214
+ }
215
+ const liveBranch = readCurrentBranch(selection.workspaceRoot, spawnSync);
216
+ if (liveBranch === selection.workspaceBranch) {
217
+ return selection;
218
+ }
219
+ return { ...selection, workspaceBranch: liveBranch };
213
220
  }
214
- const repoRoot = options.repoRoot ?? (0, identity_1.getRepoRoot)();
221
+ catch {
222
+ return selection;
223
+ }
224
+ }
225
+ function ensureSafeRepoWorkspace(options = {}) {
215
226
  const agentName = resolveAgentName(options.agentName);
216
- const canonicalRepoUrl = options.canonicalRepoUrl ?? identity_1.HARNESS_CANONICAL_REPO_URL;
217
227
  const workspaceBase = options.workspaceRoot ?? (0, identity_1.getAgentRepoWorkspacesRoot)(agentName);
218
228
  const persistSelection = shouldPersistSelection(options);
219
229
  const spawnSync = options.spawnSync ?? child_process_1.spawnSync;
220
230
  const existsSync = options.existsSync ?? fs.existsSync;
221
231
  const mkdirSync = options.mkdirSync ?? fs.mkdirSync;
222
232
  const rmSync = options.rmSync ?? fs.rmSync;
233
+ if (activeSelection) {
234
+ const refreshed = refreshSelectionWorkspaceBranch(activeSelection, spawnSync);
235
+ activeSelection = refreshed;
236
+ return refreshed;
237
+ }
238
+ const repoRoot = options.repoRoot ?? (0, identity_1.getRepoRoot)();
239
+ const canonicalRepoUrl = options.canonicalRepoUrl ?? identity_1.HARNESS_CANONICAL_REPO_URL;
223
240
  const now = options.now ?? defaultNow;
224
241
  const stamp = String(now());
225
242
  registerCleanupHook({ rmSync });
226
243
  if (persistSelection) {
227
244
  const restored = loadPersistedSelection(workspaceBase, options);
228
245
  if (restored) {
229
- activeSelection = restored;
246
+ const refreshed = refreshSelectionWorkspaceBranch(restored, spawnSync);
247
+ activeSelection = refreshed;
248
+ persistSelectionState(workspaceBase, refreshed, options);
230
249
  (0, runtime_1.emitNervesEvent)({
231
250
  component: "workspace",
232
251
  event: "workspace.safe_repo_restored",
233
252
  message: "restored safe repo workspace after runtime restart",
234
253
  meta: {
235
- runtimeKind: restored.runtimeKind,
236
- repoRoot: restored.repoRoot,
237
- workspaceRoot: restored.workspaceRoot,
238
- workspaceBranch: restored.workspaceBranch,
239
- sourceBranch: restored.sourceBranch,
240
- cleanupAfterMerge: restored.cleanupAfterMerge,
254
+ runtimeKind: refreshed.runtimeKind,
255
+ repoRoot: refreshed.repoRoot,
256
+ workspaceRoot: refreshed.workspaceRoot,
257
+ workspaceBranch: refreshed.workspaceBranch,
258
+ sourceBranch: refreshed.sourceBranch,
259
+ cleanupAfterMerge: refreshed.cleanupAfterMerge,
241
260
  },
242
261
  });
243
- return restored;
262
+ return refreshed;
244
263
  }
245
264
  }
246
265
  let selection;
@@ -3,9 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatCodingTail = formatCodingTail;
4
4
  exports.attachCodingSessionFeedback = attachCodingSessionFeedback;
5
5
  const identity_1 = require("../../heart/identity");
6
+ const socket_client_1 = require("../../heart/daemon/socket-client");
6
7
  const obligations_1 = require("../../heart/obligations");
7
8
  const runtime_1 = require("../../nerves/runtime");
8
9
  const TERMINAL_UPDATE_KINDS = new Set(["completed", "failed", "killed"]);
10
+ const OBLIGATION_WAKE_UPDATE_KINDS = new Set([
11
+ "waiting_input",
12
+ "stalled",
13
+ "completed",
14
+ "failed",
15
+ "killed",
16
+ ]);
9
17
  function clip(text, maxLength = 280) {
10
18
  const trimmed = text.trim();
11
19
  if (trimmed.length <= maxLength)
@@ -124,6 +132,27 @@ function syncObligationFromUpdate(update) {
124
132
  // Detached feedback should still reach the human even if obligation sync is unavailable.
125
133
  }
126
134
  }
135
+ async function wakeInnerDialogForObligation(update) {
136
+ if (!update.session.obligationId || !OBLIGATION_WAKE_UPDATE_KINDS.has(update.kind)) {
137
+ return;
138
+ }
139
+ try {
140
+ await (0, socket_client_1.requestInnerWake)((0, identity_1.getAgentName)());
141
+ }
142
+ catch (error) {
143
+ (0, runtime_1.emitNervesEvent)({
144
+ level: "warn",
145
+ component: "repertoire",
146
+ event: "repertoire.coding_feedback_wake_error",
147
+ message: "coding feedback wake request failed",
148
+ meta: {
149
+ sessionId: update.session.id,
150
+ kind: update.kind,
151
+ reason: error instanceof Error ? error.message : String(error),
152
+ },
153
+ });
154
+ }
155
+ }
127
156
  function formatCodingTail(session) {
128
157
  const stdout = session.stdoutTail.trim() || "(empty)";
129
158
  const stderr = session.stderrTail.trim() || "(empty)";
@@ -143,7 +172,7 @@ function formatCodingTail(session) {
143
172
  function attachCodingSessionFeedback(manager, session, target) {
144
173
  let lastMessage = "";
145
174
  let closed = false;
146
- let unsubscribe = () => { };
175
+ let unsubscribe = null;
147
176
  const sendMessage = (message) => {
148
177
  if (closed || !message || message === lastMessage) {
149
178
  return;
@@ -168,13 +197,14 @@ function attachCodingSessionFeedback(manager, session, target) {
168
197
  unsubscribe = manager.subscribe(session.id, async (update) => {
169
198
  syncObligationFromUpdate(update);
170
199
  sendMessage(formatUpdateMessage(update));
200
+ await wakeInnerDialogForObligation(update);
171
201
  if (TERMINAL_UPDATE_KINDS.has(update.kind)) {
172
202
  closed = true;
173
- unsubscribe();
203
+ unsubscribe?.();
174
204
  }
175
205
  });
176
206
  return () => {
177
207
  closed = true;
178
- unsubscribe();
208
+ unsubscribe?.();
179
209
  };
180
210
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.95",
3
+ "version": "0.1.0-alpha.97",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",