adhdev 0.9.54 → 0.9.56

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adhdev",
3
- "version": "0.9.54",
3
+ "version": "0.9.56",
4
4
  "description": "ADHDev — Agent Dashboard Hub for Dev. Remote-control AI coding agents from anywhere.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -21,6 +21,7 @@ declare class SessionHostServer extends EventEmitter {
21
21
  private recentRequests;
22
22
  private recentTransitions;
23
23
  private exitWaiters;
24
+ private lastNoOutputInputWarnAt;
24
25
  constructor(options?: SessionHostServerOptions);
25
26
  start(): Promise<void>;
26
27
  stop(): Promise<void>;
@@ -43,6 +44,7 @@ declare class SessionHostServer extends EventEmitter {
43
44
  private pushRecent;
44
45
  private recordHostLog;
45
46
  private recordRequestTrace;
47
+ private scheduleNoOutputInputDiagnostic;
46
48
  private recordRuntimeTransition;
47
49
  private waitForRuntimeExit;
48
50
  private resolveExitWaiters;
@@ -21,6 +21,7 @@ declare class SessionHostServer extends EventEmitter {
21
21
  private recentRequests;
22
22
  private recentTransitions;
23
23
  private exitWaiters;
24
+ private lastNoOutputInputWarnAt;
24
25
  constructor(options?: SessionHostServerOptions);
25
26
  start(): Promise<void>;
26
27
  stop(): Promise<void>;
@@ -43,6 +44,7 @@ declare class SessionHostServer extends EventEmitter {
43
44
  private pushRecent;
44
45
  private recordHostLog;
45
46
  private recordRequestTrace;
47
+ private scheduleNoOutputInputDiagnostic;
46
48
  private recordRuntimeTransition;
47
49
  private waitForRuntimeExit;
48
50
  private resolveExitWaiters;
@@ -387,6 +387,7 @@ var SessionHostServer = class _SessionHostServer extends import_events.EventEmit
387
387
  recentRequests = [];
388
388
  recentTransitions = [];
389
389
  exitWaiters = /* @__PURE__ */ new Map();
390
+ lastNoOutputInputWarnAt = /* @__PURE__ */ new Map();
390
391
  constructor(options = {}) {
391
392
  super();
392
393
  this.endpoint = options.endpoint || (0, import_session_host_core2.getDefaultSessionHostEndpoint)(options.appName || "adhdev");
@@ -545,7 +546,15 @@ var SessionHostServer = class _SessionHostServer extends import_events.EventEmit
545
546
  if (session?.writeOwner && session.writeOwner.clientId !== request.payload.clientId) {
546
547
  return { success: false, error: `Write owned by ${session.writeOwner.clientId}` };
547
548
  }
548
- this.requireRuntime(request.payload.sessionId).write(request.payload.data);
549
+ const runtime = this.requireRuntime(request.payload.sessionId);
550
+ const beforeSnapshotSeq = this.registry.getSnapshot(request.payload.sessionId)?.seq ?? 0;
551
+ runtime.write(request.payload.data);
552
+ this.scheduleNoOutputInputDiagnostic({
553
+ sessionId: request.payload.sessionId,
554
+ clientId: request.payload.clientId,
555
+ input: request.payload.data,
556
+ beforeSnapshotSeq
557
+ });
549
558
  return { success: true, result: this.registry.getSession(request.payload.sessionId) };
550
559
  }
551
560
  case "resize_session": {
@@ -826,6 +835,55 @@ var SessionHostServer = class _SessionHostServer extends import_events.EventEmit
826
835
  );
827
836
  }
828
837
  }
838
+ scheduleNoOutputInputDiagnostic(params) {
839
+ if (!params.input || /^\x1b/.test(params.input)) {
840
+ return;
841
+ }
842
+ const hasPotentialEcho = /[^\x00-\x1F\x7F]/.test(params.input);
843
+ if (!hasPotentialEcho && params.input !== "\r" && params.input !== "\n") {
844
+ return;
845
+ }
846
+ setTimeout(() => {
847
+ let afterSnapshotSeq = params.beforeSnapshotSeq;
848
+ try {
849
+ afterSnapshotSeq = this.registry.getSnapshot(params.sessionId)?.seq ?? params.beforeSnapshotSeq;
850
+ } catch {
851
+ return;
852
+ }
853
+ if (afterSnapshotSeq > params.beforeSnapshotSeq) {
854
+ return;
855
+ }
856
+ const now = Date.now();
857
+ const lastWarnAt = this.lastNoOutputInputWarnAt.get(params.sessionId) || 0;
858
+ if (now - lastWarnAt < 1e4) {
859
+ return;
860
+ }
861
+ this.lastNoOutputInputWarnAt.set(params.sessionId, now);
862
+ const record = this.registry.getSession(params.sessionId);
863
+ this.recordHostLog(
864
+ "warn",
865
+ "send_input produced no terminal output after PTY write; runtime may be ignoring stdin or stuck in a hidden input reader",
866
+ params.sessionId,
867
+ {
868
+ clientId: params.clientId,
869
+ inputLength: params.input.length,
870
+ beforeSnapshotSeq: params.beforeSnapshotSeq,
871
+ afterSnapshotSeq,
872
+ lifecycle: record?.lifecycle,
873
+ osPid: record?.osPid,
874
+ providerType: record?.providerType
875
+ }
876
+ );
877
+ this.recordRuntimeTransition(
878
+ params.sessionId,
879
+ "send_input_no_output_after_write",
880
+ record?.lifecycle,
881
+ `clientId=${params.clientId} inputLength=${params.input.length} seq=${params.beforeSnapshotSeq}`,
882
+ false,
883
+ "no terminal output after PTY write"
884
+ );
885
+ }, 250);
886
+ }
829
887
  recordRuntimeTransition(sessionId, action, lifecycle, detail, success = true, error) {
830
888
  const transition = {
831
889
  timestamp: Date.now(),