@llblab/pi-kit 0.29.2 → 0.30.0

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 (208) hide show
  1. package/BACKLOG.md +2 -1
  2. package/CHANGELOG.md +5 -0
  3. package/README.md +2 -2
  4. package/node_modules/@llblab/pi-telegram/AGENTS.md +9 -7
  5. package/node_modules/@llblab/pi-telegram/BACKLOG.md +1 -18
  6. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +11 -0
  7. package/node_modules/@llblab/pi-telegram/README.md +7 -11
  8. package/node_modules/@llblab/pi-telegram/api/commands.ts +3 -0
  9. package/node_modules/@llblab/pi-telegram/dist/api/commands.d.ts +1 -1
  10. package/node_modules/@llblab/pi-telegram/dist/lib/activity-verbosity.d.ts +1 -5
  11. package/node_modules/@llblab/pi-telegram/dist/lib/activity-verbosity.js +15 -42
  12. package/node_modules/@llblab/pi-telegram/dist/lib/activity.d.ts +9 -0
  13. package/node_modules/@llblab/pi-telegram/dist/lib/activity.js +39 -10
  14. package/node_modules/@llblab/pi-telegram/dist/lib/agent-messages.js +7 -3
  15. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +43 -5
  16. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +163 -20
  17. package/node_modules/@llblab/pi-telegram/dist/lib/bus-api.d.ts +12 -0
  18. package/node_modules/@llblab/pi-telegram/dist/lib/bus-api.js +182 -79
  19. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +111 -31
  20. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +1324 -359
  21. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +41 -91
  22. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +969 -637
  23. package/node_modules/@llblab/pi-telegram/dist/lib/bus-transport.js +16 -9
  24. package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +215 -18
  25. package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +1048 -327
  26. package/node_modules/@llblab/pi-telegram/dist/lib/channel-posts.d.ts +5 -0
  27. package/node_modules/@llblab/pi-telegram/dist/lib/channel-posts.js +434 -261
  28. package/node_modules/@llblab/pi-telegram/dist/lib/command-templates.d.ts +26 -5
  29. package/node_modules/@llblab/pi-telegram/dist/lib/command-templates.js +92 -176
  30. package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +168 -82
  31. package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +1409 -291
  32. package/node_modules/@llblab/pi-telegram/dist/lib/config.d.ts +1 -8
  33. package/node_modules/@llblab/pi-telegram/dist/lib/config.js +34 -76
  34. package/node_modules/@llblab/pi-telegram/dist/lib/delivery.d.ts +2 -2
  35. package/node_modules/@llblab/pi-telegram/dist/lib/delivery.js +16 -16
  36. package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +639 -171
  37. package/node_modules/@llblab/pi-telegram/dist/lib/generative-app-worker.mjs +19 -7
  38. package/node_modules/@llblab/pi-telegram/dist/lib/generative-apps.d.ts +0 -5
  39. package/node_modules/@llblab/pi-telegram/dist/lib/generative-apps.js +61 -49
  40. package/node_modules/@llblab/pi-telegram/dist/lib/inbound.d.ts +5 -0
  41. package/node_modules/@llblab/pi-telegram/dist/lib/inbound.js +35 -59
  42. package/node_modules/@llblab/pi-telegram/dist/lib/journal.d.ts +33 -3
  43. package/node_modules/@llblab/pi-telegram/dist/lib/journal.js +2063 -782
  44. package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.d.ts +2 -6
  45. package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.js +75 -58
  46. package/node_modules/@llblab/pi-telegram/dist/lib/locks.d.ts +29 -3
  47. package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +289 -108
  48. package/node_modules/@llblab/pi-telegram/dist/lib/logging.js +50 -14
  49. package/node_modules/@llblab/pi-telegram/dist/lib/media.d.ts +22 -1
  50. package/node_modules/@llblab/pi-telegram/dist/lib/media.js +46 -28
  51. package/node_modules/@llblab/pi-telegram/dist/lib/menu-model.d.ts +19 -5
  52. package/node_modules/@llblab/pi-telegram/dist/lib/menu-model.js +53 -11
  53. package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.d.ts +5 -4
  54. package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.js +45 -63
  55. package/node_modules/@llblab/pi-telegram/dist/lib/menu-settings.d.ts +5 -4
  56. package/node_modules/@llblab/pi-telegram/dist/lib/menu-settings.js +114 -78
  57. package/node_modules/@llblab/pi-telegram/dist/lib/menu-status.d.ts +1 -1
  58. package/node_modules/@llblab/pi-telegram/dist/lib/menu-status.js +8 -25
  59. package/node_modules/@llblab/pi-telegram/dist/lib/menu-thinking.d.ts +6 -1
  60. package/node_modules/@llblab/pi-telegram/dist/lib/menu-thinking.js +14 -21
  61. package/node_modules/@llblab/pi-telegram/dist/lib/menu.d.ts +8 -61
  62. package/node_modules/@llblab/pi-telegram/dist/lib/menu.js +92 -164
  63. package/node_modules/@llblab/pi-telegram/dist/lib/model.d.ts +1 -1
  64. package/node_modules/@llblab/pi-telegram/dist/lib/model.js +2 -16
  65. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-attachments.d.ts +6 -27
  66. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-attachments.js +45 -38
  67. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-buttons.js +22 -16
  68. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.d.ts +0 -2
  69. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.js +51 -64
  70. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-voice.js +6 -3
  71. package/node_modules/@llblab/pi-telegram/dist/lib/outbound.d.ts +6 -6
  72. package/node_modules/@llblab/pi-telegram/dist/lib/outbound.js +61 -51
  73. package/node_modules/@llblab/pi-telegram/dist/lib/ownership.js +6 -2
  74. package/node_modules/@llblab/pi-telegram/dist/lib/paths.d.ts +5 -0
  75. package/node_modules/@llblab/pi-telegram/dist/lib/paths.js +37 -21
  76. package/node_modules/@llblab/pi-telegram/dist/lib/pi.d.ts +2 -0
  77. package/node_modules/@llblab/pi-telegram/dist/lib/pi.js +8 -1
  78. package/node_modules/@llblab/pi-telegram/dist/lib/polling.d.ts +21 -37
  79. package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +59 -50
  80. package/node_modules/@llblab/pi-telegram/dist/lib/preview.js +39 -19
  81. package/node_modules/@llblab/pi-telegram/dist/lib/process-identity.d.ts +24 -0
  82. package/node_modules/@llblab/pi-telegram/dist/lib/process-identity.js +133 -0
  83. package/node_modules/@llblab/pi-telegram/dist/lib/prompts.js +2 -7
  84. package/node_modules/@llblab/pi-telegram/dist/lib/queue.d.ts +14 -16
  85. package/node_modules/@llblab/pi-telegram/dist/lib/queue.js +249 -126
  86. package/node_modules/@llblab/pi-telegram/dist/lib/recovery.d.ts +2 -83
  87. package/node_modules/@llblab/pi-telegram/dist/lib/recovery.js +20 -274
  88. package/node_modules/@llblab/pi-telegram/dist/lib/replies.d.ts +16 -24
  89. package/node_modules/@llblab/pi-telegram/dist/lib/replies.js +99 -116
  90. package/node_modules/@llblab/pi-telegram/dist/lib/routing.d.ts +120 -7
  91. package/node_modules/@llblab/pi-telegram/dist/lib/routing.js +4667 -1152
  92. package/node_modules/@llblab/pi-telegram/dist/lib/runtime.d.ts +1 -11
  93. package/node_modules/@llblab/pi-telegram/dist/lib/sections.d.ts +4 -29
  94. package/node_modules/@llblab/pi-telegram/dist/lib/sections.js +7 -20
  95. package/node_modules/@llblab/pi-telegram/dist/lib/skills.js +4 -3
  96. package/node_modules/@llblab/pi-telegram/dist/lib/status.js +86 -57
  97. package/node_modules/@llblab/pi-telegram/dist/lib/sync.d.ts +1 -3
  98. package/node_modules/@llblab/pi-telegram/dist/lib/sync.js +67 -43
  99. package/node_modules/@llblab/pi-telegram/dist/lib/target.d.ts +4 -0
  100. package/node_modules/@llblab/pi-telegram/dist/lib/target.js +18 -0
  101. package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.d.ts +18 -13
  102. package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.js +148 -53
  103. package/node_modules/@llblab/pi-telegram/dist/lib/text-groups.js +4 -39
  104. package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.d.ts +6 -27
  105. package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.js +369 -186
  106. package/node_modules/@llblab/pi-telegram/dist/lib/thread-display.d.ts +1 -2
  107. package/node_modules/@llblab/pi-telegram/dist/lib/thread-display.js +58 -38
  108. package/node_modules/@llblab/pi-telegram/dist/lib/thread-naming.d.ts +28 -8
  109. package/node_modules/@llblab/pi-telegram/dist/lib/thread-naming.js +175 -66
  110. package/node_modules/@llblab/pi-telegram/dist/lib/thread-reconciler.d.ts +42 -16
  111. package/node_modules/@llblab/pi-telegram/dist/lib/thread-reconciler.js +90 -50
  112. package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +82 -20
  113. package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +2247 -855
  114. package/node_modules/@llblab/pi-telegram/dist/lib/time-injection.js +1 -2
  115. package/node_modules/@llblab/pi-telegram/dist/lib/turns.js +1 -19
  116. package/node_modules/@llblab/pi-telegram/dist/lib/updates.d.ts +169 -80
  117. package/node_modules/@llblab/pi-telegram/dist/lib/updates.js +2418 -641
  118. package/node_modules/@llblab/pi-telegram/dist/lib/voice.d.ts +7 -22
  119. package/node_modules/@llblab/pi-telegram/dist/lib/voice.js +7 -22
  120. package/node_modules/@llblab/pi-telegram/dist/lib/wire.js +1 -1
  121. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.d.ts +3 -1
  122. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.js +425 -211
  123. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-identity.js +8 -13
  124. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.d.ts +1 -1
  125. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.js +328 -140
  126. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-slots.js +8 -4
  127. package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
  128. package/node_modules/@llblab/pi-telegram/docs/architecture.md +31 -29
  129. package/node_modules/@llblab/pi-telegram/docs/inbound.md +1 -1
  130. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +15 -3
  131. package/node_modules/@llblab/pi-telegram/docs/outbound.md +1 -1
  132. package/node_modules/@llblab/pi-telegram/docs/public-api.md +29 -1
  133. package/node_modules/@llblab/pi-telegram/docs/ui-style.md +25 -8
  134. package/node_modules/@llblab/pi-telegram/lib/activity-verbosity.ts +59 -82
  135. package/node_modules/@llblab/pi-telegram/lib/activity.ts +146 -102
  136. package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +12 -5
  137. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +389 -82
  138. package/node_modules/@llblab/pi-telegram/lib/bus-api.ts +263 -102
  139. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +2440 -601
  140. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +2209 -1290
  141. package/node_modules/@llblab/pi-telegram/lib/bus-transport.ts +46 -12
  142. package/node_modules/@llblab/pi-telegram/lib/bus.ts +1673 -444
  143. package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +848 -327
  144. package/node_modules/@llblab/pi-telegram/lib/command-templates.ts +152 -265
  145. package/node_modules/@llblab/pi-telegram/lib/commands.ts +2398 -555
  146. package/node_modules/@llblab/pi-telegram/lib/config.ts +177 -170
  147. package/node_modules/@llblab/pi-telegram/lib/delivery.ts +41 -29
  148. package/node_modules/@llblab/pi-telegram/lib/extension.ts +1206 -433
  149. package/node_modules/@llblab/pi-telegram/lib/generative-app-worker.mjs +19 -7
  150. package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +324 -211
  151. package/node_modules/@llblab/pi-telegram/lib/inbound.ts +95 -97
  152. package/node_modules/@llblab/pi-telegram/lib/journal.ts +5311 -1763
  153. package/node_modules/@llblab/pi-telegram/lib/keyboard.ts +1 -3
  154. package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +128 -78
  155. package/node_modules/@llblab/pi-telegram/lib/locks.ts +677 -203
  156. package/node_modules/@llblab/pi-telegram/lib/logging.ts +147 -58
  157. package/node_modules/@llblab/pi-telegram/lib/media.ts +82 -43
  158. package/node_modules/@llblab/pi-telegram/lib/menu-model.ts +85 -18
  159. package/node_modules/@llblab/pi-telegram/lib/menu-queue.ts +88 -129
  160. package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +260 -155
  161. package/node_modules/@llblab/pi-telegram/lib/menu-status.ts +20 -60
  162. package/node_modules/@llblab/pi-telegram/lib/menu-thinking.ts +41 -56
  163. package/node_modules/@llblab/pi-telegram/lib/menu.ts +112 -285
  164. package/node_modules/@llblab/pi-telegram/lib/model.ts +8 -22
  165. package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +156 -125
  166. package/node_modules/@llblab/pi-telegram/lib/outbound-buttons.ts +76 -49
  167. package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +96 -94
  168. package/node_modules/@llblab/pi-telegram/lib/outbound-voice.ts +33 -27
  169. package/node_modules/@llblab/pi-telegram/lib/outbound.ts +125 -125
  170. package/node_modules/@llblab/pi-telegram/lib/ownership.ts +19 -10
  171. package/node_modules/@llblab/pi-telegram/lib/paths.ts +148 -49
  172. package/node_modules/@llblab/pi-telegram/lib/pi.ts +35 -15
  173. package/node_modules/@llblab/pi-telegram/lib/polling.ts +144 -147
  174. package/node_modules/@llblab/pi-telegram/lib/preview.ts +93 -40
  175. package/node_modules/@llblab/pi-telegram/lib/process-identity.ts +164 -0
  176. package/node_modules/@llblab/pi-telegram/lib/prompts.ts +4 -11
  177. package/node_modules/@llblab/pi-telegram/lib/queue.ts +511 -300
  178. package/node_modules/@llblab/pi-telegram/lib/recovery.ts +50 -454
  179. package/node_modules/@llblab/pi-telegram/lib/rendering.ts +1 -3
  180. package/node_modules/@llblab/pi-telegram/lib/replies.ts +248 -209
  181. package/node_modules/@llblab/pi-telegram/lib/routing.ts +8509 -2186
  182. package/node_modules/@llblab/pi-telegram/lib/runtime.ts +1 -12
  183. package/node_modules/@llblab/pi-telegram/lib/sections.ts +24 -89
  184. package/node_modules/@llblab/pi-telegram/lib/setup.ts +1 -3
  185. package/node_modules/@llblab/pi-telegram/lib/skills.ts +9 -4
  186. package/node_modules/@llblab/pi-telegram/lib/status.ts +215 -110
  187. package/node_modules/@llblab/pi-telegram/lib/sync.ts +448 -361
  188. package/node_modules/@llblab/pi-telegram/lib/target.ts +22 -3
  189. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +302 -127
  190. package/node_modules/@llblab/pi-telegram/lib/text-groups.ts +5 -39
  191. package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +833 -331
  192. package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +213 -97
  193. package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +232 -87
  194. package/node_modules/@llblab/pi-telegram/lib/thread-reconciler.ts +155 -72
  195. package/node_modules/@llblab/pi-telegram/lib/threads.ts +5318 -1845
  196. package/node_modules/@llblab/pi-telegram/lib/time-injection.ts +1 -4
  197. package/node_modules/@llblab/pi-telegram/lib/turns.ts +15 -28
  198. package/node_modules/@llblab/pi-telegram/lib/updates.ts +5184 -1612
  199. package/node_modules/@llblab/pi-telegram/lib/voice.ts +7 -35
  200. package/node_modules/@llblab/pi-telegram/lib/wire.ts +1 -1
  201. package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +996 -416
  202. package/node_modules/@llblab/pi-telegram/lib/workspace-identity.ts +14 -17
  203. package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +878 -376
  204. package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +22 -13
  205. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  206. package/package.json +2 -2
  207. package/node_modules/@llblab/pi-telegram/scripts/check-downgrade.mjs +0 -472
  208. package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +0 -108
