@pi-unipi/unipi 2.6.0 → 2.6.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 (205) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/package.json +21 -22
  3. package/packages/ask-user/package.json +2 -2
  4. package/packages/ask-user/settings-tui.ts +18 -34
  5. package/packages/autocomplete/package.json +1 -1
  6. package/packages/autocomplete/src/constants.ts +2 -15
  7. package/packages/autocomplete/src/provider.ts +3 -17
  8. package/packages/btw/extensions/btw.ts +18 -45
  9. package/packages/btw/package.json +2 -2
  10. package/packages/compactor/README.md +2 -2
  11. package/packages/compactor/package.json +3 -3
  12. package/packages/compactor/skills/compactor/SKILL.md +1 -1
  13. package/packages/compactor/skills/compactor-detail/SKILL.md +3 -5
  14. package/packages/compactor/skills/compactor-doctor/SKILL.md +1 -1
  15. package/packages/compactor/skills/compactor-stats/SKILL.md +1 -1
  16. package/packages/compactor/src/commands/index.ts +47 -78
  17. package/packages/compactor/src/compaction/brief.ts +161 -90
  18. package/packages/compactor/src/compaction/build-sections.ts +3 -4
  19. package/packages/compactor/src/compaction/compact-args.ts +86 -0
  20. package/packages/compactor/src/compaction/cut.ts +270 -28
  21. package/packages/compactor/src/compaction/drill-down.ts +261 -0
  22. package/packages/compactor/src/compaction/format-recall.ts +96 -0
  23. package/packages/compactor/src/compaction/format.ts +8 -3
  24. package/packages/compactor/src/compaction/hooks.ts +248 -72
  25. package/packages/compactor/src/compaction/merge.ts +34 -4
  26. package/packages/compactor/src/compaction/rank.ts +270 -0
  27. package/packages/compactor/src/compaction/recall-scope.ts +28 -0
  28. package/packages/compactor/src/compaction/search-entries.ts +333 -96
  29. package/packages/compactor/src/compaction/skill-collapse.ts +35 -0
  30. package/packages/compactor/src/compaction/summarize.ts +37 -6
  31. package/packages/compactor/src/compaction/token-estimate.ts +104 -0
  32. package/packages/compactor/src/compaction/touched-files.ts +35 -0
  33. package/packages/compactor/src/config/manager.ts +2 -27
  34. package/packages/compactor/src/config/presets.ts +0 -2
  35. package/packages/compactor/src/config/schema.ts +2 -16
  36. package/packages/compactor/src/executor/executor.ts +6 -15
  37. package/packages/compactor/src/executor/runtime.ts +2 -12
  38. package/packages/compactor/src/index.ts +4 -121
  39. package/packages/compactor/src/info-screen.ts +3 -10
  40. package/packages/compactor/src/security/evaluator.ts +0 -53
  41. package/packages/compactor/src/security/policy.ts +7 -8
  42. package/packages/compactor/src/session/db.ts +0 -6
  43. package/packages/compactor/src/tools/ctx-execute-file.ts +0 -5
  44. package/packages/compactor/src/tools/register.ts +27 -50
  45. package/packages/compactor/src/tools/vcc-recall.ts +86 -48
  46. package/packages/compactor/src/tui/settings-overlay.ts +20 -40
  47. package/packages/compactor/src/types.ts +43 -100
  48. package/packages/core/constants.ts +1 -28
  49. package/packages/core/events.ts +1 -83
  50. package/packages/core/index.ts +1 -0
  51. package/packages/core/model-cache.ts +18 -12
  52. package/packages/core/package.json +3 -1
  53. package/packages/core/tui-overlay.ts +89 -0
  54. package/packages/core/tui-width.ts +18 -0
  55. package/packages/core/utils.ts +43 -0
  56. package/packages/footer/package.json +2 -2
  57. package/packages/footer/src/help.ts +2 -2
  58. package/packages/footer/src/index.ts +9 -10
  59. package/packages/footer/src/presets.ts +1 -27
  60. package/packages/footer/src/registry/index.ts +0 -23
  61. package/packages/footer/src/rendering/icons.ts +0 -13
  62. package/packages/footer/src/rendering/renderer.ts +5 -40
  63. package/packages/footer/src/rendering/separators.ts +0 -10
  64. package/packages/footer/src/rendering/theme.ts +1 -15
  65. package/packages/footer/src/segments/compactor.ts +7 -14
  66. package/packages/footer/src/segments/core.ts +15 -54
  67. package/packages/footer/src/segments/kanboard.ts +5 -5
  68. package/packages/footer/src/segments/mcp.ts +5 -5
  69. package/packages/footer/src/segments/memory.ts +4 -4
  70. package/packages/footer/src/segments/notify.ts +2 -2
  71. package/packages/footer/src/segments/ralph.ts +3 -3
  72. package/packages/footer/src/segments/status-ext.ts +1 -1
  73. package/packages/footer/src/segments/workflow.ts +3 -3
  74. package/packages/footer/src/tps-tracker.ts +0 -8
  75. package/packages/footer/src/tui/settings-tui.ts +14 -31
  76. package/packages/footer/src/types.ts +0 -15
  77. package/packages/image/package.json +2 -2
  78. package/packages/image/src/register-providers.ts +0 -11
  79. package/packages/image/src/tools.ts +0 -3
  80. package/packages/image/src/tui/model-selector.ts +36 -71
  81. package/packages/info-screen/config.ts +0 -16
  82. package/packages/info-screen/core-groups.ts +0 -10
  83. package/packages/info-screen/index.ts +22 -13
  84. package/packages/info-screen/package.json +2 -2
  85. package/packages/info-screen/registry.ts +1 -72
  86. package/packages/info-screen/tui/info-overlay.ts +85 -100
  87. package/packages/info-screen/usage-parser.ts +12 -47
  88. package/packages/input-shortcuts/package.json +2 -2
  89. package/packages/input-shortcuts/src/index.ts +3 -3
  90. package/packages/input-shortcuts/src/registers.ts +0 -8
  91. package/packages/input-shortcuts/src/settings-overlay.ts +4 -13
  92. package/packages/input-shortcuts/src/undo-redo.ts +0 -12
  93. package/packages/kanboard/package.json +2 -2
  94. package/packages/mcp/package.json +2 -2
  95. package/packages/mcp/src/bridge/client.ts +0 -15
  96. package/packages/mcp/src/config/manager.ts +0 -38
  97. package/packages/mcp/src/config/schema.ts +0 -27
  98. package/packages/mcp/src/config/sync.ts +0 -29
  99. package/packages/mcp/src/index.ts +1 -1
  100. package/packages/mcp/src/tui/add-overlay.ts +6 -6
  101. package/packages/mcp/src/types.ts +0 -6
  102. package/packages/memory/embedding.ts +0 -31
  103. package/packages/memory/mempalace.ts +0 -16
  104. package/packages/memory/package.json +4 -8
  105. package/packages/memory/storage.ts +56 -753
  106. package/packages/milestone/hooks.ts +1 -6
  107. package/packages/milestone/milestone.ts +2 -41
  108. package/packages/milestone/package.json +2 -2
  109. package/packages/notify/README.md +1 -0
  110. package/packages/notify/commands.ts +61 -3
  111. package/packages/notify/events.ts +0 -10
  112. package/packages/notify/package.json +2 -2
  113. package/packages/notify/settings.ts +0 -19
  114. package/packages/notify/tui/gotify-setup.ts +108 -143
  115. package/packages/notify/tui/ntfy-setup.ts +137 -172
  116. package/packages/notify/tui/recap-model-selector.ts +107 -101
  117. package/packages/notify/tui/settings-overlay.ts +94 -117
  118. package/packages/notify/tui/telegram-setup.ts +48 -79
  119. package/packages/notify/types.ts +0 -2
  120. package/packages/ralph/index.ts +11 -35
  121. package/packages/ralph/package.json +3 -3
  122. package/packages/ralph/ralph-loop.ts +3 -44
  123. package/packages/subagents/package.json +2 -1
  124. package/packages/subagents/src/agent-manager.ts +0 -51
  125. package/packages/subagents/src/agent-runner.ts +6 -80
  126. package/packages/subagents/src/conversation-viewer.ts +1 -19
  127. package/packages/subagents/src/core-compat.ts +8 -25
  128. package/packages/subagents/src/custom-agents.ts +0 -1
  129. package/packages/subagents/src/index.ts +3 -48
  130. package/packages/subagents/src/types.ts +0 -11
  131. package/packages/subagents/src/widget.ts +5 -5
  132. package/packages/unipi/bundled.js +4468 -7769
  133. package/packages/unipi/index.ts +6 -3
  134. package/packages/updater/package.json +2 -2
  135. package/packages/updater/src/changelog.ts +1 -16
  136. package/packages/updater/src/index.ts +0 -5
  137. package/packages/updater/src/installer.ts +4 -26
  138. package/packages/updater/src/markdown.ts +6 -152
  139. package/packages/updater/src/settings.ts +0 -15
  140. package/packages/updater/src/tui/changelog-overlay.ts +42 -234
  141. package/packages/updater/src/tui/list-detail-overlay.ts +260 -0
  142. package/packages/updater/src/tui/readme-overlay.ts +53 -210
  143. package/packages/updater/src/tui/settings-overlay.ts +13 -26
  144. package/packages/updater/src/version.ts +2 -31
  145. package/packages/utility/package.json +2 -4
  146. package/packages/utility/src/commands.ts +4 -5
  147. package/packages/utility/src/herdr-sync.ts +136 -0
  148. package/packages/utility/src/index.ts +11 -68
  149. package/packages/utility/src/lifecycle/cleanup.ts +2 -16
  150. package/packages/utility/src/{diff/settings.ts → settings.ts} +42 -80
  151. package/packages/utility/src/tools/env.ts +0 -0
  152. package/packages/utility/src/tui/name-badge-state.ts +18 -2
  153. package/packages/utility/src/tui/name-badge.ts +5 -4
  154. package/packages/utility/src/tui/util-settings-tui.ts +41 -224
  155. package/packages/web-api/package.json +2 -6
  156. package/packages/web-api/src/engine/dependencies.ts +13 -134
  157. package/packages/web-api/src/engine/extract.ts +9 -99
  158. package/packages/web-api/src/engine/format.ts +0 -75
  159. package/packages/web-api/src/engine/types.ts +0 -39
  160. package/packages/web-api/src/index.ts +1 -2
  161. package/packages/web-api/src/providers/base.ts +0 -10
  162. package/packages/web-api/src/providers/duckduckgo.ts +0 -1
  163. package/packages/web-api/src/providers/firecrawl.ts +0 -9
  164. package/packages/web-api/src/providers/jina-reader.ts +0 -9
  165. package/packages/web-api/src/providers/jina-search.ts +0 -9
  166. package/packages/web-api/src/providers/perplexity.ts +0 -9
  167. package/packages/web-api/src/providers/registry.ts +0 -80
  168. package/packages/web-api/src/providers/serpapi.ts +0 -9
  169. package/packages/web-api/src/providers/tavily.ts +0 -9
  170. package/packages/web-api/src/providers/wigolo-client.ts +0 -30
  171. package/packages/web-api/src/providers/wigolo.ts +0 -1
  172. package/packages/web-api/src/settings.ts +17 -77
  173. package/packages/web-api/src/tools.ts +21 -24
  174. package/packages/web-api/src/tui/settings-dialog.ts +0 -1
  175. package/packages/workflow/commands.ts +38 -122
  176. package/packages/workflow/index.ts +1 -5
  177. package/packages/workflow/package.json +2 -2
  178. package/packages/cocoindex/README.md +0 -94
  179. package/packages/cocoindex/bridge.ts +0 -842
  180. package/packages/cocoindex/commands.ts +0 -175
  181. package/packages/cocoindex/index.ts +0 -48
  182. package/packages/cocoindex/installer.ts +0 -397
  183. package/packages/cocoindex/package.json +0 -49
  184. package/packages/cocoindex/skills/cocoindex/SKILL.md +0 -88
  185. package/packages/cocoindex/tools.ts +0 -157
  186. package/packages/compactor/src/display/diff-renderer.ts +0 -281
  187. package/packages/compactor/src/display/line-width-safety.ts +0 -28
  188. package/packages/compactor/src/display/render-utils.ts +0 -52
  189. package/packages/compactor/src/display/thinking-label.ts +0 -18
  190. package/packages/compactor/src/display/tool-overrides.ts +0 -136
  191. package/packages/compactor/src/tools/compact.ts +0 -20
  192. package/packages/subagents/src/file-lock.ts +0 -102
  193. package/packages/utility/src/cache/ttl-cache.ts +0 -311
  194. package/packages/utility/src/diff/highlighter.ts +0 -352
  195. package/packages/utility/src/diff/parser.ts +0 -191
  196. package/packages/utility/src/diff/renderer.ts +0 -395
  197. package/packages/utility/src/diff/theme.ts +0 -316
  198. package/packages/utility/src/diff/wrapper.ts +0 -339
  199. package/packages/utility/src/display/capabilities.ts +0 -214
  200. package/packages/utility/src/display/width.ts +0 -226
  201. package/packages/utility/src/tools/batch.ts +0 -229
  202. package/packages/utility/src/tui/badge-settings-tui.ts +0 -388
  203. package/packages/utility/src/tui/badge-settings.ts +0 -67
  204. package/packages/utility/src/tui/settings-inspector.ts +0 -303
  205. package/packages/web-api/src/providers/llm-summarize.ts +0 -71
