@pi-archimedes/core 0.5.0 → 0.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-archimedes/core",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "keywords": [
6
6
  "pi-package"
package/src/index.ts CHANGED
@@ -3,7 +3,7 @@ import type { Theme } from "@earendil-works/pi-coding-agent";
3
3
  import { TUI, type EditorTheme, type Component, type SettingItem } from "@earendil-works/pi-tui";
4
4
 
5
5
  import { HephaestusEditor } from "./editor/index.js";
6
- import { patchUserMessage, resetInstanceCount } from "./message/index.js";
6
+
7
7
  import { renderHeader, patchStartupListing, type ListingRef } from "./startup/index.js";
8
8
  import { patchConsoleLog } from "./startup/capture.js";
9
9
  import { patchThinkingRenderer } from "./thinking/patch.js";
@@ -55,7 +55,6 @@ export function getCoreSettingsItems(config: CoreConfig): SettingItem[] {
55
55
 
56
56
  // Module-level state for session lifecycle (shared between session_start and session_shutdown)
57
57
  let coreRef: ListingRef | undefined;
58
- let coreResponseTimes: number[] | undefined;
59
58
  let coreCtx: ExtensionContext | undefined;
60
59
 
61
60
  export function registerCore(pi: ExtensionAPI): void {
@@ -70,12 +69,6 @@ export function registerCore(pi: ExtensionAPI): void {
70
69
  const listingRef = g["listingRef"] as ListingRef | undefined;
71
70
  if (listingRef) { listingRef.settled = true; }
72
71
 
73
- // Clear response times
74
- if (coreResponseTimes) { coreResponseTimes.length = 0; }
75
-
76
- // Reset instance count
77
- resetInstanceCount();
78
-
79
72
  // Clear editor component override
80
73
  if (coreCtx) { coreCtx.ui.setEditorComponent(undefined); }
81
74
  });
@@ -110,10 +103,6 @@ export function registerCore(pi: ExtensionAPI): void {
110
103
  };
111
104
  ctx.ui.setHeader(headerFactory);
112
105
 
113
- // Shared response times array (used by both patchUserMessage and message_end)
114
- coreResponseTimes = [];
115
- const responseTimes = coreResponseTimes;
116
-
117
106
  // Set editor component
118
107
  ctx.ui.setEditorComponent((tui: TUI, editorTheme: EditorTheme, keybindings: KeybindingsManager) => {
119
108
  const theme = ctx.ui.theme;
@@ -127,9 +116,6 @@ export function registerCore(pi: ExtensionAPI): void {
127
116
  // Patch thinking renderer
128
117
  patchThinkingRenderer(() => ctx.ui.theme);
129
118
 
130
- // Patch user message response time
131
- patchUserMessage(() => ctx.ui.theme, responseTimes);
132
-
133
119
  // Load config for thinking transformation
134
120
  const config = loadCoreConfig();
135
121
 
@@ -139,13 +125,6 @@ export function registerCore(pi: ExtensionAPI): void {
139
125
  if (config.codeUnindent) {
140
126
  transformThinkingContent(event.message as any);
141
127
  }
142
-
143
- // Track response time from the raw message
144
- const rawMsg = event.message as any;
145
- if (rawMsg.duration) {
146
- const idx = rawMsg.instanceIndex ?? responseTimes.length;
147
- responseTimes[idx] = rawMsg.duration;
148
- }
149
128
  });
150
129
  });
151
130
  }
@@ -5,7 +5,6 @@ import { detectSection, parseSectionText, parseModelScope, formatColumns, buildI
5
5
  import { fetchLatestVersion, compareVersions } from "./version.js";
6
6
  import { patchConsoleLog } from "./capture.js";
7
7
  import { stripAnsi } from "../text.js";
8
- import { resetInstanceCount } from "../message/index.js";
9
8
  import { Text, Spacer, Container, TUI, truncateToWidth, visibleWidth, type Component } from "@earendil-works/pi-tui";
10
9
 
11
10
  // Symbol keys (survive hot-reload)
@@ -216,12 +215,11 @@ export function patchStartupListing(
216
215
  }
217
216
  });
218
217
 
219
- // Patch clear() to reset message instance tracking on container rebuild
218
+ // Patch clear() to intercept container rebuild
220
219
  if (!cc[PATCHED_CLEAR]) {
221
220
  cc[PATCHED_CLEAR] = true;
222
221
  const origClear = chat.clear.bind(chat);
223
222
  chat.clear = () => {
224
- resetInstanceCount();
225
223
  return origClear();
226
224
  };
227
225
  }