@@ -5,10 +5,9 @@
5
5
  * Transport authority, durable bindings, and queue custody remain with their owners.
6
6
  */
7
7
  import * as BusFollower from "./bus-follower.ts";
8
- import * as Queue from "./queue.ts";
9
8
  import type { AgentEndEvent, AgentSettledEvent, AgentStartEvent, AssistantMessageEvent, BeforeAgentStartEvent, ExtensionAPI, ExtensionContext, InputEvent, MessageEndEvent, SessionBeforeCompactEvent, SessionCompactEvent, SessionCompactFailedEvent, SessionShutdownEvent, SessionStartEvent, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolExecutionUpdateEvent, UIPromptEndEvent, UIPromptStartEvent } from "./pi.ts";
10
- export declare function setResetTransportReplyDedup(fn: () => void): void;
11
- export declare function createAgentStartDedupHook(inner: (event: AgentStartEvent, ctx: ExtensionContext) => Promise<void>, schedulePublication?: (task: () => Promise<void>) => void): (event: AgentStartEvent, ctx: ExtensionContext) => Promise<void>;
9
+ import * as Queue from "./queue.ts";
10
+ export declare function createAgentStartDedupHook(inner: (event: AgentStartEvent, ctx: ExtensionContext) => Promise<void>, resetReplyDedup: () => void, schedulePublication?: (task: () => Promise<void>) => void): (event: AgentStartEvent, ctx: ExtensionContext) => Promise<void>;
12
11
  type TelegramBeforeAgentStartEvent = Omit<BeforeAgentStartEvent, "systemPrompt"> & {
13
12
  systemPrompt: string | string[];
14
13
  };
