@trenchwork/erosolar 1.1.54 → 1.1.56

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.
@@ -161,6 +161,10 @@ export interface IAgentController {
161
161
  * Clear conversation history
162
162
  */
163
163
  clearHistory(): void;
164
+ /**
165
+ * Restore a prior conversation into context (session resume)
166
+ */
167
+ loadHistory(history: ConversationMessage[]): void;
164
168
  }
165
169
  /**
166
170
  * Conversation message structure
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/contracts/v1/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/contracts/v1/agent.ts"],"names":[],"mappings":"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"}
@@ -21,4 +21,20 @@ export interface FileMentionResult {
21
21
  * there are no resolvable mentions.
22
22
  */
23
23
  export declare function expandFileMentions(prompt: string, workingDir: string): FileMentionResult;
24
+ /**
25
+ * List workspace files as repo-relative paths for @-mention completion. A
26
+ * bounded recursive walk (not a glob engine): skips heavy/vcs/build dirs and
27
+ * dot-directories, caps total files and depth so a giant tree can't stall the
28
+ * prompt. New files appear on the next rebuild of this list.
29
+ */
30
+ export declare function listWorkspaceFiles(workingDir: string, limit?: number, maxDepth?: number): string[];
31
+ /** The `@<partial>` immediately before the cursor, or null if none. '' = bare `@`. */
32
+ export declare function activeMentionPartial(text: string, cursor: number): string | null;
33
+ /** Files matching `partial`, ranked: basename-prefix < basename-substring < path-substring. */
34
+ export declare function rankFileMatches(partial: string, files: string[], limit?: number): string[];
35
+ /** Replace the active `@<partial>` (ending at cursor) with `@path ` (trailing space). */
36
+ export declare function applyMentionCompletion(text: string, cursor: number, path: string): {
37
+ text: string;
38
+ cursor: number;
39
+ };
24
40
  //# sourceMappingURL=fileMentions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileMentions.d.ts","sourceRoot":"","sources":["../../src/core/fileMentions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,CA4BxF"}