@@ -1,147 +0,0 @@
1
- import type { Theme, UserMessageComponent } from "@earendil-works/pi-coding-agent";
2
- import { VERSION } from "@earendil-works/pi-coding-agent";
3
- import { RESET, resolvePalette, setThemeBg } from "../chrome.js";
4
-
5
- type UserMsgCtor = typeof UserMessageComponent & { [PATCHED]?: boolean; [PATCH_VERSION]?: string };
6
-
7
- // ── Constants ──────────────────────────────────────────────
8
-
9
- const PATCHED = Symbol.for("splashscreen:userMsgPatched");
10
- const PATCH_VERSION = Symbol.for("splashscreen:userMsgPatchVersion");
11
- // Match OSC133 B (zone end) or C (zone final). v0.67 moved these from line
12
- // tail to line head — we strip from wherever they sit and re-emit at the end.
13
- const OSC133_RE = /\x1b\]133;[BC]\x07/g;
14
- const MSG_PADDING_X = 3;
15
- const TIME_COL = 9;
16
-
17
- // ── Instance tracking ──────────────────────────────────────
18
-
19
- const instanceIndex = new WeakMap<object, number>();
20
- let instanceCount = 0;
21
-
22
- export function resetInstanceCount(): void {
23
- instanceCount = 0;
24
- }
25
-
26
- function formatTime(ms: number): string {
27
- if (ms < 1000) return `${ms}ms`;
28
- if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
29
- const m = Math.floor(ms / 60000);
30
- const s = Math.round((ms % 60000) / 1000);
31
- return `${m}m ${s}s`;
32
- }
33
-
34
- // ── Patch ──────────────────────────────────────────────────
35
-
36
- export function patchUserMessage(
37
- getTheme: () => Theme,
38
- responseTimes: number[],
39
- ): void {
40
- try {
41
- let lastBg = "";
42
- const theme = getTheme();
43
- const p = resolvePalette(theme);
44
- lastBg = p.panelBg;
45
- setThemeBg(theme, "userMessageBg", lastBg);
46
-
47
- import("@earendil-works/pi-coding-agent").then(
48
- ({ UserMessageComponent }: { UserMessageComponent: UserMsgCtor }) => {
49
- const currentVersion = VERSION ?? "unknown";
50
- const patchVersion = UserMessageComponent[PATCH_VERSION];
51
- // Skip if already patched for this version
52
- if (UserMessageComponent[PATCHED] && patchVersion === currentVersion) return;
53
- if (UserMessageComponent[PATCHED] && patchVersion && patchVersion !== currentVersion) {
54
- console.warn(`[archimedes] Re-patching user message: pi version changed ${patchVersion} → ${currentVersion}`);
55
- }
56
-
57
- if (
58
- typeof UserMessageComponent.prototype.addChild !== "function" ||
59
- typeof UserMessageComponent.prototype.render !== "function"
60
- ) {
61
- console.warn("[splashscreen] UserMessageComponent shape changed — skipping patch");
62
- return;
63
- }
64
-
65
- UserMessageComponent[PATCHED] = true;
66
- UserMessageComponent[PATCH_VERSION] = currentVersion;
67
-
68
- const origAddChild = UserMessageComponent.prototype.addChild;
69
- UserMessageComponent.prototype.addChild = function (child: any) {
70
- if (child.paddingX !== undefined && !child._hephaestusPatched) {
71
- child.paddingX = MSG_PADDING_X;
72
- child._hephaestusPatched = true;
73
- }
74
- if (!instanceIndex.has(this)) {
75
- instanceIndex.set(this, instanceCount++);
76
- }
77
- return origAddChild.call(this, child);
78
- };
79
-
80
- const origRender = UserMessageComponent.prototype.render;
81
- UserMessageComponent.prototype.render = function (
82
- width: number,
83
- ): string[] {
84
- try {
85
- const currentTheme = getTheme();
86
- const p = resolvePalette(currentTheme);
87
- const bg = p.panelBg;
88
- if (bg !== lastBg) { setThemeBg(currentTheme, "userMessageBg", bg); lastBg = bg; }
89
-
90
- const idx = instanceIndex.get(this);
91
- const elapsed = idx !== undefined ? (responseTimes[idx] ?? 0) : 0;
92
- const hasTime = idx !== undefined;
93
-
94
- const contentWidth = width - TIME_COL;
95
- const lines: string[] = origRender.call(this, contentWidth);
96
- if (lines.length < 3) return lines;
97
-
98
- const timeStr = elapsed > 0 ? formatTime(elapsed) : "";
99
- const timeRight = 2;
100
- const timeLabel = timeStr.length > 0 ? p.time(timeStr) : "";
101
- // Column that shows "42ms" right-aligned with bg — spaces for visual
102
- // alignment remain, but they're wrapped in panelBg so the copy buffer
103
- // only contains the label text.
104
- const timeContent =
105
- p.panelBg +
106
- " ".repeat(Math.max(0, TIME_COL - timeStr.length - timeRight)) +
107
- timeLabel +
108
- " ".repeat(timeRight);
109
- // Use \x1b[K (erase-to-end-of-line) instead of literal spaces for the
110
- // gap between content and time column. Visually fills with panelBg but
111
- // leaves nothing in the copy buffer.
112
- const gapFill = p.panelBg + "\x1b[K";
113
- // Empty column: just bg fill to the end — no spaces in copy buffer
114
- const emptyTimeCol = p.panelBg + "\x1b[K";
115
-
116
- const firstContent = 0;
117
-
118
- for (let i = 0; i < lines.length; i++) {
119
- let line = lines[i]!;
120
-
121
- // Extract any OSC133 B/C markers (shell zone end/final). v0.67 placed
122
- // these at the head of the last line; older versions at the tail.
123
- // Strip them from the content line; re-emit after the time column.
124
- const oscMatches = line.match(OSC133_RE);
125
- const oscSuffix = oscMatches ? oscMatches.join("") : "";
126
- if (oscSuffix) line = line.replace(OSC133_RE, "");
127
-
128
- // Strip trailing spaces from the content portion (PI pads to contentWidth
129
- // with plain spaces) and replace with \x1b[K for visual fill without spaces
130
- // in the copy buffer.
131
- const strippedLine = line.replace(/((?:\x1b\[[\d;]*m)*)\s+$/, "$1");
132
- const col = i === firstContent && hasTime ? timeContent : emptyTimeCol;
133
- lines[i] = strippedLine + gapFill + col + oscSuffix;
134
- }
135
-
136
- return lines;
137
- } catch {
138
- // During /resume, getTheme() may throw — fall back to default render
139
- return origRender.call(this, width);
140
- }
141
- };
142
- },
143
- );
144
- } catch {
145
- /* skip if theme not ready */
146
- }
147
- }