@dexto/agent-management 1.5.5 → 1.5.7

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.
Files changed (128) hide show
  1. package/dist/config/config-enrichment.cjs +70 -20
  2. package/dist/config/config-enrichment.d.ts +10 -2
  3. package/dist/config/config-enrichment.d.ts.map +1 -1
  4. package/dist/config/config-enrichment.js +74 -20
  5. package/dist/config/discover-prompts.cjs +1 -1
  6. package/dist/config/discover-prompts.d.ts +11 -11
  7. package/dist/config/discover-prompts.d.ts.map +1 -1
  8. package/dist/config/discover-prompts.js +1 -1
  9. package/dist/config/loader.cjs +31 -13
  10. package/dist/config/loader.d.ts.map +1 -1
  11. package/dist/config/loader.js +31 -13
  12. package/dist/index.cjs +65 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +66 -0
  16. package/dist/models/custom-models.cjs +2 -1
  17. package/dist/models/custom-models.d.ts +7 -6
  18. package/dist/models/custom-models.d.ts.map +1 -1
  19. package/dist/models/custom-models.js +2 -1
  20. package/dist/plugins/discover-plugins.cjs +176 -0
  21. package/dist/plugins/discover-plugins.d.ts +39 -0
  22. package/dist/plugins/discover-plugins.d.ts.map +1 -0
  23. package/dist/plugins/discover-plugins.js +140 -0
  24. package/dist/plugins/discover-skills.cjs +89 -0
  25. package/dist/plugins/discover-skills.d.ts +46 -0
  26. package/dist/plugins/discover-skills.d.ts.map +1 -0
  27. package/dist/plugins/discover-skills.js +54 -0
  28. package/dist/plugins/error-codes.cjs +47 -0
  29. package/dist/plugins/error-codes.d.ts +24 -0
  30. package/dist/plugins/error-codes.d.ts.map +1 -0
  31. package/dist/plugins/error-codes.js +23 -0
  32. package/dist/plugins/errors.cjs +197 -0
  33. package/dist/plugins/errors.d.ts +68 -0
  34. package/dist/plugins/errors.d.ts.map +1 -0
  35. package/dist/plugins/errors.js +173 -0
  36. package/dist/plugins/index.cjs +144 -0
  37. package/dist/plugins/index.d.ts +23 -0
  38. package/dist/plugins/index.d.ts.map +1 -0
  39. package/dist/plugins/index.js +115 -0
  40. package/dist/plugins/install-plugin.cjs +211 -0
  41. package/dist/plugins/install-plugin.d.ts +47 -0
  42. package/dist/plugins/install-plugin.d.ts.map +1 -0
  43. package/dist/plugins/install-plugin.js +173 -0
  44. package/dist/plugins/list-plugins.cjs +134 -0
  45. package/dist/plugins/list-plugins.d.ts +26 -0
  46. package/dist/plugins/list-plugins.d.ts.map +1 -0
  47. package/dist/plugins/list-plugins.js +99 -0
  48. package/dist/plugins/load-plugin.cjs +197 -0
  49. package/dist/plugins/load-plugin.d.ts +20 -0
  50. package/dist/plugins/load-plugin.d.ts.map +1 -0
  51. package/dist/plugins/load-plugin.js +163 -0
  52. package/dist/plugins/marketplace/error-codes.cjs +45 -0
  53. package/dist/plugins/marketplace/error-codes.d.ts +21 -0
  54. package/dist/plugins/marketplace/error-codes.d.ts.map +1 -0
  55. package/dist/plugins/marketplace/error-codes.js +21 -0
  56. package/dist/plugins/marketplace/errors.cjs +188 -0
  57. package/dist/plugins/marketplace/errors.d.ts +64 -0
  58. package/dist/plugins/marketplace/errors.d.ts.map +1 -0
  59. package/dist/plugins/marketplace/errors.js +164 -0
  60. package/dist/plugins/marketplace/index.cjs +95 -0
  61. package/dist/plugins/marketplace/index.d.ts +14 -0
  62. package/dist/plugins/marketplace/index.d.ts.map +1 -0
  63. package/dist/plugins/marketplace/index.js +74 -0
  64. package/dist/plugins/marketplace/install-from-marketplace.cjs +152 -0
  65. package/dist/plugins/marketplace/install-from-marketplace.d.ts +25 -0
  66. package/dist/plugins/marketplace/install-from-marketplace.d.ts.map +1 -0
  67. package/dist/plugins/marketplace/install-from-marketplace.js +120 -0
  68. package/dist/plugins/marketplace/operations.cjs +374 -0
  69. package/dist/plugins/marketplace/operations.d.ts +43 -0
  70. package/dist/plugins/marketplace/operations.d.ts.map +1 -0
  71. package/dist/plugins/marketplace/operations.js +339 -0
  72. package/dist/plugins/marketplace/registry.cjs +166 -0
  73. package/dist/plugins/marketplace/registry.d.ts +72 -0
  74. package/dist/plugins/marketplace/registry.d.ts.map +1 -0
  75. package/dist/plugins/marketplace/registry.js +119 -0
  76. package/dist/plugins/marketplace/schemas.cjs +79 -0
  77. package/dist/plugins/marketplace/schemas.d.ts +260 -0
  78. package/dist/plugins/marketplace/schemas.d.ts.map +1 -0
  79. package/dist/plugins/marketplace/schemas.js +49 -0
  80. package/dist/plugins/marketplace/types.cjs +16 -0
  81. package/dist/plugins/marketplace/types.d.ts +156 -0
  82. package/dist/plugins/marketplace/types.d.ts.map +1 -0
  83. package/dist/plugins/marketplace/types.js +0 -0
  84. package/dist/plugins/schemas.cjs +74 -0
  85. package/dist/plugins/schemas.d.ts +262 -0
  86. package/dist/plugins/schemas.d.ts.map +1 -0
  87. package/dist/plugins/schemas.js +46 -0
  88. package/dist/plugins/types.cjs +16 -0
  89. package/dist/plugins/types.d.ts +186 -0
  90. package/dist/plugins/types.d.ts.map +1 -0
  91. package/dist/plugins/types.js +0 -0
  92. package/dist/plugins/uninstall-plugin.cjs +133 -0
  93. package/dist/plugins/uninstall-plugin.d.ts +24 -0
  94. package/dist/plugins/uninstall-plugin.d.ts.map +1 -0
  95. package/dist/plugins/uninstall-plugin.js +99 -0
  96. package/dist/plugins/validate-plugin.cjs +180 -0
  97. package/dist/plugins/validate-plugin.d.ts +53 -0
  98. package/dist/plugins/validate-plugin.d.ts.map +1 -0
  99. package/dist/plugins/validate-plugin.js +145 -0
  100. package/dist/preferences/schemas.d.ts +12 -12
  101. package/dist/runtime/AgentRuntime.cjs +1 -2
  102. package/dist/runtime/AgentRuntime.d.ts.map +1 -1
  103. package/dist/runtime/AgentRuntime.js +1 -2
  104. package/dist/tool-provider/llm-resolution.cjs +74 -0
  105. package/dist/tool-provider/llm-resolution.d.ts +51 -0
  106. package/dist/tool-provider/llm-resolution.d.ts.map +1 -0
  107. package/dist/tool-provider/llm-resolution.js +50 -0
  108. package/dist/tool-provider/runtime-service.cjs +158 -23
  109. package/dist/tool-provider/runtime-service.d.ts +32 -2
  110. package/dist/tool-provider/runtime-service.d.ts.map +1 -1
  111. package/dist/tool-provider/runtime-service.js +158 -23
  112. package/dist/tool-provider/tool-provider.cjs +2 -0
  113. package/dist/tool-provider/tool-provider.d.ts.map +1 -1
  114. package/dist/tool-provider/tool-provider.js +2 -0
  115. package/dist/tool-provider/types.d.ts +2 -0
  116. package/dist/tool-provider/types.d.ts.map +1 -1
  117. package/dist/utils/api-key-resolver.cjs +5 -2
  118. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  119. package/dist/utils/api-key-resolver.js +5 -2
  120. package/dist/utils/dexto-auth.cjs +83 -0
  121. package/dist/utils/dexto-auth.d.ts +23 -0
  122. package/dist/utils/dexto-auth.d.ts.map +1 -0
  123. package/dist/utils/dexto-auth.js +57 -0
  124. package/dist/utils/feature-flags.cjs +30 -0
  125. package/dist/utils/feature-flags.d.ts +21 -0
  126. package/dist/utils/feature-flags.d.ts.map +1 -0
  127. package/dist/utils/feature-flags.js +6 -0
  128. package/package.json +2 -2
