@yanzc/claude-pro 0.5.6 → 0.5.8
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/README.md +3 -1
- package/package.json +1 -1
- package/src/agent.js +2 -0
- package/src/api.js +591 -591
- package/src/cache.js +17 -0
- package/src/commands.js +1 -1
- package/src/session.js +8 -0
- package/src/ui/ansi.js +2 -0
- package/src/ui/render.js +8 -3
- package/src/ui/repl.js +2327 -2205
- package/src/ui/screen.js +184 -7
package/src/cache.js
CHANGED
|
@@ -80,6 +80,7 @@ export class CacheStats {
|
|
|
80
80
|
this.ttl = '5m';
|
|
81
81
|
this.model = null; // the model that answered the last request
|
|
82
82
|
this.effort = null;
|
|
83
|
+
this.clockUntil = null; // the footer's prompt cache clock (see clock): null shows none
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
// The history was cut or replaced (compaction, /rewind, /resume): the next request will not find the old
|
|
@@ -88,6 +89,21 @@ export class CacheStats {
|
|
|
88
89
|
this.expected = null;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// A compaction replaced the conversation: none of it is in the cache until the next response.
|
|
93
|
+
noteCompacted() {
|
|
94
|
+
this.noteRewrite();
|
|
95
|
+
if (this.clockUntil != null) this.clockUntil = 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// The prompt cache clock of the footer, as in Claude Code's VS Code extension: the minutes left before what
|
|
99
|
+
// the last request left in the cache runs out (each response that used the cache starts it again), or cold
|
|
100
|
+
// once it has run out and right after a compaction, until the next response. null before any response
|
|
101
|
+
// reported cache use. A resumed conversation starts from the clockUntil its session file kept.
|
|
102
|
+
clock(now = Date.now()) {
|
|
103
|
+
if (this.clockUntil == null) return null;
|
|
104
|
+
return now < this.clockUntil ? { minutes: Math.ceil((this.clockUntil - now) / 60_000) } : { cold: true };
|
|
105
|
+
}
|
|
106
|
+
|
|
91
107
|
// One finished request. `at` is when it started: the TTL counts from there, not from the end of the reply.
|
|
92
108
|
record({ usage, fingerprint: fp = null, ttl = '5m', caching = true, at = Date.now() }) {
|
|
93
109
|
const u = usage || {};
|
|
@@ -107,6 +123,7 @@ export class CacheStats {
|
|
|
107
123
|
this.expected = caching ? read + write : null;
|
|
108
124
|
this.expiresAt = at + TTL_MS[ttl];
|
|
109
125
|
this.ttl = ttl;
|
|
126
|
+
if (caching && (read || write)) this.clockUntil = this.expiresAt;
|
|
110
127
|
if (fp) {
|
|
111
128
|
this.prev = fp;
|
|
112
129
|
this.model = fp.model;
|
package/src/commands.js
CHANGED
|
@@ -624,7 +624,7 @@ export function buildCommands(app) {
|
|
|
624
624
|
reloadConfig();
|
|
625
625
|
app.screen.setFull(want === 'fullscreen');
|
|
626
626
|
out(want === 'fullscreen'
|
|
627
|
-
? `Fullscreen: the input box stays at the bottom; scroll with the wheel, PgUp/PgDn, ctrl+Home/End
|
|
627
|
+
? `Fullscreen: the input box stays at the bottom; scroll with the wheel, PgUp/PgDn, ctrl+Home/End; drag to select and copy; ctrl+f to find in the conversation. (Saved in ${file})`
|
|
628
628
|
: `Default renderer: the conversation scrolls in the terminal. (Saved in ${file})`);
|
|
629
629
|
},
|
|
630
630
|
});
|
package/src/session.js
CHANGED
|
@@ -79,6 +79,13 @@ export class SessionStore {
|
|
|
79
79
|
reset(messages) { this.append({ type: 'reset', messages, at: Date.now() }); }
|
|
80
80
|
// What the conversation's requests have cost so far (USD, see pricing.js), written after each one; the newest wins.
|
|
81
81
|
setCost(usd) { this.append({ type: 'meta', cost: usd, at: Date.now() }); }
|
|
82
|
+
// Until when the conversation's prompt cache lasts (ms since epoch; 0: cold), for the footer's clock of a
|
|
83
|
+
// resumed conversation (see CacheStats.clock). Written after each of its requests and compactions.
|
|
84
|
+
setCacheUntil(until) {
|
|
85
|
+
if (until == null || until === this.cacheUntil) return;
|
|
86
|
+
this.cacheUntil = until;
|
|
87
|
+
this.append({ type: 'meta', cacheUntil: until, at: Date.now() });
|
|
88
|
+
}
|
|
82
89
|
// The system prompt this conversation runs behind, kept so that a resumed one continues behind the same prompt
|
|
83
90
|
// and so with the prompt cache it already has (see runtime.resumeSystemPrompt). Written when it first appears
|
|
84
91
|
// and whenever it changes (after a compaction); the newest one wins when the session is loaded.
|
|
@@ -117,6 +124,7 @@ export class SessionStore {
|
|
|
117
124
|
name: typeof meta.name === 'string' && meta.name.trim() ? meta.name : null,
|
|
118
125
|
systemPrompt: typeof meta.systemPrompt === 'string' && meta.systemPrompt.trim() ? meta.systemPrompt : null,
|
|
119
126
|
cost: Number(meta.cost) > 0 ? Number(meta.cost) : 0,
|
|
127
|
+
cacheUntil: Number.isFinite(meta.cacheUntil) && meta.cacheUntil >= 0 ? meta.cacheUntil : null,
|
|
120
128
|
};
|
|
121
129
|
}
|
|
122
130
|
|
package/src/ui/ansi.js
CHANGED
|
@@ -51,6 +51,8 @@ export const c = {
|
|
|
51
51
|
plan: hex('#48968c'),
|
|
52
52
|
edits: hex('#af87ff'),
|
|
53
53
|
code: hex('#b1b9f9'),
|
|
54
|
+
userBg: hex('#373737', true), // the band behind the user's messages (see renderUserMessage)
|
|
55
|
+
userText: hex('#e4e4e4'),
|
|
54
56
|
diffAdd: hex('#225c2b', true),
|
|
55
57
|
diffDel: hex('#7a2936', true),
|
|
56
58
|
diffAddWord: hex('#38a660', true),
|
package/src/ui/render.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Formatting of transcript items: user prompts, tool calls and results, diffs, todos.
|
|
2
2
|
|
|
3
|
-
import { c, stringWidth, truncate, padEnd, wordWrap, wrapLine } from './ansi.js';
|
|
3
|
+
import { c, colorEnabled, stringWidth, truncate, padEnd, wordWrap, wrapLine } from './ansi.js';
|
|
4
4
|
import { displayPath } from '../utils/paths.js';
|
|
5
5
|
import { renderMarkdown } from './markdown.js';
|
|
6
6
|
|
|
@@ -129,14 +129,19 @@ export function renderToolResult(entry, { verbose = false, width = 100, cwd }) {
|
|
|
129
129
|
return resultLines(shown);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
// What the user wrote, on a band of background colour across the window, so that it stands apart from the replies
|
|
133
|
+
// (as in Claude Code). The band is the rest of each row erased in that colour (\x1b[K), which needs no padding and
|
|
134
|
+
// so fits any width the window is given later.
|
|
135
|
+
const userRow = (s) => (colorEnabled ? c.userBg(s + '\x1b[K') : s);
|
|
136
|
+
|
|
132
137
|
export function renderUserMessage(text, width) {
|
|
133
138
|
const lines = text.replace(/\r\n/g, '\n').split('\n');
|
|
134
139
|
const out = [];
|
|
135
140
|
lines.forEach((l, i) => {
|
|
136
141
|
const wrapped = wordWrap(l, Math.max(10, width - 3));
|
|
137
|
-
wrapped.forEach((wl, j) => out.push((i === 0 && j === 0 ? c.gray('> ') : ' ') + c.
|
|
142
|
+
wrapped.forEach((wl, j) => out.push(userRow((i === 0 && j === 0 ? c.gray('> ') : ' ') + c.userText(wl))));
|
|
138
143
|
});
|
|
139
|
-
if (out.length > 30) return [...out.slice(0, 25), c.
|
|
144
|
+
if (out.length > 30) return [...out.slice(0, 25), userRow(c.gray(` … +${out.length - 25} lines`))];
|
|
140
145
|
return out;
|
|
141
146
|
}
|
|
142
147
|
|