@dexto/agent-management 1.5.6 → 1.5.8

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 (140) hide show
  1. package/dist/config/config-enrichment.cjs +72 -21
  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 +76 -21
  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 +76 -0
  13. package/dist/index.d.ts +5 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +78 -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 +93 -0
  25. package/dist/plugins/discover-skills.d.ts +49 -0
  26. package/dist/plugins/discover-skills.d.ts.map +1 -0
  27. package/dist/plugins/discover-skills.js +58 -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/errors.cjs +11 -0
  101. package/dist/preferences/errors.d.ts +1 -0
  102. package/dist/preferences/errors.d.ts.map +1 -1
  103. package/dist/preferences/errors.js +11 -0
  104. package/dist/preferences/loader.cjs +119 -6
  105. package/dist/preferences/loader.d.ts +21 -1
  106. package/dist/preferences/loader.d.ts.map +1 -1
  107. package/dist/preferences/loader.js +102 -1
  108. package/dist/preferences/schemas.cjs +12 -0
  109. package/dist/preferences/schemas.d.ts +38 -12
  110. package/dist/preferences/schemas.d.ts.map +1 -1
  111. package/dist/preferences/schemas.js +10 -0
  112. package/dist/runtime/AgentRuntime.cjs +1 -2
  113. package/dist/runtime/AgentRuntime.d.ts.map +1 -1
  114. package/dist/runtime/AgentRuntime.js +1 -2
  115. package/dist/tool-provider/llm-resolution.cjs +74 -0
  116. package/dist/tool-provider/llm-resolution.d.ts +51 -0
  117. package/dist/tool-provider/llm-resolution.d.ts.map +1 -0
  118. package/dist/tool-provider/llm-resolution.js +50 -0
  119. package/dist/tool-provider/runtime-service.cjs +246 -34
  120. package/dist/tool-provider/runtime-service.d.ts +34 -2
  121. package/dist/tool-provider/runtime-service.d.ts.map +1 -1
  122. package/dist/tool-provider/runtime-service.js +236 -34
  123. package/dist/tool-provider/tool-provider.cjs +154 -1
  124. package/dist/tool-provider/tool-provider.d.ts +7 -1
  125. package/dist/tool-provider/tool-provider.d.ts.map +1 -1
  126. package/dist/tool-provider/tool-provider.js +161 -1
  127. package/dist/tool-provider/types.d.ts +2 -0
  128. package/dist/tool-provider/types.d.ts.map +1 -1
  129. package/dist/utils/api-key-resolver.cjs +5 -2
  130. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  131. package/dist/utils/api-key-resolver.js +5 -2
  132. package/dist/utils/dexto-auth.cjs +83 -0
  133. package/dist/utils/dexto-auth.d.ts +23 -0
  134. package/dist/utils/dexto-auth.d.ts.map +1 -0
  135. package/dist/utils/dexto-auth.js +57 -0
  136. package/dist/utils/feature-flags.cjs +32 -0
  137. package/dist/utils/feature-flags.d.ts +21 -0
  138. package/dist/utils/feature-flags.d.ts.map +1 -0
  139. package/dist/utils/feature-flags.js +8 -0
  140. package/package.json +3 -2
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var uninstall_plugin_exports = {};
30
+ __export(uninstall_plugin_exports, {
31
+ uninstallPlugin: () => uninstallPlugin
32
+ });
33
+ module.exports = __toCommonJS(uninstall_plugin_exports);
34
+ var path = __toESM(require("path"), 1);
35
+ var import_fs = require("fs");
36
+ var import_install_plugin = require("./install-plugin.js");
37
+ var import_errors = require("./errors.js");
38
+ function findPluginInstallation(pluginName, projectPath) {
39
+ const installed = (0, import_install_plugin.loadDextoInstalledPlugins)();
40
+ const normalizedName = pluginName.toLowerCase();
41
+ const currentProjectPath = projectPath || process.cwd();
42
+ if (installed.plugins[pluginName]) {
43
+ const installations = installed.plugins[pluginName];
44
+ for (const entry of installations) {
45
+ if ((entry.scope === "project" || entry.scope === "local") && entry.projectPath) {
46
+ const normalizedInstallProject = path.resolve(entry.projectPath).toLowerCase();
47
+ const normalizedCurrentProject = path.resolve(currentProjectPath).toLowerCase();
48
+ if (normalizedInstallProject === normalizedCurrentProject) {
49
+ return { entry, pluginId: pluginName };
50
+ }
51
+ continue;
52
+ }
53
+ return { entry, pluginId: pluginName };
54
+ }
55
+ }
56
+ for (const [pluginId, installations] of Object.entries(installed.plugins)) {
57
+ for (const entry of installations) {
58
+ const manifestPath = path.join(entry.installPath, ".claude-plugin", "plugin.json");
59
+ if (!(0, import_fs.existsSync)(manifestPath)) continue;
60
+ try {
61
+ const content = (0, import_fs.readFileSync)(manifestPath, "utf-8");
62
+ const manifest = JSON.parse(content);
63
+ if (manifest.name?.toLowerCase() !== normalizedName) continue;
64
+ if ((entry.scope === "project" || entry.scope === "local") && entry.projectPath) {
65
+ const normalizedInstallProject = path.resolve(entry.projectPath).toLowerCase();
66
+ const normalizedCurrentProject = path.resolve(currentProjectPath).toLowerCase();
67
+ if (normalizedInstallProject === normalizedCurrentProject) {
68
+ return { entry, pluginId };
69
+ }
70
+ continue;
71
+ }
72
+ return { entry, pluginId };
73
+ } catch {
74
+ continue;
75
+ }
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ async function uninstallPlugin(pluginName, options) {
81
+ const { projectPath } = options || {};
82
+ const atIndex = pluginName.lastIndexOf("@");
83
+ const SEMVER_SUFFIX = /^(?:v)?\d+\.\d+\.\d+(?:-[\w.-]+)?$/;
84
+ const nameWithoutVersion = atIndex > 0 && SEMVER_SUFFIX.test(pluginName.slice(atIndex + 1)) ? pluginName.slice(0, atIndex) : pluginName;
85
+ const found = findPluginInstallation(nameWithoutVersion, projectPath);
86
+ if (!found) {
87
+ throw import_errors.PluginError.uninstallNotFound(nameWithoutVersion);
88
+ }
89
+ const { entry, pluginId } = found;
90
+ let removedPath;
91
+ const shouldDeleteFiles = !entry.isLocal;
92
+ if (shouldDeleteFiles) {
93
+ try {
94
+ (0, import_fs.rmSync)(entry.installPath, { recursive: true, force: true });
95
+ removedPath = entry.installPath;
96
+ } catch (error) {
97
+ throw import_errors.PluginError.uninstallDeleteFailed(
98
+ entry.installPath,
99
+ error instanceof Error ? error.message : String(error)
100
+ );
101
+ }
102
+ } else {
103
+ removedPath = entry.installPath;
104
+ }
105
+ const installed = (0, import_install_plugin.loadDextoInstalledPlugins)();
106
+ const currentProjectPath = projectPath || process.cwd();
107
+ if (installed.plugins[pluginId]) {
108
+ installed.plugins[pluginId] = installed.plugins[pluginId].filter((e) => {
109
+ if (e.installPath !== entry.installPath) return true;
110
+ if (e.scope === entry.scope) {
111
+ if ((e.scope === "project" || e.scope === "local") && e.projectPath) {
112
+ const normalizedEntryProject = path.resolve(e.projectPath).toLowerCase();
113
+ const normalizedCurrentProject = path.resolve(currentProjectPath).toLowerCase();
114
+ return normalizedEntryProject !== normalizedCurrentProject;
115
+ }
116
+ return false;
117
+ }
118
+ return true;
119
+ });
120
+ if (installed.plugins[pluginId].length === 0) {
121
+ delete installed.plugins[pluginId];
122
+ }
123
+ }
124
+ (0, import_install_plugin.saveDextoInstalledPlugins)(installed);
125
+ return {
126
+ success: true,
127
+ removedPath
128
+ };
129
+ }
130
+ // Annotate the CommonJS export names for ESM import in node:
131
+ 0 && (module.exports = {
132
+ uninstallPlugin
133
+ });
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Plugin Uninstallation
3
+ *
4
+ * Uninstalls plugins from Dexto's plugin directory.
5
+ * Removes plugin files and updates installed_plugins.json.
6
+ */
7
+ import type { PluginUninstallResult } from './types.js';
8
+ /**
9
+ * Options for plugin uninstallation
10
+ */
11
+ export interface UninstallPluginOptions {
12
+ /** Project path for filtering project-scoped plugins */
13
+ projectPath?: string;
14
+ }
15
+ /**
16
+ * Uninstalls a plugin by name.
17
+ * Accepts both "name" and "name@version" formats.
18
+ *
19
+ * @param pluginName Plugin name to uninstall (with optional @version suffix)
20
+ * @param options Uninstallation options
21
+ * @returns Uninstallation result with success status
22
+ */
23
+ export declare function uninstallPlugin(pluginName: string, options?: UninstallPluginOptions): Promise<PluginUninstallResult>;
24
+ //# sourceMappingURL=uninstall-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/uninstall-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAwB,MAAM,YAAY,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAmED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,qBAAqB,CAAC,CA2EhC"}
@@ -0,0 +1,99 @@
1
+ import * as path from "path";
2
+ import { existsSync, readFileSync, rmSync } from "fs";
3
+ import { loadDextoInstalledPlugins, saveDextoInstalledPlugins } from "./install-plugin.js";
4
+ import { PluginError } from "./errors.js";
5
+ function findPluginInstallation(pluginName, projectPath) {
6
+ const installed = loadDextoInstalledPlugins();
7
+ const normalizedName = pluginName.toLowerCase();
8
+ const currentProjectPath = projectPath || process.cwd();
9
+ if (installed.plugins[pluginName]) {
10
+ const installations = installed.plugins[pluginName];
11
+ for (const entry of installations) {
12
+ if ((entry.scope === "project" || entry.scope === "local") && entry.projectPath) {
13
+ const normalizedInstallProject = path.resolve(entry.projectPath).toLowerCase();
14
+ const normalizedCurrentProject = path.resolve(currentProjectPath).toLowerCase();
15
+ if (normalizedInstallProject === normalizedCurrentProject) {
16
+ return { entry, pluginId: pluginName };
17
+ }
18
+ continue;
19
+ }
20
+ return { entry, pluginId: pluginName };
21
+ }
22
+ }
23
+ for (const [pluginId, installations] of Object.entries(installed.plugins)) {
24
+ for (const entry of installations) {
25
+ const manifestPath = path.join(entry.installPath, ".claude-plugin", "plugin.json");
26
+ if (!existsSync(manifestPath)) continue;
27
+ try {
28
+ const content = readFileSync(manifestPath, "utf-8");
29
+ const manifest = JSON.parse(content);
30
+ if (manifest.name?.toLowerCase() !== normalizedName) continue;
31
+ if ((entry.scope === "project" || entry.scope === "local") && entry.projectPath) {
32
+ const normalizedInstallProject = path.resolve(entry.projectPath).toLowerCase();
33
+ const normalizedCurrentProject = path.resolve(currentProjectPath).toLowerCase();
34
+ if (normalizedInstallProject === normalizedCurrentProject) {
35
+ return { entry, pluginId };
36
+ }
37
+ continue;
38
+ }
39
+ return { entry, pluginId };
40
+ } catch {
41
+ continue;
42
+ }
43
+ }
44
+ }
45
+ return null;
46
+ }
47
+ async function uninstallPlugin(pluginName, options) {
48
+ const { projectPath } = options || {};
49
+ const atIndex = pluginName.lastIndexOf("@");
50
+ const SEMVER_SUFFIX = /^(?:v)?\d+\.\d+\.\d+(?:-[\w.-]+)?$/;
51
+ const nameWithoutVersion = atIndex > 0 && SEMVER_SUFFIX.test(pluginName.slice(atIndex + 1)) ? pluginName.slice(0, atIndex) : pluginName;
52
+ const found = findPluginInstallation(nameWithoutVersion, projectPath);
53
+ if (!found) {
54
+ throw PluginError.uninstallNotFound(nameWithoutVersion);
55
+ }
56
+ const { entry, pluginId } = found;
57
+ let removedPath;
58
+ const shouldDeleteFiles = !entry.isLocal;
59
+ if (shouldDeleteFiles) {
60
+ try {
61
+ rmSync(entry.installPath, { recursive: true, force: true });
62
+ removedPath = entry.installPath;
63
+ } catch (error) {
64
+ throw PluginError.uninstallDeleteFailed(
65
+ entry.installPath,
66
+ error instanceof Error ? error.message : String(error)
67
+ );
68
+ }
69
+ } else {
70
+ removedPath = entry.installPath;
71
+ }
72
+ const installed = loadDextoInstalledPlugins();
73
+ const currentProjectPath = projectPath || process.cwd();
74
+ if (installed.plugins[pluginId]) {
75
+ installed.plugins[pluginId] = installed.plugins[pluginId].filter((e) => {
76
+ if (e.installPath !== entry.installPath) return true;
77
+ if (e.scope === entry.scope) {
78
+ if ((e.scope === "project" || e.scope === "local") && e.projectPath) {
79
+ const normalizedEntryProject = path.resolve(e.projectPath).toLowerCase();
80
+ const normalizedCurrentProject = path.resolve(currentProjectPath).toLowerCase();
81
+ return normalizedEntryProject !== normalizedCurrentProject;
82
+ }
83
+ return false;
84
+ }
85
+ return true;
86
+ });
87
+ if (installed.plugins[pluginId].length === 0) {
88
+ delete installed.plugins[pluginId];
89
+ }
90
+ }
91
+ saveDextoInstalledPlugins(installed);
92
+ return {
93
+ success: true,
94
+ removedPath
95
+ };
96
+ }
97
+ export {
98
+ uninstallPlugin
99
+ };
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var validate_plugin_exports = {};
30
+ __export(validate_plugin_exports, {
31
+ tryLoadManifest: () => tryLoadManifest,
32
+ validatePluginDirectory: () => validatePluginDirectory
33
+ });
34
+ module.exports = __toCommonJS(validate_plugin_exports);
35
+ var path = __toESM(require("path"), 1);
36
+ var import_fs = require("fs");
37
+ var import_schemas = require("./schemas.js");
38
+ function validatePluginDirectory(pluginPath) {
39
+ const errors = [];
40
+ const warnings = [];
41
+ let manifest;
42
+ let format;
43
+ const absolutePath = path.isAbsolute(pluginPath) ? pluginPath : path.resolve(pluginPath);
44
+ if (!(0, import_fs.existsSync)(absolutePath)) {
45
+ errors.push(`Directory does not exist: ${absolutePath}`);
46
+ return { valid: false, errors, warnings };
47
+ }
48
+ const dextoPluginDir = path.join(absolutePath, ".dexto-plugin");
49
+ const claudePluginDir = path.join(absolutePath, ".claude-plugin");
50
+ let manifestPath;
51
+ if ((0, import_fs.existsSync)(dextoPluginDir)) {
52
+ manifestPath = path.join(dextoPluginDir, "plugin.json");
53
+ format = "dexto";
54
+ } else if ((0, import_fs.existsSync)(claudePluginDir)) {
55
+ manifestPath = path.join(claudePluginDir, "plugin.json");
56
+ format = "claude-code";
57
+ } else {
58
+ errors.push("Missing .dexto-plugin or .claude-plugin directory");
59
+ return { valid: false, errors, warnings };
60
+ }
61
+ if (!(0, import_fs.existsSync)(manifestPath)) {
62
+ errors.push(
63
+ `Missing ${format === "dexto" ? ".dexto-plugin" : ".claude-plugin"}/plugin.json`
64
+ );
65
+ return { valid: false, errors, warnings };
66
+ }
67
+ try {
68
+ const content = (0, import_fs.readFileSync)(manifestPath, "utf-8");
69
+ let parsed;
70
+ try {
71
+ parsed = JSON.parse(content);
72
+ } catch (parseError) {
73
+ errors.push(
74
+ `Invalid JSON in plugin.json: ${parseError instanceof Error ? parseError.message : String(parseError)}`
75
+ );
76
+ return { valid: false, errors, warnings };
77
+ }
78
+ const schema = format === "dexto" ? import_schemas.DextoPluginManifestSchema : import_schemas.PluginManifestSchema;
79
+ const result = schema.safeParse(parsed);
80
+ if (!result.success) {
81
+ const issues = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
82
+ errors.push(`Schema validation failed: ${issues.join("; ")}`);
83
+ return { valid: false, errors, warnings };
84
+ }
85
+ manifest = result.data;
86
+ } catch (error) {
87
+ errors.push(
88
+ `Failed to read plugin.json: ${error instanceof Error ? error.message : String(error)}`
89
+ );
90
+ return { valid: false, errors, warnings };
91
+ }
92
+ const hasCommands = checkDirectoryHasFiles(path.join(absolutePath, "commands"), ".md");
93
+ const hasSkills = checkDirectoryHasSkills(path.join(absolutePath, "skills"));
94
+ if (!hasCommands && !hasSkills) {
95
+ warnings.push("Plugin has no commands or skills");
96
+ }
97
+ if ((0, import_fs.existsSync)(path.join(absolutePath, "hooks"))) {
98
+ warnings.push("hooks/ directory found - hooks are not supported (security risk)");
99
+ }
100
+ if ((0, import_fs.existsSync)(path.join(absolutePath, ".lsp.json"))) {
101
+ warnings.push(".lsp.json found - LSP configuration is not supported");
102
+ }
103
+ const mcpPath = path.join(absolutePath, ".mcp.json");
104
+ if ((0, import_fs.existsSync)(mcpPath)) {
105
+ try {
106
+ const mcpContent = (0, import_fs.readFileSync)(mcpPath, "utf-8");
107
+ JSON.parse(mcpContent);
108
+ } catch {
109
+ warnings.push(".mcp.json exists but contains invalid JSON");
110
+ }
111
+ }
112
+ return {
113
+ valid: errors.length === 0,
114
+ manifest,
115
+ format,
116
+ errors,
117
+ warnings
118
+ };
119
+ }
120
+ function checkDirectoryHasFiles(dirPath, extension) {
121
+ if (!(0, import_fs.existsSync)(dirPath)) {
122
+ return false;
123
+ }
124
+ try {
125
+ const entries = (0, import_fs.readdirSync)(dirPath, { withFileTypes: true });
126
+ return entries.some((entry) => entry.isFile() && entry.name.endsWith(extension));
127
+ } catch {
128
+ return false;
129
+ }
130
+ }
131
+ function checkDirectoryHasSkills(skillsDir) {
132
+ if (!(0, import_fs.existsSync)(skillsDir)) {
133
+ return false;
134
+ }
135
+ try {
136
+ const entries = (0, import_fs.readdirSync)(skillsDir, { withFileTypes: true });
137
+ return entries.some((entry) => {
138
+ if (!entry.isDirectory()) return false;
139
+ const skillMdPath = path.join(skillsDir, entry.name, "SKILL.md");
140
+ return (0, import_fs.existsSync)(skillMdPath);
141
+ });
142
+ } catch {
143
+ return false;
144
+ }
145
+ }
146
+ function tryLoadManifest(pluginPath, returnFormat) {
147
+ const dextoManifestPath = path.join(pluginPath, ".dexto-plugin", "plugin.json");
148
+ const claudeManifestPath = path.join(pluginPath, ".claude-plugin", "plugin.json");
149
+ let manifestPath;
150
+ let format;
151
+ if ((0, import_fs.existsSync)(dextoManifestPath)) {
152
+ manifestPath = dextoManifestPath;
153
+ format = "dexto";
154
+ } else if ((0, import_fs.existsSync)(claudeManifestPath)) {
155
+ manifestPath = claudeManifestPath;
156
+ format = "claude-code";
157
+ } else {
158
+ return null;
159
+ }
160
+ try {
161
+ const content = (0, import_fs.readFileSync)(manifestPath, "utf-8");
162
+ const parsed = JSON.parse(content);
163
+ const schema = format === "dexto" ? import_schemas.DextoPluginManifestSchema : import_schemas.PluginManifestSchema;
164
+ const result = schema.safeParse(parsed);
165
+ if (!result.success) {
166
+ return null;
167
+ }
168
+ if (returnFormat) {
169
+ return { manifest: result.data, format };
170
+ }
171
+ return result.data;
172
+ } catch {
173
+ return null;
174
+ }
175
+ }
176
+ // Annotate the CommonJS export names for ESM import in node:
177
+ 0 && (module.exports = {
178
+ tryLoadManifest,
179
+ validatePluginDirectory
180
+ });
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Plugin Validation
3
+ *
4
+ * Validates plugin directory structure and manifest.
5
+ * Checks for required files, valid JSON, and schema compliance.
6
+ *
7
+ * Supports two plugin formats:
8
+ * - .claude-plugin/plugin.json: Claude Code compatible format
9
+ * - .dexto-plugin/plugin.json: Dexto-native format with extended features (preferred)
10
+ */
11
+ import type { PluginValidationResult, PluginManifest, DextoPluginManifest, PluginFormat } from './types.js';
12
+ /**
13
+ * Extended validation result with plugin format
14
+ */
15
+ export interface ExtendedPluginValidationResult extends PluginValidationResult {
16
+ /** Plugin format detected */
17
+ format?: PluginFormat;
18
+ }
19
+ /**
20
+ * Validates a plugin directory structure and manifest.
21
+ *
22
+ * Checks:
23
+ * 1. Directory exists
24
+ * 2. .dexto-plugin/plugin.json OR .claude-plugin/plugin.json exists (Dexto format preferred)
25
+ * 3. plugin.json is valid JSON
26
+ * 4. plugin.json matches schema (name is required)
27
+ * 5. At least one command or skill exists (warning if none)
28
+ *
29
+ * @param pluginPath Absolute or relative path to plugin directory
30
+ * @returns Validation result with manifest (if valid), errors, and warnings
31
+ */
32
+ export declare function validatePluginDirectory(pluginPath: string): ExtendedPluginValidationResult;
33
+ /**
34
+ * Result of manifest loading with format information
35
+ */
36
+ export interface LoadedManifestResult {
37
+ manifest: PluginManifest | DextoPluginManifest;
38
+ format: PluginFormat;
39
+ }
40
+ /**
41
+ * Attempts to load and validate a plugin manifest from a directory.
42
+ * Returns null if the manifest doesn't exist, is invalid JSON, or fails schema validation.
43
+ *
44
+ * Checks for .dexto-plugin first (preferred), then falls back to .claude-plugin.
45
+ *
46
+ * This is a shared utility used by discover-plugins, list-plugins, and import-plugin.
47
+ *
48
+ * @param pluginPath Absolute path to the plugin directory
49
+ * @returns Validated manifest with format or null if not a valid plugin
50
+ */
51
+ export declare function tryLoadManifest(pluginPath: string): PluginManifest | null;
52
+ export declare function tryLoadManifest(pluginPath: string, returnFormat: true): LoadedManifestResult | null;
53
+ //# sourceMappingURL=validate-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/validate-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EACR,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,YAAY,EACf,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,8BAA+B,SAAQ,sBAAsB;IAC1E,6BAA6B;IAC7B,MAAM,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,8BAA8B,CAyG1F;AAuCD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,QAAQ,EAAE,cAAc,GAAG,mBAAmB,CAAC;IAC/C,MAAM,EAAE,YAAY,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC;AAC3E,wBAAgB,eAAe,CAC3B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,IAAI,GACnB,oBAAoB,GAAG,IAAI,CAAC"}
@@ -0,0 +1,145 @@
1
+ import * as path from "path";
2
+ import { existsSync, readFileSync, readdirSync } from "fs";
3
+ import { PluginManifestSchema, DextoPluginManifestSchema } from "./schemas.js";
4
+ function validatePluginDirectory(pluginPath) {
5
+ const errors = [];
6
+ const warnings = [];
7
+ let manifest;
8
+ let format;
9
+ const absolutePath = path.isAbsolute(pluginPath) ? pluginPath : path.resolve(pluginPath);
10
+ if (!existsSync(absolutePath)) {
11
+ errors.push(`Directory does not exist: ${absolutePath}`);
12
+ return { valid: false, errors, warnings };
13
+ }
14
+ const dextoPluginDir = path.join(absolutePath, ".dexto-plugin");
15
+ const claudePluginDir = path.join(absolutePath, ".claude-plugin");
16
+ let manifestPath;
17
+ if (existsSync(dextoPluginDir)) {
18
+ manifestPath = path.join(dextoPluginDir, "plugin.json");
19
+ format = "dexto";
20
+ } else if (existsSync(claudePluginDir)) {
21
+ manifestPath = path.join(claudePluginDir, "plugin.json");
22
+ format = "claude-code";
23
+ } else {
24
+ errors.push("Missing .dexto-plugin or .claude-plugin directory");
25
+ return { valid: false, errors, warnings };
26
+ }
27
+ if (!existsSync(manifestPath)) {
28
+ errors.push(
29
+ `Missing ${format === "dexto" ? ".dexto-plugin" : ".claude-plugin"}/plugin.json`
30
+ );
31
+ return { valid: false, errors, warnings };
32
+ }
33
+ try {
34
+ const content = readFileSync(manifestPath, "utf-8");
35
+ let parsed;
36
+ try {
37
+ parsed = JSON.parse(content);
38
+ } catch (parseError) {
39
+ errors.push(
40
+ `Invalid JSON in plugin.json: ${parseError instanceof Error ? parseError.message : String(parseError)}`
41
+ );
42
+ return { valid: false, errors, warnings };
43
+ }
44
+ const schema = format === "dexto" ? DextoPluginManifestSchema : PluginManifestSchema;
45
+ const result = schema.safeParse(parsed);
46
+ if (!result.success) {
47
+ const issues = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
48
+ errors.push(`Schema validation failed: ${issues.join("; ")}`);
49
+ return { valid: false, errors, warnings };
50
+ }
51
+ manifest = result.data;
52
+ } catch (error) {
53
+ errors.push(
54
+ `Failed to read plugin.json: ${error instanceof Error ? error.message : String(error)}`
55
+ );
56
+ return { valid: false, errors, warnings };
57
+ }
58
+ const hasCommands = checkDirectoryHasFiles(path.join(absolutePath, "commands"), ".md");
59
+ const hasSkills = checkDirectoryHasSkills(path.join(absolutePath, "skills"));
60
+ if (!hasCommands && !hasSkills) {
61
+ warnings.push("Plugin has no commands or skills");
62
+ }
63
+ if (existsSync(path.join(absolutePath, "hooks"))) {
64
+ warnings.push("hooks/ directory found - hooks are not supported (security risk)");
65
+ }
66
+ if (existsSync(path.join(absolutePath, ".lsp.json"))) {
67
+ warnings.push(".lsp.json found - LSP configuration is not supported");
68
+ }
69
+ const mcpPath = path.join(absolutePath, ".mcp.json");
70
+ if (existsSync(mcpPath)) {
71
+ try {
72
+ const mcpContent = readFileSync(mcpPath, "utf-8");
73
+ JSON.parse(mcpContent);
74
+ } catch {
75
+ warnings.push(".mcp.json exists but contains invalid JSON");
76
+ }
77
+ }
78
+ return {
79
+ valid: errors.length === 0,
80
+ manifest,
81
+ format,
82
+ errors,
83
+ warnings
84
+ };
85
+ }
86
+ function checkDirectoryHasFiles(dirPath, extension) {
87
+ if (!existsSync(dirPath)) {
88
+ return false;
89
+ }
90
+ try {
91
+ const entries = readdirSync(dirPath, { withFileTypes: true });
92
+ return entries.some((entry) => entry.isFile() && entry.name.endsWith(extension));
93
+ } catch {
94
+ return false;
95
+ }
96
+ }
97
+ function checkDirectoryHasSkills(skillsDir) {
98
+ if (!existsSync(skillsDir)) {
99
+ return false;
100
+ }
101
+ try {
102
+ const entries = readdirSync(skillsDir, { withFileTypes: true });
103
+ return entries.some((entry) => {
104
+ if (!entry.isDirectory()) return false;
105
+ const skillMdPath = path.join(skillsDir, entry.name, "SKILL.md");
106
+ return existsSync(skillMdPath);
107
+ });
108
+ } catch {
109
+ return false;
110
+ }
111
+ }
112
+ function tryLoadManifest(pluginPath, returnFormat) {
113
+ const dextoManifestPath = path.join(pluginPath, ".dexto-plugin", "plugin.json");
114
+ const claudeManifestPath = path.join(pluginPath, ".claude-plugin", "plugin.json");
115
+ let manifestPath;
116
+ let format;
117
+ if (existsSync(dextoManifestPath)) {
118
+ manifestPath = dextoManifestPath;
119
+ format = "dexto";
120
+ } else if (existsSync(claudeManifestPath)) {
121
+ manifestPath = claudeManifestPath;
122
+ format = "claude-code";
123
+ } else {
124
+ return null;
125
+ }
126
+ try {
127
+ const content = readFileSync(manifestPath, "utf-8");
128
+ const parsed = JSON.parse(content);
129
+ const schema = format === "dexto" ? DextoPluginManifestSchema : PluginManifestSchema;
130
+ const result = schema.safeParse(parsed);
131
+ if (!result.success) {
132
+ return null;
133
+ }
134
+ if (returnFormat) {
135
+ return { manifest: result.data, format };
136
+ }
137
+ return result.data;
138
+ } catch {
139
+ return null;
140
+ }
141
+ }
142
+ export {
143
+ tryLoadManifest,
144
+ validatePluginDirectory
145
+ };
@@ -66,6 +66,17 @@ class PreferenceError {
66
66
  }));
67
67
  return new import_core.DextoValidationError(issues);
68
68
  }