@@ -37,6 +37,7 @@ module.exports = __toCommonJS(config_enrichment_exports);
37
37
  var import_path = require("../utils/path.js");
38
38
  var path = __toESM(require("path"), 1);
39
39
  var import_discover_prompts = require("./discover-prompts.js");
40
+ var import_plugins = require("../plugins/index.js");
40
41
  var import_discover_prompts2 = require("./discover-prompts.js");
41
42
  function deriveAgentId(config, configPath) {
42
43
  if (config.agentId) {
@@ -59,9 +60,13 @@ function deriveAgentId(config, configPath) {
59
60
  }
60
61
  function enrichAgentConfig(config, configPath, options = {}) {
61
62
  const opts = typeof options === "boolean" ? { isInteractiveCli: options } : options;
62
- const { isInteractiveCli = false, logLevel = "error" } = opts;
63
+ const {
64
+ isInteractiveCli = false,
65
+ logLevel = "error",
66
+ skipPluginDiscovery = false,
67
+ bundledPlugins = []
68
+ } = opts;
63
69
  const agentId = deriveAgentId(config, configPath);
64
- const logPath = (0, import_path.getDextoPath)("logs", `${agentId}.log`);
65
70
  const dbPath = (0, import_path.getDextoPath)("database", `${agentId}.db`);
66
71
  const blobPath = (0, import_path.getDextoPath)("blobs", agentId);
67
72
  const enriched = {
@@ -70,24 +75,7 @@ function enrichAgentConfig(config, configPath, options = {}) {
70
75
  // Set agentId explicitly (single source of truth)
71
76
  };
72
77
  if (!config.logger) {
73
- const transports = isInteractiveCli ? [
74
- {
75
- type: "file",
76
- path: logPath,
77
- maxSize: 10 * 1024 * 1024,
78
- // 10MB
79
- maxFiles: 5
80
- }
81
- ] : [
82
- { type: "console", colorize: true },
83
- {
84
- type: "file",
85
- path: logPath,
86
- maxSize: 10 * 1024 * 1024,
87
- // 10MB
88
- maxFiles: 5
89
- }
90
- ];
78
+ const transports = isInteractiveCli ? [{ type: "silent" }] : [{ type: "console", colorize: true }];
91
79
  enriched.logger = {
92
80
  level: logLevel,
93
81
  transports
@@ -132,6 +120,68 @@ function enrichAgentConfig(config, configPath, options = {}) {
132
120
  );
133
121
  enriched.prompts = [...existingPrompts, ...filteredDiscovered];
134
122
  }
123
+ if (!skipPluginDiscovery) {
124
+ const existingPromptPaths = /* @__PURE__ */ new Set();
125
+ for (const prompt of enriched.prompts ?? []) {
126
+ if (prompt.type === "file") {
127
+ existingPromptPaths.add(path.resolve(prompt.file));
128
+ }
129
+ }
130
+ const discoveredPlugins = (0, import_plugins.discoverClaudeCodePlugins)(void 0, bundledPlugins);
131
+ for (const plugin of discoveredPlugins) {
132
+ const loaded = (0, import_plugins.loadClaudeCodePlugin)(plugin);
133
+ for (const warning of loaded.warnings) {
134
+ console.warn(`[plugin] ${warning}`);
135
+ }
136
+ for (const cmd of loaded.commands) {
137
+ const resolvedPath = path.resolve(cmd.file);
138
+ if (existingPromptPaths.has(resolvedPath)) {
139
+ continue;
140
+ }
141
+ existingPromptPaths.add(resolvedPath);
142
+ const promptEntry = {
143
+ type: "file",
144
+ file: cmd.file,
145
+ namespace: cmd.namespace
146
+ };
147
+ enriched.prompts = enriched.prompts ?? [];
148
+ enriched.prompts.push(promptEntry);
149
+ }
150
+ if (loaded.mcpConfig?.mcpServers) {
151
+ enriched.mcpServers = {
152
+ ...enriched.mcpServers,
153
+ ...loaded.mcpConfig.mcpServers
154
+ };
155
+ }
156
+ if (loaded.customToolProviders.length > 0) {
157
+ for (const providerType of loaded.customToolProviders) {
158
+ const alreadyConfigured = enriched.customTools?.some(
159
+ (tool) => typeof tool === "object" && tool !== null && tool.type === providerType
160
+ );
161
+ if (!alreadyConfigured) {
162
+ enriched.customTools = enriched.customTools ?? [];
163
+ enriched.customTools.push({ type: providerType });
164
+ }
165
+ }
166
+ }
167
+ }
168
+ const standaloneSkills = (0, import_plugins.discoverStandaloneSkills)();
169
+ for (const skill of standaloneSkills) {
170
+ const resolvedPath = path.resolve(skill.skillFile);
171
+ if (existingPromptPaths.has(resolvedPath)) {
172
+ continue;
173
+ }
174
+ existingPromptPaths.add(resolvedPath);
175
+ const promptEntry = {
176
+ type: "file",
177
+ file: skill.skillFile
178
+ // No namespace for standalone skills - they use id directly
179
+ // (unlike plugin commands which need plugin:command naming)
180
+ };
181
+ enriched.prompts = enriched.prompts ?? [];
182
+ enriched.prompts.push(promptEntry);
183
+ }
184
+ }
135
185
  const instructionFile = (0, import_discover_prompts.discoverAgentInstructionFile)();
136
186
  if (instructionFile) {
137
187
  const fileContributor = {
@@ -7,8 +7,8 @@
7
7
  *
8
8
  * Also discovers command prompts from (in priority order):
9
9
  * - Local: <projectRoot>/commands/ (dexto-source dev mode or dexto-project only)
10
- * - Local: <cwd>/.dexto/commands/, <cwd>/.claude/commands/, <cwd>/.cursor/commands/
11
- * - Global: ~/.dexto/commands/, ~/.claude/commands/, ~/.cursor/commands/
10
+ * - Local: <cwd>/.dexto/commands/
11
+ * - Global: ~/.dexto/commands/
12
12
  *
13
13
  * Core services now require explicit paths - this enrichment layer provides them.
14
14
  */
@@ -27,6 +27,14 @@ export interface EnrichAgentConfigOptions {
27
27
  isInteractiveCli?: boolean;
28
28
  /** Override log level (defaults to 'error' for SDK, CLI/server can override to 'info') */
29
29
  logLevel?: 'error' | 'warn' | 'info' | 'debug';
30
+ /** Skip Claude Code plugin discovery (useful for subagents that don't need plugins) */
31
+ skipPluginDiscovery?: boolean;
32
+ /**
33
+ * Bundled plugin paths from image definition.
34
+ * These are absolute paths to plugin directories that are discovered alongside
35
+ * user/project plugins.
36
+ */
37
+ bundledPlugins?: string[];
30
38
  }
31
39
  /**
32
40
  * Enriches agent configuration with per-agent file paths and discovered commands.
@@ -1 +1 @@
1
- {"version":3,"file":"config-enrichment.d.ts","sourceRoot":"","sources":["../../src/config/config-enrichment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,OAAO,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAE7F;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAoC9E;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,mGAAmG;IACnG,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAClD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE,wBAAwB,GAAG,OAAY,GACjD,WAAW,CAoKb"}
1
+ {"version":3,"file":"config-enrichment.d.ts","sourceRoot":"","sources":["../../src/config/config-enrichment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU/C,OAAO,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAE7F;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAoC9E;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,mGAAmG;IACnG,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE,wBAAwB,GAAG,OAAY,GACjD,WAAW,CA4Pb"}
@@ -1,6 +1,11 @@
1
1
  import { getDextoPath } from "../utils/path.js";
2
2
  import * as path from "path";
3
3
  import { discoverCommandPrompts, discoverAgentInstructionFile } from "./discover-prompts.js";
4
+ import {
5
+ discoverClaudeCodePlugins,
6
+ loadClaudeCodePlugin,
7
+ discoverStandaloneSkills
8
+ } from "../plugins/index.js";
4
9
  import { discoverCommandPrompts as discoverCommandPrompts2, discoverAgentInstructionFile as discoverAgentInstructionFile2 } from "./discover-prompts.js";
5
10
  function deriveAgentId(config, configPath) {
6
11
  if (config.agentId) {
@@ -23,9 +28,13 @@ function deriveAgentId(config, configPath) {
23
28
  }
24
29
  function enrichAgentConfig(config, configPath, options = {}) {
25
30
  const opts = typeof options === "boolean" ? { isInteractiveCli: options } : options;
26
- const { isInteractiveCli = false, logLevel = "error" } = opts;
31
+ const {
32
+ isInteractiveCli = false,
33
+ logLevel = "error",
34
+ skipPluginDiscovery = false,
35
+ bundledPlugins = []
36
+ } = opts;
27
37
  const agentId = deriveAgentId(config, configPath);
28
- const logPath = getDextoPath("logs", `${agentId}.log`);
29
38
  const dbPath = getDextoPath("database", `${agentId}.db`);
30
39
  const blobPath = getDextoPath("blobs", agentId);
31
40
  const enriched = {
@@ -34,24 +43,7 @@ function enrichAgentConfig(config, configPath, options = {}) {
34
43
  // Set agentId explicitly (single source of truth)
35
44
  };
36
45
  if (!config.logger) {
37
- const transports = isInteractiveCli ? [
38
- {
39
- type: "file",
40
- path: logPath,
41
- maxSize: 10 * 1024 * 1024,
42
- // 10MB
43
- maxFiles: 5
44
- }
45
- ] : [
46
- { type: "console", colorize: true },
47
- {
48
- type: "file",
49
- path: logPath,
50
- maxSize: 10 * 1024 * 1024,
51
- // 10MB
52
- maxFiles: 5
53
- }
54
- ];
46
+ const transports = isInteractiveCli ? [{ type: "silent" }] : [{ type: "console", colorize: true }];
55
47
  enriched.logger = {
56
48
  level: logLevel,
57
49
  transports
@@ -96,6 +88,68 @@ function enrichAgentConfig(config, configPath, options = {}) {
96
88
  );
97
89
  enriched.prompts = [...existingPrompts, ...filteredDiscovered];
98
90
  }
91
+ if (!skipPluginDiscovery) {
92
+ const existingPromptPaths = /* @__PURE__ */ new Set();
93
+ for (const prompt of enriched.prompts ?? []) {
94
+ if (prompt.type === "file") {
95
+ existingPromptPaths.add(path.resolve(prompt.file));
96
+ }
97
+ }
98
+ const discoveredPlugins = discoverClaudeCodePlugins(void 0, bundledPlugins);
99
+ for (const plugin of discoveredPlugins) {
100
+ const loaded = loadClaudeCodePlugin(plugin);
101
+ for (const warning of loaded.warnings) {
102
+ console.warn(`[plugin] ${warning}`);
103
+ }
104
+ for (const cmd of loaded.commands) {
105
+ const resolvedPath = path.resolve(cmd.file);
106
+ if (existingPromptPaths.has(resolvedPath)) {
107
+ continue;
108
+ }
109
+ existingPromptPaths.add(resolvedPath);
110
+ const promptEntry = {
111
+ type: "file",
112
+ file: cmd.file,
113
+ namespace: cmd.namespace
114
+ };
115
+ enriched.prompts = enriched.prompts ?? [];
116
+ enriched.prompts.push(promptEntry);
117
+ }
118
+ if (loaded.mcpConfig?.mcpServers) {
119
+ enriched.mcpServers = {
120
+ ...enriched.mcpServers,
121
+ ...loaded.mcpConfig.mcpServers
122
+ };
123
+ }
124
+ if (loaded.customToolProviders.length > 0) {
125
+ for (const providerType of loaded.customToolProviders) {
126
+ const alreadyConfigured = enriched.customTools?.some(
127
+ (tool) => typeof tool === "object" && tool !== null && tool.type === providerType
128
+ );
129
+ if (!alreadyConfigured) {
130
+ enriched.customTools = enriched.customTools ?? [];
131
+ enriched.customTools.push({ type: providerType });
132
+ }
133
+ }
134
+ }
135
+ }
136
+ const standaloneSkills = discoverStandaloneSkills();
137
+ for (const skill of standaloneSkills) {
138
+ const resolvedPath = path.resolve(skill.skillFile);
139
+ if (existingPromptPaths.has(resolvedPath)) {
140
+ continue;
141
+ }
142
+ existingPromptPaths.add(resolvedPath);
143
+ const promptEntry = {
144
+ type: "file",
145
+ file: skill.skillFile
146
+ // No namespace for standalone skills - they use id directly
147
+ // (unlike plugin commands which need plugin:command naming)
148
+ };
149
+ enriched.prompts = enriched.prompts ?? [];
150
+ enriched.prompts.push(promptEntry);
151
+ }
152
+ }
99
153
  const instructionFile = discoverAgentInstructionFile();
100
154
  if (instructionFile) {
101
155
  const fileContributor = {
@@ -39,8 +39,8 @@ var import_fs = require("fs");
39
39
  function discoverCommandPrompts() {
40
40
  const prompts = [];
41
41
  const seenFiles = /* @__PURE__ */ new Set();
42
- const homeDir = process.env.HOME || process.env.USERPROFILE || "";
43
42
  const cwd = process.cwd();
43
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
44
44
  const scanAndAdd = (dir) => {
45
45
  if (!(0, import_fs.existsSync)(dir)) return;
46
46
  const files = scanCommandsDirectory(dir);
@@ -3,17 +3,6 @@
3
3
  *
4
4
  * Discovers command prompts from commands/ directories based on execution context.
5
5
  * Extracted to separate file to enable proper unit testing with mocks.
6
- */
7
- /**
8
- * File prompt entry for discovered commands
9
- */
10
- export interface FilePromptEntry {
11
- type: 'file';
12
- file: string;
13
- showInStarters?: boolean;
14
- }
15
- /**
16
- * Discovers command prompts from commands/ directories.
17
6
  *
18
7
  * Discovery locations (in priority order):
19
8
  *
@@ -29,6 +18,17 @@ export interface FilePromptEntry {
29
18
  * 7. ~/.cursor/commands/ (Cursor compatibility)
30
19
  *
31
20
  * Files with the same basename are deduplicated (first found wins).
21
+ */
22
+ /**
23
+ * File prompt entry for discovered commands
24
+ */
25
+ export interface FilePromptEntry {
26
+ type: 'file';
27
+ file: string;
28
+ showInStarters?: boolean;
29
+ }
30
+ /**
31
+ * Discovers command prompts from commands/ directories.
32
32
  *
33
33
  * @returns Array of file prompt entries for discovered .md files
34
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"discover-prompts.d.ts","sourceRoot":"","sources":["../../src/config/discover-prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,EAAE,CAkF1D;AAiCD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CA0B5D"}
1
+ {"version":3,"file":"discover-prompts.d.ts","sourceRoot":"","sources":["../../src/config/discover-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAWH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,EAAE,CAkF1D;AAiCD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CA0B5D"}
@@ -9,8 +9,8 @@ import { existsSync, readdirSync } from "fs";
9
9
  function discoverCommandPrompts() {
10
10
  const prompts = [];
11
11
  const seenFiles = /* @__PURE__ */ new Set();
12
- const homeDir = process.env.HOME || process.env.USERPROFILE || "";
13
12
  const cwd = process.cwd();
13
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
14
14
  const scanAndAdd = (dir) => {
15
15
  if (!existsSync(dir)) return;
16
16
  const files = scanCommandsDirectory(dir);
@@ -35,11 +35,12 @@ var import_fs = require("fs");
35
35
  var import_path = __toESM(require("path"), 1);
36
36
  var import_yaml = require("yaml");
37
37
  var import_errors = require("./errors.js");
38
- function expandTemplateVars(config, agentDir) {
38
+ var import_path2 = require("../utils/path.js");
39
+ function expandTemplateVars(config, context) {
39
40
  const result = JSON.parse(JSON.stringify(config));
40
41
  function walk(obj) {
41
42
  if (typeof obj === "string") {
42
- return expandString(obj, agentDir);
43
+ return expandString(obj, context);
43
44
  }
44
45
  if (Array.isArray(obj)) {
45
46
  return obj.map(walk);
@@ -55,23 +56,36 @@ function expandTemplateVars(config, agentDir) {
55
56
  }
56
57
  return walk(result);
57
58
  }
58
- function expandString(str, agentDir) {
59
- const result = str.replace(/\${{\s*dexto\.agent_dir\s*}}/g, agentDir);
60
- if (result !== str) {
61
- validateExpandedPath(str, result, agentDir);
59
+ function expandString(str, context) {
60
+ let result = str;
61
+ let hasAgentDirExpansion = false;
62
+ let hasProjectDirExpansion = false;
63
+ if (/\${{\s*dexto\.agent_dir\s*}}/.test(result)) {
64
+ result = result.replace(/\${{\s*dexto\.agent_dir\s*}}/g, context.agentDir);
65
+ hasAgentDirExpansion = true;
66
+ }
67
+ if (/\${{\s*dexto\.project_dir\s*}}/.test(result)) {
68
+ result = result.replace(/\${{\s*dexto\.project_dir\s*}}/g, context.projectDir);
69
+ hasProjectDirExpansion = true;
70
+ }
71
+ if (hasAgentDirExpansion) {
72
+ validateExpandedPath(str, result, context.agentDir, "agent_dir");
73
+ }
74
+ if (hasProjectDirExpansion) {
75
+ validateExpandedPath(str, result, context.projectDir, "project_dir");
62
76
  }
63
77
  return result;
64
78
  }
65
- function validateExpandedPath(original, expanded, agentDir) {
79
+ function validateExpandedPath(original, expanded, rootDir, varName) {
66
80
  const resolved = import_path.default.resolve(expanded);
67
- const agentRoot = import_path.default.resolve(agentDir);
68
- const relative = import_path.default.relative(agentRoot, resolved);
81
+ const root = import_path.default.resolve(rootDir);
82
+ const relative = import_path.default.relative(root, resolved);
69
83
  if (relative.startsWith("..") || import_path.default.isAbsolute(relative)) {
70
84
  throw new Error(
71
- `Security: Template expansion attempted to escape agent directory.
85
+ `Security: Template expansion attempted to escape ${varName} directory.
72
86
  Original: ${original}
73
87
  Expanded: ${expanded}
74
- Agent root: ${agentRoot}`
88
+ Root: ${root}`
75
89
  );
76
90
  }
77
91
  }
@@ -102,8 +116,12 @@ async function loadAgentConfig(configPath, logger) {
102
116
  }
103
117
  try {
104
118
  const agentDir = import_path.default.dirname(absolutePath);
105
- config = expandTemplateVars(config, agentDir);
106
- logger?.debug(`Expanded template variables for agent in: ${agentDir}`);
119
+ const projectDir = (0, import_path2.getDextoPath)("");
120
+ const context = { agentDir, projectDir };
121
+ config = expandTemplateVars(config, context);
122
+ logger?.debug(
123
+ `Expanded template variables for agent in: ${agentDir}, project: ${projectDir}`
124
+ );
107
125
  } catch (error) {
108
126
  throw import_errors.ConfigError.parseError(
109
127
  absolutePath,
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgEhD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,WAAW,CAAC,CAuDtB"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAsGhD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,WAAW,CAAC,CA6DtB"}
@@ -2,11 +2,12 @@ import { promises as fs } from "fs";
2
2
  import path from "path";
3
3
  import { parse as parseYaml } from "yaml";
4
4
  import { ConfigError } from "./errors.js";
5
- function expandTemplateVars(config, agentDir) {
5
+ import { getDextoPath } from "../utils/path.js";
6
+ function expandTemplateVars(config, context) {
6
7
  const result = JSON.parse(JSON.stringify(config));
7
8
  function walk(obj) {
8
9
  if (typeof obj === "string") {
9
- return expandString(obj, agentDir);
10
+ return expandString(obj, context);
10
11
  }
11
12
  if (Array.isArray(obj)) {
12
13
  return obj.map(walk);
@@ -22,23 +23,36 @@ function expandTemplateVars(config, agentDir) {
22
23
  }
23
24
  return walk(result);
24
25
  }
25
- function expandString(str, agentDir) {
26
- const result = str.replace(/\${{\s*dexto\.agent_dir\s*}}/g, agentDir);
27
- if (result !== str) {
28
- validateExpandedPath(str, result, agentDir);
26
+ function expandString(str, context) {
27
+ let result = str;
28
+ let hasAgentDirExpansion = false;
29
+ let hasProjectDirExpansion = false;
30
+ if (/\${{\s*dexto\.agent_dir\s*}}/.test(result)) {
31
+ result = result.replace(/\${{\s*dexto\.agent_dir\s*}}/g, context.agentDir);
32
+ hasAgentDirExpansion = true;
33
+ }
34
+ if (/\${{\s*dexto\.project_dir\s*}}/.test(result)) {
35
+ result = result.replace(/\${{\s*dexto\.project_dir\s*}}/g, context.projectDir);
36
+ hasProjectDirExpansion = true;
37
+ }
38
+ if (hasAgentDirExpansion) {
39
+ validateExpandedPath(str, result, context.agentDir, "agent_dir");
40
+ }
41
+ if (hasProjectDirExpansion) {
42
+ validateExpandedPath(str, result, context.projectDir, "project_dir");
29
43
  }
30
44
  return result;
31
45
  }
32
- function validateExpandedPath(original, expanded, agentDir) {
46
+ function validateExpandedPath(original, expanded, rootDir, varName) {
33
47
  const resolved = path.resolve(expanded);
34
- const agentRoot = path.resolve(agentDir);
35
- const relative = path.relative(agentRoot, resolved);
48
+ const root = path.resolve(rootDir);
49
+ const relative = path.relative(root, resolved);
36
50
  if (relative.startsWith("..") || path.isAbsolute(relative)) {
37
51
  throw new Error(
38
- `Security: Template expansion attempted to escape agent directory.
52
+ `Security: Template expansion attempted to escape ${varName} directory.
39
53
  Original: ${original}
40
54
  Expanded: ${expanded}
41
- Agent root: ${agentRoot}`
55
+ Root: ${root}`
42
56
  );
43
57
  }
44
58
  }
@@ -69,8 +83,12 @@ async function loadAgentConfig(configPath, logger) {
69
83
  }
70
84
  try {
71
85
  const agentDir = path.dirname(absolutePath);
72
- config = expandTemplateVars(config, agentDir);
73
- logger?.debug(`Expanded template variables for agent in: ${agentDir}`);
86
+ const projectDir = getDextoPath("");
87
+ const context = { agentDir, projectDir };
88
+ config = expandTemplateVars(config, context);
89
+ logger?.debug(
90
+ `Expanded template variables for agent in: ${agentDir}, project: ${projectDir}`
91
+ );
74
92
  } catch (error) {
75
93
  throw ConfigError.parseError(
76
94
  absolutePath,