@fitchmultz/pi-subagents 0.52.7 → 0.52.9

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/agent/launch.js +1 -1
  3. package/dist/agent/observation-view.js +15 -7
  4. package/dist/agent/observe-card.js +2 -2
  5. package/dist/agent/observe-client.js +1 -1
  6. package/dist/agent/observe.js +4 -1
  7. package/dist/agent/process.js +5 -3
  8. package/dist/agent/runner.js +9 -4
  9. package/dist/agent/saved.js +16 -6
  10. package/dist/agent/view.js +5 -2
  11. package/dist/build-info.js +1 -1
  12. package/dist/pi-intercom/bridge-routes.js +1 -1
  13. package/dist/pi-intercom/bridge.js +4 -3
  14. package/dist/pi-intercom/broker/broker.js +1 -1
  15. package/dist/pi-intercom/broker/client-last.d.ts +1 -1
  16. package/dist/pi-intercom/broker/client.d.ts +9 -9
  17. package/dist/pi-intercom/broker/framing.js +6 -0
  18. package/dist/pi-intercom/broker/last.d.ts +5 -1
  19. package/dist/pi-intercom/broker/last.js +33 -15
  20. package/dist/pi-intercom/broker/parked.js +1 -1
  21. package/dist/pi-intercom/outbound.js +1 -0
  22. package/dist/pi-intercom/reply-tracker.js +11 -5
  23. package/dist/pi-intercom/session-targets.d.ts +2 -2
  24. package/dist/pi-intercom/session-targets.js +3 -2
  25. package/dist/pi-intercom/tool-registration.js +1 -0
  26. package/dist/pi-intercom/types.d.ts +37 -37
  27. package/dist/pi-intercom/types.js +9 -7
  28. package/dist/shared/output-page.js +1 -1
  29. package/package.json +5 -4
  30. package/scripts/archive-retired-history.mjs +3 -1
  31. package/src/agent/index.ts +3 -3
  32. package/src/agent/journal-tail.ts +2 -2
  33. package/src/agent/launch.ts +1 -1
  34. package/src/agent/notifications.ts +3 -3
  35. package/src/agent/observation-state.ts +2 -2
  36. package/src/agent/observation-view.ts +20 -7
  37. package/src/agent/observation.ts +4 -4
  38. package/src/agent/observe-card.ts +7 -3
  39. package/src/agent/observe-chrome.ts +2 -2
  40. package/src/agent/observe-client.ts +5 -5
  41. package/src/agent/observe-reading.ts +1 -1
  42. package/src/agent/observe-screen.ts +4 -4
  43. package/src/agent/observe-transcript.ts +4 -4
  44. package/src/agent/observe.ts +13 -8
  45. package/src/agent/parking.ts +1 -1
  46. package/src/agent/process.ts +6 -4
  47. package/src/agent/runner.ts +15 -7
  48. package/src/agent/saved.ts +17 -7
  49. package/src/agent/usage.ts +1 -1
  50. package/src/agent/view.ts +18 -9
  51. package/src/agent/wake.ts +2 -2
  52. package/src/pi-intercom/bridge-config.ts +2 -2
  53. package/src/pi-intercom/bridge-mailbox.ts +1 -1
  54. package/src/pi-intercom/bridge-presence.ts +1 -1
  55. package/src/pi-intercom/bridge-routes.ts +5 -5
  56. package/src/pi-intercom/bridge-session.ts +5 -5
  57. package/src/pi-intercom/bridge-wake.ts +2 -2
  58. package/src/pi-intercom/bridge.ts +4 -3
  59. package/src/pi-intercom/broker/broker.ts +1 -1
  60. package/src/pi-intercom/broker/client-last.ts +1 -1
  61. package/src/pi-intercom/broker/client-park.ts +1 -1
  62. package/src/pi-intercom/broker/client.ts +9 -9
  63. package/src/pi-intercom/broker/framing.ts +6 -0
  64. package/src/pi-intercom/broker/last.ts +62 -18
  65. package/src/pi-intercom/broker/parked.ts +8 -5
  66. package/src/pi-intercom/config.ts +1 -1
  67. package/src/pi-intercom/outbound.ts +1 -0
  68. package/src/pi-intercom/reply-tracker.ts +13 -6
  69. package/src/pi-intercom/reply-wait.ts +3 -3
  70. package/src/pi-intercom/runtime-types.ts +1 -1
  71. package/src/pi-intercom/session-targets.ts +5 -4
  72. package/src/pi-intercom/tool-registration.ts +1 -0
  73. package/src/pi-intercom/tool-results.ts +1 -1
  74. package/src/pi-intercom/types.ts +48 -43
  75. package/src/shared/journal-frames.ts +1 -1
  76. package/src/shared/json-projection.ts +2 -2
  77. package/src/shared/native-journal.ts +2 -2
  78. package/src/shared/output-page.ts +3 -3
  79. package/src/shared/post-exit-stdio-guard.ts +4 -4
  80. package/tsconfig.json +8 -1