69
+ static invalidAgentId(agentId) {
70
+ return new import_core.DextoValidationError([
71
+ {
72
+ code: import_error_codes.PreferenceErrorCode.INVALID_PREFERENCE_VALUE,
73
+ message: `agentId is invalid: ${agentId}`,
74
+ scope: "preference",
75
+ type: import_core.ErrorType.USER,
76
+ severity: "error"
77
+ }
78
+ ]);
79
+ }
69
80
  }
70
81
  // Annotate the CommonJS export names for ESM import in node:
71
82
  0 && (module.exports = {
@@ -14,5 +14,6 @@ export declare class PreferenceError {
14
14
  cause: string;
15
15
  }>;
16
16
  static validationFailed(zodError: ZodError): DextoValidationError;
17
+ static invalidAgentId(agentId: string): DextoValidationError;
17
18
  }
18
19
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/preferences/errors.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAa,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC;AAGpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,qBAAa,eAAe;IACxB,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM;;;IAW3C,MAAM,CAAC,aAAa,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;IAW3D,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;IAW5D,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ;CAW7C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/preferences/errors.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAa,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC;AAGpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,qBAAa,eAAe;IACxB,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM;;;IAW3C,MAAM,CAAC,aAAa,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;IAW3D,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;IAW5D,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ;IAY1C,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM;CAWxC"}