@thedevlabs-io/labd 0.6.1 → 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/README.md +1 -1
- package/dist/labd.js +241 -11
- package/dist/labd.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -129,7 +129,7 @@ more columns.
|
|
|
129
129
|
| `/sessions`, `/session` | earlier sessions here (a dialog; `enter` resumes); where this one is stored |
|
|
130
130
|
| `/new` | start a fresh session; the current one stays saved |
|
|
131
131
|
| `/sidebar`, `/clear` | show or hide the side panel; clear the screen |
|
|
132
|
-
| `/usage` | what's left of this month's allowance |
|
|
132
|
+
| `/usage` | what's left of this month's allowance, and a heatmap of your activity |
|
|
133
133
|
| `/trust` | let this project load its own extensions |
|
|
134
134
|
| `/reload` | reload extensions and the file list |
|
|
135
135
|
| `/quit` | leave - the session is saved, and `labd --resume <id>` continues it |
|
package/dist/labd.js
CHANGED
|
@@ -3,6 +3,117 @@
|
|
|
3
3
|
// packages/cli/src/index.ts
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
|
|
6
|
+
// vendor/labd/packages/protocol/src/activity.ts
|
|
7
|
+
var ACTIVITY_WEEKS = 53;
|
|
8
|
+
function utcOffsetMinutes(at2 = /* @__PURE__ */ new Date()) {
|
|
9
|
+
return -at2.getTimezoneOffset();
|
|
10
|
+
}
|
|
11
|
+
var DAY_MS = 864e5;
|
|
12
|
+
function localDate(at2 = /* @__PURE__ */ new Date()) {
|
|
13
|
+
const pad4 = (n) => String(n).padStart(2, "0");
|
|
14
|
+
return `${at2.getFullYear()}-${pad4(at2.getMonth() + 1)}-${pad4(at2.getDate())}`;
|
|
15
|
+
}
|
|
16
|
+
function dayNumber(date) {
|
|
17
|
+
return Math.floor(Date.parse(`${date}T00:00:00Z`) / DAY_MS);
|
|
18
|
+
}
|
|
19
|
+
function dateOf(day) {
|
|
20
|
+
return new Date(day * DAY_MS).toISOString().slice(0, 10);
|
|
21
|
+
}
|
|
22
|
+
function summariseActivity(activity, weeks, today = localDate()) {
|
|
23
|
+
const span = Math.max(1, Math.min(ACTIVITY_WEEKS, Math.floor(weeks)));
|
|
24
|
+
const last = dayNumber(today);
|
|
25
|
+
const monday = last - (last + 3) % 7;
|
|
26
|
+
const first = monday - (span - 1) * 7;
|
|
27
|
+
const earliest = monday - (ACTIVITY_WEEKS - 1) * 7;
|
|
28
|
+
const perDay = /* @__PURE__ */ new Map();
|
|
29
|
+
const perSurface = /* @__PURE__ */ new Map();
|
|
30
|
+
const totals = { turns: 0, input: 0, output: 0, activeDays: 0 };
|
|
31
|
+
for (const bucket of activity.days) {
|
|
32
|
+
const day = dayNumber(bucket.day);
|
|
33
|
+
if (!(day >= earliest && day <= last)) continue;
|
|
34
|
+
const tokens = bucket.input + bucket.output;
|
|
35
|
+
const d = perDay.get(day) ?? { turns: 0, tokens: 0 };
|
|
36
|
+
d.turns += bucket.turns;
|
|
37
|
+
d.tokens += tokens;
|
|
38
|
+
perDay.set(day, d);
|
|
39
|
+
if (day < first) continue;
|
|
40
|
+
const s = perSurface.get(bucket.surface) ?? { turns: 0, tokens: 0 };
|
|
41
|
+
s.turns += bucket.turns;
|
|
42
|
+
s.tokens += tokens;
|
|
43
|
+
perSurface.set(bucket.surface, s);
|
|
44
|
+
totals.turns += bucket.turns;
|
|
45
|
+
totals.input += bucket.input;
|
|
46
|
+
totals.output += bucket.output;
|
|
47
|
+
}
|
|
48
|
+
let run = 0;
|
|
49
|
+
let longest = 0;
|
|
50
|
+
for (let day = earliest; day <= last; day++) {
|
|
51
|
+
if ((perDay.get(day)?.turns ?? 0) > 0) {
|
|
52
|
+
run += 1;
|
|
53
|
+
longest = Math.max(longest, run);
|
|
54
|
+
} else if (day !== last) {
|
|
55
|
+
run = 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const shown = [...perDay.entries()].filter(([day]) => day >= first).map(([, d]) => d.tokens);
|
|
59
|
+
const ranked = [...new Set(shown.filter((t) => t > 0))].sort((a, b) => a - b);
|
|
60
|
+
const days = [];
|
|
61
|
+
let busiest = null;
|
|
62
|
+
for (let day = first; day <= last; day++) {
|
|
63
|
+
const d = perDay.get(day) ?? { turns: 0, tokens: 0 };
|
|
64
|
+
const entry = { date: dateOf(day), turns: d.turns, tokens: d.tokens, level: levelFor(d.tokens, ranked) };
|
|
65
|
+
days.push(entry);
|
|
66
|
+
if (d.turns > 0) totals.activeDays += 1;
|
|
67
|
+
if (d.tokens > 0 && (!busiest || d.tokens > busiest.tokens)) busiest = entry;
|
|
68
|
+
}
|
|
69
|
+
const hours = activity.hours.length === 24 ? activity.hours : [];
|
|
70
|
+
const peak = Math.max(0, ...hours);
|
|
71
|
+
return {
|
|
72
|
+
days,
|
|
73
|
+
totals,
|
|
74
|
+
streak: { current: run, longest },
|
|
75
|
+
peakHour: peak > 0 ? hours.indexOf(peak) : null,
|
|
76
|
+
busiest,
|
|
77
|
+
surfaces: [...perSurface.entries()].map(([surface, s]) => ({ surface, ...s })).sort((a, b) => b.tokens - a.tokens || a.surface.localeCompare(b.surface))
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function levelFor(tokens, ranked) {
|
|
81
|
+
if (!(tokens > 0)) return 0;
|
|
82
|
+
if (ranked.length === 1) return 4;
|
|
83
|
+
return 1 + Math.round(3 * ranked.indexOf(tokens) / (ranked.length - 1));
|
|
84
|
+
}
|
|
85
|
+
function formatTokens(n) {
|
|
86
|
+
const units = ["", "k", "M", "B"];
|
|
87
|
+
let value = n;
|
|
88
|
+
let unit = 0;
|
|
89
|
+
while (value >= 999.5 && unit < units.length - 1) {
|
|
90
|
+
value /= 1e3;
|
|
91
|
+
unit += 1;
|
|
92
|
+
}
|
|
93
|
+
const shown = unit === 0 || value >= 10 ? String(Math.round(value)) : value.toFixed(1).replace(/\.0$/, "");
|
|
94
|
+
return `${shown}${units[unit]}`;
|
|
95
|
+
}
|
|
96
|
+
function surfaceLabel(surface) {
|
|
97
|
+
switch (surface) {
|
|
98
|
+
case "web":
|
|
99
|
+
return "portal";
|
|
100
|
+
case "vscode":
|
|
101
|
+
return "editor";
|
|
102
|
+
case "cli":
|
|
103
|
+
return "terminal";
|
|
104
|
+
case "memory":
|
|
105
|
+
return "memory (background)";
|
|
106
|
+
case "api":
|
|
107
|
+
return "API";
|
|
108
|
+
default:
|
|
109
|
+
return surface;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function formatHour(hour) {
|
|
113
|
+
const h = hour % 12 === 0 ? 12 : hour % 12;
|
|
114
|
+
return `${h}${hour < 12 ? "am" : "pm"}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
6
117
|
// vendor/labd/packages/protocol/src/tags.ts
|
|
7
118
|
var TAG = /(^|[\s([])@(?:"([^"\n]+)"|([^\s"]+))/g;
|
|
8
119
|
var TRAILING = /[.,;:!?)\]}'"]+$/;
|
|
@@ -1556,8 +1667,6 @@ async function runTurn(question, opts) {
|
|
|
1556
1667
|
needTools = true;
|
|
1557
1668
|
return "go";
|
|
1558
1669
|
case "done":
|
|
1559
|
-
result.context = event.context;
|
|
1560
|
-
result.credits = event.credits;
|
|
1561
1670
|
ui.done?.({ credits: event.credits, context: event.context });
|
|
1562
1671
|
return "go";
|
|
1563
1672
|
case "error":
|
|
@@ -2001,6 +2110,18 @@ var AgentClient = class {
|
|
|
2001
2110
|
return null;
|
|
2002
2111
|
}
|
|
2003
2112
|
}
|
|
2113
|
+
/** The learner's usage by local hour, for the heatmap under `/usage`. */
|
|
2114
|
+
async activity(offsetMinutes) {
|
|
2115
|
+
try {
|
|
2116
|
+
const res = await this.fetch(`${this.opts.baseUrl}/v1/usage/activity?offset=${offsetMinutes}`, { headers: this.headers() });
|
|
2117
|
+
if (!res.ok) return null;
|
|
2118
|
+
const body2 = await res.json();
|
|
2119
|
+
if (!Array.isArray(body2.days) || !Array.isArray(body2.hours)) return null;
|
|
2120
|
+
return { days: body2.days.filter(isBucket), hours: body2.hours.map((n) => isCount(n) ? n : 0) };
|
|
2121
|
+
} catch {
|
|
2122
|
+
return null;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2004
2125
|
/**
|
|
2005
2126
|
* Tell the server this conversation is over and can be distilled into memory.
|
|
2006
2127
|
*
|
|
@@ -2078,6 +2199,13 @@ var AgentClient = class {
|
|
|
2078
2199
|
}
|
|
2079
2200
|
}
|
|
2080
2201
|
};
|
|
2202
|
+
function isBucket(value) {
|
|
2203
|
+
const b = value;
|
|
2204
|
+
return typeof b?.day === "string" && typeof b.surface === "string" && [b.turns, b.input, b.output].every(isCount);
|
|
2205
|
+
}
|
|
2206
|
+
function isCount(n) {
|
|
2207
|
+
return typeof n === "number" && Number.isFinite(n);
|
|
2208
|
+
}
|
|
2081
2209
|
|
|
2082
2210
|
// packages/tui/src/theme.ts
|
|
2083
2211
|
var ESC = "\x1B";
|
|
@@ -2103,6 +2231,14 @@ var paint = {
|
|
|
2103
2231
|
* Closes the foreground only, so it can sit inside a `band` without ending it.
|
|
2104
2232
|
*/
|
|
2105
2233
|
accent: wrap("38;5;214", "39"),
|
|
2234
|
+
/**
|
|
2235
|
+
* The heatmap's lower steps, walking the same orange down the cube towards
|
|
2236
|
+
* brown, with `accent` as the top one. The heatmap changes glyph with each
|
|
2237
|
+
* step too, so a light terminal where brown reads heavier is still legible.
|
|
2238
|
+
*/
|
|
2239
|
+
heat1: wrap("38;5;94", "39"),
|
|
2240
|
+
heat2: wrap("38;5;130", "39"),
|
|
2241
|
+
heat3: wrap("38;5;172", "39"),
|
|
2106
2242
|
bold: wrap("1", "22"),
|
|
2107
2243
|
dim: wrap("2", "22"),
|
|
2108
2244
|
muted: wrap("90"),
|
|
@@ -2383,8 +2519,7 @@ function statusLine(info2) {
|
|
|
2383
2519
|
if (info2.effort) bits.push(paint.muted(`think ${info2.effort}`));
|
|
2384
2520
|
const mode = info2.mode === "agent" ? paint.red(paint.bold("agent")) : info2.mode === "auto" ? paint.accent("auto") : paint.muted("ask");
|
|
2385
2521
|
bits.push(mode);
|
|
2386
|
-
|
|
2387
|
-
return `${left} ${paint.dim("|")} ${bits.join(paint.dim(" | "))}`;
|
|
2522
|
+
return `${paint.dim(FACE)} ${paint.dim("|")} ${bits.join(paint.dim(" | "))}`;
|
|
2388
2523
|
}
|
|
2389
2524
|
function spinnerFrame(tick) {
|
|
2390
2525
|
const dots = ".".repeat(tick % 3 + 1).padEnd(3);
|
|
@@ -3611,6 +3746,78 @@ var Viewport = class {
|
|
|
3611
3746
|
}
|
|
3612
3747
|
};
|
|
3613
3748
|
|
|
3749
|
+
// packages/tui/src/heatmap.ts
|
|
3750
|
+
var INDENT = " ";
|
|
3751
|
+
var DAY_LABEL = ["Mon", " ", "Wed", " ", "Fri", " ", "Sun"];
|
|
3752
|
+
var GUTTER = INDENT.length + 4;
|
|
3753
|
+
var MIN_WEEKS = 4;
|
|
3754
|
+
var GLYPH = { 0: "\xB7", 1: "\u2591", 2: "\u2592", 3: "\u2593", 4: "\u2588" };
|
|
3755
|
+
var SHADE = {
|
|
3756
|
+
0: paint.dim,
|
|
3757
|
+
1: paint.heat1,
|
|
3758
|
+
2: paint.heat2,
|
|
3759
|
+
3: paint.heat3,
|
|
3760
|
+
4: paint.accent
|
|
3761
|
+
};
|
|
3762
|
+
function heatmapWeeks(width) {
|
|
3763
|
+
return Math.max(MIN_WEEKS, Math.min(ACTIVITY_WEEKS, Math.floor((width - GUTTER) / 2)));
|
|
3764
|
+
}
|
|
3765
|
+
function heatmapLines(summary, width) {
|
|
3766
|
+
const { days, totals, streak } = summary;
|
|
3767
|
+
const columns = Math.ceil(days.length / 7);
|
|
3768
|
+
const lines = [`${INDENT}${paint.muted(`last ${columns} weeks`)}`, `${" ".repeat(GUTTER)}${monthRow(days, columns)}`];
|
|
3769
|
+
for (let row2 = 0; row2 < 7; row2++) {
|
|
3770
|
+
let cells = "";
|
|
3771
|
+
for (let column = 0; column < columns; column++) {
|
|
3772
|
+
const day = days[column * 7 + row2];
|
|
3773
|
+
cells += day ? `${SHADE[day.level](GLYPH[day.level])} ` : " ";
|
|
3774
|
+
}
|
|
3775
|
+
lines.push(`${INDENT}${paint.dim(DAY_LABEL[row2])} ${cells.trimEnd()}`);
|
|
3776
|
+
}
|
|
3777
|
+
const legend = [0, 1, 2, 3, 4].map((l) => SHADE[l](GLYPH[l])).join(" ");
|
|
3778
|
+
lines.push(`${" ".repeat(GUTTER)}${paint.dim("less")} ${legend} ${paint.dim("more")}`, "");
|
|
3779
|
+
const row = (label2, value) => `${INDENT}${paint.muted(label2.padEnd(10))}${value}`;
|
|
3780
|
+
lines.push(
|
|
3781
|
+
row("tokens", `${paint.bold(formatTokens(totals.input + totals.output))} ${paint.dim(`${formatTokens(totals.input)} in \xB7 ${formatTokens(totals.output)} out`)}`),
|
|
3782
|
+
row("requests", `${paint.bold(String(totals.turns))} ${paint.dim(`on ${plural(totals.activeDays, "day")}`)}`),
|
|
3783
|
+
row("streak", `${paint.bold(plural(streak.current, "day"))} ${paint.dim(`longest ${plural(streak.longest, "day")}`)}`)
|
|
3784
|
+
);
|
|
3785
|
+
if (summary.busiest) {
|
|
3786
|
+
lines.push(row("busiest", `${paint.bold(dayName(summary.busiest.date))} ${paint.dim(`${formatTokens(summary.busiest.tokens)} tokens`)}`));
|
|
3787
|
+
}
|
|
3788
|
+
if (summary.peakHour !== null) lines.push(row("peak hour", paint.bold(formatHour(summary.peakHour))));
|
|
3789
|
+
const where = summary.surfaces.map((s) => `${surfaceLabel(s.surface)} ${paint.bold(formatTokens(s.tokens))}`);
|
|
3790
|
+
const joined = row("where", where.join(paint.dim(" \xB7 ")));
|
|
3791
|
+
if (!where.length) return lines;
|
|
3792
|
+
if (visibleWidth(joined) <= width) lines.push(joined);
|
|
3793
|
+
else where.forEach((w, i) => lines.push(row(i === 0 ? "where" : "", w)));
|
|
3794
|
+
return lines;
|
|
3795
|
+
}
|
|
3796
|
+
function monthRow(days, columns) {
|
|
3797
|
+
const starts = [];
|
|
3798
|
+
for (let column = 0; column < columns; column++) {
|
|
3799
|
+
const week = days.slice(column * 7, column * 7 + 7);
|
|
3800
|
+
const first = column === 0 ? week[0] : week.find((d) => d.date.endsWith("-01"));
|
|
3801
|
+
if (first && column + 1 < columns) starts.push({ column, date: first.date });
|
|
3802
|
+
}
|
|
3803
|
+
if (starts.length > 1 && starts[1].column < 2) starts.shift();
|
|
3804
|
+
let out = "";
|
|
3805
|
+
for (const { column, date } of starts) {
|
|
3806
|
+
out = out.padEnd(column * 2) + localDay(date).toLocaleDateString("en-GB", { month: "short" }).slice(0, 3);
|
|
3807
|
+
}
|
|
3808
|
+
return paint.dim(out);
|
|
3809
|
+
}
|
|
3810
|
+
function localDay(date) {
|
|
3811
|
+
const [y, m, d] = date.split("-").map(Number);
|
|
3812
|
+
return new Date(y, m - 1, d);
|
|
3813
|
+
}
|
|
3814
|
+
function dayName(date) {
|
|
3815
|
+
return localDay(date).toLocaleDateString("en-GB", { day: "numeric", month: "short" });
|
|
3816
|
+
}
|
|
3817
|
+
function plural(n, word) {
|
|
3818
|
+
return `${n} ${word}${n === 1 ? "" : "s"}`;
|
|
3819
|
+
}
|
|
3820
|
+
|
|
3614
3821
|
// packages/tui/src/face.ts
|
|
3615
3822
|
var FACE_ART = [
|
|
3616
3823
|
" \u250F\u2501 \u2501\u2513 ",
|
|
@@ -4130,7 +4337,7 @@ var BUILTIN_COMMANDS = [
|
|
|
4130
4337
|
{ name: "session", what: "where this one is stored" },
|
|
4131
4338
|
{ name: "rename", args: "<name>", what: "name this session, so /sessions and --resume show it" },
|
|
4132
4339
|
{ name: "new", what: "start a fresh session; this one stays saved" },
|
|
4133
|
-
{ name: "usage", what: "what's left of this month's allowance" },
|
|
4340
|
+
{ name: "usage", what: "what's left of this month's allowance, and your activity" },
|
|
4134
4341
|
{ name: "trust", what: "let this project load its own extensions" },
|
|
4135
4342
|
{ name: "logout", what: "sign this machine out and leave" },
|
|
4136
4343
|
{ name: "reload", what: "reload extensions and the file list" },
|
|
@@ -4440,12 +4647,23 @@ async function handleCommand(input, ctx) {
|
|
|
4440
4647
|
return { effort: args };
|
|
4441
4648
|
}
|
|
4442
4649
|
case "usage": {
|
|
4443
|
-
const credits = await
|
|
4650
|
+
const [credits, activity] = await Promise.all([
|
|
4651
|
+
runtime.client.credits(),
|
|
4652
|
+
runtime.client.activity(utcOffsetMinutes())
|
|
4653
|
+
]);
|
|
4444
4654
|
if (!credits) {
|
|
4445
4655
|
print(` ${paint.muted("Couldn't check that just now.")}`);
|
|
4446
4656
|
} else {
|
|
4447
4657
|
print(` ${paint.bold(`${credits.percentLeft}%`)} ${paint.muted("of this month left")}`);
|
|
4448
4658
|
}
|
|
4659
|
+
if (activity && !activity.days.length) {
|
|
4660
|
+
print(` ${paint.muted("No activity yet. Ask labd something and it shows up here.")}`);
|
|
4661
|
+
} else if (activity) {
|
|
4662
|
+
print("");
|
|
4663
|
+
print(heatmapLines(summariseActivity(activity, heatmapWeeks(ctx.width)), ctx.width).join("\n"));
|
|
4664
|
+
} else if (credits) {
|
|
4665
|
+
print(` ${paint.muted("Couldn't read your activity just now.")}`);
|
|
4666
|
+
}
|
|
4449
4667
|
return {};
|
|
4450
4668
|
}
|
|
4451
4669
|
case "tree": {
|
|
@@ -4474,9 +4692,12 @@ async function handleCommand(input, ctx) {
|
|
|
4474
4692
|
print(` ${paint.yellow("!")} ${paint.muted(`no point here starts with "${args}"`)}`);
|
|
4475
4693
|
return {};
|
|
4476
4694
|
}
|
|
4695
|
+
const moved = match.id !== runtime.session.headId;
|
|
4477
4696
|
runtime.session.moveTo(match.id);
|
|
4478
|
-
print(
|
|
4479
|
-
|
|
4697
|
+
print(
|
|
4698
|
+
` ${paint.muted(moved ? `continuing from ${match.id.slice(0, 8)}. The other branch is still in the file.` : `already at ${match.id.slice(0, 8)}.`)}`
|
|
4699
|
+
);
|
|
4700
|
+
return { moved };
|
|
4480
4701
|
}
|
|
4481
4702
|
case "sessions": {
|
|
4482
4703
|
const bucket = dirname3(runtime.session.file);
|
|
@@ -4792,6 +5013,7 @@ async function runInteractive(runtime) {
|
|
|
4792
5013
|
mode: state.mode,
|
|
4793
5014
|
effort: state.effort,
|
|
4794
5015
|
asked: answered > 0,
|
|
5016
|
+
width: process.stdout.columns ?? 80,
|
|
4795
5017
|
print: (text) => renderer.print(text)
|
|
4796
5018
|
});
|
|
4797
5019
|
if (outcome.farewell) process.stderr.write(`${outcome.farewell}
|
|
@@ -4799,6 +5021,7 @@ async function runInteractive(runtime) {
|
|
|
4799
5021
|
if (outcome.exit) break;
|
|
4800
5022
|
if (outcome.mode) state.mode = outcome.mode;
|
|
4801
5023
|
if (outcome.effort !== void 0) state.effort = outcome.effort;
|
|
5024
|
+
if (outcome.moved) state.context = null;
|
|
4802
5025
|
continue;
|
|
4803
5026
|
}
|
|
4804
5027
|
const tags = taggedPaths(input);
|
|
@@ -4913,6 +5136,7 @@ async function runInteractive(runtime) {
|
|
|
4913
5136
|
if (state.context && state.context.percentUsed >= COMPACT_AT) {
|
|
4914
5137
|
startSpinner("summarising, to make room");
|
|
4915
5138
|
const ok = await compact({ session: runtime.session, client: runtime.client, root: runtime.root });
|
|
5139
|
+
if (ok) state.context = null;
|
|
4916
5140
|
stopSpinner();
|
|
4917
5141
|
renderer.print(paint.dim(ok ? " summarised the conversation so far." : " (could not summarise; carrying on)"));
|
|
4918
5142
|
}
|
|
@@ -5511,6 +5735,7 @@ async function runScreen(runtime, opts) {
|
|
|
5511
5735
|
mode: state.mode,
|
|
5512
5736
|
effort: state.effort,
|
|
5513
5737
|
asked: state.asked,
|
|
5738
|
+
width: layout({ rows: screen.rows, columns: screen.columns, editorLines: editor.lineCount, sidebar: state.sidebar }).transcript.width,
|
|
5514
5739
|
print: (text) => note(text)
|
|
5515
5740
|
});
|
|
5516
5741
|
if (outcome.farewell) state.farewell = outcome.farewell;
|
|
@@ -5520,6 +5745,7 @@ async function runScreen(runtime, opts) {
|
|
|
5520
5745
|
state.heldMode = null;
|
|
5521
5746
|
}
|
|
5522
5747
|
if (outcome.effort !== void 0) state.effort = outcome.effort;
|
|
5748
|
+
if (outcome.moved) state.context = null;
|
|
5523
5749
|
schedule();
|
|
5524
5750
|
}
|
|
5525
5751
|
function helpLines() {
|
|
@@ -5592,6 +5818,7 @@ async function runScreen(runtime, opts) {
|
|
|
5592
5818
|
if (state.asked) await closeConversation(runtime);
|
|
5593
5819
|
runtime.session = Session.open(file);
|
|
5594
5820
|
state.asked = false;
|
|
5821
|
+
state.context = null;
|
|
5595
5822
|
transcript.clear();
|
|
5596
5823
|
state.toolBlocks.clear();
|
|
5597
5824
|
state.answer = null;
|
|
@@ -5602,6 +5829,7 @@ async function runScreen(runtime, opts) {
|
|
|
5602
5829
|
if (state.asked) await closeConversation(runtime);
|
|
5603
5830
|
runtime.session = Session.create(bucketFor(runtime.stateDir, runtime.root));
|
|
5604
5831
|
state.asked = false;
|
|
5832
|
+
state.context = null;
|
|
5605
5833
|
transcript.clear();
|
|
5606
5834
|
state.toolBlocks.clear();
|
|
5607
5835
|
state.answer = null;
|
|
@@ -5728,8 +5956,10 @@ async function runScreen(runtime, opts) {
|
|
|
5728
5956
|
if (!abort.signal.aborted && state.context && state.context.percentUsed >= COMPACT_AT) {
|
|
5729
5957
|
setBusy("summarising, to make room");
|
|
5730
5958
|
const ok = await compact({ session: runtime.session, client: runtime.client, root: runtime.root });
|
|
5731
|
-
if (ok)
|
|
5732
|
-
|
|
5959
|
+
if (ok) {
|
|
5960
|
+
state.context = null;
|
|
5961
|
+
transcript.add({ kind: "compaction" });
|
|
5962
|
+
} else note(paint.dim(" (could not summarise; carrying on)"));
|
|
5733
5963
|
}
|
|
5734
5964
|
} catch (err) {
|
|
5735
5965
|
transcript.add({ kind: "error", text: err instanceof Error ? err.message : String(err) });
|
|
@@ -6153,7 +6383,7 @@ async function runRpc(runtime) {
|
|
|
6153
6383
|
}
|
|
6154
6384
|
|
|
6155
6385
|
// packages/cli/src/index.ts
|
|
6156
|
-
var VERSION = true ? "0.
|
|
6386
|
+
var VERSION = true ? "0.7.0" : "0.0.0-dev";
|
|
6157
6387
|
async function main(argv) {
|
|
6158
6388
|
const args = parse(argv);
|
|
6159
6389
|
if (args.color !== void 0) setColor(args.color);
|