dexto 1.6.17 → 1.6.19

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.
@@ -23,8 +23,8 @@ export type HonoInitializationResult = {
23
23
  ensureAgentAvailable: () => void;
24
24
  getActiveAgentId: () => string | undefined;
25
25
  };
26
- export declare function initializeHonoApi(agent: DextoAgent, agentCardOverride?: Partial<AgentCard>, listenPort?: number, agentId?: string, configFilePath?: string, webRoot?: string, webUIConfig?: WebUIRuntimeConfig): Promise<HonoInitializationResult>;
27
- export declare function startHonoApiServer(agent: DextoAgent, port?: number, agentCardOverride?: Partial<AgentCard>, agentId?: string, configFilePath?: string, webRoot?: string, webUIConfig?: WebUIRuntimeConfig): Promise<{
26
+ export declare function initializeHonoApi(agent: DextoAgent, agentCardOverride?: Partial<AgentCard>, listenPort?: number, agentId?: string, configFilePath?: string, workspaceRoot?: string, webRoot?: string, webUIConfig?: WebUIRuntimeConfig): Promise<HonoInitializationResult>;
27
+ export declare function startHonoApiServer(agent: DextoAgent, port?: number, agentCardOverride?: Partial<AgentCard>, agentId?: string, configFilePath?: string, workspaceRoot?: string, webRoot?: string, webUIConfig?: WebUIRuntimeConfig): Promise<{
28
28
  server: ReturnType<typeof createNodeServer>['server'];
29
29
  webhookSubscriber?: NonNullable<ReturnType<typeof createNodeServer>['webhookSubscriber']>;
30
30
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"server-hono.d.ts","sourceRoot":"","sources":["../../src/api/server-hono.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAuC,MAAM,aAAa,CAAC;AAY9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EACH,cAAc,EACd,gBAAgB,EAShB,KAAK,kBAAkB,EAC1B,MAAM,eAAe,CAAC;AA+FvB,MAAM,MAAM,wBAAwB,GAAG;IACnC,GAAG,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IACvC,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtD,iBAAiB,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC1F,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5E,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CAC9C,CAAC;AAGF,wBAAsB,iBAAiB,CACnC,KAAK,EAAE,UAAU,EACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,kBAAkB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAmXnC;AAED,wBAAsB,kBAAkB,CACpC,KAAK,EAAE,UAAU,EACjB,IAAI,SAAO,EACX,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,OAAO,CAAC,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,kBAAkB,GACjC,OAAO,CAAC;IACP,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtD,iBAAiB,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;CAC7F,CAAC,CAiCD"}
1
+ {"version":3,"file":"server-hono.d.ts","sourceRoot":"","sources":["../../src/api/server-hono.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAuC,MAAM,aAAa,CAAC;AAY9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EACH,cAAc,EACd,gBAAgB,EAShB,KAAK,kBAAkB,EAC1B,MAAM,eAAe,CAAC;AAmGvB,MAAM,MAAM,wBAAwB,GAAG;IACnC,GAAG,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IACvC,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtD,iBAAiB,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC1F,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5E,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CAC9C,CAAC;AAGF,wBAAsB,iBAAiB,CACnC,KAAK,EAAE,UAAU,EACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,kBAAkB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CA4XnC;AAED,wBAAsB,kBAAkB,CACpC,KAAK,EAAE,UAAU,EACjB,IAAI,SAAO,EACX,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,OAAO,CAAC,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,kBAAkB,GACjC,OAAO,CAAC;IACP,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtD,iBAAiB,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;CAC7F,CAAC,CAkCD"}
@@ -5,6 +5,7 @@ import { applyUserPreferences } from '../config/cli-overrides.js';
5
5
  import { createFileSessionLoggerFactory } from '../utils/session-logger-factory.js';
6
6
  import { createDextoApp, createNodeServer, createMcpTransport as createServerMcpTransport, createMcpHttpHandlers, initializeMcpServer as initializeServerMcpServer, createManualApprovalHandler, WebhookEventSubscriber, A2ASseEventSubscriber, ApprovalCoordinator, } from '@dexto/server';
7
7
  import { registerGracefulShutdown } from '../utils/graceful-shutdown.js';
8
+ import { applyWorkspaceToAgent } from '../utils/workspace.js';
8
9
  const DEFAULT_AGENT_VERSION = '1.0.0';
9
10
  const sessionLoggerFactory = createFileSessionLoggerFactory();
10
11
  /**
@@ -25,7 +26,7 @@ async function listAgents() {
25
26
  * Applies user preferences (preferences.yml) to ALL agents, not just the default.
26
27
  * See feature-plans/auto-update.md section 8.11 - Three-Layer LLM Resolution.
27
28
  */
28
- async function createAgentFromId(agentId) {
29
+ async function createAgentFromId(agentId, workspaceRoot) {
29
30
  try {
30
31
  // Use registry to resolve agent path (auto-installs if not present)
31
32
  const registry = getAgentRegistry();
@@ -53,7 +54,10 @@ async function createAgentFromId(agentId) {
53
54
  return await createDextoAgentFromConfig({
54
55
  config,
55
56
  configPath: agentPath,
56
- enrichOptions: { logLevel: 'info' },
57
+ enrichOptions: {
58
+ logLevel: 'info',
59
+ ...(workspaceRoot ? { workspaceRoot } : {}),
60
+ },
57
61
  overrides: { sessionLoggerFactory },
58
62
  });
59
63
  }
@@ -72,7 +76,7 @@ function resolveBaseUrl(port) {
72
76
  return process.env.DEXTO_BASE_URL ?? `http://localhost:${port}`;
73
77
  }
74
78
  //TODO (migration): consider moving this to the server package
75
- export async function initializeHonoApi(agent, agentCardOverride, listenPort, agentId, configFilePath, webRoot, webUIConfig) {
79
+ export async function initializeHonoApi(agent, agentCardOverride, listenPort, agentId, configFilePath, workspaceRoot, webRoot, webUIConfig) {
76
80
  // Declare before registering shutdown hook to avoid TDZ on signals
77
81
  let activeAgent = agent;
78
82
  let activeAgentId = agentId || 'coding-agent';
@@ -160,6 +164,9 @@ export async function initializeHonoApi(agent, agentCardOverride, listenPort, ag
160
164
  await wireServicesToAgent(newAgent);
161
165
  logger.info(`Starting new agent: ${agentId}`);
162
166
  await newAgent.start();
167
+ if (workspaceRoot) {
168
+ await applyWorkspaceToAgent(newAgent, workspaceRoot);
169
+ }
163
170
  // Update agent card for A2A and MCP routes
164
171
  agentCardData = createAgentCard({
165
172
  defaultName: agentId,
@@ -195,7 +202,7 @@ export async function initializeHonoApi(agent, agentCardOverride, listenPort, ag
195
202
  // 2. Create new agent from registry (will initialize fresh telemetry in createAgentServices)
196
203
  const registry = getAgentRegistry();
197
204
  newAgentConfigPath = await registry.resolveAgent(agentId, true);
198
- newAgent = await createAgentFromId(agentId);
205
+ newAgent = await createAgentFromId(agentId, workspaceRoot);
199
206
  // 3. Use common switch logic (register subscribers, start agent, stop previous)
200
207
  return await performAgentSwitch(newAgent, agentId, newAgentConfigPath, bridge);
201
208
  }
@@ -247,7 +254,10 @@ export async function initializeHonoApi(agent, agentCardOverride, listenPort, ag
247
254
  newAgent = await createDextoAgentFromConfig({
248
255
  config,
249
256
  configPath: filePath,
250
- enrichOptions: { logLevel: 'info' },
257
+ enrichOptions: {
258
+ logLevel: 'info',
259
+ ...(workspaceRoot ? { workspaceRoot } : {}),
260
+ },
251
261
  overrides: { sessionLoggerFactory },
252
262
  });
253
263
  // 4. Use enriched agentId (derived from config or filename during enrichment)
@@ -351,6 +361,9 @@ export async function initializeHonoApi(agent, agentCardOverride, listenPort, ag
351
361
  // Start the initial agent now that approval handler is set and subscribers are wired
352
362
  logger.info('Starting initial agent...');
353
363
  await activeAgent.start();
364
+ if (workspaceRoot) {
365
+ await applyWorkspaceToAgent(activeAgent, workspaceRoot);
366
+ }
354
367
  // Initialize MCP server after agent has started
355
368
  if (mcpTransport) {
356
369
  try {
@@ -376,8 +389,8 @@ export async function initializeHonoApi(agent, agentCardOverride, listenPort, ag
376
389
  getActiveAgentId: () => activeAgentId,
377
390
  };
378
391
  }
379
- export async function startHonoApiServer(agent, port = 3000, agentCardOverride, agentId, configFilePath, webRoot, webUIConfig) {
380
- const { server, webhookSubscriber } = await initializeHonoApi(agent, agentCardOverride, port, agentId, configFilePath, webRoot, webUIConfig);
392
+ export async function startHonoApiServer(agent, port = 3000, agentCardOverride, agentId, configFilePath, workspaceRoot, webRoot, webUIConfig) {
393
+ const { server, webhookSubscriber } = await initializeHonoApi(agent, agentCardOverride, port, agentId, configFilePath, workspaceRoot, webRoot, webUIConfig);
381
394
  server.listen(port, '0.0.0.0', () => {
382
395
  const networkInterfaces = os.networkInterfaces();
383
396
  let localIp = 'localhost';
@@ -34,6 +34,14 @@ export interface WorkspaceSkillScaffoldResult {
34
34
  path: string;
35
35
  status: ScaffoldEntryStatus;
36
36
  };
37
+ resourceDirectories: Array<{
38
+ path: string;
39
+ status: ScaffoldEntryStatus;
40
+ }>;
41
+ extraFiles: Array<{
42
+ path: string;
43
+ status: ScaffoldEntryStatus;
44
+ }>;
37
45
  }
38
46
  export interface WorkspacePrimaryAgentResult {
39
47
  workspace: WorkspaceScaffoldResult;
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -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>/SKILL.md\`
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
- ## Inputs
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
- ## Steps
839
- 1. Review the relevant context.
840
- 2. Apply the workflow for this skill.
841
- 3. Return a concise result with any important follow-up actions.
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, buildSkillTemplate(skillId));
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 createdPaths = formatCreatedPaths(result);
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;
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAsBpD,wBAAsB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwKxE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAuBpD,wBAAsB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAgLxE"}
@@ -1,6 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
  import { logger } from '@dexto/core';
3
3
  import { safeExit, ExitSignal } from '../../analytics/wrapper.js';
4
+ import { applyWorkspaceToAgent } from '../../utils/workspace.js';
4
5
  async function getMostRecentSessionId(agent) {
5
6
  const sessionIds = await agent.listSessions();
6
7
  if (sessionIds.length === 0) {
@@ -18,7 +19,7 @@ async function getMostRecentSessionId(agent) {
18
19
  return mostRecentId;
19
20
  }
20
21
  export async function runCliMode(context) {
21
- const { agent, opts, validatedConfig, resolvedPath, initialPrompt, getVersionCheckResult } = context;
22
+ const { agent, opts, workspaceRoot, validatedConfig, resolvedPath, initialPrompt, getVersionCheckResult, } = context;
22
23
  const needsHandler = validatedConfig.permissions.mode === 'manual' || validatedConfig.elicitation.enabled;
23
24
  if (needsHandler) {
24
25
  const { createCLIApprovalHandler } = await import('../approval/index.js');
@@ -26,8 +27,9 @@ export async function runCliMode(context) {
26
27
  agent.setApprovalHandler(handler);
27
28
  logger.debug('CLI approval handler configured for Ink CLI');
28
29
  }
29
- await agent.start();
30
30
  try {
31
+ await agent.start();
32
+ await applyWorkspaceToAgent(agent, workspaceRoot);
31
33
  const llmConfig = agent.getCurrentLLMConfig();
32
34
  const { requiresApiKey } = await import('@dexto/core');
33
35
  if (requiresApiKey(llmConfig.provider) && !llmConfig.apiKey?.trim()) {
@@ -11,6 +11,7 @@ export interface MainModeOptions {
11
11
  export interface MainModeContext {
12
12
  agent: DextoAgent;
13
13
  opts: MainModeOptions;
14
+ workspaceRoot: string;
14
15
  validatedConfig: ValidatedAgentConfig;
15
16
  resolvedPath: string;
16
17
  derivedAgentId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;IACtB,eAAe,EAAE,oBAAoB,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,qBAAqB,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAC3D"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,oBAAoB,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,qBAAqB,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAC3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C3E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkD3E"}
@@ -1,6 +1,6 @@
1
1
  import { getPort } from '../../utils/port-utils.js';
2
2
  export async function runServerMode(context) {
3
- const { agent, opts, derivedAgentId, resolvedPath, getVersionCheckResult } = context;
3
+ const { agent, opts, workspaceRoot, derivedAgentId, resolvedPath, getVersionCheckResult } = context;
4
4
  const { startHonoApiServer } = await import('../../api/server-hono.js');
5
5
  const agentCard = agent.config.agentCard ?? {};
6
6
  const defaultPort = (() => {
@@ -20,7 +20,7 @@ export async function runServerMode(context) {
20
20
  const apiPort = getPort(process.env.PORT, defaultPort, 'PORT');
21
21
  const apiUrl = process.env.DEXTO_URL ?? `http://localhost:${apiPort}`;
22
22
  console.log('🌐 Starting server (REST APIs + SSE)...');
23
- await startHonoApiServer(agent, apiPort, agentCard, derivedAgentId, resolvedPath);
23
+ await startHonoApiServer(agent, apiPort, agentCard, derivedAgentId, resolvedPath, workspaceRoot);
24
24
  console.log(`✅ Server running at ${apiUrl}`);
25
25
  console.log('Available endpoints:');
26
26
  console.log(' POST /api/message - Send async message');
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/web.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAsB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmExE"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../src/cli/modes/web.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAsB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqExE"}
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
  import { getPort } from '../../utils/port-utils.js';
3
3
  export async function runWebMode(context) {
4
- const { agent, opts, derivedAgentId, resolvedPath, getVersionCheckResult } = context;
4
+ const { agent, opts, workspaceRoot, derivedAgentId, resolvedPath, getVersionCheckResult } = context;
5
5
  const [{ resolveWebRoot }, { startHonoApiServer }, { getWebUIAnalyticsConfig }] = await Promise.all([
6
6
  import('../../web.js'),
7
7
  import('../../api/server-hono.js'),
@@ -30,7 +30,7 @@ export async function runWebMode(context) {
30
30
  console.info('For development: Run "pnpm dev" for hot reload');
31
31
  }
32
32
  const webUIConfig = webRoot ? { analytics: await getWebUIAnalyticsConfig() } : undefined;
33
- await startHonoApiServer(agent, port, agent.config.agentCard || {}, derivedAgentId, resolvedPath, webRoot, webUIConfig);
33
+ await startHonoApiServer(agent, port, agent.config.agentCard || {}, derivedAgentId, resolvedPath, workspaceRoot, webRoot, webUIConfig);
34
34
  console.log(chalk.green(`✅ Server running at ${serverUrl}`));
35
35
  const webUpdateInfo = await getVersionCheckResult();
36
36
  if (webUpdateInfo) {
@@ -351,8 +351,12 @@ async function bootstrapAgentFromGlobalOpts(options) {
351
351
  };
352
352
  const validatedConfig = AgentConfigSchema.parse(enrichedConfig);
353
353
  const services = await resolveServicesFromConfig(validatedConfig, image);
354
- const agent = new DextoAgent(toDextoAgentOptions({ config: validatedConfig, services }));
354
+ const agent = new DextoAgent(toDextoAgentOptions({
355
+ config: validatedConfig,
356
+ services,
357
+ }));
355
358
  await agent.start();
359
+ await (await import('./utils/workspace.js')).applyWorkspaceToAgent(agent, workspaceRoot);
356
360
  // Register graceful shutdown
357
361
  const shutdown = async () => {
358
362
  try {
@@ -414,6 +418,7 @@ program
414
418
  logger.debug('WARNING: .env file not found; copy .env.example and set your API keys.');
415
419
  }
416
420
  const opts = program.opts();
421
+ const workspaceRoot = findDextoProjectRoot(process.cwd()) ?? process.cwd();
417
422
  // Set dev mode early to use local repo agents instead of ~/.dexto
418
423
  if (opts.dev) {
419
424
  process.env.DEXTO_DEV_MODE = 'true';
@@ -719,7 +724,6 @@ program
719
724
  // Enrichment adds filesystem paths to storage (schema has in-memory defaults)
720
725
  // Interactive CLI mode: only log to file (console would interfere with chat UI)
721
726
  const isInteractiveCli = opts.mode === 'cli';
722
- const workspaceRoot = findDextoProjectRoot(process.cwd()) ?? process.cwd();
723
727
  const enrichedConfig = enrichAgentConfig(configWithImageDefaults, resolvedPath, {
724
728
  isInteractiveCli,
725
729
  logLevel: 'info', // CLI uses info-level logging for visibility
@@ -823,6 +827,7 @@ program
823
827
  // - other modes: start immediately (no approval support)
824
828
  if (opts.mode !== 'web' && opts.mode !== 'server' && opts.mode !== 'cli') {
825
829
  await agent.start();
830
+ await (await import('./utils/workspace.js')).applyWorkspaceToAgent(agent, workspaceRoot);
826
831
  }
827
832
  // Derive a concise agent ID for display purposes (used by API/UI)
828
833
  // Prefer agentCard.name, otherwise extract from filename
@@ -848,6 +853,7 @@ program
848
853
  await dispatchMainMode({
849
854
  agent,
850
855
  opts: mainModeOpts,
856
+ workspaceRoot,
851
857
  validatedConfig,
852
858
  resolvedPath,
853
859
  derivedAgentId,
@@ -0,0 +1,9 @@
1
+ import type { DextoAgent } from '@dexto/core';
2
+ type WorkspaceAwareAgent = Pick<DextoAgent, 'getWorkspace' | 'setWorkspace'>;
3
+ /**
4
+ * Keep the runtime workspace in sync with the host-resolved project root so
5
+ * prompt contributors and downstream services don't fall back to process.cwd().
6
+ */
7
+ export declare function applyWorkspaceToAgent(agent: WorkspaceAwareAgent, workspaceRoot: string): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/utils/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,KAAK,mBAAmB,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,GAAG,cAAc,CAAC,CAAC;AAE7E;;;GAGG;AACH,wBAAsB,qBAAqB,CACvC,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Keep the runtime workspace in sync with the host-resolved project root so
3
+ * prompt contributors and downstream services don't fall back to process.cwd().
4
+ */
5
+ export async function applyWorkspaceToAgent(agent, workspaceRoot) {
6
+ const normalizedWorkspaceRoot = workspaceRoot.trim();
7
+ if (!normalizedWorkspaceRoot) {
8
+ return;
9
+ }
10
+ const currentWorkspace = await agent.getWorkspace();
11
+ if (currentWorkspace?.path === normalizedWorkspaceRoot) {
12
+ return;
13
+ }
14
+ await agent.setWorkspace({
15
+ path: normalizedWorkspaceRoot,
16
+ });
17
+ }