@linxiraos/pi-tui 1.3.1 → 1.4.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.
@@ -1,6 +1,7 @@
1
1
  import { type Component, Input } from "../index.js";
2
2
  import type { TspPickerGroup, TspPickerItem } from "@linxiraos/pi-wire";
3
3
  import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
4
+ import { type ResumeSourceLike } from "./resume-picker.js";
4
5
  /** Session lifecycle status presented by the picker. */
5
6
  export type SessionSelectorStatus = "complete" | "interrupted" | "aborted" | "error" | "pending" | "unknown";
6
7
  /** Session listing fields consumed by the picker. */
@@ -18,6 +19,8 @@ export interface SessionSelectorEntry {
18
19
  /** Path to the parent session when this one was forked. */
19
20
  parentSessionPath?: string;
20
21
  }
22
+ import { ResumeTreeComponent } from "./resume-tree.js";
23
+ export type { ResumeConversationLike, ResumeDirectoryLike, ResumeProjectLike, ResumeQueryLike, ResumeScopeInputLike, ResumeScopeKindLike, ResumeSourceLike, ResumeViewLike, ResumeViewRowLike, ResumeWorkspaceLike, } from "./resume-picker.js";
21
24
  import { OverlayPanel } from "../chrome/overlay-box.js";
22
25
  /** The session list's part of the picker props, plus the memo keys it was built from. */
