sync: update from private repo (6c4d482)
CI / build-and-test (push) Has been cancelled

This commit is contained in:
oss-sync
2026-06-08 01:01:47 +00:00
parent caa0d03900
commit 03be80f036
21 changed files with 1140 additions and 15 deletions
+16
View File
@@ -164,6 +164,22 @@ describe('ConsoleSession', () => {
expect(audit.beginAndComplete.mock.calls[0]![0].detail.reason).toBe('host_disconnect');
});
it('tracks last output / ai-input / human-input timestamps separately', () => {
const ch = new StubChannel();
const { session } = mkSession(ch);
const t0 = session.lastOutputAt;
// simulate output
(session as any).handleOutput(Buffer.from('hi'));
expect(session.lastOutputAt).toBeGreaterThanOrEqual(t0);
session.write(Buffer.from('a'), 'ai');
expect(session.lastAiInputAt).toBeGreaterThan(0);
const aiAt = session.lastAiInputAt;
session.write(Buffer.from('b'), 'human');
expect(session.lastHumanInputAt).toBeGreaterThan(0);
expect(session.lastAiInputAt).toBe(aiAt); // human write must not move ai timestamp
expect(typeof session.idleMs()).toBe('number');
});
it('client "close" tears the session down once', async () => {
const ch = new StubChannel();
const { session, audit, client } = mkSession(ch);
+19
View File
@@ -121,6 +121,9 @@ export class ConsoleSession {
private readonly auditRepo: SshAuditRepo;
private _lastActivityAt: number;
private _lastOutputAt: number;
private _lastAiInputAt = 0;
private _lastHumanInputAt = 0;
private _totalInputBytes = 0;
private _totalOutputBytes = 0;
@@ -136,6 +139,7 @@ export class ConsoleSession {
this.startedByUserId = args.startedByUserId;
this.startedAt = Date.now();
this._lastActivityAt = this.startedAt;
this._lastOutputAt = this.startedAt;
this.cols = args.cols;
this.rows = args.rows;
this.channel = args.channel;
@@ -181,6 +185,18 @@ export class ConsoleSession {
get lastActivityAt(): number {
return this._lastActivityAt;
}
get lastOutputAt(): number {
return this._lastOutputAt;
}
get lastAiInputAt(): number {
return this._lastAiInputAt;
}
get lastHumanInputAt(): number {
return this._lastHumanInputAt;
}
idleMs(): number {
return Date.now() - this._lastOutputAt;
}
get totalInputBytes(): number {
return this._totalInputBytes;
}
@@ -239,6 +255,8 @@ export class ConsoleSession {
// Partial input (no newline) is forwarded so the shell can echo each
// character back, matching the live terminal experience the user
// expects in either role.
if (source === 'ai') this._lastAiInputAt = Date.now();
else this._lastHumanInputAt = Date.now();
const out = source === 'ai' ? normalizeLfToCr(buf) : buf;
this._totalInputBytes += out.length;
const ok = this.channel.write(out);
@@ -338,6 +356,7 @@ export class ConsoleSession {
private handleOutput(data: Buffer): void {
this._totalOutputBytes += data.length;
this._lastActivityAt = Date.now();
this._lastOutputAt = Date.now();
this.scrollback.append(data);
this.writeToHeadlessSync(data);
for (const l of this.outputListeners) {