dexto 1.13.5 → 1.14.1
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/api/mcp/http-gateway.d.ts +21 -0
- package/dist/api/mcp/http-gateway.d.ts.map +1 -0
- package/dist/api/mcp/http-gateway.js +110 -0
- package/dist/api/mcp/tool-aggregation-handler.d.ts +9 -6
- package/dist/api/mcp/tool-aggregation-handler.d.ts.map +1 -1
- package/dist/api/mcp/tool-aggregation-handler.js +203 -70
- package/dist/api/server-hono.d.ts +2 -0
- package/dist/api/server-hono.d.ts.map +1 -1
- package/dist/api/server-hono.js +377 -276
- package/dist/cli/approval/headless-approval-handler.d.ts +4 -0
- package/dist/cli/approval/headless-approval-handler.d.ts.map +1 -0
- package/dist/cli/approval/headless-approval-handler.js +19 -0
- package/dist/cli/auth/api-client.js +1 -1
- package/dist/cli/auth/constants.d.ts +1 -0
- package/dist/cli/auth/constants.d.ts.map +1 -1
- package/dist/cli/auth/constants.js +2 -1
- package/dist/cli/auth/dexto-api-key.d.ts.map +1 -1
- package/dist/cli/auth/dexto-api-key.js +3 -0
- package/dist/cli/auth/login-persistence.d.ts +1 -1
- package/dist/cli/auth/login-persistence.d.ts.map +1 -1
- package/dist/cli/auth/login-persistence.js +9 -1
- package/dist/cli/auth/service.d.ts +2 -0
- package/dist/cli/auth/service.d.ts.map +1 -1
- package/dist/cli/auth/service.js +1 -0
- package/dist/cli/commands/agents/register.d.ts.map +1 -1
- package/dist/cli/commands/agents/register.js +0 -1
- package/dist/cli/commands/auth/login.d.ts.map +1 -1
- package/dist/cli/commands/auth/login.js +9 -4
- package/dist/cli/commands/cloud/discovery.d.ts +17 -0
- package/dist/cli/commands/cloud/discovery.d.ts.map +1 -0
- package/dist/cli/commands/cloud/discovery.js +88 -0
- package/dist/cli/commands/cloud/register.d.ts +3 -0
- package/dist/cli/commands/cloud/register.d.ts.map +1 -0
- package/dist/cli/commands/cloud/register.js +27 -0
- package/dist/cli/commands/mcp/register.d.ts +1 -1
- package/dist/cli/commands/mcp/register.d.ts.map +1 -1
- package/dist/cli/commands/mcp/register.js +259 -26
- package/dist/cli/commands/mcp/standalone.d.ts +98 -0
- package/dist/cli/commands/mcp/standalone.d.ts.map +1 -0
- package/dist/cli/commands/mcp/standalone.js +489 -0
- package/dist/cli/commands/run/headless.d.ts +3 -1
- package/dist/cli/commands/run/headless.d.ts.map +1 -1
- package/dist/cli/commands/run/headless.js +13 -1
- package/dist/cli/commands/run/output.d.ts +21 -0
- package/dist/cli/commands/run/output.d.ts.map +1 -0
- package/dist/cli/commands/run/output.js +95 -0
- package/dist/cli/commands/run/register.d.ts.map +1 -1
- package/dist/cli/commands/run/register.js +27 -3
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/trace/client.d.ts +2 -2
- package/dist/cli/utils/options.js +3 -1
- package/dist/config/cli-overrides.d.ts +3 -1
- package/dist/config/cli-overrides.d.ts.map +1 -1
- package/dist/config/cli-overrides.js +9 -3
- package/dist/index-main.js +14 -11
- package/dist/utils/env.d.ts +2 -0
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +6 -0
- package/dist/utils/graceful-shutdown.d.ts +1 -1
- package/dist/utils/graceful-shutdown.d.ts.map +1 -1
- package/dist/utils/graceful-shutdown.js +28 -9
- package/package.json +14 -14
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { Option } from 'commander';
|
|
2
|
+
import { handleHeadlessApproval } from '../../approval/headless-approval-handler.js';
|
|
3
|
+
import { writeHeadlessResult } from './output.js';
|
|
1
4
|
import { resolveAgentPath } from '@dexto/agent-management';
|
|
2
5
|
import { withAnalytics, safeExit, ExitSignal } from '../../../analytics/wrapper.js';
|
|
3
6
|
export function registerRunCommand({ program, cliVersion, bootstrapAgentFromGlobalOpts, }) {
|
|
@@ -5,6 +8,9 @@ export function registerRunCommand({ program, cliVersion, bootstrapAgentFromGlob
|
|
|
5
8
|
.command('run [prompt]')
|
|
6
9
|
.description('Run a single prompt non-interactively (headless mode)')
|
|
7
10
|
.option('-m, --model <model>', 'Specify the LLM model to use for this run')
|
|
11
|
+
.addOption(new Option('--format <format>', 'Output format')
|
|
12
|
+
.choices(['text', 'json', 'jsonl'])
|
|
13
|
+
.default('text'))
|
|
8
14
|
.addHelpText('after', `
|
|
9
15
|
Examples:
|
|
10
16
|
$ dexto run "summarize this repository"
|
|
@@ -13,6 +19,8 @@ Examples:
|
|
|
13
19
|
`)
|
|
14
20
|
.action(withAnalytics('run', async (promptArg, runOptions) => {
|
|
15
21
|
let agent;
|
|
22
|
+
let sessionId;
|
|
23
|
+
let result = {};
|
|
16
24
|
let exitCode = 0;
|
|
17
25
|
let exitReason = 'ok';
|
|
18
26
|
try {
|
|
@@ -20,15 +28,19 @@ Examples:
|
|
|
20
28
|
const prompt = await resolveHeadlessPrompt(promptArg);
|
|
21
29
|
if (prompt.trim().length === 0) {
|
|
22
30
|
writeHeadlessError('Prompt cannot be empty.');
|
|
31
|
+
result = { fatalError: new Error('Prompt cannot be empty.') };
|
|
23
32
|
exitCode = 1;
|
|
24
33
|
exitReason = 'empty-prompt';
|
|
25
34
|
}
|
|
26
35
|
else {
|
|
27
|
-
const bootstrapOptions = runOptions
|
|
36
|
+
const bootstrapOptions = runOptions.model
|
|
28
37
|
? { mode: 'headless-run', modelOverride: runOptions.model }
|
|
29
38
|
: { mode: 'headless-run' };
|
|
30
39
|
agent = await bootstrapAgentFromGlobalOpts(bootstrapOptions);
|
|
31
40
|
const session = await agent.createSession();
|
|
41
|
+
sessionId = session.id;
|
|
42
|
+
const approvalAgent = agent;
|
|
43
|
+
approvalAgent.setApprovalHandler((request) => handleHeadlessApproval(request, approvalAgent, session.id));
|
|
32
44
|
const globalOpts = program.opts();
|
|
33
45
|
const resolvedAgentPath = await resolveAgentPath(globalOpts.agent, globalOpts.autoInstall !== false);
|
|
34
46
|
printHeadlessRunSummary({
|
|
@@ -39,13 +51,21 @@ Examples:
|
|
|
39
51
|
cliVersion,
|
|
40
52
|
});
|
|
41
53
|
printHeadlessMcpStartup(agent);
|
|
42
|
-
const runResult = await executeHeadlessRun(agent, session.id, prompt);
|
|
54
|
+
const runResult = await executeHeadlessRun(agent, session.id, prompt, runOptions.format);
|
|
55
|
+
result = runResult;
|
|
43
56
|
if (runResult.finalMessage !== undefined) {
|
|
44
57
|
printHeadlessAssistantResponse(runResult.finalMessage, runResult.totalTokens);
|
|
45
|
-
|
|
58
|
+
if (runOptions.format === 'text') {
|
|
59
|
+
writeFinalMessageToStdout(runResult.finalMessage);
|
|
60
|
+
}
|
|
46
61
|
}
|
|
47
62
|
else {
|
|
48
63
|
writeHeadlessError('No final response was produced.');
|
|
64
|
+
result = {
|
|
65
|
+
...runResult,
|
|
66
|
+
fatalError: runResult.fatalError ??
|
|
67
|
+
new Error('No final response was produced.'),
|
|
68
|
+
};
|
|
49
69
|
exitCode = 1;
|
|
50
70
|
exitReason = 'no-final-response';
|
|
51
71
|
}
|
|
@@ -59,6 +79,9 @@ Examples:
|
|
|
59
79
|
if (err instanceof ExitSignal)
|
|
60
80
|
throw err;
|
|
61
81
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
82
|
+
result = {
|
|
83
|
+
fatalError: err instanceof Error ? err : new Error(errorMessage),
|
|
84
|
+
};
|
|
62
85
|
process.stderr.write(`dexto run failed: ${errorMessage}\n`);
|
|
63
86
|
exitCode = 1;
|
|
64
87
|
exitReason = 'error';
|
|
@@ -73,6 +96,7 @@ Examples:
|
|
|
73
96
|
}
|
|
74
97
|
}
|
|
75
98
|
}
|
|
99
|
+
await writeHeadlessResult(runOptions.format, result, sessionId);
|
|
76
100
|
safeExit('run', exitCode, exitReason);
|
|
77
101
|
}));
|
|
78
102
|
}
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
declare const SetupCommandSchema: z.ZodObject<{
|
|
3
3
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
4
4
|
"dexto-nova": "dexto-nova";
|
|
5
|
+
local: "local";
|
|
5
6
|
openai: "openai";
|
|
6
7
|
"openai-compatible": "openai-compatible";
|
|
7
8
|
anthropic: "anthropic";
|
|
@@ -16,7 +17,6 @@ declare const SetupCommandSchema: z.ZodObject<{
|
|
|
16
17
|
glama: "glama";
|
|
17
18
|
vertex: "vertex";
|
|
18
19
|
bedrock: "bedrock";
|
|
19
|
-
local: "local";
|
|
20
20
|
ollama: "ollama";
|
|
21
21
|
}>>;
|
|
22
22
|
model: z.ZodOptional<z.ZodString>;
|
|
@@ -25,11 +25,11 @@ declare const SetupCommandSchema: z.ZodObject<{
|
|
|
25
25
|
force: z.ZodDefault<z.ZodBoolean>;
|
|
26
26
|
defaultMode: z.ZodOptional<z.ZodEnum<{
|
|
27
27
|
cli: "cli";
|
|
28
|
+
mcp: "mcp";
|
|
28
29
|
web: "web";
|
|
29
30
|
server: "server";
|
|
30
31
|
discord: "discord";
|
|
31
32
|
telegram: "telegram";
|
|
32
|
-
mcp: "mcp";
|
|
33
33
|
}>>;
|
|
34
34
|
quickStart: z.ZodDefault<z.ZodBoolean>;
|
|
35
35
|
}, z.core.$strict>;
|
|
@@ -15,8 +15,8 @@ declare const RunTraceSpanSchema: z.ZodObject<{
|
|
|
15
15
|
startedAt: z.ZodString;
|
|
16
16
|
status: z.ZodEnum<{
|
|
17
17
|
failed: "failed";
|
|
18
|
-
completed: "completed";
|
|
19
18
|
cancelled: "cancelled";
|
|
19
|
+
completed: "completed";
|
|
20
20
|
running: "running";
|
|
21
21
|
}>;
|
|
22
22
|
traceId: z.ZodString;
|
|
@@ -46,8 +46,8 @@ declare const RunTraceSchema: z.ZodObject<{
|
|
|
46
46
|
startedAt: z.ZodString;
|
|
47
47
|
status: z.ZodEnum<{
|
|
48
48
|
failed: "failed";
|
|
49
|
-
completed: "completed";
|
|
50
49
|
cancelled: "cancelled";
|
|
50
|
+
completed: "completed";
|
|
51
51
|
running: "running";
|
|
52
52
|
}>;
|
|
53
53
|
traceId: z.ZodString;
|
|
@@ -30,6 +30,7 @@ export function validateCliOptions(opts) {
|
|
|
30
30
|
return !isNaN(port) && port > 0 && port <= 65535;
|
|
31
31
|
}, { message: 'Port must be a number between 1 and 65535' })
|
|
32
32
|
.optional(),
|
|
33
|
+
permissionsMode: z.enum(['manual', 'auto-approve']).optional(),
|
|
33
34
|
autoApprove: z
|
|
34
35
|
.boolean()
|
|
35
36
|
.optional()
|
|
@@ -39,7 +40,7 @@ export function validateCliOptions(opts) {
|
|
|
39
40
|
.boolean()
|
|
40
41
|
.optional()
|
|
41
42
|
.default(false)
|
|
42
|
-
.describe('
|
|
43
|
+
.describe('Select auto-approve permissions'),
|
|
43
44
|
elicitation: z
|
|
44
45
|
.boolean()
|
|
45
46
|
.optional()
|
|
@@ -91,6 +92,7 @@ export function validateCliOptions(opts) {
|
|
|
91
92
|
provider: opts.provider,
|
|
92
93
|
model: opts.model,
|
|
93
94
|
interactive: opts.interactive,
|
|
95
|
+
permissionsMode: opts.permissionsMode,
|
|
94
96
|
autoApprove: opts.autoApprove,
|
|
95
97
|
bypassPermissions: opts.bypassPermissions,
|
|
96
98
|
elicitation: opts.elicitation,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import type { AgentConfig } from '@dexto/agent-config';
|
|
22
22
|
import { type LLMProvider } from '@dexto/llm';
|
|
23
|
-
import { type LLMConfig } from '@dexto/core';
|
|
23
|
+
import { type LLMConfig, type PermissionsMode } from '@dexto/core';
|
|
24
24
|
import type { GlobalPreferences } from '@dexto/agent-management';
|
|
25
25
|
/**
|
|
26
26
|
* CLI config override type for fields that can be overridden via CLI
|
|
@@ -28,6 +28,8 @@ import type { GlobalPreferences } from '@dexto/agent-management';
|
|
|
28
28
|
*/
|
|
29
29
|
export interface CLIConfigOverrides extends Partial<Pick<LLMConfig, 'provider' | 'model' | 'apiKey'>> {
|
|
30
30
|
autoApprove?: boolean;
|
|
31
|
+
bypassPermissions?: boolean;
|
|
32
|
+
permissionsMode?: PermissionsMode;
|
|
31
33
|
/** When false (via --no-elicitation), disables elicitation */
|
|
32
34
|
elicitation?: boolean;
|
|
33
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-overrides.d.ts","sourceRoot":"","sources":["../../src/config/cli-overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAKH,KAAK,WAAW,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,
|
|
1
|
+
{"version":3,"file":"cli-overrides.d.ts","sourceRoot":"","sources":["../../src/config/cli-overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAKH,KAAK,WAAW,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAGH,KAAK,SAAS,EACd,KAAK,eAAe,EACvB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,kBACb,SAAQ,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,2BAA2B,EAAE,OAAO,CAAC;IACrC,wBAAwB,EAAE,OAAO,CAAC;IAClC,yBAAyB,EAAE,OAAO,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,WAAW,EACvB,YAAY,CAAC,EAAE,kBAAkB,GAClC,WAAW,CAoDb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAChC,UAAU,EAAE,WAAW,EACvB,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACxC,WAAW,CAwBb;AAED,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,yBAAyB,GACnC,WAAW,CAyCb;AAcD,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,WAAW,EACrB,SAAS,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,GAC3D,OAAO,CAgBT;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,WAAW,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACnC,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,iBAAiB,GAAG,IAAI,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,GACnC,wBAAwB,CAwC1B"}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* - Merge strategy configuration for non-LLM fields
|
|
20
20
|
*/
|
|
21
21
|
import { LLM_PROVIDERS, getDefaultModelForProvider, requiresApiKey, requiresBaseURL, } from '@dexto/llm';
|
|
22
|
-
import { EnvExpandedString, resolveApiKeyForProvider } from '@dexto/core';
|
|
22
|
+
import { EnvExpandedString, resolveApiKeyForProvider, } from '@dexto/core';
|
|
23
23
|
/**
|
|
24
24
|
* Applies CLI overrides to an agent configuration
|
|
25
25
|
* This merges CLI arguments into the base config without validation.
|
|
@@ -34,6 +34,10 @@ export function applyCLIOverrides(baseConfig, cliOverrides) {
|
|
|
34
34
|
// No overrides, return base config as-is (no validation yet)
|
|
35
35
|
return baseConfig;
|
|
36
36
|
}
|
|
37
|
+
if (cliOverrides.permissionsMode === 'manual' &&
|
|
38
|
+
(cliOverrides.autoApprove || cliOverrides.bypassPermissions)) {
|
|
39
|
+
throw new Error('--permissions-mode manual conflicts with --auto-approve and --bypass-permissions.');
|
|
40
|
+
}
|
|
37
41
|
// Create a deep copy of the base config for modification
|
|
38
42
|
const mergedConfig = JSON.parse(JSON.stringify(baseConfig));
|
|
39
43
|
// Apply CLI overrides to LLM config (llm is required in AgentConfig)
|
|
@@ -46,11 +50,13 @@ export function applyCLIOverrides(baseConfig, cliOverrides) {
|
|
|
46
50
|
if (cliOverrides.apiKey) {
|
|
47
51
|
mergedConfig.llm.apiKey = cliOverrides.apiKey;
|
|
48
52
|
}
|
|
49
|
-
if (cliOverrides.
|
|
53
|
+
if (cliOverrides.permissionsMode ||
|
|
54
|
+
cliOverrides.autoApprove ||
|
|
55
|
+
cliOverrides.bypassPermissions) {
|
|
50
56
|
// Ensure permissions section exists before overriding
|
|
51
57
|
mergedConfig.permissions = {
|
|
52
58
|
...(mergedConfig.permissions ?? {}),
|
|
53
|
-
mode: 'auto-approve',
|
|
59
|
+
mode: cliOverrides.permissionsMode ?? 'auto-approve',
|
|
54
60
|
};
|
|
55
61
|
}
|
|
56
62
|
if (cliOverrides.elicitation === false) {
|
package/dist/index-main.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import { Command } from 'commander';
|
|
4
|
+
import { Command, Option } from 'commander';
|
|
5
5
|
import * as p from '@clack/prompts';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { withAnalytics, safeExit, ExitSignal } from './analytics/wrapper.js';
|
|
8
|
+
import { handleHeadlessApproval } from './cli/approval/headless-approval-handler.js';
|
|
8
9
|
function readVersionFromPackageJson(packageJsonPath) {
|
|
9
10
|
if (!existsSync(packageJsonPath)) {
|
|
10
11
|
return undefined;
|
|
@@ -46,7 +47,7 @@ process.env.DEXTO_CLI_VERSION = cliVersion;
|
|
|
46
47
|
import { logger, startLlmRegistryAutoUpdate, DextoAgent, isPath } from '@dexto/core';
|
|
47
48
|
import { getAllSupportedModels, getProviderFromModel } from '@dexto/llm';
|
|
48
49
|
import { applyImageDefaults, cleanNullValues, AgentConfigSchema, loadImage, resolveServicesFromConfig, toDextoAgentOptions, } from '@dexto/agent-config';
|
|
49
|
-
import { getDextoPackageRoot, resolveAgentPath, loadAgentConfig, findDextoProjectRoot, globalPreferencesExist, loadGlobalPreferences, resolveBundledScript, enrichAgentConfig, isDextoAuthEnabled, createModelAuthResolver, resolveApiKeyForProvider, getPrimaryApiKeyEnvVar, } from '@dexto/agent-management';
|
|
50
|
+
import { registerConfiguredSkillPrompts, getDextoPackageRoot, resolveAgentPath, loadAgentConfig, findDextoProjectRoot, globalPreferencesExist, loadGlobalPreferences, resolveBundledScript, enrichAgentConfig, isDextoAuthEnabled, createModelAuthResolver, resolveApiKeyForProvider, getPrimaryApiKeyEnvVar, } from '@dexto/agent-management';
|
|
50
51
|
import { validateCliOptions, handleCliOptionsError } from './cli/utils/options.js';
|
|
51
52
|
import { validateAgentConfig } from './cli/utils/config-validation.js';
|
|
52
53
|
import { applyCLIOverrides, applyStartupLLMFallback, applyUserPreferences, } from './config/cli-overrides.js';
|
|
@@ -55,6 +56,7 @@ import { registerSessionCommand } from './cli/commands/session/register.js';
|
|
|
55
56
|
import { registerSearchCommand } from './cli/commands/search/register.js';
|
|
56
57
|
import { registerAuthCommand } from './cli/commands/auth/register.js';
|
|
57
58
|
import { registerBillingCommand } from './cli/commands/billing/register.js';
|
|
59
|
+
import { registerCloudCommand } from './cli/commands/cloud/register.js';
|
|
58
60
|
import { registerMcpCommand } from './cli/commands/mcp/register.js';
|
|
59
61
|
import { registerImageCommand } from './cli/commands/image/register.js';
|
|
60
62
|
import { registerPluginCommand } from './cli/commands/plugin/register.js';
|
|
@@ -110,8 +112,9 @@ program
|
|
|
110
112
|
.option('--no-interactive', 'Disable interactive prompts and API key setup')
|
|
111
113
|
.option('--skip-setup', 'Skip global setup validation (useful for MCP mode, automation)')
|
|
112
114
|
.option('-m, --model <model>', 'Specify the LLM model to use')
|
|
113
|
-
.
|
|
114
|
-
.option('--
|
|
115
|
+
.addOption(new Option('--permissions-mode <mode>', "Override the local agent's configured approval mode").choices(['manual', 'auto-approve']))
|
|
116
|
+
.option('--auto-approve', 'Select auto-approve permissions (mandatory approvals still apply)')
|
|
117
|
+
.option('--bypass-permissions', 'Select auto-approve permissions (alias for --permissions-mode auto-approve)')
|
|
115
118
|
.option('--no-elicitation', 'Disable elicitation (agent cannot prompt user for input)')
|
|
116
119
|
.option('-c, --continue', 'Continue most recent session (CLI mode)')
|
|
117
120
|
.option('-r, --resume <sessionId>', 'Resume a session by ID (CLI mode)')
|
|
@@ -343,6 +346,9 @@ async function bootstrapAgentFromGlobalOpts(options) {
|
|
|
343
346
|
console.error(err.message);
|
|
344
347
|
}
|
|
345
348
|
console.error(`💡 Install it with: dexto image install ${imageName}`);
|
|
349
|
+
if (isHeadlessRun) {
|
|
350
|
+
throw new Error(`Failed to load image '${imageName}'`, { cause: err });
|
|
351
|
+
}
|
|
346
352
|
safeExit('bootstrap', 1, 'image-load-failed');
|
|
347
353
|
}
|
|
348
354
|
const configWithImageDefaults = applyImageDefaults(mergedConfig, image.defaults);
|
|
@@ -361,13 +367,6 @@ async function bootstrapAgentFromGlobalOpts(options) {
|
|
|
361
367
|
transports: [{ type: 'silent' }],
|
|
362
368
|
};
|
|
363
369
|
}
|
|
364
|
-
// Override approval config for non-interactive commands.
|
|
365
|
-
// Headless operations default to auto-approve and disable elicitation to
|
|
366
|
-
// avoid waiting for interactive approval handlers.
|
|
367
|
-
enrichedConfig.permissions = {
|
|
368
|
-
...(enrichedConfig.permissions ?? {}),
|
|
369
|
-
mode: 'auto-approve',
|
|
370
|
-
};
|
|
371
370
|
enrichedConfig.elicitation = {
|
|
372
371
|
enabled: false,
|
|
373
372
|
...(enrichedConfig.elicitation?.timeout !== undefined && {
|
|
@@ -376,6 +375,7 @@ async function bootstrapAgentFromGlobalOpts(options) {
|
|
|
376
375
|
};
|
|
377
376
|
const validatedConfig = AgentConfigSchema.parse(enrichedConfig);
|
|
378
377
|
const services = await resolveServicesFromConfig(validatedConfig, image, { workspaceRoot });
|
|
378
|
+
registerConfiguredSkillPrompts(services.skills, validatedConfig.prompts);
|
|
379
379
|
const agent = new DextoAgent(toDextoAgentOptions({
|
|
380
380
|
config: validatedConfig,
|
|
381
381
|
services,
|
|
@@ -385,6 +385,7 @@ async function bootstrapAgentFromGlobalOpts(options) {
|
|
|
385
385
|
authResolver: createModelAuthResolver(),
|
|
386
386
|
},
|
|
387
387
|
}));
|
|
388
|
+
agent.setApprovalHandler((request) => handleHeadlessApproval(request, agent, undefined));
|
|
388
389
|
await agent.start();
|
|
389
390
|
await (await import('./utils/workspace.js')).applyWorkspaceToAgent(agent, workspaceRoot);
|
|
390
391
|
// Register graceful shutdown
|
|
@@ -411,6 +412,7 @@ registerSessionCommand(runtimeCommandContext);
|
|
|
411
412
|
registerSearchCommand(runtimeCommandContext);
|
|
412
413
|
registerAuthCommand(runtimeCommandContext);
|
|
413
414
|
registerBillingCommand(runtimeCommandContext);
|
|
415
|
+
registerCloudCommand(program);
|
|
414
416
|
registerMcpCommand({ program });
|
|
415
417
|
// 13) Main dexto CLI - Interactive (CLI) or run in other modes (--mode web/server/mcp)
|
|
416
418
|
program
|
|
@@ -861,6 +863,7 @@ program
|
|
|
861
863
|
const services = await resolveServicesFromConfig(validatedConfig, image, {
|
|
862
864
|
workspaceRoot,
|
|
863
865
|
});
|
|
866
|
+
registerConfiguredSkillPrompts(services.skills, validatedConfig.prompts);
|
|
864
867
|
agent = new DextoAgent(toDextoAgentOptions({
|
|
865
868
|
config: validatedConfig,
|
|
866
869
|
services,
|
package/dist/utils/env.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Read an environment value from before CLI dotenv loading. */
|
|
2
|
+
export declare function getIncomingEnvironmentVariable(name: string): string | undefined;
|
|
1
3
|
/**
|
|
2
4
|
* Multi-layer environment variable loading with context awareness.
|
|
3
5
|
* Loads environment variables in priority order:
|
package/dist/utils/env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAWA,gEAAgE;AAChE,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC1C,SAAS,GAAE,MAAsB,GAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgDjC;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAChD,SAAS,GAAE,MAAsB,GAClC,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
package/dist/utils/env.js
CHANGED
|
@@ -2,6 +2,11 @@ import * as path from 'path';
|
|
|
2
2
|
import { homedir } from 'os';
|
|
3
3
|
import dotenv from 'dotenv';
|
|
4
4
|
import { getExecutionContext, ensureDextoGlobalDirectory, getDextoEnvPath, } from '@dexto/agent-management';
|
|
5
|
+
let incomingEnvironment;
|
|
6
|
+
/** Read an environment value from before CLI dotenv loading. */
|
|
7
|
+
export function getIncomingEnvironmentVariable(name) {
|
|
8
|
+
return (incomingEnvironment ?? process.env)[name];
|
|
9
|
+
}
|
|
5
10
|
/**
|
|
6
11
|
* Multi-layer environment variable loading with context awareness.
|
|
7
12
|
* Loads environment variables in priority order:
|
|
@@ -67,6 +72,7 @@ export async function loadEnvironmentVariables(startPath = process.cwd()) {
|
|
|
67
72
|
* @param startPath Starting directory for project detection
|
|
68
73
|
*/
|
|
69
74
|
export async function applyLayeredEnvironmentLoading(startPath = process.cwd()) {
|
|
75
|
+
incomingEnvironment = { ...process.env };
|
|
70
76
|
await ensureDextoGlobalDirectory();
|
|
71
77
|
const layeredEnv = await loadEnvironmentVariables(startPath);
|
|
72
78
|
Object.assign(process.env, layeredEnv);
|
|
@@ -13,6 +13,6 @@ export interface GracefulShutdownOptions {
|
|
|
13
13
|
*/
|
|
14
14
|
forceExitTimeout?: number;
|
|
15
15
|
}
|
|
16
|
-
export declare function registerGracefulShutdown(getCurrentAgent: () => ShutdownTarget, options?: GracefulShutdownOptions): void;
|
|
16
|
+
export declare function registerGracefulShutdown(getCurrentAgent: () => ShutdownTarget, options?: GracefulShutdownOptions): () => void;
|
|
17
17
|
export {};
|
|
18
18
|
//# sourceMappingURL=graceful-shutdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graceful-shutdown.d.ts","sourceRoot":"","sources":["../../src/utils/graceful-shutdown.ts"],"names":[],"mappings":"AAEA,UAAU,cAAc;IACpB,IAAI,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,uBAAuB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,wBAAwB,CACpC,eAAe,EAAE,MAAM,cAAc,EACrC,OAAO,GAAE,uBAA4B,GACtC,IAAI,
|
|
1
|
+
{"version":3,"file":"graceful-shutdown.d.ts","sourceRoot":"","sources":["../../src/utils/graceful-shutdown.ts"],"names":[],"mappings":"AAEA,UAAU,cAAc;IACpB,IAAI,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,uBAAuB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,wBAAwB,CACpC,eAAe,EAAE,MAAM,cAAc,EACrC,OAAO,GAAE,uBAA4B,GACtC,MAAM,IAAI,CAoIZ"}
|
|
@@ -24,13 +24,19 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
24
24
|
process.exit(1);
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
|
-
signals.
|
|
28
|
-
|
|
27
|
+
const signalListeners = signals.map((signal) => {
|
|
28
|
+
const listener = () => {
|
|
29
|
+
void performShutdown(signal);
|
|
30
|
+
};
|
|
31
|
+
process.on(signal, listener);
|
|
32
|
+
return { signal, listener };
|
|
29
33
|
});
|
|
34
|
+
let sigintListener;
|
|
35
|
+
let resetTimer;
|
|
30
36
|
// In ink mode, handle SIGINT specially - allow first one to pass through to Ink
|
|
31
37
|
if (inkMode) {
|
|
32
38
|
let firstSigintTime = null;
|
|
33
|
-
|
|
39
|
+
sigintListener = () => {
|
|
34
40
|
const now = Date.now();
|
|
35
41
|
// If already shutting down, ignore
|
|
36
42
|
if (isShuttingDown)
|
|
@@ -39,7 +45,7 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
39
45
|
if (firstSigintTime === null) {
|
|
40
46
|
firstSigintTime = now;
|
|
41
47
|
// Set timeout to clear the "first sigint" state
|
|
42
|
-
setTimeout(() => {
|
|
48
|
+
resetTimer = setTimeout(() => {
|
|
43
49
|
if (firstSigintTime !== null &&
|
|
44
50
|
Date.now() - firstSigintTime >= forceExitTimeout) {
|
|
45
51
|
firstSigintTime = null;
|
|
@@ -56,10 +62,11 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
56
62
|
// Timeout expired, treat as new first SIGINT
|
|
57
63
|
firstSigintTime = now;
|
|
58
64
|
}
|
|
59
|
-
}
|
|
65
|
+
};
|
|
66
|
+
process.on('SIGINT', sigintListener);
|
|
60
67
|
}
|
|
61
68
|
// Handle uncaught exceptions
|
|
62
|
-
|
|
69
|
+
const exceptionListener = async (error) => {
|
|
63
70
|
logger.error(`Uncaught exception: ${error instanceof Error ? error.message : String(error)}`, { error }, 'red');
|
|
64
71
|
if (!isShuttingDown) {
|
|
65
72
|
isShuttingDown = true;
|
|
@@ -74,8 +81,9 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
process.on('
|
|
84
|
+
};
|
|
85
|
+
process.on('uncaughtException', exceptionListener);
|
|
86
|
+
const rejectionListener = async (reason) => {
|
|
79
87
|
logger.error(`Unhandled rejection: ${reason}`, { reason }, 'red');
|
|
80
88
|
if (!isShuttingDown) {
|
|
81
89
|
isShuttingDown = true;
|
|
@@ -90,5 +98,16 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
100
|
process.exit(1);
|
|
93
|
-
}
|
|
101
|
+
};
|
|
102
|
+
process.on('unhandledRejection', rejectionListener);
|
|
103
|
+
return () => {
|
|
104
|
+
for (const { signal, listener } of signalListeners)
|
|
105
|
+
process.off(signal, listener);
|
|
106
|
+
if (sigintListener)
|
|
107
|
+
process.off('SIGINT', sigintListener);
|
|
108
|
+
if (resetTimer)
|
|
109
|
+
clearTimeout(resetTimer);
|
|
110
|
+
process.off('uncaughtException', exceptionListener);
|
|
111
|
+
process.off('unhandledRejection', rejectionListener);
|
|
112
|
+
};
|
|
94
113
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dexto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"dexto": "./dist/index.js"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@clack/prompts": "^0.10.1",
|
|
10
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
10
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
11
11
|
"@opentelemetry/instrumentation-http": "^0.210.0",
|
|
12
12
|
"@opentelemetry/instrumentation-undici": "^0.20.0",
|
|
13
13
|
"@opentelemetry/core": "^1.28.0",
|
|
@@ -34,18 +34,18 @@
|
|
|
34
34
|
"ws": "^8.18.1",
|
|
35
35
|
"yaml": "^2.8.3",
|
|
36
36
|
"zod": "^4.3.6",
|
|
37
|
-
"@dexto/agent-config": "1.
|
|
38
|
-
"@dexto/agent-management": "1.
|
|
39
|
-
"@dexto/analytics": "1.
|
|
40
|
-
"@dexto/client-sdk": "1.
|
|
41
|
-
"@dexto/core": "1.
|
|
42
|
-
"@dexto/image-local": "1.
|
|
43
|
-
"@dexto/image-logger-agent": "1.
|
|
44
|
-
"@dexto/llm": "1.
|
|
45
|
-
"@dexto/registry": "1.
|
|
46
|
-
"@dexto/server": "1.
|
|
47
|
-
"@dexto/storage": "1.
|
|
48
|
-
"@dexto/tui": "1.
|
|
37
|
+
"@dexto/agent-config": "1.14.1",
|
|
38
|
+
"@dexto/agent-management": "1.14.1",
|
|
39
|
+
"@dexto/analytics": "1.14.1",
|
|
40
|
+
"@dexto/client-sdk": "1.14.1",
|
|
41
|
+
"@dexto/core": "1.14.1",
|
|
42
|
+
"@dexto/image-local": "1.14.1",
|
|
43
|
+
"@dexto/image-logger-agent": "1.14.1",
|
|
44
|
+
"@dexto/llm": "1.14.1",
|
|
45
|
+
"@dexto/registry": "1.14.1",
|
|
46
|
+
"@dexto/server": "1.14.1",
|
|
47
|
+
"@dexto/storage": "1.14.1",
|
|
48
|
+
"@dexto/tui": "1.14.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/ws": "^8.5.11",
|