@oh-my-pi/pi-coding-agent 17.2.5 → 17.2.6

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 (55) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/{CHANGELOG-q2w43aw3.md → CHANGELOG-gs76k6wc.md} +18 -0
  3. package/dist/cli.js +3378 -3333
  4. package/dist/types/cli/gc-cli.d.ts +1 -0
  5. package/dist/types/launch/client.d.ts +9 -1
  6. package/dist/types/launch/protocol.d.ts +17 -0
  7. package/dist/types/modes/components/btw-panel.d.ts +3 -0
  8. package/dist/types/modes/controllers/btw-controller.d.ts +2 -0
  9. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  10. package/dist/types/modes/interactive-mode.d.ts +4 -1
  11. package/dist/types/modes/types.d.ts +3 -1
  12. package/dist/types/security/contracts/schemas.d.ts +405 -403
  13. package/dist/types/session/agent-session-types.d.ts +5 -0
  14. package/dist/types/session/agent-session.d.ts +26 -2
  15. package/dist/types/session/launch-completion.d.ts +10 -0
  16. package/dist/types/session/session-entries.d.ts +15 -1
  17. package/dist/types/session/session-manager.d.ts +7 -0
  18. package/dist/types/session/yield-queue.d.ts +6 -1
  19. package/dist/types/tools/index.d.ts +9 -0
  20. package/package.json +12 -12
  21. package/src/cli/gc-cli.ts +641 -21
  22. package/src/config/model-discovery.ts +14 -14
  23. package/src/config/model-registry.ts +10 -8
  24. package/src/config/settings.ts +1 -1
  25. package/src/export/html/index.ts +10 -3
  26. package/src/export/share.ts +4 -0
  27. package/src/launch/broker.ts +222 -6
  28. package/src/launch/client.ts +161 -9
  29. package/src/launch/protocol.ts +52 -0
  30. package/src/main.ts +13 -6
  31. package/src/mcp/config-writer.ts +1 -1
  32. package/src/modes/components/btw-panel.ts +41 -4
  33. package/src/modes/controllers/btw-controller.ts +55 -7
  34. package/src/modes/controllers/command-controller.ts +31 -0
  35. package/src/modes/controllers/input-controller.ts +24 -7
  36. package/src/modes/interactive-mode.ts +16 -2
  37. package/src/modes/types.ts +8 -1
  38. package/src/prompts/session/launch-completion.md +1 -0
  39. package/src/sdk.ts +15 -0
  40. package/src/security/contracts/schemas.ts +205 -183
  41. package/src/security/contracts/validation.ts +5 -1
  42. package/src/security/store.ts +2 -2
  43. package/src/session/agent-session-types.ts +6 -0
  44. package/src/session/agent-session.ts +191 -14
  45. package/src/session/launch-completion.ts +37 -0
  46. package/src/session/session-context.ts +26 -0
  47. package/src/session/session-entries.ts +17 -1
  48. package/src/session/session-manager.ts +21 -0
  49. package/src/session/yield-queue.ts +121 -16
  50. package/src/slash-commands/builtin-registry.ts +10 -0
  51. package/src/tools/browser/cmux/cmux-tab.ts +92 -4
  52. package/src/tools/hub/launch.ts +122 -6
  53. package/src/tools/index.ts +9 -0
  54. package/dist/types/config/file-lock.d.ts +0 -29
  55. package/src/config/file-lock.ts +0 -164
@@ -357,6 +357,11 @@ export interface FreshSessionResult {
357
357
  sessionId: string;
358
358
  closedProviderSessions: number;
359
359
  }
360
+ /** Outcome of an in-place `/reset` conversation-context reset. */
361
+ export interface ResetSessionContextResult {
362
+ /** Number of live messages dropped from the model's context. */
363
+ droppedCount: number;
364
+ }
360
365
  /** Queued user content restored to the editor. */
