dexto 1.1.4 → 1.1.5
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 +476 -0
- package/dist/analytics/constants.d.ts +19 -0
- package/dist/analytics/constants.d.ts.map +1 -0
- package/dist/analytics/constants.js +24 -0
- package/dist/analytics/events.d.ts +112 -0
- package/dist/analytics/events.d.ts.map +1 -0
- package/dist/analytics/events.js +6 -0
- package/dist/analytics/index.d.ts +37 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +145 -0
- package/dist/analytics/state.d.ts +23 -0
- package/dist/analytics/state.d.ts.map +1 -0
- package/dist/analytics/state.js +74 -0
- package/dist/analytics/wrapper.d.ts +11 -0
- package/dist/analytics/wrapper.d.ts.map +1 -0
- package/dist/analytics/wrapper.js +125 -0
- package/dist/cli/cli.d.ts +5 -0
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +10 -4
- package/dist/cli/commands/{interactive-commands/session/helpers → helpers}/formatters.d.ts +1 -1
- package/dist/cli/commands/helpers/formatters.d.ts.map +1 -0
- package/dist/cli/commands/{interactive-commands/session/helpers → helpers}/formatters.js +1 -1
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +56 -2
- package/dist/cli/commands/interactive-commands/session/index.d.ts +1 -1
- package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/index.js +1 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.js +10 -76
- package/dist/cli/commands/list-agents.d.ts +2 -2
- package/dist/cli/commands/session-commands.d.ts +28 -0
- package/dist/cli/commands/session-commands.d.ts.map +1 -0
- package/dist/cli/commands/session-commands.js +184 -0
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +9 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -1
- package/dist/cli/commands/uninstall.js +42 -1
- package/dist/cli/utils/api-key-setup.js +1 -1
- package/dist/index.js +271 -75
- package/dist/webui/.next/standalone/.next/static/chunks/854-2a6d5a5297a15d52.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/app/{layout-615a56c6184a488f.js → layout-dde711766eda096b.js} +1 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/{page-24123c97236d46cb.js → page-655c5da45b79231a.js} +1 -1
- package/dist/webui/.next/{static/css/75b11629ebbc461a.css → standalone/.next/static/css/daca29b49478cfbe.css} +1 -1
- package/dist/webui/.next/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/webui/.next/standalone/package.json +2 -1
- package/dist/webui/.next/standalone/packages/webui/.next/BUILD_ID +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/app-build-manifest.json +5 -7
- package/dist/webui/.next/standalone/packages/webui/.next/build-manifest.json +2 -2
- package/dist/webui/.next/standalone/packages/webui/.next/prerender-manifest.json +3 -3
- package/dist/webui/.next/standalone/packages/webui/.next/required-server-files.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page.js +2 -2
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js +3 -3
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page.js +3 -3
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/43.js +1 -4
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/619.js +30 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/next-font-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/next-font-manifest.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/pages/500.html +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/pages/_error.js +2 -2
- package/dist/webui/.next/standalone/packages/webui/.next/server/server-reference-manifest.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-2a6d5a5297a15d52.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/{layout-615a56c6184a488f.js → layout-dde711766eda096b.js} +1 -1
- package/dist/webui/.next/{static/chunks/app/page-24123c97236d46cb.js → standalone/packages/webui/.next/static/chunks/app/page-655c5da45b79231a.js} +1 -1
- package/dist/webui/.next/standalone/{.next/static/css/75b11629ebbc461a.css → packages/webui/.next/static/css/daca29b49478cfbe.css} +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/webui/.next/standalone/packages/webui/package.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/server.js +1 -1
- package/dist/webui/.next/static/chunks/854-2a6d5a5297a15d52.js +1 -0
- package/dist/webui/.next/static/chunks/app/{layout-615a56c6184a488f.js → layout-dde711766eda096b.js} +1 -1
- package/dist/webui/.next/{standalone/packages/webui/.next/static/chunks/app/page-24123c97236d46cb.js → static/chunks/app/page-655c5da45b79231a.js} +1 -1
- package/dist/webui/.next/{standalone/packages/webui/.next/static/css/75b11629ebbc461a.css → static/css/daca29b49478cfbe.css} +1 -1
- package/dist/webui/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/webui/package.json +1 -1
- package/package.json +7 -4
- package/dist/cli/commands/interactive-commands/session/helpers/formatters.d.ts.map +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/221-608218ab04068cb2.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/854-47418382efcea1d4.js +0 -1
- package/dist/webui/.next/standalone/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/387.js +0 -14
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/392.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/450.js +0 -139
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/514.js +0 -2
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/531.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/723.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/737.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/767.js +0 -20
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/89.js +0 -95
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/221-608218ab04068cb2.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-47418382efcea1d4.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
- package/dist/webui/.next/static/chunks/221-608218ab04068cb2.js +0 -1
- package/dist/webui/.next/static/chunks/854-47418382efcea1d4.js +0 -1
- package/dist/webui/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
- /package/dist/webui/.next/standalone/.next/static/{abgua6ybDH7yT2b5rvLlU → wcYVcRLx1mruRrV5-XkIK}/_buildManifest.js +0 -0
- /package/dist/webui/.next/standalone/.next/static/{abgua6ybDH7yT2b5rvLlU → wcYVcRLx1mruRrV5-XkIK}/_ssgManifest.js +0 -0
- /package/dist/webui/.next/standalone/packages/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → wcYVcRLx1mruRrV5-XkIK}/_buildManifest.js +0 -0
- /package/dist/webui/.next/standalone/packages/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → wcYVcRLx1mruRrV5-XkIK}/_ssgManifest.js +0 -0
- /package/dist/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → wcYVcRLx1mruRrV5-XkIK}/_buildManifest.js +0 -0
- /package/dist/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → wcYVcRLx1mruRrV5-XkIK}/_ssgManifest.js +0 -0
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import chalk from 'chalk';
|
|
21
21
|
import { logger } from '@dexto/core';
|
|
22
|
-
import { formatSessionInfo, formatHistoryMessage } from '
|
|
22
|
+
import { formatSessionInfo, formatHistoryMessage } from '../../helpers/formatters.js';
|
|
23
23
|
/**
|
|
24
24
|
* Helper to get current session info
|
|
25
25
|
*/
|
|
@@ -43,7 +43,7 @@ async function displaySessionHistory(sessionId, agent) {
|
|
|
43
43
|
console.log(formatHistoryMessage(message, index));
|
|
44
44
|
});
|
|
45
45
|
console.log(chalk.dim(`\n Total: ${history.length} messages`));
|
|
46
|
-
console.log(chalk.dim(' 💡 Use /clear to reset session or
|
|
46
|
+
console.log(chalk.dim(' 💡 Use /clear to reset session or dexto -r <id> to resume a different session\n'));
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Session management commands
|
|
@@ -65,7 +65,7 @@ export const sessionCommand = {
|
|
|
65
65
|
const sessionIds = await agent.listSessions();
|
|
66
66
|
const current = await getCurrentSessionInfo(agent);
|
|
67
67
|
if (sessionIds.length === 0) {
|
|
68
|
-
console.log(chalk.dim(' No sessions found.
|
|
68
|
+
console.log(chalk.dim(' No sessions found. Run `dexto` to start a new session, or use `dexto -c`/`dexto -r <id>`.\n'));
|
|
69
69
|
return true;
|
|
70
70
|
}
|
|
71
71
|
// Fetch metadata concurrently; errors do not abort listing
|
|
@@ -75,7 +75,7 @@ export const sessionCommand = {
|
|
|
75
75
|
return { id, metadata };
|
|
76
76
|
}
|
|
77
77
|
catch (e) {
|
|
78
|
-
logger.error(`Failed to fetch metadata for session ${id}: ${e instanceof Error ? e.message : String(e)}
|
|
78
|
+
logger.error(`Failed to fetch metadata for session ${id}: ${e instanceof Error ? e.message : String(e)}`, null, 'red');
|
|
79
79
|
return { id, metadata: undefined };
|
|
80
80
|
}
|
|
81
81
|
}));
|
|
@@ -88,7 +88,7 @@ export const sessionCommand = {
|
|
|
88
88
|
displayed++;
|
|
89
89
|
}
|
|
90
90
|
console.log(chalk.dim(`\n Total: ${displayed} of ${sessionIds.length} sessions`));
|
|
91
|
-
console.log(chalk.dim(' 💡 Use
|
|
91
|
+
console.log(chalk.dim(' 💡 Use `dexto -r <id>` to resume a session\n'));
|
|
92
92
|
}
|
|
93
93
|
catch (error) {
|
|
94
94
|
logger.error(`Failed to list sessions: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -96,69 +96,6 @@ export const sessionCommand = {
|
|
|
96
96
|
return true;
|
|
97
97
|
},
|
|
98
98
|
},
|
|
99
|
-
{
|
|
100
|
-
name: 'new',
|
|
101
|
-
description: 'Create a new session',
|
|
102
|
-
usage: '/session new [id]',
|
|
103
|
-
handler: async (args, agent) => {
|
|
104
|
-
try {
|
|
105
|
-
const sessionId = args[0]; // Optional custom ID
|
|
106
|
-
const session = await agent.createSession(sessionId);
|
|
107
|
-
console.log(chalk.green(`✅ Created new session: ${chalk.bold(session.id)}`));
|
|
108
|
-
// Switch to the new session
|
|
109
|
-
await agent.loadSessionAsDefault(session.id);
|
|
110
|
-
console.log(chalk.yellow(`🔄 Switched to new session`));
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
logger.error(`Failed to create session: ${error instanceof Error ? error.message : String(error)}`);
|
|
114
|
-
}
|
|
115
|
-
return true;
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
name: 'switch',
|
|
120
|
-
description: 'Switch to a different session',
|
|
121
|
-
usage: '/session switch <id>',
|
|
122
|
-
handler: async (args, agent) => {
|
|
123
|
-
if (args.length === 0) {
|
|
124
|
-
console.log(chalk.red('❌ Session ID required. Usage: /session switch <id>'));
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
try {
|
|
128
|
-
const sessionId = args[0]; // Safe to assert non-null since we checked args.length
|
|
129
|
-
await agent.loadSessionAsDefault(sessionId);
|
|
130
|
-
const metadata = await agent.getSessionMetadata(sessionId);
|
|
131
|
-
console.log(chalk.green(`✅ Switched to session: ${chalk.bold(sessionId)}`));
|
|
132
|
-
if (metadata && metadata.messageCount > 0) {
|
|
133
|
-
console.log(chalk.dim(` ${metadata.messageCount} messages in history`));
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
console.log(chalk.dim(' New session - no previous messages'));
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
catch (error) {
|
|
140
|
-
logger.error(`Failed to switch session: ${error instanceof Error ? error.message : String(error)}`);
|
|
141
|
-
}
|
|
142
|
-
return true;
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'current',
|
|
147
|
-
description: 'Show current session',
|
|
148
|
-
usage: '/session current',
|
|
149
|
-
handler: async (args, agent) => {
|
|
150
|
-
try {
|
|
151
|
-
const current = await getCurrentSessionInfo(agent);
|
|
152
|
-
console.log(chalk.blue('\n📍 Current Session:\n'));
|
|
153
|
-
console.log(' ' + formatSessionInfo(current.id, current.metadata, true));
|
|
154
|
-
console.log();
|
|
155
|
-
}
|
|
156
|
-
catch (error) {
|
|
157
|
-
logger.error(`Failed to get current session: ${error instanceof Error ? error.message : String(error)}`);
|
|
158
|
-
}
|
|
159
|
-
return true;
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
99
|
{
|
|
163
100
|
name: 'history',
|
|
164
101
|
description: 'Show session history for current session',
|
|
@@ -176,7 +113,7 @@ export const sessionCommand = {
|
|
|
176
113
|
console.log(chalk.dim(' Use /session list to see available sessions'));
|
|
177
114
|
}
|
|
178
115
|
else {
|
|
179
|
-
logger.error(`Failed to get session history: ${error instanceof Error ? error.message : String(error)}
|
|
116
|
+
logger.error(`Failed to get session history: ${error instanceof Error ? error.message : String(error)}`, null, 'red');
|
|
180
117
|
}
|
|
181
118
|
}
|
|
182
119
|
return true;
|
|
@@ -204,7 +141,7 @@ export const sessionCommand = {
|
|
|
204
141
|
console.log(chalk.green(`✅ Deleted session: ${chalk.bold(sessionId)}`));
|
|
205
142
|
}
|
|
206
143
|
catch (error) {
|
|
207
|
-
logger.error(`Failed to delete session: ${error instanceof Error ? error.message : String(error)}
|
|
144
|
+
logger.error(`Failed to delete session: ${error instanceof Error ? error.message : String(error)}`, null, 'red');
|
|
208
145
|
}
|
|
209
146
|
return true;
|
|
210
147
|
},
|
|
@@ -217,15 +154,12 @@ export const sessionCommand = {
|
|
|
217
154
|
console.log(chalk.bold.blue('\n📋 Session Management Commands:\n'));
|
|
218
155
|
console.log(chalk.cyan('Available subcommands:'));
|
|
219
156
|
console.log(` ${chalk.yellow('/session list')} - List all sessions with their status and activity`);
|
|
220
|
-
console.log(` ${chalk.yellow('/session new')} ${chalk.blue('[name]')} - Create a new session (optional custom name)`);
|
|
221
|
-
console.log(` ${chalk.yellow('/session switch')} ${chalk.blue('<id>')} - Switch to a different session`);
|
|
222
|
-
console.log(` ${chalk.yellow('/session current')} - Show current session info and message count`);
|
|
223
157
|
console.log(` ${chalk.yellow('/session history')} - Display session history for current session`);
|
|
224
158
|
console.log(` ${chalk.yellow('/session delete')} ${chalk.blue('<id>')} - Delete a session (cannot delete active session)`);
|
|
225
159
|
console.log(` ${chalk.yellow('/session help')} - Show this help message`);
|
|
226
160
|
console.log(chalk.dim('\n💡 Sessions allow you to maintain separate chat sessions'));
|
|
227
|
-
console.log(chalk.dim('💡 Use
|
|
228
|
-
console.log(chalk.dim('💡
|
|
161
|
+
console.log(chalk.dim('💡 Use `dexto -r <id>` to resume a different session'));
|
|
162
|
+
console.log(chalk.dim('💡 Use `dexto` to start a new session or `dexto -c` to continue most recent\n'));
|
|
229
163
|
return true;
|
|
230
164
|
},
|
|
231
165
|
},
|
|
@@ -247,7 +181,7 @@ export const sessionCommand = {
|
|
|
247
181
|
return subcmd.handler(subArgs, agent);
|
|
248
182
|
}
|
|
249
183
|
console.log(chalk.red(`❌ Unknown session subcommand: ${subcommand}`));
|
|
250
|
-
console.log(chalk.dim('Available subcommands: list,
|
|
184
|
+
console.log(chalk.dim('Available subcommands: list, history, delete, help'));
|
|
251
185
|
console.log(chalk.dim('💡 Use /session help for detailed command descriptions'));
|
|
252
186
|
return true;
|
|
253
187
|
},
|
|
@@ -4,13 +4,13 @@ declare const ListAgentsCommandSchema: z.ZodObject<{
|
|
|
4
4
|
installed: z.ZodDefault<z.ZodBoolean>;
|
|
5
5
|
available: z.ZodDefault<z.ZodBoolean>;
|
|
6
6
|
}, "strict", z.ZodTypeAny, {
|
|
7
|
+
installed: boolean;
|
|
7
8
|
verbose: boolean;
|
|
8
9
|
available: boolean;
|
|
9
|
-
installed: boolean;
|
|
10
10
|
}, {
|
|
11
|
+
installed?: boolean | undefined;
|
|
11
12
|
verbose?: boolean | undefined;
|
|
12
13
|
available?: boolean | undefined;
|
|
13
|
-
installed?: boolean | undefined;
|
|
14
14
|
}>;
|
|
15
15
|
export type ListAgentsCommandOptions = z.output<typeof ListAgentsCommandSchema>;
|
|
16
16
|
export type ListAgentsCommandOptionsInput = z.input<typeof ListAgentsCommandSchema>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-Interactive Session Management Commands
|
|
3
|
+
*
|
|
4
|
+
* This module provides CLI commands for managing sessions outside of interactive mode.
|
|
5
|
+
* These commands allow users to manage sessions via direct CLI invocation.
|
|
6
|
+
*/
|
|
7
|
+
import { DextoAgent } from '@dexto/core';
|
|
8
|
+
/**
|
|
9
|
+
* List all available sessions
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleSessionListCommand(agent: DextoAgent): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Show session history
|
|
14
|
+
*/
|
|
15
|
+
export declare function handleSessionHistoryCommand(agent: DextoAgent, sessionId?: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Delete a session
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleSessionDeleteCommand(agent: DextoAgent, sessionId: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Search session history
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleSessionSearchCommand(agent: DextoAgent, query: string, options?: {
|
|
24
|
+
sessionId?: string;
|
|
25
|
+
role?: 'user' | 'assistant' | 'system' | 'tool';
|
|
26
|
+
limit?: number;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=session-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/session-commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAU,UAAU,EAAwB,MAAM,aAAa,CAAC;AA0CvE;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD/E;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC7C,KAAK,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC5C,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC5C,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IACL,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CACb,GACP,OAAO,CAAC,IAAI,CAAC,CAyFf"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-Interactive Session Management Commands
|
|
3
|
+
*
|
|
4
|
+
* This module provides CLI commands for managing sessions outside of interactive mode.
|
|
5
|
+
* These commands allow users to manage sessions via direct CLI invocation.
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { logger } from '@dexto/core';
|
|
9
|
+
import { formatSessionInfo, formatHistoryMessage } from './helpers/formatters.js';
|
|
10
|
+
/**
|
|
11
|
+
* Escape special regex characters in a string to prevent ReDoS attacks
|
|
12
|
+
*/
|
|
13
|
+
function escapeRegExp(string) {
|
|
14
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Helper to get current session info
|
|
18
|
+
*/
|
|
19
|
+
async function getCurrentSessionInfo(agent) {
|
|
20
|
+
const currentId = agent.getCurrentSessionId();
|
|
21
|
+
const metadata = await agent.getSessionMetadata(currentId);
|
|
22
|
+
return { id: currentId, metadata };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Helper to display session history with consistent formatting
|
|
26
|
+
*/
|
|
27
|
+
async function displaySessionHistory(sessionId, agent) {
|
|
28
|
+
console.log(chalk.blue(`\n💬 Session History for: ${chalk.bold(sessionId)}\n`));
|
|
29
|
+
const history = await agent.getSessionHistory(sessionId);
|
|
30
|
+
if (history.length === 0) {
|
|
31
|
+
console.log(chalk.dim(' No messages in this session yet.\n'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Display each message with formatting
|
|
35
|
+
history.forEach((message, index) => {
|
|
36
|
+
console.log(formatHistoryMessage(message, index));
|
|
37
|
+
});
|
|
38
|
+
console.log(chalk.dim(`\n Total: ${history.length} messages`));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* List all available sessions
|
|
42
|
+
*/
|
|
43
|
+
export async function handleSessionListCommand(agent) {
|
|
44
|
+
try {
|
|
45
|
+
console.log(chalk.bold.blue('\n📋 Sessions:\n'));
|
|
46
|
+
const sessionIds = await agent.listSessions();
|
|
47
|
+
const current = await getCurrentSessionInfo(agent);
|
|
48
|
+
if (sessionIds.length === 0) {
|
|
49
|
+
console.log(chalk.dim(' No sessions found. Run `dexto` to start a new session, or use `dexto -c`/`dexto -r <id>`.\n'));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Fetch metadata concurrently; errors do not abort listing
|
|
53
|
+
const entries = await Promise.all(sessionIds.map(async (id) => {
|
|
54
|
+
try {
|
|
55
|
+
const metadata = await agent.getSessionMetadata(id);
|
|
56
|
+
return { id, metadata };
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
logger.error(`Failed to fetch metadata for session ${id}: ${e instanceof Error ? e.message : String(e)}`, null, 'red');
|
|
60
|
+
return { id, metadata: undefined };
|
|
61
|
+
}
|
|
62
|
+
}));
|
|
63
|
+
let displayed = 0;
|
|
64
|
+
for (const { id, metadata } of entries) {
|
|
65
|
+
if (!metadata)
|
|
66
|
+
continue;
|
|
67
|
+
const isCurrent = id === current.id;
|
|
68
|
+
console.log(` ${formatSessionInfo(id, metadata, isCurrent)}`);
|
|
69
|
+
displayed++;
|
|
70
|
+
}
|
|
71
|
+
console.log(chalk.dim(`\n Total: ${displayed} of ${sessionIds.length} sessions`));
|
|
72
|
+
console.log(chalk.dim(' 💡 Use `dexto -r <id>` to resume a session\n'));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
logger.error(`Failed to list sessions: ${error instanceof Error ? error.message : String(error)}`, null, 'red');
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Show session history
|
|
81
|
+
*/
|
|
82
|
+
export async function handleSessionHistoryCommand(agent, sessionId) {
|
|
83
|
+
try {
|
|
84
|
+
// Use provided session ID or current session
|
|
85
|
+
const targetSessionId = sessionId || agent.getCurrentSessionId();
|
|
86
|
+
await displaySessionHistory(targetSessionId, agent);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error instanceof Error && error.message.includes('not found')) {
|
|
90
|
+
console.log(chalk.red(`❌ Session not found: ${sessionId || 'current'}`));
|
|
91
|
+
console.log(chalk.dim(' Use `dexto session list` to see available sessions'));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
logger.error(`Failed to get session history: ${error instanceof Error ? error.message : String(error)}`, null, 'red');
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Delete a session
|
|
101
|
+
*/
|
|
102
|
+
export async function handleSessionDeleteCommand(agent, sessionId) {
|
|
103
|
+
try {
|
|
104
|
+
const current = await getCurrentSessionInfo(agent);
|
|
105
|
+
// Check if trying to delete current session
|
|
106
|
+
if (sessionId === current.id) {
|
|
107
|
+
console.log(chalk.yellow('⚠️ Cannot delete the currently active session.'));
|
|
108
|
+
console.log(chalk.dim(' Switch to another session first, then delete this one.'));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
await agent.deleteSession(sessionId);
|
|
112
|
+
console.log(chalk.green(`✅ Deleted session: ${chalk.bold(sessionId)}`));
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
logger.error(`Failed to delete session: ${error instanceof Error ? error.message : String(error)}`, null, 'red');
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Search session history
|
|
121
|
+
*/
|
|
122
|
+
export async function handleSessionSearchCommand(agent, query, options = {}) {
|
|
123
|
+
try {
|
|
124
|
+
const searchOptions = {
|
|
125
|
+
limit: options.limit || 10,
|
|
126
|
+
};
|
|
127
|
+
if (options.sessionId) {
|
|
128
|
+
searchOptions.sessionId = options.sessionId;
|
|
129
|
+
}
|
|
130
|
+
if (options.role) {
|
|
131
|
+
const allowed = new Set(['user', 'assistant', 'system', 'tool']);
|
|
132
|
+
if (!allowed.has(options.role)) {
|
|
133
|
+
console.log(chalk.red(`❌ Invalid role: ${options.role}. Use one of: user, assistant, system, tool`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
searchOptions.role = options.role;
|
|
137
|
+
}
|
|
138
|
+
console.log(chalk.blue(`🔍 Searching for: "${query}"`));
|
|
139
|
+
if (searchOptions.sessionId) {
|
|
140
|
+
console.log(chalk.dim(` Session: ${searchOptions.sessionId}`));
|
|
141
|
+
}
|
|
142
|
+
if (searchOptions.role) {
|
|
143
|
+
console.log(chalk.dim(` Role: ${searchOptions.role}`));
|
|
144
|
+
}
|
|
145
|
+
console.log(chalk.dim(` Limit: ${searchOptions.limit}`));
|
|
146
|
+
console.log();
|
|
147
|
+
const results = await agent.searchMessages(query, searchOptions);
|
|
148
|
+
if (results.results.length === 0) {
|
|
149
|
+
console.log(chalk.yellow('📭 No messages found matching your search'));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
console.log(chalk.green(`✅ Found ${results.total} result${results.total === 1 ? '' : 's'}`));
|
|
153
|
+
if (results.hasMore) {
|
|
154
|
+
console.log(chalk.dim(` Showing first ${results.results.length} results`));
|
|
155
|
+
}
|
|
156
|
+
console.log();
|
|
157
|
+
// Precompile safe regex for highlighting (only if query is not empty)
|
|
158
|
+
const highlightRegex = query.trim()
|
|
159
|
+
? new RegExp(`(${escapeRegExp(query.trim().slice(0, 256))})`, 'gi')
|
|
160
|
+
: null;
|
|
161
|
+
// Display results
|
|
162
|
+
results.results.forEach((result, index) => {
|
|
163
|
+
const roleColor = result.message.role === 'user'
|
|
164
|
+
? chalk.blue
|
|
165
|
+
: result.message.role === 'assistant'
|
|
166
|
+
? chalk.green
|
|
167
|
+
: chalk.yellow;
|
|
168
|
+
console.log(`${chalk.dim(`${index + 1}.`)} ${chalk.cyan(result.sessionId)} ${roleColor(`[${result.message.role}]`)}`);
|
|
169
|
+
// Safe highlighting - only if we have a valid regex
|
|
170
|
+
const highlightedContext = highlightRegex
|
|
171
|
+
? result.context.replace(highlightRegex, chalk.inverse('$1'))
|
|
172
|
+
: result.context;
|
|
173
|
+
console.log(` ${highlightedContext}`);
|
|
174
|
+
console.log();
|
|
175
|
+
});
|
|
176
|
+
if (results.hasMore) {
|
|
177
|
+
console.log(chalk.dim('💡 Use --limit to see more results'));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
logger.error(`Search failed: ${error instanceof Error ? error.message : String(error)}`, null, 'red');
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -12,9 +12,9 @@ declare const SetupCommandSchema: z.ZodEffects<z.ZodObject<{
|
|
|
12
12
|
model?: string | undefined;
|
|
13
13
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
14
14
|
}, {
|
|
15
|
+
interactive?: boolean | undefined;
|
|
15
16
|
model?: string | undefined;
|
|
16
17
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
17
|
-
interactive?: boolean | undefined;
|
|
18
18
|
defaultAgent?: string | undefined;
|
|
19
19
|
force?: boolean | undefined;
|
|
20
20
|
}>, {
|
|
@@ -24,9 +24,9 @@ declare const SetupCommandSchema: z.ZodEffects<z.ZodObject<{
|
|
|
24
24
|
model?: string | undefined;
|
|
25
25
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
26
26
|
}, {
|
|
27
|
+
interactive?: boolean | undefined;
|
|
27
28
|
model?: string | undefined;
|
|
28
29
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
29
|
-
interactive?: boolean | undefined;
|
|
30
30
|
defaultAgent?: string | undefined;
|
|
31
31
|
force?: boolean | undefined;
|
|
32
32
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmClB,CAAC;AAEP,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAiBtE,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyF9F"}
|
|
@@ -9,6 +9,7 @@ import { selectProvider } from '../utils/provider-setup.js';
|
|
|
9
9
|
import { requiresSetup } from '../utils/setup-utils.js';
|
|
10
10
|
import * as p from '@clack/prompts';
|
|
11
11
|
import { logger } from '@dexto/core';
|
|
12
|
+
import { capture } from '../../analytics/index.js';
|
|
12
13
|
// Zod schema for setup command validation
|
|
13
14
|
const SetupCommandSchema = z
|
|
14
15
|
.object({
|
|
@@ -103,10 +104,18 @@ export async function handleSetupCommand(options) {
|
|
|
103
104
|
throw new Error(`Provider '${provider}' requires a specific model. Use --model option.`);
|
|
104
105
|
}
|
|
105
106
|
const apiKeyVar = getPrimaryApiKeyEnvVar(provider);
|
|
107
|
+
const hadApiKeyBefore = Boolean(resolveApiKeyForProvider(provider));
|
|
106
108
|
const defaultAgent = validated.defaultAgent;
|
|
107
109
|
// Create and save preferences
|
|
108
110
|
const preferences = createInitialPreferences(provider, model, apiKeyVar, defaultAgent);
|
|
109
111
|
await saveGlobalPreferences(preferences);
|
|
112
|
+
// Track provider/model selected during setup
|
|
113
|
+
capture('dexto_setup', {
|
|
114
|
+
provider,
|
|
115
|
+
model,
|
|
116
|
+
hadApiKeyBefore,
|
|
117
|
+
setupMode: validated.interactive ? 'interactive' : 'non-interactive',
|
|
118
|
+
});
|
|
110
119
|
// Setup API key interactively (only if interactive mode enabled and key doesn't exist)
|
|
111
120
|
if (validated.interactive) {
|
|
112
121
|
const existingApiKey = resolveApiKeyForProvider(provider);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/uninstall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/uninstall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,QAAA,MAAM,sBAAsB;;;;;;;;;;;;EAMf,CAAC;AAEd,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAgC9E,wBAAsB,sBAAsB,CACxC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,CA+Gf"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// packages/cli/src/cli/commands/uninstall.ts
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { getAgentRegistry } from '@dexto/core';
|
|
4
|
+
import { capture } from '../../analytics/index.js';
|
|
4
5
|
// Zod schema for uninstall command validation
|
|
5
6
|
const UninstallCommandSchema = z
|
|
6
7
|
.object({
|
|
@@ -57,6 +58,8 @@ export async function handleUninstallCommand(agents, options) {
|
|
|
57
58
|
let successCount = 0;
|
|
58
59
|
let errorCount = 0;
|
|
59
60
|
const errors = [];
|
|
61
|
+
const uninstalled = [];
|
|
62
|
+
const failed = [];
|
|
60
63
|
// Uninstall each agent
|
|
61
64
|
for (const agentName of agentsToUninstall) {
|
|
62
65
|
try {
|
|
@@ -64,15 +67,53 @@ export async function handleUninstallCommand(agents, options) {
|
|
|
64
67
|
await registry.uninstallAgent(agentName, validated.force);
|
|
65
68
|
successCount++;
|
|
66
69
|
console.log(`✅ ${agentName} uninstalled successfully`);
|
|
70
|
+
uninstalled.push(agentName);
|
|
71
|
+
// Per-agent analytics for successful uninstall
|
|
72
|
+
try {
|
|
73
|
+
capture('dexto_uninstall_agent', {
|
|
74
|
+
agent: agentName,
|
|
75
|
+
status: 'uninstalled',
|
|
76
|
+
force: validated.force,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Analytics failures should not block CLI execution.
|
|
81
|
+
}
|
|
67
82
|
}
|
|
68
83
|
catch (error) {
|
|
69
84
|
errorCount++;
|
|
70
85
|
const errorMsg = `Failed to uninstall ${agentName}: ${error instanceof Error ? error.message : String(error)}`;
|
|
71
86
|
errors.push(errorMsg);
|
|
87
|
+
failed.push(agentName);
|
|
72
88
|
console.error(`❌ ${errorMsg}`);
|
|
89
|
+
// Per-agent analytics for failed uninstall
|
|
90
|
+
try {
|
|
91
|
+
capture('dexto_uninstall_agent', {
|
|
92
|
+
agent: agentName,
|
|
93
|
+
status: 'failed',
|
|
94
|
+
error_message: error instanceof Error ? error.message : String(error),
|
|
95
|
+
force: validated.force,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Analytics failures should not block CLI execution.
|
|
100
|
+
}
|
|
73
101
|
}
|
|
74
102
|
}
|
|
75
|
-
//
|
|
103
|
+
// Emit analytics for both single- and multi-agent cases
|
|
104
|
+
try {
|
|
105
|
+
capture('dexto_uninstall', {
|
|
106
|
+
requested: agentsToUninstall,
|
|
107
|
+
uninstalled,
|
|
108
|
+
failed,
|
|
109
|
+
successCount,
|
|
110
|
+
errorCount,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Analytics failures should not block CLI execution.
|
|
115
|
+
}
|
|
116
|
+
// For single agent operations, throw error if it failed (after emitting analytics)
|
|
76
117
|
if (agentsToUninstall.length === 1) {
|
|
77
118
|
if (errorCount > 0) {
|
|
78
119
|
throw new Error(errors[0]);
|
|
@@ -135,7 +135,7 @@ function showManualSetupInstructions(provider) {
|
|
|
135
135
|
`${chalk.bold('1. Get an API key:')}`,
|
|
136
136
|
` • ${chalk.green('Google Gemini (Free)')}: https://aistudio.google.com/apikey`,
|
|
137
137
|
` • ${chalk.blue('OpenAI')}: https://platform.openai.com/api-keys`,
|
|
138
|
-
` • ${chalk.magenta('Anthropic')}: https://console.anthropic.com/keys`,
|
|
138
|
+
` • ${chalk.magenta('Anthropic')}: https://console.anthropic.com/settings/keys`,
|
|
139
139
|
` • ${chalk.yellow('Groq (Free)')}: https://console.groq.com/keys`,
|
|
140
140
|
``,
|
|
141
141
|
...envInstructions,
|