@pontia/pi-client-plugin 0.2.1 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/index.ts +45 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pontia/pi-client-plugin",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Pi extension that connects coding-agent sessions to Pontia.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -36,14 +36,14 @@
36
36
  "typecheck": "tsc --noEmit"
37
37
  },
38
38
  "devDependencies": {
39
- "@earendil-works/pi-coding-agent": ">=0.86.1 <1",
39
+ "@earendil-works/pi-coding-agent": "^1.0.0",
40
40
  "@types/node": "^22.15.3",
41
41
  "oxfmt": "^0.70.0",
42
42
  "typescript": "^5.8.3",
43
43
  "vitest": "^3.1.2"
44
44
  },
45
45
  "peerDependencies": {
46
- "@earendil-works/pi-coding-agent": ">=0.86.1 <1"
46
+ "@earendil-works/pi-coding-agent": "*"
47
47
  },
48
48
  "pi": {
49
49
  "extensions": [
package/src/index.ts CHANGED
@@ -504,22 +504,16 @@ export function createPontiaPiExtension(
504
504
  }
505
505
 
506
506
  pi.on("before_agent_start", async (event) => {
507
- const eventRecord = event as unknown as Record<string, unknown>;
508
- pendingPrompt = optionalString(eventRecord.prompt);
509
- if (reportingDisabled || !(await confirmManagedPane())) {
510
- return {
511
- systemPrompt: typeof eventRecord.systemPrompt === "string" ? eventRecord.systemPrompt : "",
512
- };
513
- }
514
- const currentSystemPrompt =
515
- typeof eventRecord.systemPrompt === "string" ? eventRecord.systemPrompt : "";
507
+ pendingPrompt = event.prompt;
508
+ if (reportingDisabled || !(await confirmManagedPane())) return;
516
509
  try {
517
510
  const profilePrompt = await loadProfileSystemPrompt(
518
511
  rpcConnection,
519
512
  boundSessionContext?.sessionId,
520
513
  );
521
- if (!profilePrompt) return { systemPrompt: currentSystemPrompt };
522
- return { systemPrompt: `${currentSystemPrompt}\n\n${profilePrompt}` };
514
+ if (profilePrompt) {
515
+ event.systemPromptOptions.sections.pontia_execution_profile = profilePrompt;
516
+ }
523
517
  } catch (error) {
524
518
  await logDiagnostic(currentHookLogFile(), {
525
519
  level: "warn",
@@ -527,7 +521,6 @@ export function createPontiaPiExtension(
527
521
  message: "failed to append pontia execution profile system prompt",
528
522
  details: error instanceof Error ? error.message : String(error),
529
523
  });
530
- return { systemPrompt: currentSystemPrompt };
531
524
  }
532
525
  });
533
526
 
@@ -540,7 +533,13 @@ export function createPontiaPiExtension(
540
533
  if (reportingDisabled) return;
541
534
  const reason = (event as unknown as Record<string, unknown> | undefined)?.reason;
542
535
  if (readyReported && reason !== "fork" && reason !== "resume" && reason !== "new") return;
543
- if (reason !== "startup" && reason !== "new" && reason !== "resume" && reason !== "fork")
536
+ if (
537
+ reason !== "startup" &&
538
+ reason !== "reload" &&
539
+ reason !== "new" &&
540
+ reason !== "resume" &&
541
+ reason !== "fork"
542
+ )
544
543
  return;
545
544
  await closeControlSocket();
546
545
  const parentSessionId = boundSessionContext?.sessionId;
@@ -595,7 +594,20 @@ export function createPontiaPiExtension(
595
594
  await registrationConnection(),
596
595
  sessionDetails,
597
596
  );
597
+ if (reason === "reload" && !existingSession) {
598
+ reportingDisabled = true;
599
+ deferredManualSessionDetails = undefined;
600
+ await closeControlSocket();
601
+ await logDiagnostic(logFile, {
602
+ level: "error",
603
+ code: "reload_session_context_missing",
604
+ message: "pi reload could not recover the existing pontia runtime binding",
605
+ details: { client_session_key: sessionDetails.clientSessionKey },
606
+ });
607
+ return;
608
+ }
598
609
  if (
610
+ reason !== "reload" &&
599
611
  existingSession &&
600
612
  ["idle", "busy", "interrupted"].includes(existingSession.sessionState)
601
613
  ) {
@@ -625,13 +637,26 @@ export function createPontiaPiExtension(
625
637
 
626
638
  context = await bindSession(await registrationConnection(), env, sessionDetails, {
627
639
  runtimeInstanceId:
628
- existingSession?.sessionState === "starting"
629
- ? existingSession.runtimeInstanceId
640
+ reason === "reload" || existingSession?.sessionState === "starting"
641
+ ? existingSession?.runtimeInstanceId
630
642
  : undefined,
631
643
  });
632
- if (reason === "resume" || reason === "new") readyReported = false;
644
+ if (
645
+ reason === "reload" &&
646
+ (context?.sessionId !== existingSession!.sessionId ||
647
+ context.runtimeInstanceId !== existingSession!.runtimeInstanceId)
648
+ ) {
649
+ reportingDisabled = true;
650
+ deferredManualSessionDetails = undefined;
651
+ throw new Error("pi reload runtime binding changed identity");
652
+ }
653
+ if (reason === "reload" || reason === "resume" || reason === "new") readyReported = false;
633
654
  }
634
655
  if (!context || !(await confirmManagedPane(true))) {
656
+ if (reason === "reload") {
657
+ reportingDisabled = true;
658
+ deferredManualSessionDetails = undefined;
659
+ }
635
660
  await closeControlSocket();
636
661
  return;
637
662
  }
@@ -815,12 +840,12 @@ export function createPontiaPiExtension(
815
840
  if (isTranscriptBoundaryMessageUpdate(event)) await scheduleMessageRefresh("update");
816
841
  });
817
842
 
818
- pi.on("tool_execution_start", async () => {
819
- await scheduleMessageRefresh("update");
843
+ pi.on("tool_execution_start", async (event) => {
844
+ if (!event.parentToolCallId) await scheduleMessageRefresh("update");
820
845
  });
821
846
 
822
- pi.on("tool_execution_end", async () => {
823
- await scheduleMessageRefresh("update");
847
+ pi.on("tool_execution_end", async (event) => {
848
+ if (!event.parentToolCallId) await scheduleMessageRefresh("update");
824
849
  });
825
850
 
826
851
  pi.on("message_end", async (event, ctx) => {