1
+ {"version":3,"file":"fileMentions.d.ts","sourceRoot":"","sources":["../../src/core/fileMentions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,CA4BxF;AAQD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,SAAO,EAAE,QAAQ,SAAI,GAAG,MAAM,EAAE,CAmB3F;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhF;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAerF;AAED,yFAAyF;AACzF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQnH"}
@@ -8,8 +8,8 @@
8
8
  * only the agent-bound copy is expanded — interactiveShell expands
9
9
  * `sanitizedPrompt` before `controller.send`.
10
10
  */
11
- import { readFileSync, statSync } from 'node:fs';
12
- import { isAbsolute, resolve } from 'node:path';
11
+ import { readFileSync, statSync, readdirSync } from 'node:fs';
12
+ import { isAbsolute, resolve, join, relative } from 'node:path';
13
13
  // Cap per file so a huge file can't blow the context; mentions over this are
14
14
  // skipped (the agent can still Read them on demand).
15
15
  const MAX_FILE_BYTES = 100 * 1024;
@@ -56,4 +56,81 @@ export function expandFileMentions(prompt, workingDir) {
56
56
  return { prompt, included: [] };
57
57
  return { prompt: `${prompt}\n\n--- Referenced files ---\n${blocks.join('\n\n')}`, included };
58
58
  }
59
+ // ── @-mention autocomplete (the typing layer) ────────────────────────────────
60
+ const IGNORE_DIRS = new Set([
61
+ 'node_modules', '.git', 'dist', 'coverage', 'build', '.next', '.cache', '.erosolar', '.turbo', 'out',
62
+ ]);
63
+ /**
64
+ * List workspace files as repo-relative paths for @-mention completion. A
65
+ * bounded recursive walk (not a glob engine): skips heavy/vcs/build dirs and
66
+ * dot-directories, caps total files and depth so a giant tree can't stall the
67
+ * prompt. New files appear on the next rebuild of this list.
68
+ */
69
+ export function listWorkspaceFiles(workingDir, limit = 4000, maxDepth = 8) {
70
+ const out = [];
71
+ const walk = (dir, depth) => {
72
+ if (out.length >= limit || depth > maxDepth)
73
+ return;
74
+ let entries;
75
+ try {
76
+ entries = readdirSync(dir, { withFileTypes: true });
77
+ }
78
+ catch {
79
+ return;
80
+ }
81
+ for (const e of entries) {
82
+ if (out.length >= limit)
83
+ return;
84
+ const full = join(dir, e.name);
85
+ if (e.isDirectory()) {
86
+ if (IGNORE_DIRS.has(e.name) || e.name.startsWith('.'))
87
+ continue;
88
+ walk(full, depth + 1);
89
+ }
90
+ else if (e.isFile()) {
91
+ out.push(relative(workingDir, full));
92
+ }
93
+ }
94
+ };
95
+ walk(workingDir, 0);
96
+ return out;
97
+ }
98
+ /** The `@<partial>` immediately before the cursor, or null if none. '' = bare `@`. */
99
+ export function activeMentionPartial(text, cursor) {
100
+ const m = text.slice(0, Math.max(0, cursor)).match(/(?:^|\s)@([^\s@]*)$/);
101
+ return m ? (m[1] ?? '') : null;
102
+ }
103
+ /** Files matching `partial`, ranked: basename-prefix < basename-substring < path-substring. */
104
+ export function rankFileMatches(partial, files, limit = 8) {
105
+ const q = partial.toLowerCase();
106
+ if (!q)
107
+ return files.slice(0, limit);
108
+ const scored = [];
109
+ for (const f of files) {
110
+ const lf = f.toLowerCase();
111
+ const base = lf.slice(lf.lastIndexOf('/') + 1);
112
+ let score = -1;
113
+ if (base.startsWith(q))
114
+ score = 0;
115
+ else if (base.includes(q))
116
+ score = 1;
117
+ else if (lf.includes(q))
118
+ score = 2;
119
+ if (score >= 0)
120
+ scored.push({ f, score });
121
+ }
122
+ scored.sort((a, b) => a.score - b.score || a.f.length - b.f.length || (a.f < b.f ? -1 : 1));
123
+ return scored.slice(0, limit).map((s) => s.f);
124
+ }
125
+ /** Replace the active `@<partial>` (ending at cursor) with `@path ` (trailing space). */
126
+ export function applyMentionCompletion(text, cursor, path) {
127
+ const upto = text.slice(0, cursor);
128
+ const m = upto.match(/(?:^|\s)@([^\s@]*)$/);
129
+ if (!m)
130
+ return { text, cursor };
131
+ const atIdx = cursor - (m[1] ?? '').length - 1; // index of '@'
132
+ const before = text.slice(0, atIdx);
133
+ const insert = `@${path} `;
134
+ return { text: before + insert + text.slice(cursor), cursor: (before + insert).length };
135
+ }
59
136
  //# sourceMappingURL=fileMentions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileMentions.js","sourceRoot":"","sources":["../../src/core/fileMentions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,6EAA6E;AAC7E,qDAAqD;AACrD,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC;AAElC,0EAA0E;AAC1E,+EAA+E;AAC/E,0EAA0E;AAC1E,MAAM,OAAO,GAAG,mBAAmB,CAAC;AASpC,SAAS,iBAAiB,CAAC,CAAS;IAClC,OAAO,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,UAAkB;IACnE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAEtE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;IACtB,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEd,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,GAAG,cAAc;gBAAE,SAAS;YACvD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,cAAc,OAAO,UAAU,CAAC,CAAC;YACpD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;QACtE,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACzD,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,iCAAiC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;AAC/F,CAAC"}
1
+ {"version":3,"file":"fileMentions.js","sourceRoot":"","sources":["../../src/core/fileMentions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Compact "time ago" label for session timestamps (e.g. "3m ago", "2d ago").
3
+ * `now` is injectable so tests stay deterministic. Returns '' for unparseable
4
+ * input rather than throwing — a malformed session index must not crash the
5
+ * /resume picker.
6
+ */
7
+ export declare function relativeTime(iso: string, now?: number): string;
8
+ //# sourceMappingURL=relativeTime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relativeTime.d.ts","sourceRoot":"","sources":["../../src/core/relativeTime.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,CAgB1E"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Compact "time ago" label for session timestamps (e.g. "3m ago", "2d ago").
3
+ * `now` is injectable so tests stay deterministic. Returns '' for unparseable
4
+ * input rather than throwing — a malformed session index must not crash the
5
+ * /resume picker.
6
+ */
7
+ export function relativeTime(iso, now = Date.now()) {
8
+ const then = Date.parse(iso);
9
+ if (!Number.isFinite(then)) {
10
+ return '';
11
+ }
12
+ const sec = Math.max(0, Math.round((now - then) / 1000));
13
+ if (sec < 45)
14
+ return 'just now';
15
+ const min = Math.round(sec / 60);
16
+ if (min < 60)
17
+ return `${Math.max(1, min)}m ago`;
18
+ const hr = Math.round(min / 60);
19
+ if (hr < 24)
20
+ return `${hr}h ago`;
21
+ const day = Math.round(hr / 24);
22
+ if (day < 30)
23
+ return `${day}d ago`;
24
+ const mon = Math.round(day / 30);
25
+ if (mon < 12)
26
+ return `${mon}mo ago`;
27
+ return `${Math.round(mon / 12)}y ago`;
28
+ }
29
+ //# sourceMappingURL=relativeTime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relativeTime.js","sourceRoot":"","sources":["../../src/core/relativeTime.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAc,IAAI,CAAC,GAAG,EAAE;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACzD,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,UAAU,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IACjC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IAChD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IAChC,IAAI,EAAE,GAAG,EAAE;QAAE,OAAO,GAAG,EAAE,OAAO,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAChC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,GAAG,GAAG,OAAO,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IACjC,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,GAAG,GAAG,QAAQ,CAAC;IACpC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC;AACxC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/headless/interactiveShell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoJH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA0CD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAErE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDzF"}
1
+ {"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/headless/interactiveShell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAsJH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA0CD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAErE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDzF"}
@@ -30,9 +30,11 @@ const exitCriticalSection = (_name) => { };
30
30
  import { authorizedShutdown, installSignalHandlers, onShutdown } from '../core/shutdown.js';
31
31
  import { resolveProfileConfig } from '../config.js';
32
32
  import { createAgentController } from '../runtime/agentController.js';
33
- import { expandFileMentions } from '../core/fileMentions.js';
33
+ import { expandFileMentions, listWorkspaceFiles } from '../core/fileMentions.js';
34
34
  import { resolveWorkspaceCaptureOptions, buildWorkspaceContext } from '../workspace.js';
35
35
  import { loadAllSecrets, listSecretDefinitions, setSecretValue, getSecretValue } from '../core/secretStore.js';
36
+ import { listSessions, loadSessionById, saveSessionSnapshot } from '../core/sessionStore.js';
37
+ import { relativeTime } from '../core/relativeTime.js';
36
38
  import { getConfiguredProviders, getProvidersStatus, quickCheckProviders, getCachedDiscoveredModels, sortModelsByPriority } from '../core/modelDiscovery.js';
37
39
  import { saveModelPreference } from '../core/preferences.js';
38
40
  import { setDebugMode, debugSnippet } from '../utils/debugLogger.js';
@@ -240,6 +242,10 @@ class InteractiveShell {
240
242
  shouldExit = false;
241
243
  pendingPrompts = [];
242
244
  debugEnabled = false;
245
+ // Stable id for THIS run's persisted session, so each autosave updates the
246
+ // same snapshot in place. Assigned from the first saveSessionSnapshot; set
247
+ // to a resumed session's id after /resume so the restored thread continues.
248
+ sessionId = null;
243
249
  ctrlCCount = 0;
244
250
  lastCtrlCTime = 0;
245
251
  // Set when the user Ctrl+C interrupts a run; suppresses the auto-continue
@@ -372,6 +378,12 @@ class InteractiveShell {
372
378
  // Start the UI
373
379
  this.promptController.start();
374
380
  this.applyDebugState(this.debugEnabled);
381
+ // Build the @-mention completion file list (bounded walk; new files appear
382
+ // on the next launch). Best-effort — a scan failure must not block the UI.
383
+ try {
384
+ this.promptController.setCompletionFiles(listWorkspaceFiles(this.workingDir));
385
+ }
386
+ catch { /* ignore — completion is a convenience */ }
375
387
  // Set up sudo password prompt handler
376
388
  this.setupSudoPasswordHandler();
377
389
  // Set initial status
@@ -829,6 +841,12 @@ class InteractiveShell {
829
841
  this.showKeyboardShortcuts();
830
842
  return true;
831
843
  }
844
+ // /resume — pick a saved conversation and restore its full history into
845
+ // context (the agent continues where it left off).
846
+ if (lower === '/resume' || lower === '/sessions') {
847
+ this.handleResume();
848
+ return true;
849
+ }
832
850
  // Everything is on by default for max performance — there are no toggles.
833
851
  // Ultracode + max thought, the adversarial verifier, and auto-continue all
834
852
  // run under the hood. The /auto, /adversarial, /debug, /ultracode, /model,
@@ -1251,6 +1269,79 @@ class InteractiveShell {
1251
1269
  }, 500);
1252
1270
  }
1253
1271
  }
1272
+ /**
1273
+ * Snapshot the live conversation to the session store so /resume can
1274
+ * restore it later. Best-effort: a persistence failure must never break a
1275
+ * turn, so everything is wrapped. Skips empty/system-only histories so we
1276
+ * don't litter the picker with sessions that have no real exchange.
1277
+ */
1278
+ persistSessionSnapshot() {
1279
+ try {
1280
+ const messages = this.controller.getHistory();
1281
+ if (!messages.some((m) => m.role === 'user')) {
1282
+ return;
1283
+ }
1284
+ const summary = saveSessionSnapshot({
1285
+ id: this.sessionId,
1286
+ profile: this.profile,
1287
+ provider: this.profileConfig.provider,
1288
+ model: this.profileConfig.model,
1289
+ workspaceRoot: this.workingDir,
1290
+ messages,
1291
+ });
1292
+ this.sessionId = summary.id;
1293
+ }
1294
+ catch {
1295
+ // best-effort persistence — never interrupt the user's turn
1296
+ }
1297
+ }
1298
+ /**
1299
+ * /resume — present saved conversations newest-first and restore the
1300
+ * chosen one's full message history into the agent's context.
1301
+ */
1302
+ handleResume() {
1303
+ const renderer = this.promptController?.getRenderer();
1304
+ const sessions = listSessions().filter((s) => s.id !== this.sessionId && s.messageCount > 0);
1305
+ if (sessions.length === 0) {
1306
+ renderer?.addEvent('system', chalk.dim('No saved conversations to resume yet.'));
1307
+ return;
1308
+ }
1309
+ const items = sessions.slice(0, 25).map((s) => ({
1310
+ id: s.id,
1311
+ label: s.title,
1312
+ description: `${s.messageCount} msg · ${relativeTime(s.updatedAt)}`,
1313
+ }));
1314
+ this.promptController?.setMenu(items, { title: 'Resume a conversation' }, (selected) => {
1315
+ if (selected) {
1316
+ this.resumeSession(selected.id);
1317
+ }
1318
+ });
1319
+ }
1320
+ /**
1321
+ * Load a saved session by id, restore its history into the controller (and
1322
+ * thus the agent's context), and reprint the prior exchange so the user
1323
+ * sees where they left off.
1324
+ */
1325
+ resumeSession(id) {
1326
+ const renderer = this.promptController?.getRenderer();
1327
+ const stored = loadSessionById(id);
1328
+ if (!stored) {
1329
+ renderer?.addEvent('error', 'That conversation could not be loaded.');
1330
+ return;
1331
+ }
1332
+ this.controller.loadHistory(stored.messages);
1333
+ this.sessionId = stored.id;
1334
+ const restored = stored.messages.filter((m) => m.role === 'user' || m.role === 'assistant');
1335
+ renderer?.addEvent('system', chalk.dim(`Resumed "${stored.title}" — ${restored.length} message${restored.length === 1 ? '' : 's'} restored`));
1336
+ for (const m of stored.messages) {
1337
+ if (m.role === 'user') {
1338
+ renderer?.addUserHistoryItem(m.content);
1339
+ }
1340
+ else if (m.role === 'assistant' && m.content.trim()) {
1341
+ renderer?.addEvent('response', m.content);
1342
+ }
1343
+ }
1344
+ }
1254
1345
  showHelp() {
1255
1346
  if (!this.promptController?.supportsInlinePanel()) {
1256
1347
  this.promptController?.setStatusMessage('Help: /key sk-… (everything else is automatic)');
@@ -1267,6 +1358,7 @@ class InteractiveShell {
1267
1358
  '',
1268
1359
  cmd('/key sk-…') + dim(' Set your DeepSeek API key'),
1269
1360
  cmd('/update') + dim(' Check npm and upgrade to the latest version'),
1361
+ cmd('/resume') + dim(' Restore a previous conversation'),
1270
1362
  '',
1271
1363
  dim('Everything else runs automatically for max performance —'),
1272
1364
  dim('deepseek-v4-pro · max thought · ultracode · adversarial verifier, all on.'),
@@ -1305,6 +1397,9 @@ class InteractiveShell {
1305
1397
  ` ${kb('Shift+Tab')} ${desc('Cycle permission mode (default · accept edits · plan)')}`,
1306
1398
  ` ${kb('Ctrl+O')} ${desc('Expand the last truncated tool result')}`,
1307
1399
  '',
1400
+ chalk.hex('#cbf24e')('Mentions'),
1401
+ ` ${kb('@')} ${desc('Autocomplete a file (↑/↓ · Tab/Enter); its content is inlined for the agent')}`,
1402
+ '',
1308
1403
  chalk.hex('#cbf24e')('Control'),
1309
1404
  ` ${kb('Ctrl+C')} ${desc('Clear input / interrupt')}`,
1310
1405
  ` ${kb('Ctrl+D')} ${desc('Exit (when empty)')}`,
@@ -1398,7 +1493,7 @@ class InteractiveShell {
1398
1493
  this.isProcessing = true;
1399
1494
  this.currentResponseBuffer = '';
1400
1495
  this.promptController?.setStreaming(true);
1401
- this.promptController?.setStatusMessage('🔄 Analyzing request...');
1496
+ this.promptController?.setStatusMessage('Analyzing request');
1402
1497
  const renderer = this.promptController?.getRenderer();
1403
1498
  let episodeSuccess = false;
1404
1499
  const toolsUsed = [];
@@ -1740,6 +1835,9 @@ class InteractiveShell {
1740
1835
  // Note: pendingPrompts may still have items if a drain just started
1741
1836
  // a new processPrompt; the new run will manage the list.
1742
1837
  this.currentResponseBuffer = '';
1838
+ // Autosave the conversation so /resume has something to restore. Each
1839
+ // turn updates the same snapshot in place (keyed by this.sessionId).
1840
+ this.persistSessionSnapshot();
1743
1841
  // Process any queued prompts (late safety net; primary drain is now per-turn
1744
1842
  // after each assistant response for "ASAP before the running prompt finishes").
1745
1843
  if (this.pendingPrompts.length > 0 && !this.shouldExit) {