@@ -202,9 +201,6 @@ export interface TelegramMessageActivityTypingDeps<TContext> {
202
201
  recordRuntimeEvent?: (category: string, error: unknown, details?: Record<string, unknown>) => void;
203
202
  }
204
203
  export declare function createTelegramMessageActivityTypingHooks<TContext extends ExtensionContext>(deps: TelegramMessageActivityTypingDeps<TContext>): Pick<TelegramLifecycleRegistrationDeps, "onMessageStart" | "onMessageUpdate">;
205
- export declare function createDedupAgentStartHook(dedup: {
206
- reset(): void;
207
- }, inner: (event: AgentStartEvent, ctx: ExtensionContext) => Promise<void>): (event: AgentStartEvent, ctx: ExtensionContext) => Promise<void>;
208
204
  export interface TelegramExtraLifecycleHooks {
209
205
  onSessionStart?: (event: SessionStartEvent, ctx: ExtensionContext) => Promise<void>;
210
206
  onSessionShutdown?: (event: SessionShutdownEvent, ctx: ExtensionContext) => Promise<void>;
@@ -5,53 +5,58 @@
5
5
  * Transport authority, durable bindings, and queue custody remain with their owners.
6
6
  */
7
7
  import { randomUUID } from "node:crypto";
8
- import { formatTelegramConnectionFailure } from "./status.js";
9
8
  import * as BusFollower from "./bus-follower.js";
10
9
  import * as Queue from "./queue.js";
10
+ import { formatTelegramConnectionFailure } from "./status.js";
11
11
  import * as TextGroups from "./text-groups.js";
12
- let resetTransportReplyDedupFn;
13
- export function setResetTransportReplyDedup(fn) {
14
- resetTransportReplyDedupFn = fn;
15
- }
16
- export function createAgentStartDedupHook(inner, schedulePublication) {
12
+ export function createAgentStartDedupHook(inner, resetReplyDedup, schedulePublication) {
17
13
  return async (event, ctx) => {
18
- const reset = resetTransportReplyDedupFn;
19
- if (reset) {
20
- // A new turn must not erase the anchor of a final still ahead in the FIFO.
21
- if (schedulePublication)
22
- schedulePublication(async () => { reset(); });
23
- else
24
- reset();
25
- }
14
+ // A new turn must not erase the anchor of a final still ahead in the FIFO.
15
+ if (schedulePublication)
16
+ schedulePublication(async () => {
17
+ resetReplyDedup();
18
+ });
19
+ else
20
+ resetReplyDedup();
26
21
  return inner(event, ctx);
27
22
  };
28
23
  }
29
24
  const HANDOFF_KEY = Symbol.for("pi-telegram.connection-resume.v1");
30
25
  function processHandoffStore() {
31
26
  const globals = globalThis;
32
- return globals[HANDOFF_KEY] ??= {};
27
+ return (globals[HANDOFF_KEY] ??= {});
33
28
  }
34
29
  export function createTelegramConnectionLifecycle(deps) {
35
30
  return {
36
31
  onSessionShutdown(event, ctx) {
37
- deps.intent.suspend({ reason: event.reason, cwd: ctx.cwd,
38
- targetSessionFile: event.targetSessionFile, connected: deps.isConnected(),
39
- profileName: deps.getProfileName() });
32
+ deps.intent.suspend({
33
+ reason: event.reason,
34
+ cwd: ctx.cwd,
35
+ targetSessionFile: event.targetSessionFile,
36
+ connected: deps.isConnected(),
37
+ profileName: deps.getProfileName(),
38
+ });
40
39
  },
41
40
  prepare(event, ctx) {
42
- const intent = deps.intent.resume({ reason: event.reason, cwd: ctx.cwd,
43
- sessionFile: event.reason === "resume" ? ctx.sessionManager.getSessionFile() : undefined });
41
+ const intent = deps.intent.resume({
42
+ reason: event.reason,
43
+ cwd: ctx.cwd,
44
+ sessionFile: event.reason === "resume"
45
+ ? ctx.sessionManager.getSessionFile()
46
+ : undefined,
47
+ });
44
48
  if (!intent)
45
49
  return undefined;
46
50
  const generation = deps.getGeneration();
47
51
  const isCurrent = () => deps.intent.isActive(intent.id) &&
48
- generation === deps.getGeneration() && deps.isCurrent(ctx);
52
+ generation === deps.getGeneration() &&
53
+ deps.isCurrent(ctx);
49
54
  return () => {
50
55
  // Startup remains extension-owned background work; no captured command ctx crosses resume.
51
56
  void (async () => {
52
57
  if (!isCurrent())
53
58
  return;
54
- if (!await deps.activateProfile(intent.profileName, isCurrent)) {
59
+ if (!(await deps.activateProfile(intent.profileName, isCurrent))) {
55
60
  if (isCurrent())
56
61
  ctx.ui.notify("Telegram profile unavailable. Run /telegram-setup.", "warning");
57
62
  return;
@@ -65,11 +70,13 @@ export function createTelegramConnectionLifecycle(deps) {
65
70
  deps.recordError(new Error(result.message ?? "Telegram resume connection failed."));
66
71
  ctx.ui.notify(formatTelegramConnectionFailure(result.message), "warning");
67
72
  }
68
- })().catch((error) => {
73
+ })()
74
+ .catch((error) => {
69
75
  deps.recordError(error);
70
76
  if (isCurrent())
71
77
  ctx.ui.notify(formatTelegramConnectionFailure(error), "warning");
72
- }).finally(() => deps.intent.finish(intent.id));
78
+ })
79
+ .finally(() => deps.intent.finish(intent.id));
73
80
  };
74
81
  },
75
82
  };
@@ -97,23 +104,38 @@ export function createTelegramConnectionIntentRuntime(options = {}) {
97
104
  store.pending = undefined;
98
105
  },
99
106
  suspend(input) {
100
- const intent = active ?? (input.connected
101
- ? { id: randomUUID(), cwd: input.cwd, profileName: input.profileName }
102
- : undefined);
107
+ const intent = active ??
108
+ (input.connected
109
+ ? { id: randomUUID(), cwd: input.cwd, profileName: input.profileName }
110
+ : undefined);
103
111
  active = undefined;
104
- store.pending = input.reason === "resume" && input.targetSessionFile &&
105
- intent?.cwd === input.cwd
106
- ? { ...intent, pid, targetSessionFile: input.targetSessionFile, expiresAtMs: now() + 30_000 }
107
- : undefined;
112
+ store.pending =
113
+ input.reason === "resume" &&
114
+ input.targetSessionFile &&
115
+ intent?.cwd === input.cwd
116
+ ? {
117
+ ...intent,
118
+ pid,
119
+ targetSessionFile: input.targetSessionFile,
120
+ expiresAtMs: now() + 30_000,
121
+ }
122
+ : undefined;
108
123
  },
109
124
  resume(input) {
110
125
  const handoff = store.pending;
111
126
  store.pending = undefined;
112
- if (!handoff || handoff.pid !== pid || now() >= handoff.expiresAtMs ||
113
- input.reason !== "resume" || input.cwd !== handoff.cwd ||
127
+ if (!handoff ||
128
+ handoff.pid !== pid ||
129
+ now() >= handoff.expiresAtMs ||
130
+ input.reason !== "resume" ||
131
+ input.cwd !== handoff.cwd ||
114
132
  input.sessionFile !== handoff.targetSessionFile)
115
133
  return undefined;
116
- active = { id: randomUUID(), cwd: handoff.cwd, profileName: handoff.profileName };
134
+ active = {
135
+ id: randomUUID(),
136
+ cwd: handoff.cwd,
137
+ profileName: handoff.profileName,
138
+ };
117
139
  return { ...active };
118
140
  },
119
141
  };
@@ -258,10 +280,13 @@ export function createTelegramBridgeSessionLifecycleAssembly(deps) {
258
280
  let preserveThread;
259
281
  if (event.reason === "quit") {
260
282
  try {
261
- preserveThread = deps.services.prepareThreadPreservationOnQuit?.(isCurrent);
283
+ preserveThread =
284
+ deps.services.prepareThreadPreservationOnQuit?.(isCurrent);
262
285
  }
263
286
  catch (error) {
264
- deps.follower.recordRuntimeEvent("session", error, { phase: "preserve-thread-on-quit" });
287
+ deps.follower.recordRuntimeEvent("session", error, {
288
+ phase: "preserve-thread-on-quit",
289
+ });
265
290
  }
266
291
  }
267
292
  deps.services.guestPlaceholder?.stopAll();
@@ -280,7 +305,9 @@ export function createTelegramBridgeSessionLifecycleAssembly(deps) {
280
305
  await preserveThread?.();
281
306
  }
282
307
  catch (error) {
283
- deps.follower.recordRuntimeEvent("session", error, { phase: "preserve-thread-on-quit" });
308
+ deps.follower.recordRuntimeEvent("session", error, {
309
+ phase: "preserve-thread-on-quit",
310
+ });
284
311
  }
285
312
  },
286
313
  };
@@ -316,6 +343,14 @@ export function createTelegramCompactionObserverRuntime(deps) {
316
343
  clearTimer(fallbackTimer);
317
344
  fallbackTimer = undefined;
318
345
  };
346
+ // Stop only a typing loop this observer started; a pre-existing agent-owned loop is preserved.
347
+ const releaseCompactionPresence = (ctx) => {
348
+ deps.setCompactionInProgress(false);
349
+ if (typingStartedByObserver)
350
+ deps.stopTypingLoop?.();
351
+ typingStartedByObserver = false;
352
+ deps.updateStatus(ctx);
353
+ };
319
354
  const requestDispatch = () => {
320
355
  deps.requestDeferredDispatchNextQueuedTelegramTurn(deps.dispatchNextQueuedTelegramTurn);
321
356
  };
@@ -337,11 +372,7 @@ export function createTelegramCompactionObserverRuntime(deps) {
337
372
  fallbackTimer = undefined;
338
373
  if (deps.isContextActive && !deps.isContextActive(ctx))
339
374
  return;
340
- deps.setCompactionInProgress(false);
341
- if (typingStartedByObserver)
342
- deps.stopTypingLoop?.();
343
- typingStartedByObserver = false;
344
- deps.updateStatus(ctx);
375
+ releaseCompactionPresence(ctx);
345
376
  deps.recordRuntimeEvent?.("compact", new Error("Compaction observer timed out"));
346
377
  // Observer expiry releases local presence, not Pi's eventual terminal result.
347
378
  requestDispatch();
@@ -352,22 +383,14 @@ export function createTelegramCompactionObserverRuntime(deps) {
352
383
  if (deps.isContextActive && !deps.isContextActive(ctx))
353
384
  return;
354
385
  clearFallbackTimer();
355
- deps.setCompactionInProgress(false);
356
- if (typingStartedByObserver)
357
- deps.stopTypingLoop?.();
358
- typingStartedByObserver = false;
359
- deps.updateStatus(ctx);
386
+ releaseCompactionPresence(ctx);
360
387
  requestDispatch();
361
388
  },
362
389
  onSessionCompactFailed: (_event, ctx) => {
363
390
  if (deps.isContextActive && !deps.isContextActive(ctx))
364
391
  return;
365
392
  clearFallbackTimer();
366
- deps.setCompactionInProgress(false);
367
- if (typingStartedByObserver)
368
- deps.stopTypingLoop?.();
369
- typingStartedByObserver = false;
370
- deps.updateStatus(ctx);
393
+ releaseCompactionPresence(ctx);
371
394
  deps.onCompactionAbandoned?.();
372
395
  requestDispatch();
373
396
  },
@@ -402,12 +425,6 @@ export function createTelegramMessageActivityTypingHooks(deps) {
402
425
  onMessageUpdate: (event, ctx) => handleMessageActivity("update", event, ctx, deps.onMessageUpdate),
403
426
  };
404
427
  }
405
- export function createDedupAgentStartHook(dedup, inner) {
406
- return async (event, ctx) => {
407
- dedup.reset();
408
- await inner(event, ctx);
409
- };
410
- }
411
428
  export function appendTelegramLifecycleHooks(base, extra, isSessionActive) {
412
429
  return {
413
430
  onSessionStart: async (event, ctx) => {
@@ -84,7 +84,7 @@ export interface TelegramLockRuntime<TContext extends TelegramLockContext> {
84
84
  owns: (ctx?: TelegramLockContext) => boolean;
85
85
  commitIfOwned: (commit: () => void) => boolean;
86
86
  /** Consolidated-store publication; domain reducers retain their own exact payload/CAS rules. */
87
- publishStateSectionIfOwned?: <T>(section: "workspace" | "runtime", mutate: (current: unknown, observed: Readonly<TelegramRuntimeStateProfile>) => TelegramRuntimeStateMutation<T>, options: TelegramOwnedStatePublicationOptions) => TelegramOwnedStatePublicationResult<T>;
87
+ publishStateSectionIfOwned?: <T>(section: "workspace" | "runtime", mutate: TelegramRuntimeStateSectionReducer<T>, options: TelegramOwnedStatePublicationOptions) => TelegramOwnedStatePublicationResult<T>;
88
88
  refresh: (ctx?: TelegramLockContext) => boolean;
89
89
  /** The polling journal named by owners.json for this key, owned or not. */
90
90
  getJournalPath: () => string | undefined;
@@ -135,6 +135,31 @@ interface TelegramRenameRetryOptions {
135
135
  attempts?: number;
136
136
  retryDelayMs?: number;
137
137
  }
138
+ export type TelegramPrivateFileFailure = "capacity" | "unsafe" | "changed";
139
+ /** Typed private-file refusal; owners map the failure into their own error vocabulary. */
140
+ export declare class TelegramPrivateFileError extends Error {
141
+ readonly failure: TelegramPrivateFileFailure;
142
+ constructor(failure: TelegramPrivateFileFailure, message: string);
143
+ }
144
+ /**
145
+ * Read flags for private runtime files. Where the platform offers them, no-follow and non-blocking opens refuse a
146
+ * swapped link or FIFO at open time. Windows has neither flag and no FIFOs in the file namespace; there the
147
+ * lstat-before/fstat-after identity binding every strict reader performs is the guard, so a link swapped in after
148
+ * inspection opens a different file and is refused as changed.
149
+ */
150
+ export declare const TELEGRAM_STRICT_READ_FLAGS: number;
151
+ /** POSIX owner and permission bits; Windows has no uid, so its ACL-protected agent directory carries privacy. */
152
+ export declare function isTelegramOwnerPrivate(stat: {
153
+ uid: bigint;
154
+ mode: bigint;
155
+ }): boolean;
156
+ /**
157
+ * Read one owner-private, single-link, bounded regular file without following links. Absence returns undefined;
158
+ * an inode or metadata change between inspection and open refuses as `changed`.
159
+ */
160
+ export declare function readTelegramPrivateFile(path: string, maxBytes: number): string | undefined;
161
+ /** Atomically publish owner-private contents through a unique staging file; the rename consumes staging. */
162
+ export declare function publishTelegramPrivateFile(path: string, temporaryBasePath: string, contents: string, label: string, onBoundary?: (boundary: "after-write-before-rename" | "after-rename") => void): void;
138
163
  /** Rename one Telegram runtime artifact with bounded Windows sharing retries. */
139
164
  export declare function renameTelegramPathWithRetry(sourcePath: string, destinationPath: string, options?: TelegramRenameRetryOptions): boolean;
140
165
  export interface TelegramFileTransactionOptions {
@@ -162,6 +187,8 @@ export declare function readTelegramRuntimeState(path: string): TelegramRuntimeS
162
187
  * continuity. Filesystem access errors are not damage and still throw. Returns whether a reset was published.
163
188
  */
164
189
  export declare function resetDamagedTelegramRuntimeState(path: string, validateProfile?: (profile: string, sections: Readonly<TelegramRuntimeStateProfile>) => void): boolean;
190
+ /** Pure section reducer: receives the stored section and its profile, returns the next section and result. */
191
+ export type TelegramRuntimeStateSectionReducer<T> = (current: unknown, observed: Readonly<TelegramRuntimeStateProfile>) => TelegramRuntimeStateMutation<T>;
165
192
  export interface TelegramRuntimeStateMutation<T> {
166
193
  value: unknown;
167
194
  result: T;
@@ -183,10 +210,9 @@ export interface TelegramOwnedStatePublicationOptions extends TelegramRuntimeSta
183
210
  * One physical read/check/write transaction for one named section. The caller supplies domain policy; copies expose
184
211
  * current sibling facts without granting writes to them. No await, nested transaction, repair or legacy import.
185
212
  */
186
- export declare function mutateTelegramRuntimeStateSection<T>(path: string, profile: string, section: TelegramRuntimeStateSection, mutate: (current: unknown, observed: Readonly<TelegramRuntimeStateProfile>) => TelegramRuntimeStateMutation<T>, options: TelegramRuntimeStatePublicationOptions): T;
213
+ export declare function mutateTelegramRuntimeStateSection<T>(path: string, profile: string, section: TelegramRuntimeStateSection, mutate: TelegramRuntimeStateSectionReducer<T>, options: TelegramRuntimeStatePublicationOptions): T;
187
214
  export declare function writeLocks(path: string, locks: Record<string, unknown>): void;
188
215
  export declare function parseTelegramLockEntry(value: unknown): TelegramLockEntry | undefined;
189
- export declare function isProcessAlive(pid: number): boolean;
190
216
  export declare function createTelegramLockRuntime<TContext extends TelegramLockContext>(options?: TelegramLockRuntimeOptions): TelegramLockRuntime<TContext>;
191
217
  export declare function createTelegramLockOwnershipGuard<TContext extends TelegramLockContext>(lock: TelegramLockRuntime<TContext>): TelegramLockOwnershipGuard<TContext>;
192
218
  export declare function createTelegramDirectDeliveryOwnershipChecker<TContext extends TelegramLockContext>(deps: {