@bybrawe/opencode-loop 0.6.6 → 0.6.7

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.
@@ -134,7 +134,7 @@ export function createNativeLoopRuntime(options = {}) {
134
134
  async function finish(scope) {
135
135
  const run = scope.active
136
136
  if (!run || scope.compaction || scope.busy) return result({ reason: "no-terminal-boundary" })
137
- if ((run.kind === "prompt" && !run.delivered) || (run.kind === "command" && !run.commandFinished) || (run.kind === "shell" && !run.shellFinished) || (["compact", "cadence"].includes(run.kind) && !run.compactFinished)) {
137
+ if ((run.kind === "prompt" && !run.delivered) || (run.kind === "command" && !run.commandFinished) || (run.kind === "shell" && !run.shellFinished) || (["compact", "cadence"].includes(run.kind) && (!run.compactionStarted || !run.compactFinished))) {
138
138
  return result({ reason: "awaiting-owned-completion" })
139
139
  }
140
140
  clear(scope, "deadline")
@@ -368,6 +368,14 @@ export function createNativeLoopRuntime(options = {}) {
368
368
  }
369
369
  if (event.kind === "compaction" && event.action === "started") {
370
370
  scope.compaction ||= { ended: false, terminal: false }
371
+ // Host versions may differ in compaction inbox-delivery events. The
372
+ // authoritative boundary is the published manual-compaction inputID
373
+ // matching our admitted durable item, not delivery alone.
374
+ if (
375
+ ["compact", "cadence"].includes(scope.active?.kind)
376
+ && event.reason === "manual"
377
+ && event.inputID && event.inputID === scope.active.inboxID
378
+ ) scope.active.compactionStarted = true
371
379
  scope.busy = true
372
380
  clear(scope, "timer")
373
381
  return result({ reason: "compacting" })
@@ -420,10 +428,28 @@ export function createNativeLoopRuntime(options = {}) {
420
428
  return finish(scope)
421
429
  }
422
430
  if ((event.kind === "session" && ["error", "failed", "interrupted"].includes(event.action)) || (event.kind === "compaction" && event.action === "failed")) {
431
+ const run = scope.active
432
+ // Unowned compaction failures must not pause unrelated scheduled Loop
433
+ // work. An automated host summary can fail when no Loop job owns it,
434
+ // and a different manual inputID cannot settle our pending request.
435
+ if (event.kind === "compaction" && event.action === "failed") {
436
+ const compactRun = ["compact", "cadence"].includes(run?.kind)
437
+ const owned = compactRun && event.reason === "manual" &&
438
+ ((event.inputID && event.inputID === run.inboxID) ||
439
+ (!event.inputID && run.compactionStarted))
440
+ if (!run || (compactRun && !owned)) {
441
+ delete scope.compaction
442
+ scope.busy = false
443
+ return result({ reason: "unowned-compaction-failed" })
444
+ }
445
+ }
423
446
  delete scope.compaction
424
447
  scope.busy = false
425
- const run = scope.active
426
- const paused = await pauseActive(scope, event.reason || `${event.kind}-${event.action}`)
448
+ const detail = String(event.error || "").replace(/\s+/g, " ").trim().slice(0, 160)
449
+ const reason = event.kind === "compaction"
450
+ ? `compaction-failed${detail ? `: ${detail}` : ""}`
451
+ : event.reason || `${event.kind}-${event.action}`
452
+ const paused = await pauseActive(scope, reason)
427
453
  if (run && (run.delivered || ["compact", "cadence", "shell"].includes(run.kind))) {
428
454
  const state = await read(scope)
429
455
  const job = (state.jobs || []).find((entry) => entry.id === run.jobID)
@@ -435,7 +461,7 @@ export function createNativeLoopRuntime(options = {}) {
435
461
  if (event.kind === "compaction" && event.action === "ended") {
436
462
  scope.compaction ||= { ended: false, terminal: false }
437
463
  scope.compaction.ended = true
438
- if (["compact", "cadence"].includes(scope.active?.kind)) scope.active.compactFinished = true
464
+ if (["compact", "cadence"].includes(scope.active?.kind) && scope.active.compactionStarted && event.reason === "manual") scope.active.compactFinished = true
439
465
  if (!scope.compaction.terminal) return result({ reason: "awaiting-execution-terminal" })
440
466
  } else if (event.kind === "session" && event.action === "idle") {
441
467
  if (scope.compaction) { scope.compaction.terminal = true; if (!scope.compaction.ended) return result({ reason: "awaiting-compaction-end" }) }