@llblab/pi-kit 0.18.0 → 0.18.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 (42) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -2
  3. package/node_modules/@llblab/pi-state-flow/AGENTS.md +1 -1
  4. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +5 -0
  5. package/node_modules/@llblab/pi-state-flow/README.md +1 -1
  6. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +3 -3
  7. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.d.ts +1 -1
  8. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +1 -1
  9. package/node_modules/@llblab/pi-state-flow/dist/package.json +5 -5
  10. package/node_modules/@llblab/pi-state-flow/docs/compatibility.md +27 -82
  11. package/node_modules/@llblab/pi-state-flow/docs/performance.md +2 -2
  12. package/node_modules/@llblab/pi-state-flow/docs/usage.md +1 -1
  13. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +3 -3
  14. package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +1 -1
  15. package/node_modules/@llblab/pi-state-flow/package.json +5 -5
  16. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +7 -0
  17. package/node_modules/@llblab/pi-telegram/README.md +1 -2
  18. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +1 -3
  19. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +1 -6
  20. package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +1 -4
  21. package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +13 -33
  22. package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +1 -4
  23. package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.d.ts +1 -0
  24. package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.js +72 -1
  25. package/node_modules/@llblab/pi-telegram/dist/lib/queue.d.ts +7 -0
  26. package/node_modules/@llblab/pi-telegram/dist/lib/queue.js +27 -0
  27. package/node_modules/@llblab/pi-telegram/dist/lib/replies.d.ts +3 -0
  28. package/node_modules/@llblab/pi-telegram/dist/lib/replies.js +17 -0
  29. package/node_modules/@llblab/pi-telegram/dist/lib/sync.js +8 -1
  30. package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
  31. package/node_modules/@llblab/pi-telegram/docs/architecture.md +2 -0
  32. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +1 -1
  33. package/node_modules/@llblab/pi-telegram/docs/public-api.md +1 -1
  34. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +0 -10
  35. package/node_modules/@llblab/pi-telegram/lib/commands.ts +18 -41
  36. package/node_modules/@llblab/pi-telegram/lib/extension.ts +1 -8
  37. package/node_modules/@llblab/pi-telegram/lib/menu-queue.ts +126 -1
  38. package/node_modules/@llblab/pi-telegram/lib/queue.ts +46 -0
  39. package/node_modules/@llblab/pi-telegram/lib/replies.ts +19 -0
  40. package/node_modules/@llblab/pi-telegram/lib/sync.ts +8 -1
  41. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  42. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to `@llblab/pi-kit` are documented here.
4
4
 
5
+ ## 0.18.2 - 2026-09-22
6
+
7
+ - `Telegram Operational Hotfixes`: Advances the exact Telegram pin to `0.50.1`, restoring follower registration when canonical Workspace binding deduplication changes a provisional slot and letting the busy leader permanently skip queued Guest prompts while visually clearing their inline placeholders.
8
+ - `Lifecycle And Command Safety`: Adds one-use authorization to armed internal lifecycle actions, prevents Thread naming from Pi commands, and aligns concise autocomplete hints with Pi's argument-first style.
9
+ - `Package Cohort`: Keeps every other bundled package at its current exact version; the package set, resource inventory, and explicit load order remain unchanged.
10
+
11
+ ## 0.18.1 - 2026-09-20
12
+
13
+ - `Passive State Flow Guidance`: Advances the exact State Flow pin to `0.16.3`, requiring finalization barriers only in active episodes while preventing gratuitous final-only patches during passive memory use.
14
+ - `Compatibility Contract`: Carries the minimum Pi SDK version `0.84.4` without an artificial upper peer-dependency bound and removes stale compatibility evidence without dropping supported storage migrations or current safety checks.
15
+ - `Package Cohort`: Keeps every other bundled package at its current exact version; the package set, resource inventory, and explicit load order remain unchanged.
16
+
5
17
  ## 0.18.0 - 2026-09-18
6
18
 
7
19
  - `Telegram Lifecycle Gateway`: Advances the exact Telegram pin to `0.50.0`, replacing the session-specific technical command with one guarded internal gateway for runtime-armed lifecycle actions while preserving `/new` settlement, continuity, and terminal-result guarantees.
