@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.
- package/dist/contracts/v1/agent.d.ts +4 -0
- package/dist/contracts/v1/agent.d.ts.map +1 -1
- package/dist/core/fileMentions.d.ts +16 -0
- package/dist/core/fileMentions.d.ts.map +1 -1
- package/dist/core/fileMentions.js +79 -2
- package/dist/core/fileMentions.js.map +1 -1
- package/dist/core/relativeTime.d.ts +8 -0
- package/dist/core/relativeTime.d.ts.map +1 -0
- package/dist/core/relativeTime.js +29 -0
- package/dist/core/relativeTime.js.map +1 -0
- package/dist/headless/interactiveShell.d.ts.map +1 -1
- package/dist/headless/interactiveShell.js +100 -2
- package/dist/headless/interactiveShell.js.map +1 -1
- package/dist/runtime/agentController.d.ts +8 -0
- package/dist/runtime/agentController.d.ts.map +1 -1
- package/dist/runtime/agentController.js +12 -0
- package/dist/runtime/agentController.js.map +1 -1
- package/dist/ui/ink/InkPromptController.d.ts +3 -0
- package/dist/ui/ink/InkPromptController.d.ts.map +1 -1
- package/dist/ui/ink/InkPromptController.js +4 -0
- package/dist/ui/ink/InkPromptController.js.map +1 -1
- package/dist/ui/ink/Prompt.d.ts +2 -0
- package/dist/ui/ink/Prompt.d.ts.map +1 -1
- package/dist/ui/ink/Prompt.js +58 -1
- package/dist/ui/ink/Prompt.js.map +1 -1
- package/package.json +1 -1
|
@@ -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":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,kBAAkB,GAClB,WAAW,GACX,OAAO,GACP,OAAO,GACP,mBAAmB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,IAAI,EAAE,mBAAmB,CAAC;IAC1B,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,iBAAiB,GACjB,oBAAoB,GACpB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,oBAAoB,GACpB,cAAc,GACd,UAAU,GACV,UAAU,GACV,qBAAqB,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAAC,eAAe,CAAC,CAAC;IAE9D;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,eAAe,IAAI,kBAAkB,CAAC;IAEtC;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAEzD;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,UAAU,IAAI,mBAAmB,EAAE,CAAC;IAEpC;;OAEG;IACH,YAAY,IAAI,IAAI,CAAC;IAErB;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -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;
|
|
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;
|
|
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('
|
|
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) {
|