@@ -4,12 +4,12 @@ import path from "node:path";
4
4
 
5
5
  export interface TargetIdentity {
6
6
  readonly id: string;
7
- readonly name?: string;
7
+ readonly name?: string | undefined;
8
8
  }
9
9
 
10
10
  export interface ProjectSessionIdentity extends TargetIdentity {
11
11
  readonly cwd: string;
12
- readonly projectId?: string;
12
+ readonly projectId?: string | undefined;
13
13
  }
14
14
 
15
15
  export const MIN_SESSION_TARGET_PREFIX_LENGTH = 8;
@@ -170,8 +170,9 @@ export function formatPeerAwarenessHint(
170
170
  }
171
171
 
172
172
  function matchedTargets<T extends TargetIdentity>(matches: readonly T[]): TargetResolution<T> {
173
- if (matches.length === 1) {
174
- return { status: "found", target: matches[0], matches };
173
+ const [target] = matches;
174
+ if (matches.length === 1 && target !== undefined) {
175
+ return { status: "found", target, matches };
175
176
  }
176
177
  return matches.length > 1 ? { status: "ambiguous", matches } : { status: "none", matches: [] };
177
178
  }
@@ -16,6 +16,7 @@ export function registerIntercomTools(
16
16
  "Message connected Pi sessions in your group; mains also reach other mains across projects. List shows target IDs. Ask waits for a correlated reply; reply answers the active or sole pending ask. Pending lists asks; status shows connection and inbound queue. Last pages a peer's last completed response without waking it. Broker acceptance is not recipient persistence, consumption or completion.",
17
17
  parameters: intercomSchema,
18
18
  renderResult: renderCompactResult,
19
+ // oxlint-disable-next-line max-params
19
20
  async execute(_id, params, signal, _update, ctx) {
20
21
  const result = throwIfToolError(await tools.execute(params, signal, ctx));
21
22
  return { content: [...result.content], details: result.details };
@@ -33,7 +33,7 @@ export function firstTextContent(result: {
33
33
  );
34
34
  }
35
35
  export class ToolExecutionFailure extends Error {
36
- readonly details?: Readonly<Record<string, unknown>>;
36
+ readonly details?: Readonly<Record<string, unknown>> | undefined;
37
37
  constructor(message: string, details?: Readonly<Record<string, unknown>>) {
38
38
  super(message);
39
39
  this.details = details;
@@ -16,23 +16,23 @@ export type WakeResult =
16
16
 
17
17
  export interface SessionInfo {
18
18
  readonly id: string;
19
- readonly name?: string;
19
+ readonly name?: string | undefined;
20
20
  readonly cwd: string;
21
21
  readonly model: string;
22
22
  /** Opaque same-repository/worktree identity used for ambient peer awareness. */
23
- readonly projectId?: string;
24
- readonly rootSessionId?: string;
25
- readonly parentSessionId?: string;
26
- readonly incarnation?: string;
27
- readonly guardedDelivery?: 1;
28
- readonly applicationGuard?: string;
29
- readonly status?: string;
30
- readonly lastSeen?: number;
31
- readonly lastIntercomActivity?: number;
32
- readonly pendingAsks?: number;
33
- readonly acceptsAsks?: boolean;
34
- readonly subscriptions?: readonly TopicSubscription[];
35
- readonly topics?: readonly TopicUpdate[];
23
+ readonly projectId?: string | undefined;
24
+ readonly rootSessionId?: string | undefined;
25
+ readonly parentSessionId?: string | undefined;
26
+ readonly incarnation?: string | undefined;
27
+ readonly guardedDelivery?: 1 | undefined;
28
+ readonly applicationGuard?: string | undefined;
29
+ readonly status?: string | undefined;
30
+ readonly lastSeen?: number | undefined;
31
+ readonly lastIntercomActivity?: number | undefined;
32
+ readonly pendingAsks?: number | undefined;
33
+ readonly acceptsAsks?: boolean | undefined;
34
+ readonly subscriptions?: readonly TopicSubscription[] | undefined;
35
+ readonly topics?: readonly TopicUpdate[] | undefined;
36
36
  }
37
37
 
38
38
  export interface TopicSubscription {
@@ -102,10 +102,10 @@ export interface DeliveryGuard extends ContextTarget {
102
102
  export interface PublicationReplyHint {
103
103
  readonly tool: string;
104
104
  readonly commandId: string;
105
- readonly commandFingerprint?: string;
105
+ readonly commandFingerprint?: string | undefined;
106
106
  }
107
107
  export type SendOptions = Omit<Message, "id" | "timestamp" | "content"> &
108
- Message["content"] & { readonly messageId?: string };
108
+ Message["content"] & { readonly messageId?: string | undefined };
109
109
  export function isContextTarget(value: unknown): value is ContextTarget {
110
110
  return (
111
111
  isRecord(value) &&
@@ -150,20 +150,20 @@ export function isHumanMessageOrigin(value: unknown): value is HumanMessageOrigi
150
150
  export interface Message {
151
151
  readonly id: string;
152
152
  readonly timestamp: number;
153
- readonly replyTo?: string;
154
- readonly expectsReply?: boolean;
153
+ readonly replyTo?: string | undefined;
154
+ readonly expectsReply?: boolean | undefined;
155
155
  /** Recipients verify parent ownership before elevating human origin. */
156
- readonly human?: HumanMessageOrigin;
157
- readonly topic?: TopicUpdate;
158
- readonly delivery?: MessageDelivery;
159
- readonly queueMode?: QueueMode;
160
- readonly threadId?: string;
161
- readonly passive?: boolean;
162
- readonly guard?: DeliveryGuard;
163
- readonly replyHint?: PublicationReplyHint;
156
+ readonly human?: HumanMessageOrigin | undefined;
157
+ readonly topic?: TopicUpdate | undefined;
158
+ readonly delivery?: MessageDelivery | undefined;
159
+ readonly queueMode?: QueueMode | undefined;
160
+ readonly threadId?: string | undefined;
161
+ readonly passive?: boolean | undefined;
162
+ readonly guard?: DeliveryGuard | undefined;
163
+ readonly replyHint?: PublicationReplyHint | undefined;
164
164
  readonly content: {
165
165
  readonly text: string;
166
- readonly attachments?: readonly Attachment[];
166
+ readonly attachments?: readonly Attachment[] | undefined;
167
167
  };
168
168
  }
169
169
  export interface Attachment {
@@ -378,26 +378,31 @@ export interface SessionSnapshot {
378
378
  }
379
379
 
380
380
  type CompactTopicMessage = Omit<Message, "topic"> & {
381
- readonly topic?: Omit<TopicUpdate, "text"> & { readonly text?: string };
381
+ readonly topic?: (Omit<TopicUpdate, "text"> & { readonly text?: string | undefined }) | undefined;
382
382
  };
383
383
  /** Topic text and the standard coalescing key need only one copy on the wire. */
384
384
  export function compactTopicMessage(message: Message): CompactTopicMessage {
385
385
  if (!message.topic) {
386
386
  return message;
387
387
  }
388
+ const { threadId, ...rest } = message;
389
+ const dropThreadId =
390
+ message.queueMode === "replace" && threadId === `topic:${message.topic.topic}`;
388
391
  return {
389
- ...message,
392
+ ...rest,
390
393
  topic:
391
- message.topic.text === message.content.text
392
- ? { ...message.topic, text: undefined }
393
- : message.topic,
394
- threadId:
395
- message.queueMode === "replace" && message.threadId === `topic:${message.topic.topic}`
396
- ? undefined
397
- : message.threadId,
394
+ message.topic.text === message.content.text ? withoutTopicText(message.topic) : message.topic,
395
+ ...(dropThreadId || threadId === undefined ? {} : { threadId }),
398
396
  };
399
397
  }
400
398
 
399
+ function withoutTopicText(
400
+ topic: TopicUpdate,
401
+ ): Omit<TopicUpdate, "text"> & { readonly text?: string | undefined } {
402
+ const { text: _duplicate, ...rest } = topic;
403
+ return rest;
404
+ }
405
+
401
406
  export function normalizeMessage(value: unknown): Message | null {
402
407
  if (isMessage(value)) {
403
408
  return value;
@@ -424,9 +429,9 @@ export function normalizeMessage(value: unknown): Message | null {
424
429
  }
425
430
 
426
431
  export interface LastMessageQuery {
427
- readonly entryId?: string;
428
- readonly offset?: number;
429
- readonly limit?: number;
432
+ readonly entryId?: string | undefined;
433
+ readonly offset?: number | undefined;
434
+ readonly limit?: number | undefined;
430
435
  }
431
436
 
432
437
  export const LAST_MESSAGE_PAGE_LIMIT = 16384;
@@ -468,13 +473,13 @@ export interface NativeReceipt extends ReceiptQuery {
468
473
  readonly version: 1;
469
474
  readonly sender: {
470
475
  readonly peerId: string;
471
- readonly rootSessionId?: string;
472
- readonly incarnation?: string;
476
+ readonly rootSessionId?: string | undefined;
477
+ readonly incarnation?: string | undefined;
473
478
  };
474
479
  readonly textSha256: string;
475
480
  readonly delivery: MessageDelivery;
476
- readonly guard?: DeliveryGuard;
477
- readonly replyHint?: PublicationReplyHint;
481
+ readonly guard?: DeliveryGuard | undefined;
482
+ readonly replyHint?: PublicationReplyHint | undefined;
478
483
  readonly checkpointEntryId: string;
479
484
  readonly receivedAt: number;
480
485
  /** Historical observations, not a promise that an input is still queued. */
@@ -13,7 +13,7 @@ export interface JournalOptions {
13
13
  readonly requireNewline?: boolean;
14
14
  readonly start?: number;
15
15
  readonly end?: number;
16
- readonly stringChunk?: StringChunk;
16
+ readonly stringChunk?: StringChunk | undefined;
17
17
  }
18
18
 
19
19
  /** Byte-framed JSONL. Publication framing is independent of malformed-record tolerance. */
@@ -12,7 +12,7 @@ export type StringChunk = (
12
12
  ) => void;
13
13
  interface Container {
14
14
  readonly path: readonly (string | number)[];
15
- readonly value?: Record<string, unknown> | unknown[];
15
+ readonly value?: Record<string, unknown> | unknown[] | undefined;
16
16
  readonly array: boolean;
17
17
  key: string;
18
18
  index: number;
@@ -95,7 +95,7 @@ export class JsonProjection {
95
95
  private text = "";
96
96
  private numberState = 0;
97
97
  private readonly select: Projection;
98
- private readonly stringChunk?: StringChunk;
98
+ private readonly stringChunk?: StringChunk | undefined;
99
99
  private readonly keys: KeyLimit;
100
100
  value: unknown;
101
101
  constructor(select: Projection, stringChunk?: StringChunk, keys: KeyLimit = () => 4096) {
@@ -8,8 +8,8 @@ import { isRecord, type UnknownRecord } from "./unknown.ts";
8
8
  export interface NativePreview extends UnknownRecord {
9
9
  readonly id: string;
10
10
  readonly type: string;
11
- readonly parentId?: string | null;
12
- readonly timestamp?: string;
11
+ readonly parentId?: string | null | undefined;
12
+ readonly timestamp?: string | undefined;
13
13
  }
14
14
  export interface NativeRecord extends JournalRecord {
15
15
  readonly value: NativePreview;
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  interface OutputPageOptions {
3
- readonly offset?: number;
4
- readonly length?: number;
3
+ readonly offset?: number | undefined;
4
+ readonly length?: number | undefined;
5
5
  }
6
6
  function pageLength(options: OutputPageOptions): number {
7
7
  const length = options.length ?? 64 * 1024;
@@ -40,7 +40,7 @@ function utf8Bounds(bytes: Buffer, count: number, more: boolean): { start: numbe
40
40
  last--;
41
41
  }
42
42
  const lead = bytes[last];
43
- if (last + width(lead) > end) {
43
+ if (lead === undefined || last + width(lead) > end) {
44
44
  end = last;
45
45
  }
46
46
  }
@@ -9,7 +9,7 @@ const BIRTH_FIELDS = ["lstart=", "pgid="];
9
9
  export const PS_COMMAND = process.platform === "darwin" ? "/bin/ps" : "ps";
10
10
 
11
11
  interface AgentProcessExit {
12
- readonly pid?: number;
12
+ readonly pid?: number | undefined;
13
13
  readonly code: number | null;
14
14
  readonly signal: NodeJS.Signals | null;
15
15
  readonly at: number;
@@ -22,7 +22,7 @@ interface ChildWithPipedStdio {
22
22
  }
23
23
 
24
24
  interface ChildWithKill {
25
- readonly pid?: number;
25
+ readonly pid?: number | undefined;
26
26
  readonly kill: (signal?: NodeJS.Signals | number) => boolean;
27
27
  }
28
28
 
@@ -265,8 +265,8 @@ class OwnedChildLifecycle implements ChildProcessLifecycle {
265
265
  private isStopping = false;
266
266
  private isSettledCleanup = false;
267
267
  private exit?: AgentProcessExit;
268
- private drainTimer?: NodeJS.Timeout;
269
- private escalationTimer?: NodeJS.Timeout;
268
+ private drainTimer?: NodeJS.Timeout | undefined;
269
+ private escalationTimer?: NodeJS.Timeout | undefined;
270
270
  private readonly child: ChildWithPipedStdio & ChildWithKill;
271
271
  private readonly clearStdioGuard: () => void;
272
272
  constructor(child: ChildWithPipedStdio & ChildWithKill) {
package/tsconfig.json CHANGED
@@ -16,7 +16,14 @@
16
16
  "allowJs": true,
17
17
  "checkJs": false,
18
18
  "types": ["node"],
19
- "noUnusedLocals": true
19
+ "noUnusedLocals": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noImplicitOverride": true,
22
+ "noUncheckedIndexedAccess": true,
23
+ "exactOptionalPropertyTypes": true,
24
+ "noUncheckedSideEffectImports": true,
25
+ "forceConsistentCasingInFileNames": true,
26
+ "noCheck": false
20
27
  },
21
28
  "include": [
22
29
  "**/*.ts",