codeep 1.2.27 → 1.2.29
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/acp/commands.d.ts +19 -4
- package/dist/acp/commands.js +199 -58
- package/dist/acp/server.js +59 -4
- package/package.json +1 -1
package/dist/acp/commands.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
import { Message } from '../config/index.js';
|
|
2
|
+
export interface AcpSession {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
workspaceRoot: string;
|
|
5
|
+
/** In-memory message history for the ACP conversation */
|
|
6
|
+
history: Message[];
|
|
7
|
+
/** Codeep session name (maps to .codeep/sessions/<name>.json) */
|
|
8
|
+
codeepSessionId: string;
|
|
9
|
+
}
|
|
1
10
|
export interface CommandResult {
|
|
2
11
|
handled: boolean;
|
|
3
12
|
response: string;
|
|
4
13
|
}
|
|
5
14
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
15
|
+
* Ensure workspace has a .codeep folder, initialise it as a project if needed,
|
|
16
|
+
* and load the most recent session (or start a new one).
|
|
17
|
+
*
|
|
18
|
+
* Returns the welcome message to stream back to the client.
|
|
9
19
|
*/
|
|
10
|
-
export declare function
|
|
20
|
+
export declare function initWorkspace(workspaceRoot: string): {
|
|
21
|
+
codeepSessionId: string;
|
|
22
|
+
history: Message[];
|
|
23
|
+
welcomeText: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function handleCommand(input: string, session: AcpSession): CommandResult;
|
package/dist/acp/commands.js
CHANGED
|
@@ -1,43 +1,157 @@
|
|
|
1
|
-
//
|
|
1
|
+
// acp/commands.ts
|
|
2
2
|
// Slash command handler for ACP sessions.
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import {
|
|
3
|
+
// Mirrors CLI commands from renderer/commands.ts but returns plain text
|
|
4
|
+
// responses (no TUI) suitable for streaming back via session/update.
|
|
5
|
+
import { config, getCurrentProvider, getModelsForCurrentProvider, setProvider, setApiKey, isConfigured, listSessionsWithInfo, startNewSession, loadSession, saveSession, initializeAsProject, isManuallyInitializedProject, setProjectPermission, hasWritePermission, hasReadPermission, } from '../config/index.js';
|
|
6
|
+
import { getProviderList, getProvider } from '../config/providers.js';
|
|
7
|
+
import { getProjectContext } from '../utils/project.js';
|
|
8
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
// ─── Workspace / session init (called on session/new) ─────────────────────────
|
|
6
11
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
12
|
+
* Ensure workspace has a .codeep folder, initialise it as a project if needed,
|
|
13
|
+
* and load the most recent session (or start a new one).
|
|
14
|
+
*
|
|
15
|
+
* Returns the welcome message to stream back to the client.
|
|
10
16
|
*/
|
|
11
|
-
export function
|
|
17
|
+
export function initWorkspace(workspaceRoot) {
|
|
18
|
+
// 1. Ensure .codeep directory exists
|
|
19
|
+
const codeepDir = join(workspaceRoot, '.codeep');
|
|
20
|
+
if (!existsSync(codeepDir)) {
|
|
21
|
+
mkdirSync(codeepDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
// 2. Auto-initialize as project if not already (workspace root is always a project in ACP context)
|
|
24
|
+
if (!isManuallyInitializedProject(workspaceRoot)) {
|
|
25
|
+
initializeAsProject(workspaceRoot);
|
|
26
|
+
}
|
|
27
|
+
// 3. Grant read+write permission for this workspace (ACP always has access)
|
|
28
|
+
if (!hasReadPermission(workspaceRoot)) {
|
|
29
|
+
setProjectPermission(workspaceRoot, true, true);
|
|
30
|
+
}
|
|
31
|
+
// 4. Load most recent session, or start fresh
|
|
32
|
+
const sessions = listSessionsWithInfo(workspaceRoot);
|
|
33
|
+
let codeepSessionId;
|
|
34
|
+
let history = [];
|
|
35
|
+
if (sessions.length > 0) {
|
|
36
|
+
const latest = sessions[0]; // already sorted newest-first
|
|
37
|
+
const loaded = loadSession(latest.name, workspaceRoot);
|
|
38
|
+
if (loaded) {
|
|
39
|
+
codeepSessionId = latest.name;
|
|
40
|
+
history = loaded;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
codeepSessionId = startNewSession();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
codeepSessionId = startNewSession();
|
|
48
|
+
}
|
|
49
|
+
// 5. Build welcome text
|
|
50
|
+
const provider = getCurrentProvider();
|
|
51
|
+
const model = config.get('model');
|
|
52
|
+
const projectCtx = getProjectContext(workspaceRoot);
|
|
53
|
+
const hasWrite = hasWritePermission(workspaceRoot);
|
|
54
|
+
const lines = [
|
|
55
|
+
`**Codeep** • ${provider.name} • \`${model}\``,
|
|
56
|
+
'',
|
|
57
|
+
`**Workspace:** ${workspaceRoot}`,
|
|
58
|
+
projectCtx
|
|
59
|
+
? `**Project:** ${projectCtx.name} (${projectCtx.type})`
|
|
60
|
+
: '**Project:** detected',
|
|
61
|
+
hasWrite ? '**Access:** Read & Write' : '**Access:** Read only',
|
|
62
|
+
'',
|
|
63
|
+
sessions.length > 0
|
|
64
|
+
? `**Session:** ${codeepSessionId} (${history.length} messages restored)`
|
|
65
|
+
: '**Session:** new',
|
|
66
|
+
'',
|
|
67
|
+
'Type `/help` to see available commands.',
|
|
68
|
+
];
|
|
69
|
+
return { codeepSessionId, history, welcomeText: lines.join('\n') };
|
|
70
|
+
}
|
|
71
|
+
// ─── Command dispatch ─────────────────────────────────────────────────────────
|
|
72
|
+
export function handleCommand(input, session) {
|
|
12
73
|
const trimmed = input.trim();
|
|
13
74
|
if (!trimmed.startsWith('/'))
|
|
14
75
|
return { handled: false, response: '' };
|
|
15
|
-
const [
|
|
16
|
-
|
|
76
|
+
const [rawCmd, ...args] = trimmed.slice(1).split(/\s+/);
|
|
77
|
+
const cmd = rawCmd.toLowerCase();
|
|
78
|
+
switch (cmd) {
|
|
17
79
|
case 'help':
|
|
18
80
|
return { handled: true, response: buildHelp() };
|
|
19
|
-
case '
|
|
20
|
-
return { handled: true, response:
|
|
81
|
+
case 'status':
|
|
82
|
+
return { handled: true, response: buildStatus(session) };
|
|
83
|
+
case 'version': {
|
|
84
|
+
const provider = getCurrentProvider();
|
|
85
|
+
const model = config.get('model');
|
|
86
|
+
return { handled: true, response: `Codeep • ${provider.name} • \`${model}\`` };
|
|
87
|
+
}
|
|
21
88
|
case 'provider': {
|
|
22
|
-
|
|
23
|
-
if (!id)
|
|
89
|
+
if (!args.length)
|
|
24
90
|
return { handled: true, response: buildProviderList() };
|
|
25
|
-
return { handled: true, response: setProviderCmd(
|
|
91
|
+
return { handled: true, response: setProviderCmd(args[0]) };
|
|
26
92
|
}
|
|
27
93
|
case 'model': {
|
|
28
|
-
|
|
29
|
-
if (!id)
|
|
94
|
+
if (!args.length)
|
|
30
95
|
return { handled: true, response: buildModelList() };
|
|
31
|
-
return { handled: true, response: setModelCmd(
|
|
96
|
+
return { handled: true, response: setModelCmd(args[0]) };
|
|
32
97
|
}
|
|
33
98
|
case 'apikey': {
|
|
34
|
-
|
|
35
|
-
if (!key)
|
|
99
|
+
if (!args.length)
|
|
36
100
|
return { handled: true, response: showApiKey() };
|
|
37
|
-
return { handled: true, response: setApiKeyCmd(
|
|
101
|
+
return { handled: true, response: setApiKeyCmd(args[0]) };
|
|
102
|
+
}
|
|
103
|
+
case 'login': {
|
|
104
|
+
// In ACP context login = set API key for a provider
|
|
105
|
+
// Usage: /login <providerId> <apiKey>
|
|
106
|
+
const [providerId, apiKey] = args;
|
|
107
|
+
if (!providerId || !apiKey) {
|
|
108
|
+
return { handled: true, response: 'Usage: `/login <providerId> <apiKey>`\n\n' + buildProviderList() };
|
|
109
|
+
}
|
|
110
|
+
return { handled: true, response: loginCmd(providerId, apiKey) };
|
|
111
|
+
}
|
|
112
|
+
case 'sessions': {
|
|
113
|
+
return { handled: true, response: buildSessionList(session.workspaceRoot) };
|
|
114
|
+
}
|
|
115
|
+
case 'session': {
|
|
116
|
+
const sub = args[0];
|
|
117
|
+
if (sub === 'new') {
|
|
118
|
+
const id = startNewSession();
|
|
119
|
+
session.codeepSessionId = id;
|
|
120
|
+
session.history = [];
|
|
121
|
+
return { handled: true, response: `New session started: \`${id}\`` };
|
|
122
|
+
}
|
|
123
|
+
if (sub === 'load' && args[1]) {
|
|
124
|
+
const loaded = loadSession(args[1], session.workspaceRoot);
|
|
125
|
+
if (loaded) {
|
|
126
|
+
session.codeepSessionId = args[1];
|
|
127
|
+
session.history = loaded;
|
|
128
|
+
return { handled: true, response: `Session loaded: \`${args[1]}\` (${session.history.length} messages)` };
|
|
129
|
+
}
|
|
130
|
+
return { handled: true, response: `Session not found: \`${args[1]}\`` };
|
|
131
|
+
}
|
|
132
|
+
return { handled: true, response: 'Usage: `/session new` or `/session load <name>`' };
|
|
133
|
+
}
|
|
134
|
+
case 'save': {
|
|
135
|
+
const name = args.length ? args.join('-') : session.codeepSessionId;
|
|
136
|
+
if (saveSession(name, session.history, session.workspaceRoot)) {
|
|
137
|
+
session.codeepSessionId = name;
|
|
138
|
+
return { handled: true, response: `Session saved as: \`${name}\`` };
|
|
139
|
+
}
|
|
140
|
+
return { handled: true, response: 'Failed to save session.' };
|
|
141
|
+
}
|
|
142
|
+
case 'grant': {
|
|
143
|
+
setProjectPermission(session.workspaceRoot, true, true);
|
|
144
|
+
const ctx = getProjectContext(session.workspaceRoot);
|
|
145
|
+
return { handled: true, response: `Write access granted for \`${ctx?.name || session.workspaceRoot}\`` };
|
|
146
|
+
}
|
|
147
|
+
case 'lang': {
|
|
148
|
+
if (!args.length) {
|
|
149
|
+
const current = config.get('language') || 'auto';
|
|
150
|
+
return { handled: true, response: `Current language: \`${current}\`. Usage: \`/lang <code>\` (e.g. \`en\`, \`hr\`, \`auto\`)` };
|
|
151
|
+
}
|
|
152
|
+
config.set('language', args[0]);
|
|
153
|
+
return { handled: true, response: `Language set to \`${args[0]}\`` };
|
|
38
154
|
}
|
|
39
|
-
case 'status':
|
|
40
|
-
return { handled: true, response: buildSettings() };
|
|
41
155
|
default:
|
|
42
156
|
return {
|
|
43
157
|
handled: true,
|
|
@@ -45,7 +159,7 @@ export function handleCommand(input) {
|
|
|
45
159
|
};
|
|
46
160
|
}
|
|
47
161
|
}
|
|
48
|
-
// ───
|
|
162
|
+
// ─── Renderers ────────────────────────────────────────────────────────────────
|
|
49
163
|
function buildHelp() {
|
|
50
164
|
return [
|
|
51
165
|
'## Codeep Commands',
|
|
@@ -53,50 +167,58 @@ function buildHelp() {
|
|
|
53
167
|
'| Command | Description |',
|
|
54
168
|
'|---------|-------------|',
|
|
55
169
|
'| `/help` | Show this help |',
|
|
56
|
-
'| `/
|
|
170
|
+
'| `/status` | Show current configuration and session info |',
|
|
171
|
+
'| `/version` | Show version and current model |',
|
|
57
172
|
'| `/provider` | List available providers |',
|
|
58
|
-
'| `/provider <id>` | Switch
|
|
173
|
+
'| `/provider <id>` | Switch provider (e.g. `/provider anthropic`) |',
|
|
59
174
|
'| `/model` | List models for current provider |',
|
|
60
175
|
'| `/model <id>` | Switch model (e.g. `/model claude-opus-4-5`) |',
|
|
176
|
+
'| `/login <providerId> <apiKey>` | Set API key for a provider |',
|
|
177
|
+
'| `/apikey` | Show masked API key for current provider |',
|
|
61
178
|
'| `/apikey <key>` | Set API key for current provider |',
|
|
62
|
-
'| `/
|
|
63
|
-
'| `/
|
|
179
|
+
'| `/sessions` | List saved sessions |',
|
|
180
|
+
'| `/session new` | Start a new session |',
|
|
181
|
+
'| `/session load <name>` | Load a saved session |',
|
|
182
|
+
'| `/save [name]` | Save current session |',
|
|
183
|
+
'| `/grant` | Grant write access for current workspace |',
|
|
184
|
+
'| `/lang <code>` | Set response language (e.g. `en`, `hr`, `auto`) |',
|
|
64
185
|
].join('\n');
|
|
65
186
|
}
|
|
66
|
-
function
|
|
67
|
-
const provider =
|
|
187
|
+
function buildStatus(session) {
|
|
188
|
+
const provider = getCurrentProvider();
|
|
68
189
|
const model = config.get('model');
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
const
|
|
190
|
+
const lang = config.get('language') || 'auto';
|
|
191
|
+
const hasWrite = hasWritePermission(session.workspaceRoot);
|
|
192
|
+
const configured = isConfigured();
|
|
72
193
|
return [
|
|
73
|
-
'## Current
|
|
194
|
+
'## Current Status',
|
|
74
195
|
'',
|
|
75
|
-
`- **Provider:** ${
|
|
196
|
+
`- **Provider:** ${provider.name} (\`${provider.id}\`)`,
|
|
76
197
|
`- **Model:** \`${model}\``,
|
|
77
|
-
`- **
|
|
78
|
-
`- **
|
|
79
|
-
|
|
80
|
-
|
|
198
|
+
`- **API Key:** ${configured ? 'configured' : '_not set_ — use `/login` or `/apikey`_'}`,
|
|
199
|
+
`- **Language:** \`${lang}\``,
|
|
200
|
+
`- **Workspace:** \`${session.workspaceRoot}\``,
|
|
201
|
+
`- **Access:** ${hasWrite ? 'Read & Write' : 'Read only'}`,
|
|
202
|
+
`- **Session:** \`${session.codeepSessionId}\` (${session.history.length} messages)`,
|
|
81
203
|
].join('\n');
|
|
82
204
|
}
|
|
83
205
|
function buildProviderList() {
|
|
84
|
-
const current =
|
|
206
|
+
const current = getCurrentProvider();
|
|
207
|
+
const providers = getProviderList();
|
|
85
208
|
const lines = ['## Available Providers', ''];
|
|
86
|
-
for (const
|
|
87
|
-
const marker = id === current ? ' ✓' : '';
|
|
88
|
-
lines.push(`- \`${id}\`${marker} — **${p.name}**: ${p.description}`);
|
|
209
|
+
for (const p of providers) {
|
|
210
|
+
const marker = p.id === current.id ? ' ✓' : '';
|
|
211
|
+
lines.push(`- \`${p.id}\`${marker} — **${p.name}**: ${p.description || ''}`);
|
|
89
212
|
}
|
|
90
213
|
lines.push('', 'Use `/provider <id>` to switch.');
|
|
91
214
|
return lines.join('\n');
|
|
92
215
|
}
|
|
93
216
|
function setProviderCmd(id) {
|
|
94
|
-
|
|
217
|
+
const provider = getProvider(id);
|
|
218
|
+
if (!provider)
|
|
95
219
|
return `Provider \`${id}\` not found.\n\n${buildProviderList()}`;
|
|
96
|
-
}
|
|
97
220
|
setProvider(id);
|
|
98
|
-
|
|
99
|
-
return `Switched to **${p.name}** (\`${id}\`). Default model: \`${p.defaultModel}\`.`;
|
|
221
|
+
return `Switched to **${provider.name}** (\`${id}\`). Default model: \`${provider.defaultModel}\`.`;
|
|
100
222
|
}
|
|
101
223
|
function buildModelList() {
|
|
102
224
|
const current = config.get('model');
|
|
@@ -111,21 +233,40 @@ function buildModelList() {
|
|
|
111
233
|
}
|
|
112
234
|
function setModelCmd(id) {
|
|
113
235
|
const models = getModelsForCurrentProvider();
|
|
114
|
-
if (!models[id])
|
|
115
|
-
return `Model \`${id}\` not available
|
|
116
|
-
}
|
|
236
|
+
if (!models[id])
|
|
237
|
+
return `Model \`${id}\` not available.\n\n${buildModelList()}`;
|
|
117
238
|
config.set('model', id);
|
|
118
239
|
return `Model set to \`${id}\`.`;
|
|
119
240
|
}
|
|
120
241
|
function showApiKey() {
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
return
|
|
124
|
-
? `API key for \`${
|
|
125
|
-
: `No API key set for \`${
|
|
242
|
+
const providerId = getCurrentProvider().id;
|
|
243
|
+
const configured = isConfigured(providerId);
|
|
244
|
+
return configured
|
|
245
|
+
? `API key for \`${providerId}\`: configured (use \`/apikey <key>\` to update)`
|
|
246
|
+
: `No API key set for \`${providerId}\`. Use \`/apikey <key>\` to set one.`;
|
|
126
247
|
}
|
|
127
248
|
function setApiKeyCmd(key) {
|
|
128
|
-
const
|
|
129
|
-
setApiKey(
|
|
130
|
-
|
|
249
|
+
const providerId = getCurrentProvider().id;
|
|
250
|
+
// setApiKey is async (keychain) — fire-and-forget, config cache updated synchronously
|
|
251
|
+
setApiKey(key, providerId);
|
|
252
|
+
return `API key for \`${providerId}\` saved.`;
|
|
253
|
+
}
|
|
254
|
+
function loginCmd(providerId, apiKey) {
|
|
255
|
+
const provider = getProvider(providerId);
|
|
256
|
+
if (!provider)
|
|
257
|
+
return `Provider \`${providerId}\` not found.\n\n${buildProviderList()}`;
|
|
258
|
+
setProvider(providerId);
|
|
259
|
+
setApiKey(apiKey, providerId);
|
|
260
|
+
return `Logged in as **${provider.name}** (\`${providerId}\`). Model: \`${provider.defaultModel}\`.`;
|
|
261
|
+
}
|
|
262
|
+
function buildSessionList(workspaceRoot) {
|
|
263
|
+
const sessions = listSessionsWithInfo(workspaceRoot);
|
|
264
|
+
if (sessions.length === 0)
|
|
265
|
+
return 'No saved sessions. Start chatting to create one.';
|
|
266
|
+
const lines = ['## Saved Sessions', ''];
|
|
267
|
+
for (const s of sessions) {
|
|
268
|
+
lines.push(`- \`${s.name}\` — ${s.messageCount} messages — ${new Date(s.createdAt).toLocaleString()}`);
|
|
269
|
+
}
|
|
270
|
+
lines.push('', 'Use `/session load <name>` to restore.');
|
|
271
|
+
return lines.join('\n');
|
|
131
272
|
}
|
package/dist/acp/server.js
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
import { randomUUID } from 'crypto';
|
|
4
4
|
import { StdioTransport } from './transport.js';
|
|
5
5
|
import { runAgentSession } from './session.js';
|
|
6
|
+
import { initWorkspace, handleCommand } from './commands.js';
|
|
7
|
+
import { autoSaveSession } from '../config/index.js';
|
|
6
8
|
export function startAcpServer() {
|
|
7
9
|
const transport = new StdioTransport();
|
|
8
|
-
// sessionId →
|
|
10
|
+
// ACP sessionId → full AcpSession (includes history + codeep session tracking)
|
|
9
11
|
const sessions = new Map();
|
|
10
12
|
transport.start((msg) => {
|
|
11
13
|
switch (msg.method) {
|
|
@@ -46,9 +48,46 @@ export function startAcpServer() {
|
|
|
46
48
|
}
|
|
47
49
|
function handleSessionNew(msg) {
|
|
48
50
|
const params = msg.params;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const acpSessionId = randomUUID();
|
|
52
|
+
// Initialise workspace: create .codeep folder, load/create codeep session
|
|
53
|
+
const { codeepSessionId, history, welcomeText } = initWorkspace(params.cwd);
|
|
54
|
+
sessions.set(acpSessionId, {
|
|
55
|
+
sessionId: acpSessionId,
|
|
56
|
+
workspaceRoot: params.cwd,
|
|
57
|
+
history,
|
|
58
|
+
codeepSessionId,
|
|
59
|
+
abortController: null,
|
|
60
|
+
});
|
|
61
|
+
transport.respond(msg.id, { sessionId: acpSessionId });
|
|
62
|
+
// Advertise available slash commands to Zed
|
|
63
|
+
transport.notify('session/update', {
|
|
64
|
+
sessionId: acpSessionId,
|
|
65
|
+
update: {
|
|
66
|
+
sessionUpdate: 'available_commands_update',
|
|
67
|
+
availableCommands: [
|
|
68
|
+
{ name: 'help', description: 'Show available commands' },
|
|
69
|
+
{ name: 'status', description: 'Show current configuration and session info' },
|
|
70
|
+
{ name: 'version', description: 'Show version and current model' },
|
|
71
|
+
{ name: 'provider', description: 'List or switch AI provider', input: { hint: '<provider-id>' } },
|
|
72
|
+
{ name: 'model', description: 'List or switch model', input: { hint: '<model-id>' } },
|
|
73
|
+
{ name: 'login', description: 'Set API key for a provider', input: { hint: '<providerId> <apiKey>' } },
|
|
74
|
+
{ name: 'apikey', description: 'Show or set API key for current provider', input: { hint: '<key>' } },
|
|
75
|
+
{ name: 'sessions', description: 'List saved sessions' },
|
|
76
|
+
{ name: 'session', description: 'Manage sessions: new or load', input: { hint: 'new | load <name>' } },
|
|
77
|
+
{ name: 'save', description: 'Save current session', input: { hint: '[name]' } },
|
|
78
|
+
{ name: 'grant', description: 'Grant write access for current workspace' },
|
|
79
|
+
{ name: 'lang', description: 'Set response language', input: { hint: '<code> (e.g. en, hr, auto)' } },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
// Stream welcome message so the client sees it immediately after session/new
|
|
84
|
+
transport.notify('session/update', {
|
|
85
|
+
sessionId: acpSessionId,
|
|
86
|
+
update: {
|
|
87
|
+
sessionUpdate: 'agent_message_chunk',
|
|
88
|
+
content: { type: 'text', text: welcomeText },
|
|
89
|
+
},
|
|
90
|
+
});
|
|
52
91
|
}
|
|
53
92
|
function handleSessionPrompt(msg) {
|
|
54
93
|
const params = msg.params;
|
|
@@ -62,6 +101,19 @@ export function startAcpServer() {
|
|
|
62
101
|
.filter((b) => b.type === 'text')
|
|
63
102
|
.map((b) => b.text)
|
|
64
103
|
.join('\n');
|
|
104
|
+
// Handle slash commands — no agent loop needed
|
|
105
|
+
const cmd = handleCommand(prompt, session);
|
|
106
|
+
if (cmd.handled) {
|
|
107
|
+
transport.notify('session/update', {
|
|
108
|
+
sessionId: params.sessionId,
|
|
109
|
+
update: {
|
|
110
|
+
sessionUpdate: 'agent_message_chunk',
|
|
111
|
+
content: { type: 'text', text: cmd.response },
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
transport.respond(msg.id, { stopReason: 'end_turn' });
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
65
117
|
const abortController = new AbortController();
|
|
66
118
|
session.abortController = abortController;
|
|
67
119
|
runAgentSession({
|
|
@@ -82,6 +134,9 @@ export function startAcpServer() {
|
|
|
82
134
|
// file edits are streamed via onChunk for now
|
|
83
135
|
},
|
|
84
136
|
}).then(() => {
|
|
137
|
+
// Persist conversation history after each agent turn
|
|
138
|
+
session.history.push({ role: 'user', content: prompt });
|
|
139
|
+
autoSaveSession(session.history, session.workspaceRoot);
|
|
85
140
|
transport.respond(msg.id, { stopReason: 'end_turn' });
|
|
86
141
|
}).catch((err) => {
|
|
87
142
|
if (err.name === 'AbortError') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.29",
|
|
4
4
|
"description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|