23
26
  interface SessionPickerView {
@@ -76,6 +79,11 @@ declare class SessionList<T extends SessionSelectorEntry> implements Component {
76
79
  constructor(sessions: T[], showCwd?: boolean, historyMatcher?: SessionHistoryMatcher, getTerminalRows?: () => number, pinnedIds?: ReadonlySet<string>, currentSessionPath?: string | (() => string | undefined));
77
80
  /** Replace the visible dataset, e.g. when toggling folder/all-projects scope. */
78
81
  setSessions(sessions: T[], showCwd: boolean, pinnedIds?: ReadonlySet<string>): void;
82
+ /**
83
+ * Resume-model mode: the given sessions are already the model's ordered,
84
+ * filtered view, so mirror them and keep the selection when it survives.
85
+ */
86
+ syncSessions(sessions: readonly T[], preferredPath?: string | null): void;
79
87
  /** Cancel pending async search work; idempotent, called on every picker exit path. */
80
88
  dispose(): void;
81
89
  removeSession(sessionPath: string): void;
@@ -125,6 +133,17 @@ export interface SessionSelectorOptions<T extends SessionSelectorEntry = Session
125
133
  loadAllSessions?: () => Promise<T[]>;
126
134
  /** Preloaded all-projects list; cached so the first Tab toggle is instant. */
127
135
  allSessions?: T[];
136
+ /**
137
+ * The host's resume model (project → workspace → conversation) and its
138
+ * pure view builder. When set, the native `picker` describes the resume
139
+ * tree instead of the flat day-grouped list; the ANSI path is unchanged.
140
+ */
141
+ resumeSource?: ResumeSourceLike;
142
+ /**
143
+ * What delete does to the session file: an in-session picker moves it to
144
+ * the trash, `--resume` deletes it permanently. Wording only.
145
+ */
146
+ deleteMode?: "trash" | "permanent";
128
147
  /** Picker heading; defaults to "Resume Session". */
129
148
  title?: string;
130
149
  /** Primary action label; defaults to "Resume" (ANSI footer defaults to "select"). */
@@ -160,9 +179,7 @@ export interface SessionSelectorOptions<T extends SessionSelectorEntry = Session
160
179
  */
161
180
  standalone?: boolean;
162
181
  }
163
- /**
164
- * Component that renders a session selector with optional confirmation dialog
165
- */
182
+ /** Component that renders a session selector with optional confirmation dialog. */
166
183
  export declare class SessionSelectorComponent<T extends SessionSelectorEntry = SessionSelectorEntry> extends OverlayPanel {
167
184
  #private;
168
185
  constructor(sessions: T[], onSelect: (session: T) => void, onCancel: () => void, onExit: () => void, options?: SessionSelectorOptions<T>);
@@ -196,5 +213,6 @@ export declare class SessionSelectorComponent<T extends SessionSelectorEntry = S
196
213
  handleNativeEvent(event: NativeUiEvent): void;
197
214
  handleInput(keyData: string): void;
198
215
  getSessionList(): SessionList<T>;
216
+ /** The ANSI resume tree when the host supplied a resume source. */
217
+ getResumeTree(): ResumeTreeComponent | undefined;
199
218
  }
200
- export {};
@@ -18,7 +18,7 @@ export declare enum NotifyProtocol {
18
18
  Osc99 = "\u001B]99;;",
19
19
  Osc9 = "\u001B]9;"
20
20
  }
21
- export type TerminalId = "kitty" | "ghostty" | "wezterm" | "iterm2" | "vscode" | "alacritty" | "warp" | "orca" | "otty" | "rio" | "tern" | "monstar" | "base" | "trueColor";
21
+ export type TerminalId = "kitty" | "ghostty" | "wezterm" | "iterm2" | "vscode" | "alacritty" | "warp" | "orca" | "otty" | "rio" | "tern" | "monstar" | "zetawork" | "base" | "trueColor";
22
22
  /** Terminal capability details used for rendering and protocol selection. */
23
23
  export declare class TerminalInfo {
24
24
  readonly id: TerminalId;
@@ -123,6 +123,8 @@ export interface CoordinationDetails {
123
123
  }[];
124
124
  /** Running subagents not represented by a job row in this result. */
125
125
  agents?: AgentActivitySnapshot[];
126
+ /** `wait` returned early because blocking would deadlock (mesh S6). */
127
+ status?: "peer-waiting-on-you";
126
128
  }
127
129
  /** Hub result details: coordination snapshots or launch (process) state. */
128
130
  export type HubDetails = CoordinationDetails | LaunchToolDetails;
@@ -204,7 +206,7 @@ export interface IrcMessage {
204
206
  /** Delivery outcome for one peer recipient. */
205
207
  export interface IrcDeliveryReceipt {
206
208
  to: string;
207
- outcome: "injected" | "woken" | "revived" | "failed";
209
+ outcome: "injected" | "woken" | "revived" | "queued" | "failed";
208
210
  error?: string;
209
211
  }
210
212
  /** Broker-facing launch parameters; the hub adapts its `ps` op to `list` before calling in. */
@@ -23,7 +23,11 @@ export interface IrcMessage {
23
23
  /** Delivery outcome for one peer recipient. */
24
24
  export interface IrcDeliveryReceipt {
25
25
  to: string;
26
- outcome: "injected" | "woken" | "revived" | "failed";
26
+ /**
27
+ * `queued` is the cross-process offline path: the message is in the peer's
28
+ * persistent mailbox and will be injected when its process next starts.
29
+ */
30
+ outcome: "injected" | "woken" | "revived" | "queued" | "failed";
27
31
  error?: string;
28
32
  }
29
33
  /** Status ordering for peer rosters in child prompts. */
@@ -96,6 +96,12 @@ export interface CoordinationDetails {
96
96
  agents?: AgentActivitySnapshot[];
97
97
  /** `wait` was cut short by steering, a peer message, or a completion notice that injects next. */
98
98
  interrupted?: boolean;
99
+ /**
100
+ * `wait` returned early without a message because continuing would deadlock:
101
+ * the peer it was waiting on is itself waiting on this agent. Both sides can
102
+ * keep working — answer the peer, then wait again.
103
+ */
104
+ status?: "peer-waiting-on-you";
99
105
  }
100
106
  /** Pending wait frame. */
101
107
  declare function waitRenderCall(_args: object, _options: RenderResultOptions, uiTheme: Theme): Component;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@linxiraos/pi-tui",
4
- "version": "1.3.1",
4
+ "version": "1.4.0",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://linxira-os.github.io/zeta/",
7
7
  "author": "Linxira-OS",
@@ -38,14 +38,14 @@
38
38
  "gen:glyphs": "bun scripts/gen-glyphs.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@linxiraos/pi-omptype": "1.3.1",
42
- "@linxiraos/pi-agent-core": "1.3.1",
43
- "@linxiraos/pi-ai": "1.3.1",
44
- "@linxiraos/pi-catalog": "1.3.1",
45
- "@linxiraos/pi-natives": "1.3.1",
46
- "@linxiraos/pi-utils": "1.3.1",
47
- "@linxiraos/pi-wire": "1.3.1",
48
- "@linxiraos/pi-snapcompact": "1.3.1"
41
+ "@linxiraos/pi-omptype": "1.4.0",
42
+ "@linxiraos/pi-agent-core": "1.4.0",
43
+ "@linxiraos/pi-ai": "1.4.0",
44
+ "@linxiraos/pi-catalog": "1.4.0",
45
+ "@linxiraos/pi-natives": "1.4.0",
46
+ "@linxiraos/pi-utils": "1.4.0",
47
+ "@linxiraos/pi-wire": "1.4.0",
48
+ "@linxiraos/pi-snapcompact": "1.4.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "kitty-vt-wasm": "^0.2.0"
@@ -1,9 +1,12 @@
1
1
  import { logger } from "@linxiraos/pi-utils";
2
2
  import {
3
+ type ResumeSourceLike,
3
4
  SessionSelectorComponent,
4
- type SessionSelectorEntry,
5
5
  type SessionHistoryMatcher,
6
+ type SessionSelectorEntry,
7
+ type SessionSelectorOptions,
6
8
  } from "../overlays/session-selector";
9
+ import type { ResumeTreeSource } from "../overlays/resume-tree";
7
10
  import { runStandaloneTui } from "./standalone-picker";
8
11
 
9
12
  /** Persistence and history capabilities supplied by the session-owning host. */
@@ -12,6 +15,8 @@ export interface SessionPickerHost<T extends SessionSelectorEntry = SessionSelec
12
15
  loadHistoryMatcher?(): SessionHistoryMatcher;
13
16
  deleteSession?(session: T): Promise<boolean>;
14
17
  loadAllSessions?(): Promise<T[]>;
18
+ /** Builds the three-level resume source for the standalone `--resume` tree. */
19
+ loadResumeSource?(deleteMode: "trash" | "permanent", workspacePath?: string): Promise<ResumeTreeSource | undefined>;
15
20
  }
16
21
 
17
22
  /** Presentation and capability controls for the standalone session picker. */
@@ -24,6 +29,12 @@ export interface SessionPickerOptions<T extends SessionSelectorEntry = SessionSe
24
29
  allowGlobalScope?: boolean;
25
30
  historySearch?: boolean;
26
31
  pinnedIds?: ReadonlySet<string>;
32
+ /** Opt into the three-level resume tree; `deleteMode` words the confirm step. */
33
+ resume?: { deleteMode: "trash" | "permanent"; workspacePath?: string };
34
+ /** The host's resume model; when set, the native picker renders the project tree. */
35
+ resumeSource?: ResumeSourceLike;
36
+ /** Delete wording: in-session moves to trash, `--resume` deletes permanently. */
37
+ deleteMode?: "trash" | "permanent";
27
38
  }
28
39
 
29
40
  /**
@@ -51,6 +62,11 @@ export async function selectSession<T extends SessionSelectorEntry>(
51
62
  }
52
63
  }
53
64
 
65
+ const resumeMode = options.resume?.deleteMode;
66
+ const resumeSource = resumeMode
67
+ ? await host.loadResumeSource?.(resumeMode, options.resume?.workspacePath)
68
+ : undefined;
69
+
54
70
  return runStandaloneTui<T | null>(
55
71
  ({ ui, finish }) => {
56
72
  const selector = new SessionSelectorComponent(
@@ -73,7 +89,9 @@ export async function selectSession<T extends SessionSelectorEntry>(
73
89
  scopeLabel: options.scopeLabel,
74
90
  showCwd: options.showCwd,
75
91
  pinnedIds,
76
- },
92
+ resumeSource: resumeSource ?? options.resumeSource,
93
+ deleteMode: resumeMode ?? options.deleteMode,
94
+ } as SessionSelectorOptions<T> & { resumeSource?: ResumeTreeSource; deleteMode?: "trash" | "permanent" },
77
95
  );
78
96
  selector.setOnRequestRender(() => ui.requestRender());
79
97
  return selector;