pi-sessions 0.14.2 → 0.14.3

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.
@@ -24,7 +24,8 @@ import { installSubagents } from "./subagents/install.ts";
24
24
  * The single advertised entrypoint. It loads settings once, constructs each feature in
25
25
  * dependency order, and wires them by constructor parameters.
26
26
  * It also owns the single `session_start`/`session_shutdown` subscription so lifecycle order
27
- * is deterministic: broker registration (messaging) resolves before any other feature hook.
27
+ * is deterministic: broker registration (messaging) resolves before any other feature hook,
28
+ * and incoming messages start turns only once every feature hook has resolved.
28
29
  */
29
30
  export default function piSessions(pi: ExtensionAPI): void {
30
31
  const settings = loadSettings();
@@ -141,6 +142,9 @@ export default function piSessions(pi: ExtensionAPI): void {
141
142
  for (const lifecycle of lifecycles) {
142
143
  await lifecycle.onSessionStart?.(event, ctx);
143
144
  }
145
+ for (const lifecycle of lifecycles) {
146
+ lifecycle.onSessionReady?.(ctx);
147
+ }
144
148
  });
145
149
 
146
150
  pi.on("session_shutdown", async (event, ctx) => {
@@ -65,11 +65,13 @@ export function installMessaging(
65
65
  onIncomingSubagentReport: (handler) => service.onIncomingSubagentReport(handler),
66
66
  async onSessionStart(_event, ctx) {
67
67
  incomingRuntime.bindContext(ctx);
68
- incomingRuntime.replayPending(ctx);
69
68
  try {
70
69
  await service.start(ctx);
71
70
  } catch {}
72
71
  },
72
+ onSessionReady() {
73
+ incomingRuntime.open();
74
+ },
73
75
  onSessionShutdown() {
74
76
  incomingRuntime.clearContext();
75
77
  service.stop();
@@ -21,6 +21,7 @@ interface IncomingMessageActions {
21
21
 
22
22
  export class IncomingSessionMessageRuntime {
23
23
  private context: ExtensionContext | undefined;
24
+ private ready = false;
24
25
  private readonly actions: IncomingMessageActions;
25
26
 
26
27
  constructor(pi: ExtensionAPI) {
@@ -32,10 +33,17 @@ export class IncomingSessionMessageRuntime {
32
33
 
33
34
  bindContext(ctx: ExtensionContext): void {
34
35
  this.context = ctx;
36
+ this.ready = false;
37
+ }
38
+
39
+ open(): void {
40
+ this.replayPending(this.requireContext());
41
+ this.ready = true;
35
42
  }
36
43
 
37
44
  clearContext(): void {
38
45
  this.context = undefined;
46
+ this.ready = false;
39
47
  }
40
48
 
41
49
  deliver(received: ReceivedMessageEntry): void {
@@ -47,14 +55,18 @@ export class IncomingSessionMessageRuntime {
47
55
  throw new Error(SESSION_STARTING_MESSAGE);
48
56
  }
49
57
  this.actions.appendEntry(MESSAGE_RECEIVED_CUSTOM_TYPE, received);
50
- this.inject(ctx, received);
58
+ // The broker connects before other features finish session_start, and a turn started now
59
+ // would run without the tools they activate. The receipt is durable; open() replays it.
60
+ if (this.ready) {
61
+ this.inject(ctx, received);
62
+ }
51
63
  }
52
64
 
53
65
  cancel(): void {
54
66
  this.requireContext().abort();
55
67
  }
56
68
 
57
- replayPending(ctx: ExtensionContext): void {
69
+ private replayPending(ctx: ExtensionContext): void {
58
70
  const entries = ctx.sessionManager.getEntries();
59
71
  const deliveredMessageIds = new Set<string>();
60
72
  const pendingReceipts: ReceivedMessageEntry[] = [];
@@ -11,6 +11,8 @@ import type {
11
11
  */
12
12
  export interface SessionLifecycle {
13
13
  onSessionStart?(event: SessionStartEvent, ctx: ExtensionContext): Promise<void> | void;
14
+ /** Runs once every feature's onSessionStart has resolved. */
15
+ onSessionReady?(ctx: ExtensionContext): void;
14
16
  onSessionShutdown?(event: SessionShutdownEvent, ctx: ExtensionContext): Promise<void> | void;
15
17
  }
16
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-sessions",
3
- "version": "0.14.2",
3
+ "version": "0.14.3",
4
4
  "type": "module",
5
5
  "description": "Pi session search, ask, handoff, messaging, auto-titling, and indexing tools",
6
6
  "license": "MIT",