@@ -8,12 +8,6 @@ import type { Message } from "@earendil-works/pi-ai";
8
8
  // Normalized blocks (from pi-vcc)
9
9
  // ─────────────────────────────────────────────────────────
10
10
 
11
- export interface FileOps {
12
- readFiles?: string[];
13
- modifiedFiles?: string[];
14
- createdFiles?: string[];
15
- }
16
-
17
11
  export type NormalizedBlock =
18
12
  | { kind: "user"; text: string; sourceIndex?: number }
19
13
  | { kind: "assistant"; text: string; sourceIndex?: number }
@@ -21,6 +15,13 @@ export type NormalizedBlock =
21
15
  | { kind: "tool_result"; name: string; text: string; isError: boolean; sourceIndex?: number }
22
16
  | { kind: "thinking"; text: string; redacted: boolean; sourceIndex?: number };
23
17
 
18
+ /** Hook-provided file activity (pi-vcc parity) — structural signal for ranking */
19
+ export interface FileOps {
20
+ readFiles?: string[];
21
+ modifiedFiles?: string[];
22
+ createdFiles?: string[];
23
+ }
24
+
24
25
  // ─────────────────────────────────────────────────────────
25
26
  // Section data (from pi-vcc)
26
27
  // ─────────────────────────────────────────────────────────
