dexto 1.6.16 → 1.6.18
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/cli/cloud-chat.d.ts +18 -0
- package/dist/cli/cloud-chat.d.ts.map +1 -0
- package/dist/cli/cloud-chat.js +697 -0
- package/dist/cli/commands/deploy/client.d.ts +92 -0
- package/dist/cli/commands/deploy/client.d.ts.map +1 -1
- package/dist/cli/commands/deploy/client.js +260 -4
- package/dist/cli/commands/deploy/index.d.ts +1 -0
- package/dist/cli/commands/deploy/index.d.ts.map +1 -1
- package/dist/cli/commands/deploy/index.js +73 -0
- package/dist/cli/commands/deploy/register.d.ts.map +1 -1
- package/dist/cli/commands/deploy/register.js +19 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +259 -8
- package/dist/index-main.js +30 -3
- package/dist/utils/graceful-shutdown.d.ts +5 -2
- package/dist/utils/graceful-shutdown.d.ts.map +1 -1
- package/dist/utils/graceful-shutdown.js +9 -3
- package/dist/webui/assets/{index-UDAdxmci.js → index-COTVlYsv.js} +1 -1
- package/dist/webui/index.html +1 -1
- package/package.json +15 -14
|
@@ -14,6 +14,9 @@ import { confirmOrExit, multiselectOrExit, selectOrExit, textOrExit, } from '../
|
|
|
14
14
|
import { ensureImageImporterConfigured } from '../utils/image-importer.js';
|
|
15
15
|
const AGENTS_FILENAME = 'AGENTS.md';
|
|
16
16
|
const WORKSPACE_DIRECTORIES = ['agents', 'skills'];
|
|
17
|
+
const SKILL_RESOURCE_DIRECTORIES = ['handlers', 'scripts', 'mcps', 'references'];
|
|
18
|
+
const STARTER_SKILL_ID = 'create-skill';
|
|
19
|
+
const STARTER_SKILL_IDS = [STARTER_SKILL_ID];
|
|
17
20
|
const DEFAULT_AGENT_PROVIDER = 'openai';
|
|
18
21
|
const DEFAULT_AGENT_MODEL = 'gpt-5.3-codex';
|
|
19
22
|
const DEFAULT_AGENTS_MD = `<!-- dexto-workspace -->
|
|
@@ -24,7 +27,8 @@ This workspace can define project-specific agents and skills.
|
|
|
24
27
|
|
|
25
28
|
## Structure
|
|
26
29
|
- Put custom agents and subagents in \`agents/\`
|
|
27
|
-
- Put custom skills in \`skills/<skill-id
|
|
30
|
+
- Put custom skills in \`skills/<skill-id>/\`
|
|
31
|
+
- Each skill bundle should keep \`SKILL.md\` plus optional \`handlers/\`, \`scripts/\`, \`mcps/\`, and \`references/\`
|
|
28
32
|
- Use \`.dexto/\` only for Dexto-managed state and installed assets
|
|
29
33
|
|
|
30
34
|
## Defaults
|
|
@@ -831,14 +835,22 @@ description: "TODO: Describe when to use this skill."
|
|
|
831
835
|
## Purpose
|
|
832
836
|
Describe what this skill helps the agent accomplish.
|
|
833
837
|
|
|
834
|
-
##
|
|
838
|
+
## When To Use
|
|
835
839
|
- The task or context that should trigger this skill
|
|
836
840
|
- Relevant files, paths, or constraints
|
|
837
841
|
|
|
838
|
-
##
|
|
839
|
-
1. Review the relevant context.
|
|
840
|
-
2.
|
|
841
|
-
3.
|
|
842
|
+
## Workflow
|
|
843
|
+
1. Review the relevant context and only open bundled files that are actually needed.
|
|
844
|
+
2. Use \`references/\` for background knowledge, schemas, or examples.
|
|
845
|
+
3. Use \`scripts/\` for deterministic helper code and \`handlers/\` for reusable workflow logic.
|
|
846
|
+
4. Use \`mcps/\` for any MCP server configs this skill needs to carry with it.
|
|
847
|
+
5. Return a concise result with any important follow-up actions.
|
|
848
|
+
|
|
849
|
+
## Bundled Resources
|
|
850
|
+
- \`handlers/\`: Reusable workflow helpers or code snippets this skill can point to
|
|
851
|
+
- \`scripts/\`: Executable helpers for deterministic or repetitive tasks
|
|
852
|
+
- \`mcps/\`: MCP server config JSON files associated with this skill
|
|
853
|
+
- \`references/\`: Docs, schemas, examples, or domain notes to load on demand
|
|
842
854
|
|
|
843
855
|
## Output Format
|
|
844
856
|
- Summary of what was found or changed
|
|
@@ -846,6 +858,215 @@ Describe what this skill helps the agent accomplish.
|
|
|
846
858
|
- Follow-up actions, if any
|
|
847
859
|
`;
|
|
848
860
|
}
|
|
861
|
+
function buildCreateSkillStarterTemplate() {
|
|
862
|
+
return `---
|
|
863
|
+
name: "${STARTER_SKILL_ID}"
|
|
864
|
+
description: "Create or update Dexto skill bundles with SKILL.md, handlers, scripts, mcps, and references."
|
|
865
|
+
toolkits: ["creator-tools"]
|
|
866
|
+
allowed-tools: ["skill_create", "skill_update", "skill_refresh", "skill_search", "skill_list", "tool_catalog"]
|
|
867
|
+
---
|
|
868
|
+
|
|
869
|
+
# Create Skill
|
|
870
|
+
|
|
871
|
+
Create or update standalone Dexto skill bundles. Treat \`skills/<id>/\` as the canonical workspace location unless the user explicitly asks for a global skill.
|
|
872
|
+
|
|
873
|
+
## Core Flow
|
|
874
|
+
1. Search for overlap first with \`skill_list\` and \`skill_search\`.
|
|
875
|
+
2. Propose a kebab-case id, one-sentence description, scope, and the minimum tool access the skill needs.
|
|
876
|
+
3. Create or update the skill bundle.
|
|
877
|
+
4. Keep \`SKILL.md\` focused on trigger conditions, workflow, and when to open bundled files.
|
|
878
|
+
5. Add bundled files only when they materially improve the workflow:
|
|
879
|
+
- \`references/\` for larger docs, copied external material, schemas, examples, or policies
|
|
880
|
+
- \`scripts/\` for deterministic helpers
|
|
881
|
+
- \`handlers/\` for reusable workflow logic or structured helper code
|
|
882
|
+
- \`mcps/\` for MCP configs the skill should carry with it
|
|
883
|
+
- When a skill needs a real bundled MCP server, prefer the SDK-based stdio pattern in \`references/mcp-server-pattern.md\`
|
|
884
|
+
6. Prefer extending existing skills or references over duplicating content.
|
|
885
|
+
7. If you edit \`SKILL.md\` or bundled files with non-creator tools, run \`skill_refresh\` before relying on the skill in the current session.
|
|
886
|
+
8. Creating \`mcps/*.json\` only creates bundled MCP config. Do not say you created a real MCP server unless the config points at a bundled runnable implementation or a verified external command/package.
|
|
887
|
+
|
|
888
|
+
## Authoring Rules
|
|
889
|
+
- Default to workspace scope.
|
|
890
|
+
- Default to no extra toolkits and no \`allowed-tools\` unless the skill needs them.
|
|
891
|
+
- Keep most actionable instructions in \`SKILL.md\` so the agent can act without opening extra files.
|
|
892
|
+
- Use \`references/\` sparingly for larger copied docs, external references, schemas, examples, or policies.
|
|
893
|
+
- Keep references one level deep from \`SKILL.md\` and link them explicitly.
|
|
894
|
+
- Reuse language and conventions from nearby skills when possible.
|
|
895
|
+
- If you add MCP config files or update bundled resources outside creator tools, run \`skill_refresh\` so the current session reloads the skill metadata before invoking it.
|
|
896
|
+
- For real bundled MCPs, prefer the official \`@modelcontextprotocol/sdk\` server APIs with \`StdioServerTransport\`. Avoid hand-rolled Content-Length framing unless the user explicitly asks for low-level protocol code.
|
|
897
|
+
|
|
898
|
+
## SKILL.md Structure
|
|
899
|
+
- \`# <Title>\`
|
|
900
|
+
- \`## Purpose\`
|
|
901
|
+
- \`## When To Use\`
|
|
902
|
+
- \`## Workflow\`
|
|
903
|
+
- \`## Bundled Resources\`
|
|
904
|
+
- \`## Output Format\`
|
|
905
|
+
|
|
906
|
+
## Resource Guide
|
|
907
|
+
Read \`references/skill-anatomy.md\` when you need the bundle layout or packaging checklist.
|
|
908
|
+
Read \`references/mcp-server-pattern.md\` when the skill needs a bundled MCP server implementation.
|
|
909
|
+
`;
|
|
910
|
+
}
|
|
911
|
+
function buildCreateSkillStarterReference() {
|
|
912
|
+
return `# Skill Anatomy
|
|
913
|
+
|
|
914
|
+
## Canonical Layout
|
|
915
|
+
\`\`\`
|
|
916
|
+
skills/<skill-id>/
|
|
917
|
+
├── SKILL.md
|
|
918
|
+
├── handlers/
|
|
919
|
+
├── scripts/
|
|
920
|
+
├── mcps/
|
|
921
|
+
└── references/
|
|
922
|
+
\`\`\`
|
|
923
|
+
|
|
924
|
+
## What Goes Where
|
|
925
|
+
- \`SKILL.md\`: The trigger, workflow, and navigation entrypoint.
|
|
926
|
+
- \`handlers/\`: Reusable helper code or structured workflow fragments the skill can reference.
|
|
927
|
+
- \`scripts/\`: Deterministic helpers the agent can run instead of rewriting logic.
|
|
928
|
+
- \`mcps/\`: JSON config fragments for MCP servers used by the skill. This is config only, not proof that the MCP implementation exists.
|
|
929
|
+
- \`references/\`: Supporting material the agent should open only when needed, especially larger copied docs, schemas, external references, or long examples.
|
|
930
|
+
|
|
931
|
+
## Creation Checklist
|
|
932
|
+
1. Search existing skills first to avoid duplicates.
|
|
933
|
+
2. Pick a kebab-case id and concise description.
|
|
934
|
+
3. Keep actionable workflow in \`SKILL.md\`; move only larger reference material into \`references/\`.
|
|
935
|
+
4. Add scripts or handlers only when they remove repeated work or improve reliability.
|
|
936
|
+
5. Add MCP configs only when the skill truly depends on them.
|
|
937
|
+
6. Reference bundled files from \`SKILL.md\` using relative paths.
|
|
938
|
+
|
|
939
|
+
## MCP Notes
|
|
940
|
+
- Store standalone skill MCP configs as JSON files in \`mcps/\`.
|
|
941
|
+
- Each file may define one or more servers using the same shape as \`.mcp.json\`.
|
|
942
|
+
- Skill MCP configs are bundled metadata. They do not by themselves implement or verify an MCP server.
|
|
943
|
+
- If you claim the skill ships a real MCP, the config must point to a bundled runnable server or a verified external package/command.
|
|
944
|
+
- Run \`skill_refresh\` after editing bundled files so the running session reloads the latest skill content and MCP metadata.
|
|
945
|
+
`;
|
|
946
|
+
}
|
|
947
|
+
function buildCreateSkillMcpReference() {
|
|
948
|
+
return `# MCP Server Pattern
|
|
949
|
+
|
|
950
|
+
Use this pattern when a skill needs to bundle a real MCP server in \`scripts/\`.
|
|
951
|
+
|
|
952
|
+
## Preferred Approach
|
|
953
|
+
- Use the official \`@modelcontextprotocol/sdk\` server APIs.
|
|
954
|
+
- Use \`StdioServerTransport\` for bundled local servers.
|
|
955
|
+
- Keep the MCP config in \`mcps/*.json\` simple and skill-relative.
|
|
956
|
+
- Prefer \`.mjs\` for bundled MCP server scripts to avoid CommonJS/ESM ambiguity.
|
|
957
|
+
|
|
958
|
+
## Avoid
|
|
959
|
+
- Do not hand-roll MCP framing with manual \`Content-Length\` parsing unless the user explicitly asks for low-level protocol code.
|
|
960
|
+
- Do not claim the MCP works just because the script exists or passes \`node --check\`.
|
|
961
|
+
- Do not stop at writing \`mcps/*.json\` if the user asked for a real MCP implementation.
|
|
962
|
+
|
|
963
|
+
## Minimal Server Template
|
|
964
|
+
\`\`\`js
|
|
965
|
+
#!/usr/bin/env node
|
|
966
|
+
|
|
967
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
968
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
969
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
970
|
+
|
|
971
|
+
const server = new Server(
|
|
972
|
+
{
|
|
973
|
+
name: 'my-skill-server',
|
|
974
|
+
version: '1.0.0',
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
capabilities: {
|
|
978
|
+
tools: {},
|
|
979
|
+
},
|
|
980
|
+
}
|
|
981
|
+
);
|
|
982
|
+
|
|
983
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
984
|
+
tools: [
|
|
985
|
+
{
|
|
986
|
+
name: 'my_tool',
|
|
987
|
+
description: 'Describe what the tool does.',
|
|
988
|
+
inputSchema: {
|
|
989
|
+
type: 'object',
|
|
990
|
+
properties: {
|
|
991
|
+
value: {
|
|
992
|
+
type: 'string',
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
required: ['value'],
|
|
996
|
+
},
|
|
997
|
+
},
|
|
998
|
+
],
|
|
999
|
+
}));
|
|
1000
|
+
|
|
1001
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1002
|
+
if (request.params.name !== 'my_tool') {
|
|
1003
|
+
throw new Error(\`Unknown tool: \${request.params.name}\`);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
const value =
|
|
1007
|
+
typeof request.params.arguments?.value === 'string' ? request.params.arguments.value : '';
|
|
1008
|
+
|
|
1009
|
+
return {
|
|
1010
|
+
content: [
|
|
1011
|
+
{
|
|
1012
|
+
type: 'text',
|
|
1013
|
+
text: \`Handled: \${value}\`,
|
|
1014
|
+
},
|
|
1015
|
+
],
|
|
1016
|
+
structuredContent: {
|
|
1017
|
+
value,
|
|
1018
|
+
},
|
|
1019
|
+
};
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
const transport = new StdioServerTransport();
|
|
1023
|
+
await server.connect(transport);
|
|
1024
|
+
\`\`\`
|
|
1025
|
+
|
|
1026
|
+
## Matching MCP Config
|
|
1027
|
+
\`\`\`json
|
|
1028
|
+
{
|
|
1029
|
+
"mcpServers": {
|
|
1030
|
+
"my_server": {
|
|
1031
|
+
"type": "stdio",
|
|
1032
|
+
"command": "node",
|
|
1033
|
+
"args": ["scripts/my-skill-server.mjs"]
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
\`\`\`
|
|
1038
|
+
|
|
1039
|
+
## Verification Sequence
|
|
1040
|
+
1. Create or update \`SKILL.md\`, \`scripts/\`, and \`mcps/\`.
|
|
1041
|
+
2. Run \`skill_refresh\` after non-creator file edits.
|
|
1042
|
+
3. Invoke the skill in the current session.
|
|
1043
|
+
4. Confirm the bundled MCP connects and the new MCP tool appears.
|
|
1044
|
+
5. Call the MCP tool once with a simple input and confirm the result.
|
|
1045
|
+
|
|
1046
|
+
If step 3 or 4 fails, the skill is not done yet.
|
|
1047
|
+
`;
|
|
1048
|
+
}
|
|
1049
|
+
function buildSkillExtraFiles(skillId) {
|
|
1050
|
+
if (skillId === STARTER_SKILL_ID) {
|
|
1051
|
+
return [
|
|
1052
|
+
{
|
|
1053
|
+
relativePath: path.join('references', 'skill-anatomy.md'),
|
|
1054
|
+
content: buildCreateSkillStarterReference(),
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
relativePath: path.join('references', 'mcp-server-pattern.md'),
|
|
1058
|
+
content: buildCreateSkillMcpReference(),
|
|
1059
|
+
},
|
|
1060
|
+
];
|
|
1061
|
+
}
|
|
1062
|
+
return [];
|
|
1063
|
+
}
|
|
1064
|
+
function buildSkillTemplateForId(skillId) {
|
|
1065
|
+
if (skillId === STARTER_SKILL_ID) {
|
|
1066
|
+
return buildCreateSkillStarterTemplate();
|
|
1067
|
+
}
|
|
1068
|
+
return buildSkillTemplate(skillId);
|
|
1069
|
+
}
|
|
849
1070
|
async function loadWorkspaceProjectRegistry(workspaceRoot) {
|
|
850
1071
|
const existingPath = await findSharedProjectRegistryPath(workspaceRoot);
|
|
851
1072
|
if (!existingPath) {
|
|
@@ -985,14 +1206,29 @@ export async function createWorkspaceSkillScaffold(skillIdInput, workspaceRoot =
|
|
|
985
1206
|
const workspace = await createWorkspaceScaffold(workspaceRoot);
|
|
986
1207
|
const skillDirPath = path.join(workspace.root, 'skills', skillId);
|
|
987
1208
|
const skillFilePath = path.join(skillDirPath, 'SKILL.md');
|
|
1209
|
+
const resourceDirectories = [];
|
|
1210
|
+
const extraFiles = [];
|
|
988
1211
|
await ensureDirectory(skillDirPath);
|
|
989
|
-
const skillFileStatus = await ensureFile(skillFilePath,
|
|
1212
|
+
const skillFileStatus = await ensureFile(skillFilePath, buildSkillTemplateForId(skillId));
|
|
1213
|
+
for (const directory of SKILL_RESOURCE_DIRECTORIES) {
|
|
1214
|
+
const resourcePath = path.join(skillDirPath, directory);
|
|
1215
|
+
const status = await ensureDirectory(resourcePath);
|
|
1216
|
+
resourceDirectories.push({ path: resourcePath, status });
|
|
1217
|
+
}
|
|
1218
|
+
for (const file of buildSkillExtraFiles(skillId)) {
|
|
1219
|
+
const filePath = path.join(skillDirPath, file.relativePath);
|
|
1220
|
+
await ensureDirectory(path.dirname(filePath));
|
|
1221
|
+
const status = await ensureFile(filePath, file.content);
|
|
1222
|
+
extraFiles.push({ path: filePath, status });
|
|
1223
|
+
}
|
|
990
1224
|
return {
|
|
991
1225
|
workspace,
|
|
992
1226
|
skillFile: {
|
|
993
1227
|
path: skillFilePath,
|
|
994
1228
|
status: skillFileStatus,
|
|
995
1229
|
},
|
|
1230
|
+
resourceDirectories,
|
|
1231
|
+
extraFiles,
|
|
996
1232
|
};
|
|
997
1233
|
}
|
|
998
1234
|
export async function setWorkspacePrimaryAgent(agentIdInput, workspaceRoot = process.cwd()) {
|
|
@@ -1088,6 +1324,16 @@ function formatSkillPaths(result) {
|
|
|
1088
1324
|
if (result.skillFile.status === 'created') {
|
|
1089
1325
|
createdPaths.push(path.relative(result.workspace.root, result.skillFile.path));
|
|
1090
1326
|
}
|
|
1327
|
+
for (const directory of result.resourceDirectories) {
|
|
1328
|
+
if (directory.status === 'created') {
|
|
1329
|
+
createdPaths.push(path.relative(result.workspace.root, directory.path));
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
for (const file of result.extraFiles) {
|
|
1333
|
+
if (file.status === 'created') {
|
|
1334
|
+
createdPaths.push(path.relative(result.workspace.root, file.path));
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1091
1337
|
return createdPaths;
|
|
1092
1338
|
}
|
|
1093
1339
|
async function listWorkspaceSkillIds(workspaceRoot) {
|
|
@@ -1234,7 +1480,12 @@ async function resolvePrimaryAgentSelection(agentIdInput, workspaceRoot) {
|
|
|
1234
1480
|
export async function handleInitCommand(workspaceRoot = process.cwd()) {
|
|
1235
1481
|
p.intro(chalk.inverse('Dexto Init'));
|
|
1236
1482
|
const result = await createWorkspaceScaffold(workspaceRoot);
|
|
1237
|
-
const
|
|
1483
|
+
const starterSkills = await Promise.all(STARTER_SKILL_IDS.map((skillId) => createWorkspaceSkillScaffold(skillId, workspaceRoot)));
|
|
1484
|
+
const workspacePaths = formatCreatedPaths(result);
|
|
1485
|
+
const createdPaths = [
|
|
1486
|
+
...workspacePaths,
|
|
1487
|
+
...starterSkills.flatMap((skill) => formatSkillPaths(skill).filter((item) => !workspacePaths.includes(item))),
|
|
1488
|
+
];
|
|
1238
1489
|
if (createdPaths.length === 0) {
|
|
1239
1490
|
p.outro(chalk.green('Workspace already initialized.'));
|
|
1240
1491
|
return;
|
package/dist/index-main.js
CHANGED
|
@@ -100,6 +100,7 @@ program
|
|
|
100
100
|
.description('AI-powered CLI and WebUI for interacting with MCP servers.')
|
|
101
101
|
.version(cliVersion, '-v, --version', 'output the current version')
|
|
102
102
|
.option('-a, --agent <id|path>', 'Agent ID or path to agent config file')
|
|
103
|
+
.option('--cloud-agent <id>', 'Connect the interactive CLI to a deployed cloud agent by ID')
|
|
103
104
|
.option('-p, --prompt <text>', 'Start the interactive CLI and immediately run the prompt')
|
|
104
105
|
.option('-s, --strict', 'Require all server connections to succeed')
|
|
105
106
|
.option('--no-verbose', 'Disable verbose output')
|
|
@@ -350,7 +351,10 @@ async function bootstrapAgentFromGlobalOpts(options) {
|
|
|
350
351
|
};
|
|
351
352
|
const validatedConfig = AgentConfigSchema.parse(enrichedConfig);
|
|
352
353
|
const services = await resolveServicesFromConfig(validatedConfig, image);
|
|
353
|
-
const agent = new DextoAgent(toDextoAgentOptions({
|
|
354
|
+
const agent = new DextoAgent(toDextoAgentOptions({
|
|
355
|
+
config: validatedConfig,
|
|
356
|
+
services,
|
|
357
|
+
}));
|
|
354
358
|
await agent.start();
|
|
355
359
|
// Register graceful shutdown
|
|
356
360
|
const shutdown = async () => {
|
|
@@ -445,8 +449,9 @@ program
|
|
|
445
449
|
// the first positional argument as an agent name to avoid ambiguity with prompts.
|
|
446
450
|
// ——— FORCE CLI MODE FOR PROMPT/SESSION FLAGS ———
|
|
447
451
|
// If a prompt or session flag was provided, force CLI mode.
|
|
448
|
-
if ((initialPrompt || opts.continue || opts.resume
|
|
449
|
-
|
|
452
|
+
if ((initialPrompt || opts.continue || opts.resume || opts.cloudAgent) &&
|
|
453
|
+
opts.mode !== 'cli') {
|
|
454
|
+
console.error(`ℹ️ Forcing CLI mode due to --prompt/--continue/--resume/--cloud-agent.`);
|
|
450
455
|
console.error(` Original mode: ${opts.mode} → Overridden to: cli`);
|
|
451
456
|
opts.mode = 'cli';
|
|
452
457
|
}
|
|
@@ -456,6 +461,28 @@ program
|
|
|
456
461
|
console.error('💡 For non-interactive runs, use `dexto run "<prompt>"`, or use --mode server for automation.');
|
|
457
462
|
safeExit('main', 1, 'no-tty');
|
|
458
463
|
}
|
|
464
|
+
if (opts.cloudAgent) {
|
|
465
|
+
if (opts.agent) {
|
|
466
|
+
console.error('❌ `--agent` and `--cloud-agent` are mutually exclusive. Use one chat target at a time.');
|
|
467
|
+
safeExit('main', 1, 'cloud-agent-conflict');
|
|
468
|
+
}
|
|
469
|
+
try {
|
|
470
|
+
const { startCloudChatCli } = await import('./cli/cloud-chat.js');
|
|
471
|
+
await startCloudChatCli({
|
|
472
|
+
cloudAgentId: String(opts.cloudAgent),
|
|
473
|
+
...(initialPrompt ? { initialPrompt } : {}),
|
|
474
|
+
...(opts.resume ? { resume: String(opts.resume) } : {}),
|
|
475
|
+
...(opts.continue ? { continueMostRecent: true } : {}),
|
|
476
|
+
});
|
|
477
|
+
safeExit('main', 0);
|
|
478
|
+
}
|
|
479
|
+
catch (err) {
|
|
480
|
+
if (err instanceof ExitSignal)
|
|
481
|
+
throw err;
|
|
482
|
+
console.error(`❌ Cloud chat failed: ${err}`);
|
|
483
|
+
safeExit('main', 1, 'cloud-chat-error');
|
|
484
|
+
}
|
|
485
|
+
}
|
|
459
486
|
// ——— Infer provider & API key from model ———
|
|
460
487
|
if (opts.model) {
|
|
461
488
|
if (opts.model.includes('/')) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
interface ShutdownTarget {
|
|
2
|
+
stop?: (() => Promise<void>) | undefined;
|
|
3
|
+
}
|
|
2
4
|
export interface GracefulShutdownOptions {
|
|
3
5
|
/**
|
|
4
6
|
* When true, the first SIGINT is ignored to let the application handle it
|
|
@@ -11,5 +13,6 @@ export interface GracefulShutdownOptions {
|
|
|
11
13
|
*/
|
|
12
14
|
forceExitTimeout?: number;
|
|
13
15
|
}
|
|
14
|
-
export declare function registerGracefulShutdown(getCurrentAgent: () =>
|
|
16
|
+
export declare function registerGracefulShutdown(getCurrentAgent: () => ShutdownTarget, options?: GracefulShutdownOptions): void;
|
|
17
|
+
export {};
|
|
15
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":"
|
|
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,CAmHN"}
|
|
@@ -14,7 +14,9 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
14
14
|
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
15
15
|
try {
|
|
16
16
|
const agent = getCurrentAgent();
|
|
17
|
-
|
|
17
|
+
if (typeof agent.stop === 'function') {
|
|
18
|
+
await agent.stop();
|
|
19
|
+
}
|
|
18
20
|
process.exit(0);
|
|
19
21
|
}
|
|
20
22
|
catch (error) {
|
|
@@ -63,7 +65,9 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
63
65
|
isShuttingDown = true;
|
|
64
66
|
try {
|
|
65
67
|
const agent = getCurrentAgent();
|
|
66
|
-
|
|
68
|
+
if (typeof agent.stop === 'function') {
|
|
69
|
+
await agent.stop();
|
|
70
|
+
}
|
|
67
71
|
}
|
|
68
72
|
catch (innerError) {
|
|
69
73
|
logger.error(`Error during shutdown initiated by uncaughtException: ${innerError instanceof Error ? innerError.message : String(innerError)}`, { error: innerError });
|
|
@@ -77,7 +81,9 @@ export function registerGracefulShutdown(getCurrentAgent, options = {}) {
|
|
|
77
81
|
isShuttingDown = true;
|
|
78
82
|
try {
|
|
79
83
|
const agent = getCurrentAgent();
|
|
80
|
-
|
|
84
|
+
if (typeof agent.stop === 'function') {
|
|
85
|
+
await agent.stop();
|
|
86
|
+
}
|
|
81
87
|
}
|
|
82
88
|
catch (innerError) {
|
|
83
89
|
logger.error(`Error during shutdown initiated by unhandledRejection: ${innerError instanceof Error ? innerError.message : String(innerError)}`, { error: innerError });
|