@songsid/agend 2.2.0-alpha.1 → 2.2.0-alpha.2
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/README.md +2 -0
- package/README.zh-TW.md +2 -0
- package/dist/agent-cli.js +6 -1
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +68 -12
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-token-header.d.ts +13 -0
- package/dist/agent-token-header.js +16 -0
- package/dist/agent-token-header.js.map +1 -0
- package/dist/backend/antigravity.js +4 -3
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/grok.js +1 -1
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +7 -0
- package/dist/backend/kiro.js +82 -33
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +1 -1
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +6 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-analysis.d.ts +92 -0
- package/dist/cache-analysis.js +147 -0
- package/dist/cache-analysis.js.map +1 -0
- package/dist/cache-ledger.d.ts +108 -0
- package/dist/cache-ledger.js +230 -0
- package/dist/cache-ledger.js.map +1 -0
- package/dist/cache-prices.d.ts +32 -0
- package/dist/cache-prices.js +73 -0
- package/dist/cache-prices.js.map +1 -0
- package/dist/cache-scan.d.ts +39 -0
- package/dist/cache-scan.js +115 -0
- package/dist/cache-scan.js.map +1 -0
- package/dist/cache-service.d.ts +115 -0
- package/dist/cache-service.js +417 -0
- package/dist/cache-service.js.map +1 -0
- package/dist/cli-entry.d.ts +19 -0
- package/dist/cli-entry.js +36 -0
- package/dist/cli-entry.js.map +1 -0
- package/dist/cli.js +251 -24
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +6 -0
- package/dist/daemon.js +90 -37
- package/dist/daemon.js.map +1 -1
- package/dist/event-log.d.ts +4 -1
- package/dist/event-log.js +6 -3
- package/dist/event-log.js.map +1 -1
- package/dist/fleet-control-audit.d.ts +5 -0
- package/dist/fleet-control-audit.js +7 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-level-config.js +22 -0
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +46 -0
- package/dist/fleet-manager.js +287 -40
- package/dist/fleet-manager.js.map +1 -1
- package/dist/full-restart.js +2 -3
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +3 -1
- package/dist/install-lock.d.ts +49 -0
- package/dist/install-lock.js +200 -0
- package/dist/install-lock.js.map +1 -0
- package/dist/instance-config-impact.js +3 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/locale.js +14 -0
- package/dist/locale.js.map +1 -1
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/package-preimage.d.ts +26 -0
- package/dist/package-preimage.js +96 -0
- package/dist/package-preimage.js.map +1 -0
- package/dist/public-web-gateway.js +2 -2
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart.js +10 -4
- package/dist/quickstart.js.map +1 -1
- package/dist/restart-guard.d.ts +52 -0
- package/dist/restart-guard.js +109 -0
- package/dist/restart-guard.js.map +1 -0
- package/dist/scheduler/db.js +6 -2
- package/dist/scheduler/db.js.map +1 -1
- package/dist/service-activation.d.ts +47 -5
- package/dist/service-activation.js +156 -51
- package/dist/service-activation.js.map +1 -1
- package/dist/service-installer.d.ts +56 -1
- package/dist/service-installer.js +134 -12
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +65 -0
- package/dist/service-plan.js +108 -0
- package/dist/service-plan.js.map +1 -0
- package/dist/settings-api.js +46 -5
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +34 -6
- package/dist/settings-change.js.map +1 -1
- package/dist/setup-host.js +2 -3
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +2 -1
- package/dist/setup-wizard.js.map +1 -1
- package/dist/sqlite-open-errors.d.ts +12 -0
- package/dist/sqlite-open-errors.js +13 -0
- package/dist/sqlite-open-errors.js.map +1 -0
- package/dist/tmux-control.d.ts +22 -0
- package/dist/tmux-control.js +89 -5
- package/dist/tmux-control.js.map +1 -1
- package/dist/topic-commands.js +14 -5
- package/dist/topic-commands.js.map +1 -1
- package/dist/ui/chat-commands.js +43 -0
- package/dist/ui/chat-render.js +2 -2
- package/dist/ui/chat-store.js +30 -1
- package/dist/ui/chat-strings.js +22 -2
- package/dist/ui/chat-thread.js +47 -10
- package/dist/ui/fleet-cache.js +168 -0
- package/dist/ui/panel-chat.js +104 -18
- package/dist/ui/panel-fleet.js +26 -12
- package/dist/ui/panel-settings.js +12 -8
- package/dist/ui/preview-panel.js +202 -0
- package/dist/ui/preview.js +7 -3
- package/dist/ui/settings-strings.js +4 -2
- package/dist/ui/shared/app-route.js +1 -1
- package/dist/ui/shared/app-shell.js +6 -4
- package/dist/ui/shared/app.css +147 -3
- package/dist/ui/shared/signin.js +13 -1
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/signin.html +2 -1
- package/dist/update-dispatch.d.ts +28 -0
- package/dist/update-dispatch.js +73 -0
- package/dist/update-dispatch.js.map +1 -0
- package/dist/update-install.d.ts +65 -7
- package/dist/update-install.js +126 -26
- package/dist/update-install.js.map +1 -1
- package/dist/web-api.d.ts +14 -0
- package/dist/web-api.js +65 -0
- package/dist/web-api.js.map +1 -1
- package/dist/web-commands.d.ts +77 -0
- package/dist/web-commands.js +81 -0
- package/dist/web-commands.js.map +1 -0
- package/dist/web-shell-routes.d.ts +1 -1
- package/dist/web-shell-routes.js +1 -1
- package/dist/web-shell-routes.js.map +1 -1
- package/launcher/agend +110 -0
- package/launcher/agend-agent +110 -0
- package/launcher/agend-agent.cjs +4 -0
- package/launcher/agend.cjs +4 -0
- package/launcher/install-admission.cjs +105 -0
- package/launcher/launch.cjs +64 -0
- package/launcher/postinstall.cjs +114 -0
- package/launcher/run-in-process.cjs +13 -0
- package/launcher/runtime-platform.cjs +86 -0
- package/launcher/runtime-select.cjs +217 -0
- package/package.json +12 -4
- package/scripts/preinstall-guard.cjs +40 -21
- package/templates/launchd.plist.ejs +2 -2
- package/templates/systemd.service.ejs +1 -1
package/dist/daemon.d.ts
CHANGED
|
@@ -536,6 +536,8 @@ export declare class Daemon extends EventEmitter {
|
|
|
536
536
|
/** Generation/signature fence for safety dialogs while their screen is still visible. */
|
|
537
537
|
private autoResolvedDialogKey;
|
|
538
538
|
private autoResolvedDialogGeneration;
|
|
539
|
+
/** Per-launch safety phases survive startup handoff, redraws and failed/uncertain key ACKs. */
|
|
540
|
+
private launchDialogClaims;
|
|
539
541
|
/**
|
|
540
542
|
* (#1103) Proof that THIS spawn's Codex went onto Luna Reserve: AgEnD saw (and
|
|
541
543
|
* answered) the usage-limit menu that codex shows when it switches itself to
|
|
@@ -1493,6 +1495,8 @@ export declare class Daemon extends EventEmitter {
|
|
|
1493
1495
|
private static dialogMatches;
|
|
1494
1496
|
/** Refresh the separate stdin-blocked observation from one pane capture. */
|
|
1495
1497
|
private updateInputBlockedState;
|
|
1498
|
+
private hasAutoDialogClaim;
|
|
1499
|
+
private claimAutoDialog;
|
|
1496
1500
|
/** Whether a runtime prompt currently owns the pane's stdin. */
|
|
1497
1501
|
isInputBlocked(): boolean;
|
|
1498
1502
|
/**
|
|
@@ -1767,6 +1771,8 @@ export declare class Daemon extends EventEmitter {
|
|
|
1767
1771
|
* an invariant maintained by comments.
|
|
1768
1772
|
*/
|
|
1769
1773
|
private sendDeliveryEnter;
|
|
1774
|
+
/** Write half only: callers must finish the availability wait before any final recovery ownership proof. */
|
|
1775
|
+
private sendDeliveryEnterAfterAvailability;
|
|
1770
1776
|
private writeMessageToPane;
|
|
1771
1777
|
/**
|
|
1772
1778
|
* The single place a pasted message is judged submitted, shared by the
|
package/dist/daemon.js
CHANGED
|
@@ -1168,6 +1168,8 @@ export class Daemon extends EventEmitter {
|
|
|
1168
1168
|
/** Generation/signature fence for safety dialogs while their screen is still visible. */
|
|
1169
1169
|
autoResolvedDialogKey = null;
|
|
1170
1170
|
autoResolvedDialogGeneration = 0;
|
|
1171
|
+
/** Per-launch safety phases survive startup handoff, redraws and failed/uncertain key ACKs. */
|
|
1172
|
+
launchDialogClaims = null;
|
|
1171
1173
|
/**
|
|
1172
1174
|
* (#1103) Proof that THIS spawn's Codex went onto Luna Reserve: AgEnD saw (and
|
|
1173
1175
|
* answered) the usage-limit menu that codex shows when it switches itself to
|
|
@@ -3166,8 +3168,9 @@ export class Daemon extends EventEmitter {
|
|
|
3166
3168
|
const readyPattern = this.backend.getReadyPattern();
|
|
3167
3169
|
const busyPattern = this.backend.getBusyPattern?.() ?? null;
|
|
3168
3170
|
this.errorMonitorTimer = setInterval(async () => {
|
|
3169
|
-
if (!this.tmux || this.spawning)
|
|
3171
|
+
if (!this.tmux || this.spawning || this.deliveryWritesStopping)
|
|
3170
3172
|
return;
|
|
3173
|
+
const pollTmux = this.tmux;
|
|
3171
3174
|
// This poll belongs to the spawn and the monitors it started under. Every await below can outlive them (a stop,
|
|
3172
3175
|
// a pause, a respawn); a stale poll must not touch state a newer one owns, so it checks before committing.
|
|
3173
3176
|
const pollSpawn = this.spawnGeneration;
|
|
@@ -3176,18 +3179,19 @@ export class Daemon extends EventEmitter {
|
|
|
3176
3179
|
const captureOrder = ++this.interactionCaptureSerial;
|
|
3177
3180
|
const captureMono = performance.now();
|
|
3178
3181
|
const stale = () => pollSpawn !== this.spawnGeneration || pollFence !== this.launchFenceEpoch
|
|
3179
|
-
|| !sameInteractionOwner(pollOwner, this.interactionOwner()) || this.runtimeMonitorsFrozen || this.spawning
|
|
3182
|
+
|| !sameInteractionOwner(pollOwner, this.interactionOwner()) || this.runtimeMonitorsFrozen || this.spawning
|
|
3183
|
+
|| this.deliveryWritesStopping || this.tmux !== pollTmux;
|
|
3180
3184
|
let scanStartedAt = null;
|
|
3181
3185
|
const endScan = () => { if (scanStartedAt !== null)
|
|
3182
3186
|
noteSyncWork("daemon.errorMonitorScan", scanStartedAt); scanStartedAt = null; };
|
|
3183
3187
|
try {
|
|
3184
|
-
const alive = await
|
|
3188
|
+
const alive = await pollTmux.isWindowAlive();
|
|
3185
3189
|
if (stale())
|
|
3186
3190
|
return;
|
|
3187
3191
|
if (!alive)
|
|
3188
3192
|
return;
|
|
3189
3193
|
const captureAt = Date.now();
|
|
3190
|
-
const pane = await
|
|
3194
|
+
const pane = await pollTmux.capturePane();
|
|
3191
3195
|
// The scan of this pane is synchronous until it answers a dialog (an await) or ends: attributed (#1235).
|
|
3192
3196
|
scanStartedAt = performance.now();
|
|
3193
3197
|
if (stale())
|
|
@@ -3264,9 +3268,7 @@ export class Daemon extends EventEmitter {
|
|
|
3264
3268
|
continue;
|
|
3265
3269
|
}
|
|
3266
3270
|
const autoKey = dialog.autoResolutionKey;
|
|
3267
|
-
if (dialog.verifyAfterKeys && autoKey
|
|
3268
|
-
&& this.autoResolvedDialogGeneration === this.spawnGeneration
|
|
3269
|
-
&& this.autoResolvedDialogKey === autoKey) {
|
|
3271
|
+
if (dialog.verifyAfterKeys && autoKey && this.hasAutoDialogClaim(dialog)) {
|
|
3270
3272
|
// A previous poll sent the safety choice but the CLI has not
|
|
3271
3273
|
// repainted yet. Never send another Enter into the same screen.
|
|
3272
3274
|
continue;
|
|
@@ -3285,7 +3287,7 @@ export class Daemon extends EventEmitter {
|
|
|
3285
3287
|
const currentAt = Date.now();
|
|
3286
3288
|
const currentMono = performance.now();
|
|
3287
3289
|
const currentOrder = ++this.interactionCaptureSerial;
|
|
3288
|
-
const currentPane = await
|
|
3290
|
+
const currentPane = await pollTmux.capturePane();
|
|
3289
3291
|
// Every await below can outlive the spawn / monitors this poll started under: after each one, before
|
|
3290
3292
|
// any state is touched or any further key is sent, `stale()` (fixed at the poll's start) is asked again.
|
|
3291
3293
|
if (stale())
|
|
@@ -3309,28 +3311,26 @@ export class Daemon extends EventEmitter {
|
|
|
3309
3311
|
// not evidence that the old request was answered, and the one-minute fallback must keep running.
|
|
3310
3312
|
if (this.dialogAnswers?.key === Daemon.answerKey(dialog) && this.dialogAnswers.screen !== before)
|
|
3311
3313
|
this.endDialogEpisode(dialog.requestIdentity !== undefined);
|
|
3312
|
-
if (dialog.verifyAfterKeys && autoKey
|
|
3313
|
-
&& this.autoResolvedDialogGeneration === this.spawnGeneration
|
|
3314
|
-
&& this.autoResolvedDialogKey === autoKey)
|
|
3314
|
+
if (dialog.verifyAfterKeys && autoKey && this.hasAutoDialogClaim(dialog))
|
|
3315
3315
|
return;
|
|
3316
|
-
if (dialog.verifyAfterKeys && autoKey)
|
|
3317
|
-
this.
|
|
3318
|
-
this.autoResolvedDialogKey = autoKey;
|
|
3319
|
-
}
|
|
3316
|
+
if (dialog.verifyAfterKeys && autoKey)
|
|
3317
|
+
this.claimAutoDialog(dialog);
|
|
3320
3318
|
this.logger.info(`Auto-dismissing runtime dialog: ${dialog.description}`);
|
|
3321
3319
|
const SPECIAL_KEYS = new Set(["Up", "Down", "Enter", "Escape", "Right", "Left"]);
|
|
3322
3320
|
for (const key of dialog.keys) {
|
|
3321
|
+
if (stale())
|
|
3322
|
+
return;
|
|
3323
3323
|
let sent = false;
|
|
3324
3324
|
if (SPECIAL_KEYS.has(key)) {
|
|
3325
|
-
sent = await
|
|
3325
|
+
sent = await pollTmux.sendSpecialKey(key);
|
|
3326
3326
|
}
|
|
3327
3327
|
else {
|
|
3328
|
-
sent = await
|
|
3328
|
+
sent = await pollTmux.pasteText(key, this.systemPasteOptions());
|
|
3329
3329
|
}
|
|
3330
3330
|
if (stale())
|
|
3331
3331
|
return;
|
|
3332
3332
|
if (!sent) {
|
|
3333
|
-
if (dialog.verifyAfterKeys && autoKey) {
|
|
3333
|
+
if (dialog.verifyAfterKeys && autoKey && !dialog.oncePerLaunch) {
|
|
3334
3334
|
this.autoResolvedDialogGeneration = 0;
|
|
3335
3335
|
this.autoResolvedDialogKey = null;
|
|
3336
3336
|
}
|
|
@@ -3345,7 +3345,7 @@ export class Daemon extends EventEmitter {
|
|
|
3345
3345
|
const afterKeysAt = Date.now();
|
|
3346
3346
|
const afterKeysMono = performance.now();
|
|
3347
3347
|
const afterKeysOrder = ++this.interactionCaptureSerial;
|
|
3348
|
-
const afterKeysPane = await
|
|
3348
|
+
const afterKeysPane = await pollTmux.capturePane();
|
|
3349
3349
|
if (stale())
|
|
3350
3350
|
return;
|
|
3351
3351
|
const dialogStillActive = dialog.inputBlocked
|
|
@@ -3375,7 +3375,7 @@ export class Daemon extends EventEmitter {
|
|
|
3375
3375
|
// backend-named identity any difference on the screen (a ticking timer) proves nothing either way: nothing
|
|
3376
3376
|
// is reported and the parked clock is left alone. Two requests that look exactly alike cannot be told apart.
|
|
3377
3377
|
await new Promise(r => setTimeout(r, DIALOG_ANSWER_SETTLE_MS));
|
|
3378
|
-
const afterPane = await
|
|
3378
|
+
const afterPane = await pollTmux.capturePane();
|
|
3379
3379
|
if (stale())
|
|
3380
3380
|
return; // (nothing was touched since the last check: only a read)
|
|
3381
3381
|
const stillThere = Daemon.dialogMatches(dialog, afterPane);
|
|
@@ -6727,6 +6727,32 @@ export class Daemon extends EventEmitter {
|
|
|
6727
6727
|
}
|
|
6728
6728
|
return active;
|
|
6729
6729
|
}
|
|
6730
|
+
hasAutoDialogClaim(dialog) {
|
|
6731
|
+
const key = dialog.autoResolutionKey;
|
|
6732
|
+
if (!key)
|
|
6733
|
+
return false;
|
|
6734
|
+
if (dialog.oncePerLaunch) {
|
|
6735
|
+
const claims = this.launchDialogClaims;
|
|
6736
|
+
return claims !== null && claims.spawn === this.spawnGeneration && claims.attempt === this.launchAttempt
|
|
6737
|
+
&& claims.keys.has(key);
|
|
6738
|
+
}
|
|
6739
|
+
return this.autoResolvedDialogGeneration === this.spawnGeneration && this.autoResolvedDialogKey === key;
|
|
6740
|
+
}
|
|
6741
|
+
claimAutoDialog(dialog) {
|
|
6742
|
+
const key = dialog.autoResolutionKey;
|
|
6743
|
+
if (!key)
|
|
6744
|
+
return;
|
|
6745
|
+
if (dialog.oncePerLaunch) {
|
|
6746
|
+
if (!this.launchDialogClaims || this.launchDialogClaims.spawn !== this.spawnGeneration
|
|
6747
|
+
|| this.launchDialogClaims.attempt !== this.launchAttempt) {
|
|
6748
|
+
this.launchDialogClaims = { spawn: this.spawnGeneration, attempt: this.launchAttempt, keys: new Set() };
|
|
6749
|
+
}
|
|
6750
|
+
this.launchDialogClaims.keys.add(key);
|
|
6751
|
+
return;
|
|
6752
|
+
}
|
|
6753
|
+
this.autoResolvedDialogGeneration = this.spawnGeneration;
|
|
6754
|
+
this.autoResolvedDialogKey = key;
|
|
6755
|
+
}
|
|
6730
6756
|
/** Whether a runtime prompt currently owns the pane's stdin. */
|
|
6731
6757
|
isInputBlocked() {
|
|
6732
6758
|
return this.inputBlockedDialogKey !== null;
|
|
@@ -6788,8 +6814,7 @@ export class Daemon extends EventEmitter {
|
|
|
6788
6814
|
// this spawn is not what the screen is waiting on any more — the entry
|
|
6789
6815
|
// after it (typically a hold) describes it.
|
|
6790
6816
|
if (dialog.verifyAfterKeys && dialog.autoResolutionKey
|
|
6791
|
-
&& this.
|
|
6792
|
-
&& this.autoResolvedDialogKey === dialog.autoResolutionKey
|
|
6817
|
+
&& this.hasAutoDialogClaim(dialog)
|
|
6793
6818
|
&& dialogs.some(other => other !== dialog && Daemon.dialogMatches(other, pane)))
|
|
6794
6819
|
continue;
|
|
6795
6820
|
this.trackDialogParked(dialog);
|
|
@@ -7766,6 +7791,10 @@ export class Daemon extends EventEmitter {
|
|
|
7766
7791
|
async sendDeliveryEnter(phase, stillCurrent, durableAttempt) {
|
|
7767
7792
|
if (!(await this.waitForInputTransientToClear(phase)))
|
|
7768
7793
|
return false;
|
|
7794
|
+
return this.sendDeliveryEnterAfterAvailability(phase, stillCurrent, durableAttempt);
|
|
7795
|
+
}
|
|
7796
|
+
/** Write half only: callers must finish the availability wait before any final recovery ownership proof. */
|
|
7797
|
+
async sendDeliveryEnterAfterAvailability(phase, stillCurrent, durableAttempt) {
|
|
7769
7798
|
// A recovery Enter may have waited for a transient while cancel or spawn
|
|
7770
7799
|
// replaced the delivery. Check at the last point before the tmux write.
|
|
7771
7800
|
if (this.deliveryWritesStopping || (stillCurrent && !stillCurrent()))
|
|
@@ -8547,12 +8576,12 @@ export class Daemon extends EventEmitter {
|
|
|
8547
8576
|
// read as ours, we would press Enter to "recover" it, and the turn IT
|
|
8548
8577
|
// starts would confirm a message that never reached the pane.
|
|
8549
8578
|
//
|
|
8550
|
-
//
|
|
8551
|
-
// unreadable
|
|
8552
|
-
//
|
|
8553
|
-
//
|
|
8579
|
+
// Structured evidence (Claude's box and Codex's current input/footer pair) requires both snapshots to be READ.
|
|
8580
|
+
// An unreadable baseline says nothing about what the box held; treating it as empty would claim an older draft
|
|
8581
|
+
// as ours and press Enter on it (#1353/#1359). Codex's native warning viewer can ignore the paste and first Enter,
|
|
8582
|
+
// then reveal an older draft when the user dismisses it. Row-only backends retain their existing attribution.
|
|
8554
8583
|
const attributable = baseline != null
|
|
8555
|
-
&& (!this.
|
|
8584
|
+
&& (!this.structuredInputEvidence() || (baseline.inputReadable && after.inputReadable));
|
|
8556
8585
|
if (after.strandedInput && (signature.unique || (attributable && baseline.strandedInput === false)))
|
|
8557
8586
|
return "stranded";
|
|
8558
8587
|
// A paste the CLI shows collapsed carries no signature at all. One the box did not hold before we pasted is
|
|
@@ -8802,12 +8831,36 @@ export class Daemon extends EventEmitter {
|
|
|
8802
8831
|
return true; // best effort, exactly as before — nothing here is verified
|
|
8803
8832
|
}
|
|
8804
8833
|
if (proof !== "submitted") {
|
|
8805
|
-
// A bare Enter is a no-op at an empty prompt, so this is safe even if the
|
|
8806
|
-
// first one did land; when the text is still in the input row it is the
|
|
8807
|
-
// submit it never got. Re-pasting would append the text to itself.
|
|
8808
8834
|
await new Promise(r => setTimeout(r, NORMAL_ENTER_SETTLE_MS));
|
|
8809
|
-
if (
|
|
8835
|
+
if (current && !current())
|
|
8810
8836
|
return false;
|
|
8837
|
+
const retryPhase = `${label}-retry`;
|
|
8838
|
+
if (this.structuredInputEvidence()) {
|
|
8839
|
+
// Both the retry delay and the Enter availability wait may outlive the
|
|
8840
|
+
// paste. Complete those waits BEFORE the last ownership/positive proof.
|
|
8841
|
+
if (!(await this.waitForInputTransientToClear(retryPhase)))
|
|
8842
|
+
return false;
|
|
8843
|
+
if (this.deliveryWritesStopping || (current && !current()))
|
|
8844
|
+
return false;
|
|
8845
|
+
proof = await this.confirmSubmitted(signature, baseline);
|
|
8846
|
+
if (this.deliveryWritesStopping || (current && !current()))
|
|
8847
|
+
return false;
|
|
8848
|
+
if (proof === "submitted")
|
|
8849
|
+
return true;
|
|
8850
|
+
if (proof !== "stranded") {
|
|
8851
|
+
this.logger.warn({ label, proof }, "System paste recovery input could not be attributed");
|
|
8852
|
+
return false;
|
|
8853
|
+
}
|
|
8854
|
+
// No further availability wait may invalidate this proof. The write
|
|
8855
|
+
// half retains the same stopping/admission fence immediately before IPC.
|
|
8856
|
+
if (!(await this.sendDeliveryEnterAfterAvailability(retryPhase, current)))
|
|
8857
|
+
return false;
|
|
8858
|
+
}
|
|
8859
|
+
else {
|
|
8860
|
+
// Row-only backends retain their ordinary availability wait and retry.
|
|
8861
|
+
if (!(await this.sendDeliveryEnter(retryPhase, current)))
|
|
8862
|
+
return false;
|
|
8863
|
+
}
|
|
8811
8864
|
proof = await this.confirmSubmitted(signature, baseline);
|
|
8812
8865
|
if (current && !current())
|
|
8813
8866
|
return false;
|
|
@@ -9353,7 +9406,8 @@ export class Daemon extends EventEmitter {
|
|
|
9353
9406
|
instanceName: this.name,
|
|
9354
9407
|
mcpServers: isCliMode ? {} : {
|
|
9355
9408
|
"agend": {
|
|
9356
|
-
|
|
9409
|
+
// The Node this daemon runs on (#1450 C5): the CLIs start the MCP server with it, not a `node` from PATH.
|
|
9410
|
+
command: process.execPath,
|
|
9357
9411
|
args: [serverJs],
|
|
9358
9412
|
env: mcpEnv,
|
|
9359
9413
|
},
|
|
@@ -10499,7 +10553,8 @@ export class Daemon extends EventEmitter {
|
|
|
10499
10553
|
const ownerTmux = this.tmux;
|
|
10500
10554
|
const ownerSpawn = this.spawnGeneration;
|
|
10501
10555
|
const ownerFence = this.launchFenceEpoch;
|
|
10502
|
-
const owned = () => this.
|
|
10556
|
+
const owned = () => !this.deliveryWritesStopping && this.tmux === ownerTmux
|
|
10557
|
+
&& this.spawnGeneration === ownerSpawn && this.launchFenceEpoch === ownerFence;
|
|
10503
10558
|
do {
|
|
10504
10559
|
this.startupAdmission?.();
|
|
10505
10560
|
attempts++;
|
|
@@ -10545,8 +10600,7 @@ export class Daemon extends EventEmitter {
|
|
|
10545
10600
|
if (Daemon.dialogMatches(dialog, pane)) {
|
|
10546
10601
|
if (dialog.autoResolutionKey
|
|
10547
10602
|
&& (attemptedSafetyChoices.has(dialog.autoResolutionKey)
|
|
10548
|
-
||
|
|
10549
|
-
&& this.autoResolvedDialogKey === dialog.autoResolutionKey)))
|
|
10603
|
+
|| this.hasAutoDialogClaim(dialog)))
|
|
10550
10604
|
continue;
|
|
10551
10605
|
lastDialog = dialog;
|
|
10552
10606
|
this.noteCodexReserveDialog(dialog, pane);
|
|
@@ -10610,8 +10664,7 @@ export class Daemon extends EventEmitter {
|
|
|
10610
10664
|
}
|
|
10611
10665
|
if (dialog.autoResolutionKey) {
|
|
10612
10666
|
attemptedSafetyChoices.add(dialog.autoResolutionKey);
|
|
10613
|
-
this.
|
|
10614
|
-
this.autoResolvedDialogKey = dialog.autoResolutionKey;
|
|
10667
|
+
this.claimAutoDialog(dialog);
|
|
10615
10668
|
}
|
|
10616
10669
|
for (const key of dialog.keys) {
|
|
10617
10670
|
this.startupAdmission?.();
|