@@ -32,16 +33,6 @@ export interface SectionData {
32
33
  outstandingContext: string[];
33
34
  userPreferences: string[];
34
35
  briefTranscript: string;
35
- transcriptEntries: TranscriptEntry[];
36
- }
37
-
38
- export interface TranscriptEntry {
39
- role: "user" | "assistant" | "tool_error";
40
- text?: string;
41
- tool?: string;
42
- cmd?: string;
43
- ref?: string;
44
- count?: number;
45
36
  }
46
37
 
47
38
  export interface BriefLine {
@@ -49,16 +40,6 @@ export interface BriefLine {
49
40
  lines: string[];
50
41
  }
51
42
 
52
- /** Runtime stats tracked during a live session. */
53
- export interface RuntimeStats {
54
- bytesReturned: Record<string, number>;
55
- bytesSandboxed: number;
56
- calls: Record<string, number>;
57
- sessionStart: number;
58
- cacheHits: number;
59
- cacheBytesSaved: number;
60
- }
61
-
62
43
  // ─────────────────────────────────────────────────────────
63
44
  // Compaction input / output
64
45
  // ─────────────────────────────────────────────────────────
@@ -66,26 +47,48 @@ export interface RuntimeStats {
66
47
  export interface CompileInput {
67
48
  messages: Message[];
68
49
  previousSummary?: string;
69
- fileOps?: FileOps;
70
50
  }
71
51
 
72
52
  export interface CompactionStats {
73
53
  summarized: number;
74
54
  kept: number;
75
- totalMessages: number;
55
+ totalMessages?: number;
76
56
  /** Actual token count from Pi's preparation */
77
- tokensBefore: number;
57
+ tokensBefore?: number;
78
58
  /** Estimated tokens after compaction (proportional from kept/total chars) */
79
- tokensAfterEst: number;
59
+ tokensAfterEst?: number;
60
+ keptUserTurns: number;
61
+ totalUserTurns: number;
62
+ requestedKeepUserTurns: number;
63
+ keepUserTurnsExplicit: boolean;
64
+ keepFallbackToCompactAll: boolean;
65
+ /** Set when the tail came from a token-budget cut instead of a user-turn cut. */
66
+ budgetCut?: BudgetCutKind;
67
+ keptTokensEst: number;
68
+ /** True when smart-keep boosted the default keep beyond 1. */
69
+ smartKeepAdjusted?: boolean;
70
+ /** Base keep before smart adjustment (for toast like "1→3"). */
71
+ smartFromKeep?: number;
80
72
  }
81
73
 
74
+ export type BudgetCutKind = "no_anchor" | "oversized_tail";
75
+
82
76
  export type OwnCutCancelReason =
83
77
  | "no_live_messages"
84
- | "too_few_live_messages"
85
- | "no_user_message";
78
+ | "too_few_live_messages";
86
79
 
87
80
  export type OwnCutResult =
88
- | { ok: true; messages: Message[]; firstKeptEntryId: string; compactAll: boolean }
81
+ | {
82
+ ok: true;
83
+ messages: Message[];
84
+ firstKeptEntryId: string;
85
+ compactAll: boolean;
86
+ keptUserTurns: number;
87
+ totalUserTurns: number;
88
+ requestedKeepUserTurns: number;
89
+ keepFallbackToCompactAll: boolean;
90
+ budgetCut?: BudgetCutKind;
91
+ }
89
92
  | { ok: false; reason: OwnCutCancelReason };
90
93
 
91
94
  // ─────────────────────────────────────────────────────────
@@ -125,25 +128,13 @@ export interface CompactorConfig {
125
128
  /** @deprecated Category filtering was never implemented; ignored by runtime. */
126
129
  eventCategories: string[];
127
130
  };
128
- /** @deprecated Project indexing moved to @pi-unipi/cocoindex; retained for config compatibility. */
131
+ /** @deprecated Retained for config compatibility. */
129
132
  fts5Index: CompactorStrategyConfig & { mode: "auto" | "manual" | "off"; chunkSize: number; cacheTtlHours: number };
130
133
  sandboxExecution: CompactorStrategyConfig & { mode: "all" | "safe-only" | "off"; allowedLanguages: Language[]; outputLimit: number };
131
- /** @deprecated Display profiles were never connected to runtime; retained for config compatibility. */
132
- toolDisplay: CompactorStrategyConfig & { mode: "opencode" | "balanced" | "verbose" | "custom"; diffLayout: "auto" | "split" | "unified"; diffIndicator: "bars" | "classic" | "none"; showThinkingLabels: boolean; showUserMessageBox: boolean; showBashSpinner: boolean; showPendingPreviews: boolean };
133
134
 
134
135
  // Pipeline features
135
136
  pipeline: {
136
- /** @deprecated Reserved compatibility field; ignored by runtime. */
137
- ttlCache: boolean;
138
137
  autoInjection: boolean;
139
- /** @deprecated Reserved compatibility field; ignored by runtime. */
140
- proximityReranking: boolean;
141
- /** @deprecated Reserved compatibility field; ignored by runtime. */
142
- timelineSort: boolean;
143
- /** @deprecated Reserved compatibility field; ignored by runtime. */
144
- progressiveThrottling: boolean;
145
- /** @deprecated Reserved compatibility field; ignored by runtime. */
146
- mmapPragma: boolean;
147
138
  customNoisePatterns: string[];
148
139
  };
149
140
 
@@ -152,9 +143,12 @@ export interface CompactorConfig {
152
143
 
153
144
  // Global settings
154
145
  overrideDefaultCompaction: boolean;
146
+ /** Boost default keep:1 to a larger tail when it is small (≤5k tok, capped 25k). Explicit keep:N always respected. */
147
+ smartKeepTail: boolean;
148
+ /** Ask the agent to continue after automatic (threshold/overflow) compaction. */
149
+ continueAfterThresholdCompact: boolean;
150
+ /** Write detailed compaction diagnostics to /tmp/compactor-debug.json. */
155
151
  debug: boolean;
156
- /** @deprecated Truncation hints were never connected to runtime; retained for config compatibility. */
157
- showTruncationHints: boolean;
158
152
  }
159
153
 
160
154
  export type CompactorPreset = "precise" | "balanced" | "thorough" | "lean" | "opencode" | "verbose" | "minimal" | "custom";
@@ -236,61 +230,10 @@ export type Language =
236
230
  | "elixir";
237
231
 
238
232
  // ─────────────────────────────────────────────────────────
239
- // Content store — REMOVED (moved to @pi-unipi/cocoindex)
233
+ // Content store — REMOVED
240
234
  // SearchResult, IndexResult, StoreStats types no longer needed.
241
235
  // ─────────────────────────────────────────────────────────
242
236
 
243
- // ─────────────────────────────────────────────────────────
244
- // Security (from context-mode)
245
- // ─────────────────────────────────────────────────────────
246
-
247
- export type PermissionDecision = "allow" | "deny" | "ask";
248
-
249
- export interface SecurityPolicy {
250
- allow: string[];
251
- deny: string[];
252
- ask: string[];
253
- }
254
-
255
- // ─────────────────────────────────────────────────────────
256
- // Display (from pi-tool-display)
257
- // ─────────────────────────────────────────────────────────
258
-
259
- export type DiffLayout = "auto" | "split" | "unified";
260
- export type DiffIndicator = "bars" | "classic" | "none";
261
- export type OutputMode = "hidden" | "summary" | "preview" | "count";
262
-
263
- export interface ToolDisplayConfig {
264
- registerToolOverrides: {
265
- read: boolean;
266
- grep: boolean;
267
- find: boolean;
268
- ls: boolean;
269
- bash: boolean;
270
- edit: boolean;
271
- write: boolean;
272
- };
273
- enableNativeUserMessageBox: boolean;
274
- readOutputMode: OutputMode;
275
- searchOutputMode: OutputMode;
276
- mcpOutputMode: OutputMode;
277
- previewLines: number;
278
- expandedPreviewMaxLines: number;
279
- bashOutputMode: OutputMode;
280
- bashCollapsedLines: number;
281
- diffViewMode: DiffLayout;
282
- diffIndicatorMode: DiffIndicator;
283
- diffSplitMinWidth: number;
284
- diffCollapsedLines: number;
285
- diffWordWrap: boolean;
286
- showTruncationHints: boolean;
287
- showRtkCompactionHints: boolean;
288
- }
289
-
290
- // ─────────────────────────────────────────────────────────
291
- // Runtime counters (live session stats)
292
- // ─────────────────────────────────────────────────────────
293
-
294
237
  export interface RuntimeCounters {
295
238
  sandboxRuns: number;
296
239
  searchQueries: number;
@@ -38,7 +38,6 @@ export const MODULES = {
38
38
  FOOTER: "@pi-unipi/footer",
39
39
  UPDATER: "@pi-unipi/updater",
40
40
  INPUT_SHORTCUTS: "@pi-unipi/input-shortcuts",
41
- COCOINDEX: "@pi-unipi/cocoindex",
42
41
  IMAGE: "@pi-unipi/image",
43
42
  } as const;
44
43
 
@@ -134,13 +133,6 @@ export const MEMORY_DEFAULTS = {
134
133
  } as const;
135
134
 
136
135
  /** Memory types */
137
- export const MEMORY_TYPES = {
138
- PREFERENCE: "preference",
139
- DECISION: "decision",
140
- PATTERN: "pattern",
141
- SUMMARY: "summary",
142
- } as const;
143
-
144
136
  /** Default ralph loop settings */
145
137
  export const RALPH_DEFAULTS = {
146
138
  MAX_ITERATIONS: 50,
@@ -297,6 +289,7 @@ export const NOTIFY_COMMANDS = {
297
289
  SET_NTFY: "notify-set-ntfy",
298
290
  TEST: "notify-test",
299
291
  RECAP_MODEL: "notify-recap-model",
292
+ NOTIFY_EVENT: "notify-event",
300
293
  } as const;
301
294
 
302
295
  /** Notify tool names */
@@ -369,23 +362,3 @@ export const COMPACTOR_DEFAULTS = {
369
362
  CACHE_TTL_HOURS: 24,
370
363
  } as const;
371
364
 
372
- /** CocoIndex minimum supported CLI version. */
373
- export const COCOINDEX_MIN_VERSION = "1.0" as const;
374
-
375
- /** CocoIndex package spec installed by the interactive installer. */
376
- export const COCOINDEX_PACKAGE_SPEC = `cocoindex[lancedb]>=${COCOINDEX_MIN_VERSION}` as const;
377
-
378
- /** CocoIndex tool names */
379
- export const COCOINDEX_TOOLS = {
380
- SEARCH: "cocoindex_search",
381
- STATUS: "cocoindex_status",
382
- } as const;
383
-
384
- /** CocoIndex command names */
385
- export const COCOINDEX_COMMANDS = {
386
- UPDATE: "cocoindex-update",
387
- STATUS: "cocoindex-status",
388
- INIT: "cocoindex-init",
389
- SETTINGS: "cocoindex-settings",
390
- SEARCH: "cocoindex-search",
391
- } as const;
@@ -9,8 +9,6 @@
9
9
  export const UNIPI_EVENTS = {
10
10
  /** Module loaded and ready */
11
11
  MODULE_READY: "unipi:module:ready",
12
- /** @deprecated No built-in emitter; retained for external compatibility. */
13
- MODULE_GONE: "unipi:module:gone",
14
12
 
15
13
  /** Workflow command started */
16
14
  WORKFLOW_START: "unipi:workflow:start",
@@ -24,10 +22,6 @@ export const UNIPI_EVENTS = {
24
22
  /** Ralph loop iteration completed */
25
23
  RALPH_ITERATION_DONE: "unipi:ralph:iteration:done",
26
24
 
27
- /** @deprecated No built-in responders; use the info registry and /unipi:info. */
28
- MODULE_STATUS_REQUEST: "unipi:module:status:request",
29
- /** @deprecated No built-in aggregator; use the info registry and /unipi:info. */
30
- MODULE_STATUS_RESPONSE: "unipi:module:status:response",
31
25
 
32
26
  /** Info screen group registered */
33
27
  INFO_GROUP_REGISTERED: "unipi:info:group:registered",
@@ -38,8 +32,6 @@ export const UNIPI_EVENTS = {
38
32
  MEMORY_STORED: "unipi:memory:stored",
39
33
  /** Memory deleted */
40
34
  MEMORY_DELETED: "unipi:memory:deleted",
41
- /** @deprecated No built-in emitter; retained for external compatibility. */
42
- MEMORY_SEARCHED: "unipi:memory:searched",
43
35
  /** Memory consolidation completed */
44
36
  MEMORY_CONSOLIDATED: "unipi:memory:consolidated",
45
37
 
@@ -60,18 +52,12 @@ export const UNIPI_EVENTS = {
60
52
  COMPACTOR_COMPACTED: "unipi:compactor:compacted",
61
53
  /** @deprecated Footer reads live Pi session data; retained for compatibility. */
62
54
  COMPACTOR_STATS_UPDATED: "unipi:compactor:stats:updated",
63
- /** @deprecated No built-in emitter; retained for external compatibility. */
64
- UTILITY_CLEANUP_START: "unipi:utility:cleanup:start",
65
55
  /** Utility module cleanup completed */
66
56
  UTILITY_CLEANUP_DONE: "unipi:utility:cleanup:done",
67
57
  /** Utility diagnostics started */
68
58
  UTILITY_DIAGNOSTICS_START: "unipi:utility:diagnostics:start",
69
59
  /** Utility diagnostics completed */
70
60
  UTILITY_DIAGNOSTICS_DONE: "unipi:utility:diagnostics:done",
71
- /** @deprecated No built-in emitter; retained for external compatibility. */
72
- UTILITY_CACHE_INVALIDATED: "unipi:utility:cache:invalidated",
73
- /** @deprecated No built-in emitter; retained for external compatibility. */
74
- UTILITY_LIFECYCLE_STATE: "unipi:utility:lifecycle:state",
75
61
 
76
62
  /** Notification sent */
77
63
  NOTIFICATION_SENT: "unipi:notify:sent",
@@ -91,12 +77,6 @@ export const UNIPI_EVENTS = {
91
77
  /** Update error */
92
78
  UPDATE_ERROR: "unipi:update:error",
93
79
 
94
- /** @deprecated Reserved external contract; no built-in emitter. */
95
- COCOINDEX_UPDATE_STARTED: "unipi:cocoindex:update:started",
96
- /** @deprecated Reserved external contract; no built-in emitter. */
97
- COCOINDEX_UPDATE_COMPLETED: "unipi:cocoindex:update:completed",
98
- /** @deprecated Reserved external contract; no built-in emitter. */
99
- COCOINDEX_SEARCH_PERFORMED: "unipi:cocoindex:search:performed",
100
80
  } as const;
101
81
 
102
82
  /** Payload for MODULE_READY / MODULE_GONE */
@@ -151,21 +131,7 @@ export interface UnipiRalphIterationEvent {
151
131
  nextIteration: number;
152
132
  }
153
133
 
154
- /** @deprecated No built-in responders; retained for compatibility. */
155
- export interface UnipiStatusRequestEvent {
156
- /** Request ID for correlation */
157
- requestId: string;
158
- }
159
134
 
160
- /** @deprecated No built-in aggregator; retained for compatibility. */
161
- export interface UnipiStatusResponseEvent {
162
- /** Request ID this responds to */
163
- requestId: string;
164
- /** Module name */
165
- name: string;
166
- /** Module status data */
167
- status: Record<string, unknown>;
168
- }
169
135
 
170
136
  /** Payload for MEMORY_STORED */
171
137
  export interface UnipiMemoryStoredEvent {
@@ -191,15 +157,6 @@ export interface UnipiMemoryDeletedEvent {
191
157
  project: string;
192
158
  }
193
159
 
194
- /** Payload for MEMORY_SEARCHED */
195
- export interface UnipiMemorySearchedEvent {
196
- /** Search query */
197
- query: string;
198
- /** Number of results */
199
- resultCount: number;
200
- /** Project scope */
201
- project: string;
202
- }
203
160
 
204
161
  /** Payload for MEMORY_CONSOLIDATED */
205
162
  export interface UnipiMemoryConsolidatedEvent {
@@ -307,15 +264,6 @@ export interface UnipiUtilityDiagnosticsEvent {
307
264
  report?: unknown;
308
265
  }
309
266
 
310
- /** Payload for UTILITY_LIFECYCLE_STATE */
311
- export interface UnipiUtilityLifecycleEvent {
312
- /** New lifecycle state */
313
- state: "running" | "shutting_down" | "orphaned" | "error";
314
- /** Previous state */
315
- previousState?: string;
316
- /** Reason for state change */
317
- reason?: string;
318
- }
319
267
 
320
268
  /** Payload for BADGE_GENERATE_REQUEST */
321
269
  export interface UnipiBadgeGenerateRequestEvent {
@@ -375,31 +323,8 @@ export interface UnipiUpdateErrorEvent {
375
323
  phase: "check" | "install";
376
324
  }
377
325
 
378
- /** Payload for COCOINDEX_UPDATE_STARTED */
379
- export interface UnipiCocoindexUpdateStartedEvent {
380
- /** Project directory being indexed */
381
- projectDir: string;
382
- }
383
326
 
384
- /** Payload for COCOINDEX_UPDATE_COMPLETED */
385
- export interface UnipiCocoindexUpdateCompletedEvent {
386
- /** Whether the update succeeded */
387
- success: boolean;
388
- /** Number of chunks processed */
389
- chunksProcessed: number;
390
- /** Duration in ms */
391
- durationMs: number;
392
- /** Error message if failed */
393
- error?: string;
394
- }
395
327
 
396
- /** Payload for COCOINDEX_SEARCH_PERFORMED */
397
- export interface UnipiCocoindexSearchPerformedEvent {
398
- /** Search query */
399
- query: string;
400
- /** Number of results */
401
- resultCount: number;
402
- }
403
328
 
404
329
  /** Payload for NOTIFICATION_SENT */
405
330
  export interface UnipiNotificationSentEvent {
@@ -421,11 +346,8 @@ export type UnipiEventPayload =
421
346
  | UnipiWorkflowEvent
422
347
  | UnipiRalphLoopEvent
423
348
  | UnipiRalphIterationEvent
424
- | UnipiStatusRequestEvent
425
- | UnipiStatusResponseEvent
426
349
  | UnipiMemoryStoredEvent
427
350
  | UnipiMemoryDeletedEvent
428
- | UnipiMemorySearchedEvent
429
351
  | UnipiMemoryConsolidatedEvent
430
352
  | UnipiInfoGroupEvent
431
353
  | UnipiInfoDataEvent
@@ -436,14 +358,10 @@ export type UnipiEventPayload =
436
358
  | UnipiCompactorStatsEvent
437
359
  | UnipiUtilityCleanupEvent
438
360
  | UnipiUtilityDiagnosticsEvent
439
- | UnipiUtilityLifecycleEvent
440
361
  | UnipiNotificationSentEvent
441
362
  | UnipiBadgeGenerateRequestEvent
442
363
  | UnipiAskUserPromptEvent
443
364
  | UnipiUpdateCheckEvent
444
365
  | UnipiUpdateAvailableEvent
445
366
  | UnipiUpdateAppliedEvent
446
- | UnipiUpdateErrorEvent
447
- | UnipiCocoindexUpdateStartedEvent
448
- | UnipiCocoindexUpdateCompletedEvent
449
- | UnipiCocoindexSearchPerformedEvent;
367
+ | UnipiUpdateErrorEvent;
@@ -10,4 +10,5 @@ export * from "./sandbox.js";
10
10
  export * from "./utils.js";
11
11
  export * from "./model-cache.js";
12
12
  export * from "./tui-width.js";
13
+ export * from "./tui-overlay.js";
13
14
  export * from "./bounded-output.js";
@@ -9,14 +9,18 @@
9
9
  import * as fs from "node:fs";
10
10
  import * as path from "node:path";
11
11
 
12
- /** Path to the model cache directory */
13
- const CACHE_DIR = path.join(
14
- process.env.HOME ?? process.env.USERPROFILE ?? "~",
15
- ".unipi/config",
16
- );
12
+ /** Resolve the model cache directory at call time (respects HOME changes). */
13
+ function cacheDir(): string {
14
+ return path.join(
15
+ process.env.HOME ?? process.env.USERPROFILE ?? "~",
16
+ ".unipi/config",
17
+ );
18
+ }
17
19
 
18
- /** Path to the model cache file */
19
- const CACHE_FILE = path.join(CACHE_DIR, "models-cache.json");
20
+ /** Resolve the model cache file path at call time. */
21
+ function cacheFile(): string {
22
+ return path.join(cacheDir(), "models-cache.json");
23
+ }
20
24
 
21
25
  /** A single cached model entry */
22
26
  export interface CachedModel {
@@ -42,8 +46,9 @@ export interface ModelCache {
42
46
  */
43
47
  export function readModelCache(): CachedModel[] {
44
48
  try {
45
- if (!fs.existsSync(CACHE_FILE)) return [];
46
- const parsed = JSON.parse(fs.readFileSync(CACHE_FILE, "utf-8"));
49
+ const file = cacheFile();
50
+ if (!fs.existsSync(file)) return [];
51
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
47
52
  return Array.isArray(parsed.models) ? parsed.models : [];
48
53
  } catch {
49
54
  return [];
@@ -56,14 +61,15 @@ export function readModelCache(): CachedModel[] {
56
61
  */
57
62
  export function writeModelCache(models: CachedModel[]): void {
58
63
  try {
59
- if (!fs.existsSync(CACHE_DIR)) {
60
- fs.mkdirSync(CACHE_DIR, { recursive: true });
64
+ const dir = cacheDir();
65
+ if (!fs.existsSync(dir)) {
66
+ fs.mkdirSync(dir, { recursive: true });
61
67
  }
62
68
  const cache: ModelCache = {
63
69
  updatedAt: new Date().toISOString(),
64
70
  models,
65
71
  };
66
- fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2) + "\n", "utf-8");
72
+ fs.writeFileSync(cacheFile(), JSON.stringify(cache, null, 2) + "\n", "utf-8");
67
73
  } catch {
68
74
  // Best effort — cache is optional
69
75
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/core",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Shared utilities, event types, and constants for Unipi extension suite",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,10 +25,12 @@
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@earendil-works/pi-coding-agent": "^0.80.0",
28
+ "@earendil-works/pi-tui": "^0.80.0",
28
29
  "typebox": "^1.1.38"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@earendil-works/pi-coding-agent": "^0.80.0",
33
+ "@earendil-works/pi-tui": "^0.80.0",
32
34
  "typebox": "^1.1.38",
33
35
  "@types/node": "^22.0.0"
34
36
  },
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @pi-unipi/core — Shared TUI overlay helpers
3
+ *
4
+ * Eliminates the frameLine/borderLine/ruleLine/fg/bold duplication across
5
+ * 9+ overlay files. Each overlay creates an OverlayTheme instance and
6
+ * delegates box-drawing and theming to it.
7
+ *
8
+ * The key-handling bug (raw \x1b comparisons vs matchesKey) would have been
9
+ * caught at one site instead of 10 if these helpers had existed from the start.
10
+ */
11
+ import type { Theme } from "@earendil-works/pi-coding-agent";
12
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
13
+ import { safeRepeat } from "./tui-width.ts";
14
+
15
+ /** ANSI codes used when no Theme is available (terminal default). */
16
+ const FALLBACK_COLORS: Record<string, string> = {
17
+ accent: "\x1b[36m",
18
+ success: "\x1b[32m",
19
+ warning: "\x1b[33m",
20
+ error: "\x1b[31m",
21
+ dim: "\x1b[2m",
22
+ borderMuted: "\x1b[90m",
23
+ };
24
+
25
+ /**
26
+ * Shared theme + box-drawing helper for TUI overlays.
27
+ *
28
+ * Usage:
29
+ * ```ts
30
+ * class MyOverlay implements Component {
31
+ * private overlay = new OverlayTheme();
32
+ *
33
+ * setTheme(theme: Theme) { this.overlay.setTheme(theme); }
34
+ *
35
+ * render(width: number): string[] {
36
+ * const inner = boxInnerWidth(width);
37
+ * return [
38
+ * this.overlay.borderLine(inner, "top"),
39
+ * this.overlay.frameLine("Title", inner),
40
+ * this.overlay.borderLine(inner, "bottom"),
41
+ * ];
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ export class OverlayTheme {
47
+ private theme: Theme | null = null;
48
+
49
+ setTheme(theme: Theme | null): void {
50
+ this.theme = theme;
51
+ }
52
+
53
+ /** Color text using the active theme, or a fallback ANSI code. */
54
+ fg(color: string, text: string): string {
55
+ if (this.theme) return this.theme.fg(color as never, text);
56
+ return `${FALLBACK_COLORS[color] ?? ""}${text}\x1b[0m`;
57
+ }
58
+
59
+ /** Bold text using the active theme, or a fallback ANSI code. */
60
+ bold(text: string): string {
61
+ if (this.theme) return this.theme.bold(text);
62
+ return `\x1b[1m${text}\x1b[0m`;
63
+ }
64
+
65
+ /** Background color using the active theme, or text unchanged. */
66
+ bg(color: string, text: string): string {
67
+ if (this.theme) return this.theme.bg(color as never, text);
68
+ return text;
69
+ }
70
+
71
+ /** Frame a content line with `│` borders, padded and truncated to innerWidth. */
72
+ frameLine(content: string, innerWidth: number): string {
73
+ const truncated = truncateToWidth(content, innerWidth, "");
74
+ const padding = Math.max(0, innerWidth - visibleWidth(truncated));
75
+ return `${this.fg("borderMuted", "│")}${truncated}${safeRepeat(" ", padding)}${this.fg("borderMuted", "│")}`;
76
+ }
77
+
78
+ /** Horizontal rule: `├───┤`. */
79
+ ruleLine(innerWidth: number): string {
80
+ return this.fg("borderMuted", `├${safeRepeat("─", innerWidth)}┤`);
81
+ }
82
+
83
+ /** Top or bottom border: `┌───┐` / `└───┘`. */
84
+ borderLine(innerWidth: number, edge: "top" | "bottom"): string {
85
+ const left = edge === "top" ? "┌" : "└";
86
+ const right = edge === "top" ? "┐" : "┘";
87
+ return this.fg("borderMuted", `${left}${safeRepeat("─", innerWidth)}${right}`);
88
+ }
89
+ }
@@ -125,3 +125,21 @@ export class WidthKeyedCache {
125
125
  this.width = -1;
126
126
  }
127
127
  }
128
+
129
+ /** Shared ANSI escape codes for TUI overlays. */
130
+ export const ansi = {
131
+ reset: "\x1b[0m",
132
+ bold: "\x1b[1m",
133
+ dim: "\x1b[2m",
134
+ cyan: "\x1b[36m",
135
+ green: "\x1b[32m",
136
+ yellow: "\x1b[33m",
137
+ red: "\x1b[31m",
138
+ gray: "\x1b[90m",
139
+ white: "\x1b[37m",
140
+ blue: "\x1b[34m",
141
+ };
142
+
143
+ /** Toggle symbols for TUI settings overlays. */
144
+ export const TOGGLE_ON = `${ansi.green}●${ansi.reset}`;
145
+ export const TOGGLE_OFF = `${ansi.dim}○${ansi.reset}`;