package/README.md CHANGED
@@ -14,8 +14,8 @@ Package links lead to the owning repositories for usage, documentation, issues,
14
14
  | [`@llblab/pi-clean-room`](https://github.com/llblab/pi-clean-room) | `0.1.1` | Isolated nested Pi TUI with explicitly selected extensions |
15
15
  | [`@llblab/pi-codex-usage`](https://github.com/llblab/pi-codex-usage) | `0.10.0` | Compact Codex/Spark subscription-limit and Business credit-usage status |
16
16
  | [`@llblab/pi-grow-loop`](https://github.com/llblab/pi-grow-loop) | `0.8.1` | Visible continuation scheduling and bounded worker Skills |
17
- | [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.16.2` | Incremental scoped state/context/memory compiler with proportional operational guidance, intentional agency, reactive dangling-reference diagnostics, compiled runtime delivery, safe compaction, and exact publication |
18
- | [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.50.0` | Telegram companion with native fresh-session replacement, a guarded internal lifecycle gateway, buffered thinking cadence, adaptive Thread continuity, exact queues, files, voice, controls, and Generative Apps guidance |
17
+ | [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.16.3` | Incremental scoped state/context/memory compiler with mode-aware passive guidance, proportional operational guidance, intentional agency, reactive dangling-reference diagnostics, safe compaction, and exact publication |
18
+ | [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.50.1` | Telegram companion with guarded lifecycle actions, recoverable Workspace slots, immediate Guest queue Skip, concise Pi command hints, adaptive Thread continuity, exact queues, files, voice, controls, and Generative Apps guidance |
19
19
  | [`@llblab/skills`](https://github.com/llblab/skills) | `1.15.0` | Portable workflows for engineering, review, design, context maintenance, and other focused tasks |
20
20
 
21
21
  Versions are exact by design. An upstream release does not change an installed kit until this repository explicitly advances the dependency and publishes a new kit version. Runtime defects and package-specific feature requests belong in the linked repository; package selection and kit installation issues belong here.
@@ -44,7 +44,7 @@
44
44
  - Explicit `/state-flow-start` creates the State Flow directory when missing and returns after locally usable runtime acceptance for normal `turn-end`/`off` policy. If Git is installed, initialize an exact-root Git repository when needed, including a populated file-only store, preserving all existing bytes and unrelated files; an ancestor repository is not a valid substitute. Skip full predecessor-format migration planning only when all exact legacy snapshot names are absent, and defer Markdown freshness discovery until before the next enabled inference. If Git is absent, use file persistence. Manual-mode startup/status/restore do not initialize Git; configured automatic start of a genuinely new session uses the same initialization as explicit start. Never create external accounts, remote repositories, credentials, or remote configuration; those remain operator-owned. Never auto-import, delete, or reset files/history in a previous Knowledge-backed store; old branch revisions require their original Git history to remain available in the selected store. `/state-flow-start` must initialize missing global, CWD, and current-session checkpoint/tail pairs plus session config/meta through compare-and-swap publication when required, enable only the current session branch, and bootstrap prior conversation when needed. Explicit start on a proven pre-runtime branch (no checkpoint or an ordinary-disabled marker) establishes an empty session origin rather than importing a later same-session layer; validate existing runtime identity, retain shared streams unchanged, and preserve later branch data in cold Git history. Ordinary new sessions remain manual unless agent-level `autoStart` is true; CWD materialization alone grants no automatic activation. Configured new sessions may initialize missing CWD state and receive distinct empty session layers while inheriting global/CWD values. Resumed and tree-selected branches restore their own config and temporal lineage, regardless of the global flag.
45
45
  - `/state-flow-stop` returns to the configured passive bootstrap/tool combination and must persist only the current session/branch's `config.enabled = false` and necessary runtime provenance, preserving all semantic checkpoints/tails and creating no semantic transition. Retain a frozen handoff plus the active user-run trajectory (including later tool results), post-stop conversation, and foreign context-bearing custom messages across same-physical-session reload/resume/tree. Exclude completed pre-run conversation and private State Flow validation feedback; idle Stop does not retain the completed run. Active restart replaces passive mode but uses that bounded boundary for its one migration run; new and forked physical sessions inherit neither projection. It does not rewrite agent-level `autoStart` or change its policy for future new sessions.
46
46
  - After an accepted non-bootstrap run settles with no pending input, State Flow may request native manual compaction under a generation-private marker only when public `getContextUsage()` reports at least 24,000 tokens. Keep the complete latest accepted user iteration, store only revision/step identity in details, and never duplicate state in the summary. Unknown or smaller usage skips compaction; a benign native refusal releases the attempt for later work. Skip prefixes containing foreign custom context. Never customize user manual or native threshold/overflow compaction, discard unfinished pre-patch work, create a State Flow origin, or rewrite Pi's append-only JSONL/tree.
47
- - Keep the injected runtime protocol compact and normative; put rationale and extended explanation in README rather than the model prompt. Never parse or strip State Flow HTML comments; they are ordinary historical text, while foreign comment handling remains owned by other extensions.
47
+ - Keep the injected runtime protocol compact and normative; put rationale and extended explanation in README rather than the model prompt. Foreign comment handling remains owned by other extensions.
48
48
  - Do not claim strict boundedness for state, the current run trajectory, the turn specification, or the external full trace.
49
49
  - Remain extension-agnostic in core semantics, storage, and inference: core modules never import, name, special-case, or encode policy for another extension or transport. One optional leaf presentation adapter (`lib/telegram.ts`) may import public `pi-telegram` membranes to mirror the live status on exactly one main-menu section button and expose the same start/stop affordances already owned by `state-flow-start` and `state-flow-stop`; it must fail open when the transport is absent or its registry is unready and must never alter core behavior.
50
50
  - Activate State Flow model tools while an episode is enabled or passive tools are configured; preserve every unrelated active tool when toggling them. Passive reads never initialize storage, while an explicit passive patch may initialize or migrate storage without enabling episode barriers, continuation, or compaction. Keep mutation confined to `patch_state` and historical observation read-only.
@@ -4,6 +4,11 @@
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.16.3: Passive guidance and compatibility cleanup
8
+
9
+ - `Passive finalization guidance`: Makes the always-available `patch_state` tool contract mode-aware, requiring `final:true` only for active episodes and explicitly forbidding final-only calls in passive turns so tool-level guidance no longer contradicts passive runtime context.
10
+ - `Pi compatibility range`: Declares `0.84.4` as the minimum Pi SDK version without an upper peer-dependency bound, replaces stale candidate reports and historical run internals with a concise tested-stack contract, and removes dead legacy test scaffolding plus retired HTML-envelope fixtures without dropping supported storage migrations or current negative-boundary coverage.
11
+
7
12
  ## 0.16.2: Passive first-CWD memory hotfix
8
13
 
9
14
  - `Passive first-CWD memory`: Treats global-only storage as a valid passive-memory state before the current CWD has ever materialized, projecting an empty CWD overlay instead of warning that shared storage is incomplete; CWD-without-global storage still fails closed.
@@ -26,7 +26,7 @@ The agent curates what matters; the extension validates, persists, and projects
26
26
 
27
27
  ## Quick start
28
28
 
29
- Requires Pi `0.84.4–0.84.x` or `0.85.1–0.85.x` and Node.js `22.19.0` or newer. See the [SDK compatibility matrix](docs/compatibility.md) for exact tested stacks. Git is optional; using it requires a configured commit identity.
29
+ Requires Pi `0.84.4` or newer and Node.js `22.19.0` or newer. There is no declared upper Pi version bound; see the [SDK compatibility matrix](docs/compatibility.md) for exact tested stacks. Git is optional; using it requires a configured commit identity.
30
30
 
31
31
  From npm:
32
32
 
@@ -619,10 +619,10 @@ export default function stateFlowExtension(pi, options = {}) {
619
619
  pi.registerTool({
620
620
  name: PATCH_STATE_TOOL_NAME,
621
621
  label: "Patch State",
622
- description: "The sole State Flow semantic mutation protocol. Supply any combination of global, cwd, and session patches; all supplied scopes commit atomically. Set final:true when the current iteration may finish at a later turn_end. final:true does not stop reasoning, tools, or later patch_state calls. Use {final:true} when no semantic update is needed. This call must be the only State Flow barrier in its assistant response.",
623
- promptSnippet: "Atomically patch global/cwd/session; final:true permits a later turn_end",
622
+ description: "The sole State Flow semantic mutation protocol. Supply any combination of global, cwd, and session patches; all supplied scopes commit atomically. In an active State Flow episode, set final:true when the current iteration may finish at a later turn_end; use {final:true} when no semantic update is needed. Passive turns have no terminal barrier: never call patch_state only to set final:true. This call must be the only State Flow barrier in its assistant response.",
623
+ promptSnippet: "Atomically patch global/cwd/session; active episodes use final:true before turn_end",
624
624
  promptGuidelines: [
625
- "Use patch_state for durable semantic changes. Before a final answer, make the iteration terminal-eligible with final:true, optionally alongside atomic global/cwd/session patches.",
625
+ "Use patch_state for durable semantic changes. Only in an active State Flow episode, make the iteration terminal-eligible before a final answer with final:true, optionally alongside atomic global/cwd/session patches. In passive mode, never call patch_state only to set final:true.",
626
626
  "Use patch_state as reconciliation, not append-only notes: place new knowledge at the narrowest valid scope and remove superseded or completed state from touched branches.",
627
627
  "Call patch_state alone in an assistant response; after its acknowledgement, further reasoning, tools, and later patch_state calls remain allowed.",
628
628
  ],
@@ -10,5 +10,5 @@ export declare function separatedFailure(error: unknown): Error;
10
10
  /** The compact model-facing contract. Semantic writes never travel through terminal prose. */
11
11
  export declare function stateFlowProtocol(bootstrap: boolean): string;
12
12
  export declare function assistantToolCallCount(content: unknown): number;
13
- /** The post-handler assistant message is authoritative; State Flow does not parse service comments. */
13
+ /** The accepted post-handler assistant text is authoritative. */
14
14
  export declare function finalizedAssistantResponse(message: AgentMessage): string;
@@ -89,7 +89,7 @@ export function assistantToolCallCount(content) {
89
89
  return 0;
90
90
  return content.filter((block) => typeof block === "object" && block !== null && block.type === "toolCall").length;
91
91
  }
92
- /** The post-handler assistant message is authoritative; State Flow does not parse service comments. */
92
+ /** The accepted post-handler assistant text is authoritative. */
93
93
  export function finalizedAssistantResponse(message) {
94
94
  if (message.role !== "assistant" || !Array.isArray(message.content)) {
95
95
  throw new Error("Finalized State Flow turn does not contain an assistant response");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-state-flow",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "private": false,
5
5
  "description": "Incremental scoped state/context/memory compiler for Pi, inspired by SKILL.state",
6
6
  "keywords": [
@@ -66,10 +66,10 @@
66
66
  "node": ">=22.19.0"
67
67
  },
68
68
  "peerDependencies": {
69
- "@earendil-works/pi-agent-core": "^0.84.4 || ^0.85.1",
70
- "@earendil-works/pi-ai": "^0.84.4 || ^0.85.1",
71
- "@earendil-works/pi-coding-agent": "^0.84.4 || ^0.85.1",
72
- "@earendil-works/pi-tui": "^0.84.4 || ^0.85.1"
69
+ "@earendil-works/pi-agent-core": ">=0.84.4",
70
+ "@earendil-works/pi-ai": ">=0.84.4",
71
+ "@earendil-works/pi-coding-agent": ">=0.84.4",
72
+ "@earendil-works/pi-tui": ">=0.84.4"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@earendil-works/pi-tui": "0.84.4",
@@ -1,101 +1,46 @@
1
1
  # Pi SDK compatibility
2
2
 
3
- This matrix records exact tested dependency stacks, not the version of an operator's running Pi process. Package peer ranges admit `^0.84.4 || ^0.85.1`; keep Pi, AI and agent-core on a matching release line. Mixed-version stacks and later releases are not separate test evidence.
3
+ State Flow requires matching Pi SDK packages at `>=0.84.4` without an upper peer-dependency bound. Keep `pi-coding-agent`, `pi-agent-core`, `pi-ai`, and `pi-tui` on the same release line.
4
4
 
5
- ## Current release candidate
5
+ The peer range permits newer releases so npm does not impose an artificial ceiling. It does not claim that every future SDK release has been tested. Revalidate the public host seams below when adopting a new Pi release line.
6
6
 
7
- The 0.16.0 candidate passes `npm run validate` on the repository-local 0.84.4 dependency graph: build, typecheck, import check, package dry run, and 444/444 tests. Its focused context/Skill/invariant cohort passes 43/43, including discovery of the separate operational and memory-curation Skills and release-package inventory checks for both compiled Skill paths. Current and historical reads use semantic `path`/`paths`; the retired top-level `state` segment and legacy top-level `offset`/`scope` inputs are rejected. The 0.85.1 full-suite evidence below belongs to the earlier recorded source checkpoint and has not been repeated for this candidate.
7
+ ## Tested stacks
8
8
 
9
- ## Tested matrix
9
+ The current repository-local stack uses Linux/x64, Node 26.8.1, Git 2.55.0, and Pi SDK 0.84.4.
10
10
 
11
- The historical compatibility checks use Linux/x64, Node 26.8.1, Git 2.55.0, TypeScript 7.0.2 and Node types 26.4.0.
11
+ | Pi SDK stack | Validation | Evidence status |
12
+ | --- | --- | --- |
13
+ | 0.84.4 | Build, typecheck, import, package dry-run, 445/445 tests | Current full-suite baseline |
14
+ | 0.85.1 | Build, typecheck, import, full suite | Earlier compatibility baseline; not rerun for every later State Flow change |
12
15
 
13
- | Pi / AI / agent-core | SDK's pi-tui / TypeBox | Typecheck / import | Full suite |
14
- | --- | --- | --- | --- |
15
- | 0.84.4 / 0.84.4 / 0.84.4 | 0.84.4 / 1.3.7 | Pass / pass | 417/417 |
16
- | 0.85.1 / 0.85.1 / 0.85.1 | 0.85.1 / 1.3.7 | Pass / pass | 417/417 |
17
-
18
- The first row is the repository-local stack. The second used a disposable copy of the same working source, with read-only dependency links to the already installed 0.85.1 SDK and its actual AI/agent-core/pi-tui graph. All commands exited zero for the accepted results. The repository lockfile still resolves 0.84.4; broadening its root peer metadata did not install or upgrade dependencies. No live Pi process, installation, production session or state store was modified.
19
-
20
- Both stacks passed `npm run validate` after adding the four [fatal-writer interruption witnesses](temporal-acceptance.md#fatal-writer-interruption). No runtime correction was needed: runtime SHA-256 remains `ce820cd33c34c4c882c11fc55e93f3914cfc8dffae57683e32cdcaa70f225cd2` from the [context-copy correction](performance.md#context-projection-and-trajectory-selection). Sorted `index.ts`, `lib/*.ts` and `tests/*.ts`, framed as path + NUL + bytes + NUL, now yield `1c5fafc1433631fed33177381e925eeeca52827932ba327690f615d2a4db81ba`. Copied/original source, runtime, test and package bytes were checked unchanged through validation, along with both selected dependency-resolution graphs and their manifests. These hashes do not cover every installed binary or environmental influence. The [benchmark workload fingerprint](performance.md) remains `b861fae36798bf76f56f411cc654c70fc948597bb84cc7a422c83f69ba1ca3e9`. Subsequent [matched runtime-performance controls](performance.md#matched-final-candidate-controls) use the 0.84.4 graph only, not a two-SDK timing comparison. The earlier fork/context witnesses remain included; these results do not replace separate integrated-candidate acceptance.
21
-
22
- ### Post-measurement integrated acceptance
23
-
24
- After the nine-invocation performance series, inline review traced accumulated Git/CAS, provenance, worker ownership, fork/recovery, Stop/context and discovery changes against their callers and negative/native witnesses, without a confirmed blocker in that inspected closure. Separate `state-flow-integrated-0844` and `state-flow-integrated-0851` Runs repeated `npm run validate`: each passed 417/417 with no failed, cancelled, skipped or todo tests, plus typecheck and import-check, and actual command exit zero. Full captures are 47,957 and 47,950 bytes. All 78 selected runtime/test/package files and both actual dependency graphs remained unchanged; documentation is separately reviewed rather than represented by that source hash.
25
-
26
- The twenty-property map resolves its quoted witnesses; that structural check is not exhaustive semantic proof. Domain validation reports 31 source files/133 acyclic local edges and no reverse entrypoint imports, with 25 existing header warnings. Context validation reports zero errors/five warnings. The package dry run includes 44 files and no tests. This accepts the local candidate within the documented synthetic/Linux/SDK boundaries, not arbitrary-host compatibility, production-incident attribution, publication permission or remote release-CI success. That checkpoint preceded the final compaction/status slice and its intentional 0.10.0 version alignment.
27
-
28
- The final slice adds seven compaction policy/race tests and two native lifecycle witnesses, bringing the complete repository-local 0.84.4 suite to 426/426 with typecheck/import-check. On 0.85.1, all affected policy/status and native compaction/tree tests plus typecheck pass; the operator declined a redundant second full-suite repetition after this focused equivalence evidence. Native completed-history compaction preserves full JSONL/tree/state/UUID while shortening active/resumed entries without another model summary; threshold compaction before the first patch remains Pi-owned. Package version is 0.10.0. Remote release CI remains authoritative for the tagged tree.
29
-
30
- Matching versions do not imply one physical dependency instance. Before/after resolution walks retain separate root and SDK-local 0.84.4 AI/agent-core copies and three TypeBox 1.3.7 locations in the repository installation. The first row describes that actual graph, not a deduplicated installation. The disposable 0.85.1 copy explicitly shares the SDK's AI/agent-core/pi-tui instances. Record canonical resolution edges as well as versions for comparisons; no dependency installation was changed to force a verifier assumption.
31
-
32
- The focused parent-traversal and barrier cohort passed 3/3 on each stack. The earlier 0.85.1 native cohort passed 10/10: large state/answers, selected-tree restoration, quit/reload push ownership, ordinary/bootstrap mid-tool Stop, compaction/tree/restart, scoped barriers, historical reads, and sibling-tool rejection. The full suite includes those witnesses plus benchmark, persistence, provenance, migration and concurrency contracts; tests are available in a source checkout, not the published runtime package.
16
+ Only exact matching stacks that were actually exercised are test evidence. Mixed SDK versions and untested newer releases are permitted by package metadata but remain unverified.
33
17
 
34
18
  ## Public host seams
35
19
 
36
- Inspect the installed package's `dist/core/` implementations and declarations alongside upstream [SDK documentation](https://github.com/earendil-works/pi-mono/blob/v0.85.1/packages/coding-agent/docs/sdk.md). Both tested stacks retain these seams:
37
-
38
- - `session-manager.js` / `session-manager.d.ts`: Read-only extension context exposes `getLeafEntry()`, `getEntry(id)` and each entry's `parentId`. Both lookups use the native ID map; `getBranch()` instead walks to the root and reverses a newly allocated path. State Flow now uses that public parent traversal for preflight without deleting or replacing native history.
39
- - `agent-session.js`, `_handleAgentEvent()` / `_installAgentToolHooks()`, and agent-core's `agent-loop.js`: `message_end` extension handlers run before session persistence; the awaited event then appends the accepted assistant message before tool preflight. Inspect that synchronized current assistant, not a presumed last persisted assistant inside `message_end`. The native sibling-tool regression is the executable barrier witness.
40
- - `sdk.js` and `extensions/runner.js`, `emitContext()`: Pi connects context transformation to the extension runner, which first `structuredClone`s native messages. State Flow projection runs after that host copy. Reducing extension traversal cannot make total inference work independent of history size.
41
- - `agent-session.js`, `prompt()` / `reload()` / `dispose()`: The system prompt is composed at `before_agent_start`; Stop can change tools/projection but not that already composed prompt for the current run. Reload awaits `session_shutdown` before replacement. Bare disposal invalidates/disconnects without emitting shutdown; use the [embedding contract](architecture.md#embedding).
42
- - `agent-session-runtime.js`, `teardownCurrent()`: Owner-driven new/resume/fork aborts the outgoing session, awaits shutdown, then disposes and creates the replacement. Active-push witnesses now cover new, same-file resume and fork teardown before invalidation, alongside quit and actual reload. Correct teardown does not imply successful fork restoration.
43
- - `sdk.js`, `createAgentSession()`: Session selection precedes default resource/extension loading. No extension-only pre-session resolver seam was established; native default continuation remains an [external integration boundary](architecture.md#session-continuation).
44
-
45
- These observations establish the specific seams used here, not compatibility with every Pi UI mode, extension combination, provider or operating system. Native tests use deterministic faux inference, temporary sessions/stores and local remotes. An installed SDK version does not fingerprint a still-running host. Actual-process incident attribution remains unproven; final comparable measurements and integrated acceptance remain in [BACKLOG.md](../BACKLOG.md).
46
-
47
- ## Native replacement witnesses
20
+ State Flow depends on these public Pi SDK behaviors:
48
21
 
49
- `tests/pi-harness.ts` now constructs a public `AgentSessionRuntime` from its existing isolated sessions and coherent CWD-bound services, forwarding complete session-start metadata and binding each replacement. No private host hook or production runtime change was needed. The three `tests/integration.test.ts` replacement witnesses pass on both SDK stacks and require:
22
+ - Extension lifecycle events and branch metadata for start, stop, reload, resume, fork, and tree navigation.
23
+ - Read-only session parent traversal through `getLeafEntry()` and `getEntry(id)`.
24
+ - `message_end` and `turn_end` ordering before accepted assistant messages are reconciled.
25
+ - Context transformation through the extension runner.
26
+ - `getContextUsage()` and native compaction hooks.
27
+ - Sequential tool execution and tool-call preflight.
28
+ - Session replacement awaiting outgoing shutdown before invalidation.
50
29
 
51
- - An accepted multi-scope patch and answer to supersede a still-running activation push.
52
- - The exact shutdown reason/target, child exit and a claimable lease at `setBeforeSessionInvalidate()`, before a successor can start.
53
- - Byte-identical outgoing JSONL and session checkpoint/tail/config/meta, the same selected leaf, and exact cold state at the accepted revision.
54
- - An empty private layer plus inherited shared state for configured new sessions, and exact selected state/identity for same-file resume.
55
- - No old-generation relaunch or queue writes after replacement; only a valid successor attempts the exact pending target and acknowledges its controlled child result.
30
+ Compatibility with those seams does not prove every UI mode, provider, operating system, extension combination, or future SDK release.
56
31
 
57
- **Native fork replacement now creates a child-owned session copy over current shared memory.** The active-push case forks before the first user request: private state is empty at that selected origin, not the parent's later accepted private work. Current global/CWD state remains visible, and the new child publication target descends from the retained parent target. Native session naming still does not prove the child JSONL is already persisted when its prefix contains no assistant.
32
+ ## Validation procedure
58
33
 
59
- Further native witnesses cover nonempty selected private state versus newer parent/shared state, retained native prefix and checkpoint/tail data, owned reload/resume, independent child writes and aligned post-origin history. Disabled sources remain disabled and copied parent Stop projection cannot reappear after child reload. Header UUID/CWD mismatches leave storage and selection unchanged; Start retries the exact source in the same loaded fork when evidence is corrected. Selecting inherited pre-origin pointers is unavailable, not permission to fall through to an older disabled marker and erase child state. That last witness failed with `true !== false` before the targeted ownership-aware recovery correction.
34
+ Validate another Pi SDK line in an isolated copy so the live extension, sessions, and runtime store remain unchanged:
60
35
 
61
- The fork-specific 13-test focused cohort covers these native cases plus runtime copying/CAS/file-expiration and header safety. An initial prefix assertion compared persisted JSON with in-memory objects containing explicit `undefined` fields; it was corrected to compare native persisted entries, without changing runtime behavior. The earlier outgoing-shutdown falsifier failed before invalidation with `null !== 'SIGKILL'`. Controlled push children do not prove external delivery; arbitrary cross-CWD replacement and every UI mode remain outside these witnesses. Ordinary inference abort retains accepted patches for same-session continuation and has no new immediate-enqueue requirement. See [fork support and limits](usage.md#fork-support-and-limits) and the [copy contract](fork-contract.md).
62
-
63
- ## Isolated validation procedure
64
-
65
- Keep the live host and repository dependencies unchanged:
66
-
67
- 1. Copy the intended current source, including retained uncommitted files and tests, to a fresh temporary directory. Do not substitute baseline `HEAD` for a dirty candidate. Give the copy its own synthetic Git `HEAD` for benchmark source-identity checks; never copy production session/store data.
68
- 2. Create a real `node_modules` directory in the copy. Link the existing development dependencies, then link `@earendil-works/pi-coding-agent` to the selected installed SDK and AI/agent-core/pi-tui to the dependencies actually resolved by that SDK. Do not use `--preserve-symlinks` or install into the live package. Verify the SDK and extension resolve the same selected dependency instances.
69
- 3. Resolve import-only package manifests with `findPackageJSON(name, pathToFileURL(ownerManifest))`, not `require.resolve(name)`. Record canonical manifest paths, package names/versions and hashes before and after testing. For example, run the following inside the copy:
70
-
71
- ```bash
72
- node --input-type=module <<'JS'
73
- import { findPackageJSON } from 'node:module';
74
- import { readFileSync, realpathSync } from 'node:fs';
75
- import { pathToFileURL } from 'node:url';
76
- const owner = pathToFileURL(`${process.cwd()}/package.json`);
77
- for (const name of ['pi-coding-agent', 'pi-ai', 'pi-agent-core', 'pi-tui']) {
78
- const path = realpathSync(findPackageJSON(`@earendil-works/${name}`, owner));
79
- console.log(path, JSON.parse(readFileSync(path, 'utf8')).version);
80
- }
81
- JS
82
- ```
83
-
84
- Use a fresh `PI_CODING_AGENT_DIR`, `PI_OFFLINE=1`, `GIT_CONFIG_NOSYSTEM=1` and a temporary `GIT_CONFIG_GLOBAL` containing only a synthetic commit identity and disabled commit signing. Fixtures already supply in-memory credentials, no model-catalog refresh and explicit resource/session roots. Leave fixture-local Git hooks enabled: tests intentionally use temporary `pre-receive`/`post-receive` hooks.
85
-
86
- Inside that prepared copy, the compatibility checks are ordinary project commands:
36
+ 1. Copy the complete candidate source, including retained uncommitted changes, into a temporary directory.
37
+ 2. Install or link one matching version of `pi-coding-agent`, `pi-agent-core`, `pi-ai`, and `pi-tui`.
38
+ 3. Confirm all four packages resolve to the intended release line.
39
+ 4. Use isolated Pi agent/session directories and synthetic Git identity; do not copy production session or State Flow data.
40
+ 5. Run:
87
41
 
88
42
  ```bash
89
- npm run typecheck
90
- npm run check
91
- node --experimental-strip-types --test \
92
- --test-name-pattern='tool preflight walks only|patch_state is the only tool|real Pi executes only patch_state|replacement closes its outgoing publisher' \
93
- tests/extension.test.ts tests/integration.test.ts
94
- npm test
43
+ npm run validate
95
44
  ```
96
45
 
97
- `npm run validate` combines typecheck, the full suite and import smoke for subsequent candidates. Retain actual command exits, complete logs and source/dependency identities; a filtered command succeeding does not replace the full suite.
98
-
99
- ### Rejected setup and correction
100
-
101
- The first 0.85.1 full run passed 395/397 because the temporary global Git config incorrectly set `core.hooksPath` to an empty directory. This disabled two fixtures' hooks: prepared receipts no longer observed the synthetic post-push write, and file-to-Git adoption no longer observed the intentionally pending push. The same two failures reproduced on 0.84.4 with that config. Removing only the temporary override made both witnesses pass on both SDKs, followed by 397/397 on 0.85.1. No runtime or test correction was needed; the failed run is not an SDK incompatibility or a successful full-suite result.
46
+ A successful focused test does not replace the full suite. Record the exact dependency graph and command exit for any compatibility claim.
@@ -131,7 +131,7 @@ Native controls have two rather than three inferences per request and no State F
131
131
  - **Short runs are not uniformly faster:** At twenty 8 KiB requests, B2's 1132.5ms p50 exceeds A1's 1115.7ms despite fewer calls. Both B short-case p95 values exceed A1's 1140.8ms. A1/A2 also change materially without code changes: long 8 KiB run p50 is 1373.7 → 1165.1ms, while short 128 KiB is 1602.8 → 1234.7ms. Keep these observations rather than collapsing the controls into one average.
132
132
  - **No history-independent latency claim:** B1's first-context medians rise 316.6 → 387.4ms and 297.6 → 347.5ms with unchanged 31 calls; B2's 128 KiB case rises 311.9 → 388.2ms. Identical counts do not bound internal Git work, host cloning, allocation or scheduling. These samples do not isolate the cause.
133
133
  - **Projection and native trace remain distinct:** First resumed enabled contexts are exactly 9694 / 9712 bytes at 8 KiB and 132574 / 132592 at 128 KiB across all four invocations. Native first-context medians grow from about 105 KB to 1.054 MB. Preserving a compact delivered context does not bound semantic state, the full native trace or Pi's pre-projection history clone.
134
- - **Remaining evidence is separate:** This block covers the 4 KiB-read lifecycle comparison only. The larger-read pair and current large-state boundary follow below; the publisher pair also follows. Separate [integrated-candidate acceptance](compatibility.md#post-measurement-integrated-acceptance) is recorded independently. It establishes neither the production incident's cause nor real-provider latency or universal responsiveness.
134
+ - **Remaining evidence is separate:** This block covers the 4 KiB-read lifecycle comparison only. The larger-read pair and current large-state boundary follow below; the publisher pair also follows. Repository validation is recorded independently from these measurements. It establishes neither the production incident's cause nor real-provider latency or universal responsiveness.
135
135
 
136
136
  ### Larger delivered history: matched A/B pair
137
137
 
@@ -191,7 +191,7 @@ Reported mixed-attempt p50/p95 milliseconds are A/B: same-session 3.1/465.9 vers
191
191
 
192
192
  All nine planned invocations are accepted, sequential and source-bound; the seven lifecycle invocations contain 108 preserved copied probes, excluding six setup probes. Complete captures, actual exits and guards are retained with `/tmp/state-flow-final-controls-CzaHqM/final-series-receipts.json`. Lifecycle distributions were independently recomputed from retained samples; publisher aggregates have the narrower evidence boundary above.
193
193
 
194
- The candidate reduces proven Git/allocation work and shows lower enabled long-case medians in these controls while preserving selected state and accepted continuation. It does not eliminate native history handling, payload cost, timing variability or safe contention refusal. Adverse short-case/tail observations remain. No further runtime correction is justified by these measurements alone; original production slowdown attribution remains unproven. Separate [integrated review/acceptance](compatibility.md#post-measurement-integrated-acceptance), not this measurement closure, governs local candidate readiness; release authorization and remote CI remain separate gates.
194
+ The candidate reduces proven Git/allocation work and shows lower enabled long-case medians in these controls while preserving selected state and accepted continuation. It does not eliminate native history handling, payload cost, timing variability or safe contention refusal. Adverse short-case/tail observations remain. No further runtime correction is justified by these measurements alone; original production slowdown attribution remains unproven. Separate repository validation, not this measurement closure, governs local candidate readiness; release authorization and remote CI remain separate gates.
195
195
 
196
196
  The following older datasets retain their own source identities and adverse observations; they are not substituted for this matched final-runtime comparison.
197
197
 
@@ -24,7 +24,7 @@ The child starts at step zero and a new temporal origin. Its copied tail is pres
24
24
 
25
25
  Initial copying requires a native fork start event, a regular canonical direct-parent session file, matching CWD/identity, a readable temporal source and an unused child namespace. Missing/unsafe evidence or CAS conflicts leave the copy unavailable rather than importing unrelated or newer private state. Explicit Start can retry an unaccepted copy in the same loaded fork after the cause is corrected.
26
26
 
27
- Selecting a copied parent checkpoint through the child's `/tree` does not make it child-owned: State Flow stays disabled without resetting existing child data. Select a child-owned checkpoint or resume the original session. Cold recovery before the first child checkpoint, startup paths lacking the fork event, in-memory parent locators and cross-CWD imports remain outside this slice. File-only copying requires an exact still-available source cohort. See the [contract](fork-contract.md) and [SDK evidence](compatibility.md#native-replacement-witnesses); do not rewrite UUIDs or delete pointers to force recovery.
27
+ Selecting a copied parent checkpoint through the child's `/tree` does not make it child-owned: State Flow stays disabled without resetting existing child data. Select a child-owned checkpoint or resume the original session. Cold recovery before the first child checkpoint, startup paths lacking the fork event, in-memory parent locators and cross-CWD imports remain outside this slice. File-only copying requires an exact still-available source cohort. See the [contract](fork-contract.md) and [SDK compatibility boundary](compatibility.md#public-host-seams); do not rewrite UUIDs or delete pointers to force recovery.
28
28
 
29
29
  ## Configuration
30
30
 
@@ -662,10 +662,10 @@ export default function stateFlowExtension(pi: ExtensionAPI, options: StateFlowE
662
662
  pi.registerTool({
663
663
  name: PATCH_STATE_TOOL_NAME,
664
664
  label: "Patch State",
665
- description: "The sole State Flow semantic mutation protocol. Supply any combination of global, cwd, and session patches; all supplied scopes commit atomically. Set final:true when the current iteration may finish at a later turn_end. final:true does not stop reasoning, tools, or later patch_state calls. Use {final:true} when no semantic update is needed. This call must be the only State Flow barrier in its assistant response.",
666
- promptSnippet: "Atomically patch global/cwd/session; final:true permits a later turn_end",
665
+ description: "The sole State Flow semantic mutation protocol. Supply any combination of global, cwd, and session patches; all supplied scopes commit atomically. In an active State Flow episode, set final:true when the current iteration may finish at a later turn_end; use {final:true} when no semantic update is needed. Passive turns have no terminal barrier: never call patch_state only to set final:true. This call must be the only State Flow barrier in its assistant response.",
666
+ promptSnippet: "Atomically patch global/cwd/session; active episodes use final:true before turn_end",
667
667
  promptGuidelines: [
668
- "Use patch_state for durable semantic changes. Before a final answer, make the iteration terminal-eligible with final:true, optionally alongside atomic global/cwd/session patches.",
668
+ "Use patch_state for durable semantic changes. Only in an active State Flow episode, make the iteration terminal-eligible before a final answer with final:true, optionally alongside atomic global/cwd/session patches. In passive mode, never call patch_state only to set final:true.",
669
669
  "Use patch_state as reconciliation, not append-only notes: place new knowledge at the narrowest valid scope and remove superseded or completed state from touched branches.",
670
670
  "Call patch_state alone in an assistant response; after its acknowledgement, further reasoning, tools, and later patch_state calls remain allowed.",
671
671
  ],
@@ -91,7 +91,7 @@ export function assistantToolCallCount(content: unknown): number {
91
91
  return content.filter((block) => typeof block === "object" && block !== null && (block as { type?: unknown }).type === "toolCall").length;
92
92
  }
93
93
 
94
- /** The post-handler assistant message is authoritative; State Flow does not parse service comments. */
94
+ /** The accepted post-handler assistant text is authoritative. */
95
95
  export function finalizedAssistantResponse(message: AgentMessage): string {
96
96
  if (message.role !== "assistant" || !Array.isArray(message.content)) {
97
97
  throw new Error("Finalized State Flow turn does not contain an assistant response");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-state-flow",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "private": false,
5
5
  "description": "Incremental scoped state/context/memory compiler for Pi, inspired by SKILL.state",
6
6
  "keywords": [
@@ -66,10 +66,10 @@
66
66
  "node": ">=22.19.0"
67
67
  },
68
68
  "peerDependencies": {
69
- "@earendil-works/pi-agent-core": "^0.84.4 || ^0.85.1",
70
- "@earendil-works/pi-ai": "^0.84.4 || ^0.85.1",
71
- "@earendil-works/pi-coding-agent": "^0.84.4 || ^0.85.1",
72
- "@earendil-works/pi-tui": "^0.84.4 || ^0.85.1"
69
+ "@earendil-works/pi-agent-core": ">=0.84.4",
70
+ "@earendil-works/pi-ai": ">=0.84.4",
71
+ "@earendil-works/pi-coding-agent": ">=0.84.4",
72
+ "@earendil-works/pi-tui": ">=0.84.4"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@earendil-works/pi-tui": "0.84.4",
@@ -4,6 +4,13 @@
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.50.1: Queue, lifecycle, and Workspace hotfixes
8
+
9
+ - `Workspace slot recovery`: Uses the canonical binding returned by target-deduplicating Workspace commit for the live leader record and connection result, preventing a provisional recovery slot from consuming a second letter and falsely blocking follower registration at A–Z capacity.
10
+ - `Guest queue Skip`: Lets the leader discard a waiting Guest Mode prompt directly from the queue menu while other work is active. Guest callbacks use stable queue identity, settle durable admission before removal, stop placeholder rotation, and visually clear the inline globe placeholder without starting a model turn.
11
+ - `Internal lifecycle safety`: Binds each armed `/telegram-internal` lifecycle action to an unpredictable one-use token, so manual, mismatched, and replayed calls cannot consume or execute it.
12
+ - `Command surface`: Uses Pi-style argument-first autocomplete hints, keeps descriptions concise and punctuation-consistent, uses `profile` consistently, describes `/telegram-internal` as a manual-use warning, and removes Workspace Thread naming from `/telegram-connect`; Thread names remain configurable from Telegram.
13
+
7
14
  ## 0.50.0: Internal lifecycle gateway and thinking cadence
8
15
 
9
16
  - `Internal lifecycle gateway`: Replaces the session-specific technical command with one `/telegram-internal` gateway for runtime-armed typed actions. Manual invocation performs no action and explains that the command cannot be run manually; settled `/new` replacement retains the same lifecycle and terminal-result guarantees.
@@ -55,7 +55,7 @@ Paste the bot token. If `~/.pi/agent/telegram.json` already contains a saved tok
55
55
  /telegram-connect
56
56
  ```
57
57
 
58
- The connected Pi instance owns Telegram polling. Use `/telegram-connect <profile>` to activate a named profile, and optionally append `as=Name` to name a fresh Workspace Thread. Each profile is a parallel bot runtime with isolated polling, diagnostics, Threaded Mode state, and local bus transport; the `default` profile keeps unsuffixed runtime paths. In classic mode each profile uses a singleton lock. When Telegram private-chat Threaded Mode is available, one live instance becomes the profile's leader and later visible Pi instances register as followers. Reopening or resuming the same Pi session restores its remembered Thread at session startup; a distinct session in the same directory has its own binding and still requires explicit `/telegram-connect` when no remembered binding exists.
58
+ The connected Pi instance owns Telegram polling. Use `/telegram-connect <profile>` to activate a named profile. Each profile is a parallel bot runtime with isolated polling, diagnostics, Threaded Mode state, and local bus transport; the `default` profile keeps unsuffixed runtime paths. In classic mode each profile uses a singleton lock. When Telegram private-chat Threaded Mode is available, one live instance becomes the profile's leader and later visible Pi instances register as followers. Reopening or resuming the same Pi session restores its remembered Thread at session startup; a distinct session in the same directory has its own binding and still requires explicit `/telegram-connect` when no remembered binding exists.
59
59
 
60
60
  After an unclean computer shutdown, `/telegram-connect` detects truncated or structurally invalid temporary ownership/routing files, quarantines only the damaged files under `tmp/telegram/recovery/`, and retries once. A journal snapshot removed by older broad temp cleanup is rebuilt when its complete segment history proves an empty result, while a revisionless snapshot is repaired from the first surviving segment's exact predecessor when the reconstructed tail validates. Otherwise the snapshot and segments are quarantined as recovery evidence, a fresh journal is published, and startup continues with an informational diagnostic instead of requiring manual JSON repair. Unsupported journal versions block recovery without rewriting or quarantining the retained files; use a compatible runtime rather than deleting journals. Saved `telegram.json` configuration and runtime diagnostics remain intact. Recovery never replaces a verifiable live owner; if safe automatic recovery cannot complete, the command gives one explicit Pi-restart instruction instead of requiring deletion of the whole `tmp/` directory.
61
61
 
@@ -183,7 +183,6 @@ Run these inside Pi.
183
183
  | `/telegram-setup <profile>` | Save or update a named-profile bot token |
184
184
  | `/telegram-connect` / `/telegram-connect default` | Activate `profiles.default` and acquire its transport ownership |
185
185
  | `/telegram-connect <profile>` | Activate a named profile and acquire its transport ownership |
186
- | `/telegram-connect [profile] as=Name` | Give a fresh Workspace Thread one unique capitalized Latin-word identity while connecting |
187
186
  | `/telegram-disconnect` | Confirm, then stop polling, release ownership, and delete this instance's Threaded Mode tab; graceful Pi quit always preserves restart ownership and independently deletes the tab only when automatic cleanup is enabled |
188
187
  | `/telegram-status` | Inspect connection, mode, separate polling/worker progress, journal depth, queue, transport, automatic retry state, and recent diagnostics |
189
188
 
@@ -165,8 +165,6 @@ interface TelegramCommandsAndToolsBindingDeps {
165
165
  stopPolling?: () => Promise<void | string>;
166
166
  recoverPollingStart?: Commands.TelegramBridgeCommandRegistrationDeps["recoverPollingStart"];
167
167
  getDisconnectThreadName?: () => string | undefined;
168
- setRequestedThreadNameForPollingStart?: (threadName: string | undefined) => void;
169
- validateThreadName?: Commands.TelegramBridgeCommandRegistrationDeps["validateThreadName"];
170
168
  onTransportChanged?: () => Promise<void> | void;
171
169
  getStatusLines: (options?: Status.TelegramBridgeStatusLineOptions) => string[];
172
170
  buttonActionStore: OutboundHandlers.TelegramButtonActionStore;
@@ -196,7 +194,7 @@ interface TelegramCommandsAndToolsBindingDeps {
196
194
  updateStatus: TelegramBridgeStatusUpdater;
197
195
  recordRuntimeEvent: TelegramRuntimeEventRecorder;
198
196
  }
199
- export declare function registerTelegramCommandsAndTools({ pi, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, recoverPollingStart, getDisconnectThreadName, setRequestedThreadNameForPollingStart, validateThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, }: TelegramCommandsAndToolsBindingDeps): void;
197
+ export declare function registerTelegramCommandsAndTools({ pi, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, recoverPollingStart, getDisconnectThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, }: TelegramCommandsAndToolsBindingDeps): void;
200
198
  interface TelegramLifecycleBindingDeps {
201
199
  pi: Pi.ExtensionAPI;
202
200
  publicationRuntime: TelegramBridgePublicationRuntime;
@@ -323,7 +323,7 @@ export function createTelegramActivityBindingRuntime(deps) {
323
323
  },
324
324
  };
325
325
  }
326
- export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, recoverPollingStart, getDisconnectThreadName, setRequestedThreadNameForPollingStart, validateThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, }) {
326
+ export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, recoverPollingStart, getDisconnectThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, }) {
327
327
  GenerativeApps.registerTelegramBindTool(pi, {
328
328
  agentDir,
329
329
  getActiveProfileName: configStore.getActiveProfileName,
@@ -453,7 +453,6 @@ export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, pe
453
453
  hasBotToken: configStore.hasBotToken,
454
454
  getBotTokenDiagnostic: configStore.getBotTokenDiagnostic,
455
455
  startPolling: async (ctx, options) => {
456
- setRequestedThreadNameForPollingStart?.(options?.requestedThreadName);
457
456
  try {
458
457
  return await lockedPollingRuntime.start(ctx, options);
459
458
  }
@@ -461,14 +460,10 @@ export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, pe
461
460
  recordRuntimeEvent("recovery", error, { phase: "polling-start" });
462
461
  throw error;
463
462
  }
464
- finally {
465
- setRequestedThreadNameForPollingStart?.(undefined);
466
- }
467
463
  },
468
464
  stopPolling: stopPolling ?? lockedPollingRuntime.stop,
469
465
  recoverPollingStart,
470
466
  getDisconnectThreadName,
471
- validateThreadName,
472
467
  queueAgentConnectionContext,
473
468
  updateStatus,
474
469
  getProfileNames: () => Config.getTelegramProfileNames(configStore.getStoredConfig()),
@@ -87,7 +87,6 @@ export declare function createTelegramBotCommandRegistrar(deps: TelegramBotComma
87
87
  export interface TelegramBridgeCommandStartPollingOptions {
88
88
  force?: boolean;
89
89
  forceFreshLeaderThread?: boolean;
90
- requestedThreadName?: string;
91
90
  }
92
91
  export interface TelegramBridgeCommandStartPollingResult {
93
92
  ok: boolean;
@@ -119,7 +118,6 @@ export interface TelegramBridgeCommandRegistrationDeps {
119
118
  getProfileNames?: () => string[];
120
119
  activateDefaultProfileConfig?: (ctx: ExtensionCommandContext) => Promise<void>;
121
120
  activateProfileConfig?: (ctx: ExtensionCommandContext, profileName: string) => Promise<boolean>;
122
- validateThreadName?: (threadName: string) => string | undefined;
123
121
  }
124
122
  export type TelegramThreadDisplayNameRenamePort = (target: {
125
123
  chatId: number;
@@ -145,7 +143,6 @@ export declare function createTelegramThreadDisplayNameRenameBinding(): {
145
143
  bind: (rename: TelegramThreadDisplayNameRenamePort) => void;
146
144
  rename: TelegramThreadDisplayNameRenamePort;
147
145
  };
148
- export declare function parseTelegramRequestedThreadName(args: string): string | undefined;
149
146
  export declare function registerTelegramBridgeCommands(pi: ExtensionAPI, deps: TelegramBridgeCommandRegistrationDeps): void;
150
147
  export declare const TELEGRAM_RESERVED_COMMAND_NAMES: readonly ["stop", "name", "new", "abort", "next", "continue", "status", "queue", "compact", "model", "thinking", "settings", "help", "start"];
151
148
  export type TelegramReservedCommandName = (typeof TELEGRAM_RESERVED_COMMAND_NAMES)[number];
@@ -575,7 +572,7 @@ export declare function createTelegramCommandOrPromptRuntime<TMessage, TContext>
575
572
  dispatchMessages: (messages: TMessage[], ctx: TContext) => Promise<void>;
576
573
  };
577
574
  export declare const TELEGRAM_INTERNAL_COMMAND_NAME = "telegram-internal";
578
- export declare const TELEGRAM_INTERNAL_COMMAND_DESCRIPTION = "(internal) dispatch one settled Telegram lifecycle action";
575
+ export declare const TELEGRAM_INTERNAL_COMMAND_DESCRIPTION = "Internal Telegram command cannot be run manually";
579
576
  export declare const TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE = "This internal Telegram command cannot be run manually.";
580
577
  export declare function delayTelegramSessionAction(delayMs: number): Promise<void>;
581
578
  export interface TelegramSessionActionRuntimeDeps {