361
366
  export type RestoredQueuedMessage = {
362
367
  text: string;
@@ -37,6 +37,7 @@ import { GoalRuntime } from "../goals/runtime.js";
37
37
  import type { GoalModeState } from "../goals/state.js";
38
38
  import type { HindsightSessionState } from "../hindsight/state.js";
39
39
  import type { IrcMessage } from "../irc/bus.js";
40
+ import type { DaemonCompletionNotification } from "../launch/protocol.js";
40
41
  import { type MnemopiSessionState } from "../mnemopi/state.js";
41
42
  import { type PlanApprovalDetails } from "../plan-mode/approved-plan.js";
42
43
  import type { PlanModeState } from "../plan-mode/state.js";
@@ -49,7 +50,7 @@ import type { TodoPhase } from "../tools/todo.js";
49
50
  import type { InspectImageMode } from "../utils/inspect-image-mode.js";
50
51
  import type { VibeModeState } from "../vibe/state.js";
51
52
  import type { AgentSessionEventListener } from "./agent-session-events.js";
52
- import type { AgentSessionConfig, AgentSessionDisposeOptions, AsyncJobSnapshot, CommandMetadataChangedListener, ContextUsageBreakdown, FollowUpOptions, FreshSessionResult, HandoffResult, ModelCycleResult, Prewalk, PromptOptions, ResolvedRoleModel, RestoredQueuedMessage, RoleModelCycle, RoleModelCycleResult, SessionHandoffOptions, SessionOAuthAccountList, SessionStats, UsageFallbackConfirmation } from "./agent-session-types.js";
53
+ import type { AgentSessionConfig, AgentSessionDisposeOptions, AsyncJobSnapshot, CommandMetadataChangedListener, ContextUsageBreakdown, FollowUpOptions, FreshSessionResult, HandoffResult, ModelCycleResult, Prewalk, PromptOptions, ResetSessionContextResult, ResolvedRoleModel, RestoredQueuedMessage, RoleModelCycle, RoleModelCycleResult, SessionHandoffOptions, SessionOAuthAccountList, SessionStats, UsageFallbackConfirmation } from "./agent-session-types.js";
53
54
  import type { ClientBridge } from "./client-bridge.js";
54
55
  import { type CustomMessage, type CustomMessagePayload } from "./messages.js";
55
56
  import { type AdvisorStats } from "./session-advisors.js";
@@ -180,6 +181,8 @@ export declare class AgentSession {
180
181
  * Multiple listeners can be added. Returns unsubscribe function for this listener.
181
182
  */
182
183
  subscribe(listener: AgentSessionEventListener): () => void;
184
+ /** Register cleanup that runs when this AgentSession adopts a different session ID. */
185
+ registerSessionChangeCallback(callback: () => void): () => void;
183
186
  subscribeCommandMetadataChanged(listener: CommandMetadataChangedListener): () => void;
184
187
  /** Run one abortable auto-learn capture outside the primary agent loop. */
185
188
  runAutolearnCapture(capture: (signal: AbortSignal) => Promise<void>): Promise<void>;
@@ -199,6 +202,25 @@ export declare class AgentSession {
199
202
  beginDispose(): void;
200
203
  dispose(options?: AgentSessionDisposeOptions): Promise<void>;
201
204
  freshSession(): FreshSessionResult | undefined;
205
+ /**
206
+ * Reset the current conversation in place: drop every message, queued turn,
207
+ * and pending tool call from the model's context while keeping the session
208
+ * itself — its id, title, cwd, model, settings, and on-disk transcript all
209
+ * survive. The next turn is sent with only the base system prompt plus the
210
+ * project rules/AGENTS.md.
211
+ *
212
+ * This is the in-place sibling of {@link newSession}: it reuses the same
213
+ * conversation-boundary teardown (drop the conversation, rotate provider-side
214
+ * session state so providers that keep history server-side resume nothing,
215
+ * re-prime the advisors, and undo any memory promotion) but skips minting a
216
+ * new session id and opening a fresh transcript file. Unlike
217
+ * {@link freshSession} (which only rotates provider stream state) it also
218
+ * clears the conversation.
219
+ *
220
+ * Returns `undefined` without mutating anything while a response is
221
+ * streaming or a foreground bash/python execution is in flight.
222
+ */
223
+ resetSessionContext(): Promise<ResetSessionContextResult | undefined>;
202
224
  /** Full agent state */
203
225
  get state(): AgentState;
204
226
  /** Current model (may be undefined if not yet selected) */
@@ -476,6 +498,7 @@ export declare class AgentSession {
476
498
  */
477
499
  followUp(text: string, images?: ImageContent[], options?: FollowUpOptions): Promise<void>;
478
500
  queueDeferredMessage(message: CustomMessage): void;
501
+ queueLaunchCompletion(notification: DaemonCompletionNotification): Promise<void>;
479
502
  /**
480
503
  * Send a custom message to the session. Creates a CustomMessageEntry.
481
504
  *
@@ -805,7 +828,8 @@ export declare class AgentSession {
805
828
  selectedImages: ImageContent[];
806
829
  cancelled: boolean;
807
830
  }>;
808
- branchFromBtw(question: string, assistantMessage: AssistantMessage): Promise<{
831
+ /** Promotes a completed /btw answer from the explicitly authorized session and leaf. */
832
+ branchFromBtw(question: string, assistantMessage: AssistantMessage, leafId: string, sessionId: string): Promise<{
809
833
  cancelled: boolean;
810
834
  sessionFile: string | undefined;
811
835
  }>;
@@ -0,0 +1,10 @@
1
+ import type { DaemonCompletionNotification } from "../launch/protocol.js";
2
+ import type { CustomMessage } from "./messages.js";
3
+ /** Yield-queue kind for broker-owned supervised process completions. */
4
+ export declare const LAUNCH_COMPLETION_MESSAGE_TYPE = "launch-completion";
5
+ /** One broker completion awaiting injection into its owning session. */
6
+ export type LaunchCompletionEntry = DaemonCompletionNotification;
7
+ /** Whether a broker completion belongs to the primary session or its advisor. */
8
+ export declare function isLaunchCompletionOwner(owner: string, sessionId: string): boolean;
9
+ /** Build one model-visible notification per terminal supervised process exit. */
10
+ export declare function buildLaunchCompletionBatchMessage(entries: LaunchCompletionEntry[]): CustomMessage;
@@ -31,6 +31,8 @@ export interface SessionHeader {
31
31
  */
32
32
  additionalDirectories?: string[];
33
33
  parentSession?: string;
34
+ /** Prior absolute JSONL locations recorded by successful session moves. */
35
+ previousSessionFiles?: string[];
34
36
  /** Provider prompt-cache identity inherited by exact-route full forks. */
35
37
  providerPromptCacheKey?: string;
36
38
  }
@@ -102,6 +104,17 @@ export interface BranchSummaryEntry<T = unknown> extends SessionEntryBase {
102
104
  /** True if generated by an extension, false if pi-generated */
103
105
  fromExtension?: boolean;
104
106
  }
107
+ /**
108
+ * Pure marker entry recorded by `/reset` (resetSessionContext). It carries no
109
+ * payload — its presence on the branch is a durable boundary the collapsed
110
+ * live transcript and the model-context rebuild start emission after, so a
111
+ * rebuild (theme change, focus attach, /shake, resume) does not resurrect the
112
+ * pre-reset conversation. The on-disk record and the plain `transcript:true`
113
+ * export path keep the full pre-reset history.
114
+ */
115
+ export interface ResetBoundaryEntry extends SessionEntryBase {
116
+ type: "reset_boundary";
117
+ }
105
118
  /**
106
119
  * Custom entry for extensions to store extension-specific data in the session.
107
120
  * Use customType to identify your extension's entries.
@@ -135,6 +148,7 @@ declare module "@oh-my-pi/pi-agent-core/compaction/entries" {
135
148
  interface CustomCompactionSessionEntries {
136
149
  titleChange: TitleChangeEntry;
137
150
  credentialPin: CredentialPinEntry;
151
+ resetBoundary: ResetBoundaryEntry;
138
152
  }
139
153
  }
140
154
  /** TTSR injection entry - tracks which time-traveling rules have been injected this session. */
@@ -210,7 +224,7 @@ export interface CustomMessageEntry<T = unknown> extends SessionEntryBase {
210
224
  attribution?: MessageAttribution;
211
225
  }
212
226
  /** Session entry - has id/parentId for tree structure (returned by "read" methods in SessionManager) */
213
- export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ServiceTierChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | TitleChangeEntry | TtsrInjectionEntry | SessionInitEntry | ModeChangeEntry | CredentialPinEntry;
227
+ export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ServiceTierChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | TitleChangeEntry | TtsrInjectionEntry | SessionInitEntry | ModeChangeEntry | CredentialPinEntry | ResetBoundaryEntry;
214
228
  /** Raw logical file entry after loaders strip any fixed-width title slot. */
215
229
  export type FileEntry = SessionHeader | SessionEntry;
216
230
  /** Physical JSONL entry before slot-aware loaders fold the title slot. */
@@ -233,6 +233,13 @@ export declare class SessionManager {
233
233
  readSummarize?: boolean;
234
234
  }): string;
235
235
  appendCompaction<T = unknown>(summary: string, shortSummary: string | undefined, firstKeptEntryId: string, tokensBefore: number, details?: T, fromExtension?: boolean, preserveData?: Record<string, unknown>): string;
236
+ /**
237
+ * Append the durable conversation boundary recorded by `/reset`. The
238
+ * collapsed live transcript and the model-context rebuild start after the
239
+ * latest one, while the full history stays on disk (the plain
240
+ * `transcript:true` export walks it unchanged).
241
+ */
242
+ appendResetBoundary(): string;
236
243
  appendCustomEntry(customType: string, data?: unknown): string;
237
244
  /**
238
245
  * Rewrite the session file after in-place entry updates (e.g. pruning old tool
@@ -1,4 +1,4 @@
1
- import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
1
+ import { type AgentMessage } from "@oh-my-pi/pi-agent-core";
2
2
  export interface YieldDispatcher<P> {
3
3
  /** Drop entries already delivered through another path. Called per-entry at flush time. */
4
4
  isStale?(entry: P): boolean;
@@ -19,7 +19,10 @@ export declare class YieldQueue {
19
19
  constructor(options: YieldQueueOptions);
20
20
  register<P>(kind: string, dispatcher: YieldDispatcher<P>): () => void;
21
21
  enqueue<P>(kind: string, entry: P): void;
22
+ enqueueWithReceipt<P>(kind: string, entry: P): Promise<void>;
22
23
  has(kind?: string): boolean;
24
+ /** Arrange an idle flush for entries queued near the end of a streaming run. */
25
+ requestIdleFlush(): void;
23
26
  flush(mode: YieldFlushMode): Promise<void>;
24
27
  /**
25
28
  * Snapshot and remove all queued entries, returning one lazy thunk per kind.
@@ -33,5 +36,7 @@ export declare class YieldQueue {
33
36
  /** Drop queued entries. With `kind`, drop only that kind's entries (leaving
34
37
  * any pending idle-flush for other kinds intact); otherwise drop everything. */
35
38
  clear(kind?: string): void;
39
+ /** Clear a scheduled-flush latch when its host task is cancelled before running. */
40
+ cancelIdleFlushScheduling(): void;
36
41
  }
37
42
  export {};
@@ -10,6 +10,7 @@ import type { Skill } from "../extensibility/skills.js";
10
10
  import type { GoalModeState, GoalRuntime } from "../goals/index.js";
11
11
  import type { HindsightSessionState } from "../hindsight/state.js";
12
12
  import type { LocalProtocolOptions } from "../internal-urls/index.js";
13
+ import type { DaemonCompletionNotification } from "../launch/protocol.js";
13
14
  import type { MCPManager } from "../mcp/index.js";
14
15
  import type { MnemopiSessionState } from "../mnemopi/state.js";
15
16
  import type { PlanModeState } from "../plan-mode/state.js";
@@ -115,6 +116,8 @@ export interface ToolSession {
115
116
  additionalDirectories?: string[];
116
117
  /** Whether UI is available */
117
118
  hasUI: boolean;
119
+ /** Whether this session has begun disposal. */
120
+ isDisposed?: () => boolean;
118
121
  /**
119
122
  * Suppress the spawn specialization/coordination advisory appended to `task`
120
123
  * results. Set by internal/programmatic callers (e.g. the commit agent's
@@ -345,6 +348,12 @@ export interface ToolSession {
345
348
  noopLoopGuard?: import("../edit/hashline/noop-loop-guard.js").NoopLoopGuard;
346
349
  /** Queue a hidden message to be injected at the next agent turn. */
347
350
  queueDeferredMessage?(message: CustomMessage): void;
351
+ /** Queue a broker supervised-process completion for the owning session. */
352
+ queueLaunchCompletion?(notification: DaemonCompletionNotification): Promise<void>;
353
+ /** Register cleanup that runs when this session is disposed; returns a handle that removes the cleanup. */
354
+ registerDisposeCallback?(callback: () => void): (() => void) | void;
355
+ /** Register cleanup that runs when this ToolSession adopts a different session ID. */
356
+ registerSessionChangeCallback?(callback: () => void): (() => void) | void;
348
357
  /** Queue late LSP diagnostics (arrived after an edit/write returned) to be shown
349
358
  * in the transcript and delivered to the model at the next yield, like background
350
359
  * job results. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "17.2.5",
4
+ "version": "17.2.6",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -52,17 +52,17 @@
52
52
  "@agentclientprotocol/sdk": "1.2.1",
53
53
  "@babel/parser": "^7.29.7",
54
54
  "@mozilla/readability": "^0.6.0",
55
- "@oh-my-pi/hashline": "17.2.5",
56
- "@oh-my-pi/omp-stats": "17.2.5",
57
- "@oh-my-pi/pi-agent-core": "17.2.5",
58
- "@oh-my-pi/pi-ai": "17.2.5",
59
- "@oh-my-pi/pi-catalog": "17.2.5",
60
- "@oh-my-pi/pi-mnemopi": "17.2.5",
61
- "@oh-my-pi/pi-natives": "17.2.5",
62
- "@oh-my-pi/pi-tui": "17.2.5",
63
- "@oh-my-pi/pi-utils": "17.2.5",
64
- "@oh-my-pi/pi-wire": "17.2.5",
65
- "@oh-my-pi/snapcompact": "17.2.5",
55
+ "@oh-my-pi/hashline": "17.2.6",
56
+ "@oh-my-pi/omp-stats": "17.2.6",
57
+ "@oh-my-pi/pi-agent-core": "17.2.6",
58
+ "@oh-my-pi/pi-ai": "17.2.6",
59
+ "@oh-my-pi/pi-catalog": "17.2.6",
60
+ "@oh-my-pi/pi-mnemopi": "17.2.6",
61
+ "@oh-my-pi/pi-natives": "17.2.6",
62
+ "@oh-my-pi/pi-tui": "17.2.6",
63
+ "@oh-my-pi/pi-utils": "17.2.6",
64
+ "@oh-my-pi/pi-wire": "17.2.6",
65
+ "@oh-my-pi/snapcompact": "17.2.6",
66
66
  "@opentelemetry/api": "^1.9.1",
67
67
  "@opentelemetry/api-logs": "^0.220.0",
68
68
  "@opentelemetry/context-async-hooks": "^2.9.0",