@dexto/agent-management 1.5.7 → 1.6.0

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 (145) hide show
  1. package/dist/AgentFactory.cjs +5 -9
  2. package/dist/AgentFactory.d.ts +6 -5
  3. package/dist/AgentFactory.d.ts.map +1 -1
  4. package/dist/AgentFactory.js +5 -9
  5. package/dist/AgentManager.cjs +2 -2
  6. package/dist/AgentManager.d.ts +1 -1
  7. package/dist/AgentManager.d.ts.map +1 -1
  8. package/dist/AgentManager.js +4 -4
  9. package/dist/agent-creation.cjs +95 -0
  10. package/dist/agent-creation.d.ts +15 -0
  11. package/dist/agent-creation.d.ts.map +1 -0
  12. package/dist/agent-creation.js +78 -0
  13. package/dist/config/config-enrichment.cjs +2 -12
  14. package/dist/config/config-enrichment.d.ts +1 -1
  15. package/dist/config/config-enrichment.d.ts.map +1 -1
  16. package/dist/config/config-enrichment.js +2 -12
  17. package/dist/config/config-manager.cjs +4 -4
  18. package/dist/config/config-manager.d.ts +1 -1
  19. package/dist/config/config-manager.d.ts.map +1 -1
  20. package/dist/config/config-manager.js +3 -1
  21. package/dist/config/loader.d.ts +3 -3
  22. package/dist/config/loader.d.ts.map +1 -1
  23. package/dist/images/image-store.cjs +256 -0
  24. package/dist/images/image-store.d.ts +70 -0
  25. package/dist/images/image-store.d.ts.map +1 -0
  26. package/dist/images/image-store.js +210 -0
  27. package/dist/index.cjs +43 -2
  28. package/dist/index.d.ts +5 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +43 -1
  31. package/dist/models/custom-models.cjs +1 -1
  32. package/dist/models/custom-models.d.ts +7 -7
  33. package/dist/models/custom-models.d.ts.map +1 -1
  34. package/dist/models/custom-models.js +1 -1
  35. package/dist/plugins/discover-plugins.cjs +15 -31
  36. package/dist/plugins/discover-plugins.d.ts.map +1 -1
  37. package/dist/plugins/discover-plugins.js +15 -31
  38. package/dist/plugins/discover-skills.cjs +4 -0
  39. package/dist/plugins/discover-skills.d.ts +6 -3
  40. package/dist/plugins/discover-skills.d.ts.map +1 -1
  41. package/dist/plugins/discover-skills.js +4 -0
  42. package/dist/plugins/index.cjs +0 -2
  43. package/dist/plugins/index.d.ts +5 -6
  44. package/dist/plugins/index.d.ts.map +1 -1
  45. package/dist/plugins/index.js +0 -2
  46. package/dist/plugins/list-plugins.cjs +3 -1
  47. package/dist/plugins/list-plugins.d.ts.map +1 -1
  48. package/dist/plugins/list-plugins.js +3 -1
  49. package/dist/plugins/load-plugin.cjs +0 -13
  50. package/dist/plugins/load-plugin.d.ts +3 -5
  51. package/dist/plugins/load-plugin.d.ts.map +1 -1
  52. package/dist/plugins/load-plugin.js +0 -13
  53. package/dist/plugins/schemas.cjs +1 -11
  54. package/dist/plugins/schemas.d.ts +14 -69
  55. package/dist/plugins/schemas.d.ts.map +1 -1
  56. package/dist/plugins/schemas.js +1 -10
  57. package/dist/plugins/types.d.ts +2 -20
  58. package/dist/plugins/types.d.ts.map +1 -1
  59. package/dist/plugins/validate-plugin.cjs +7 -37
  60. package/dist/plugins/validate-plugin.d.ts +6 -24
  61. package/dist/plugins/validate-plugin.d.ts.map +1 -1
  62. package/dist/plugins/validate-plugin.js +8 -38
  63. package/dist/preferences/errors.cjs +11 -0
  64. package/dist/preferences/errors.d.ts +1 -0
  65. package/dist/preferences/errors.d.ts.map +1 -1
  66. package/dist/preferences/errors.js +11 -0
  67. package/dist/preferences/loader.cjs +119 -6
  68. package/dist/preferences/loader.d.ts +21 -1
  69. package/dist/preferences/loader.d.ts.map +1 -1
  70. package/dist/preferences/loader.js +102 -1
  71. package/dist/preferences/schemas.cjs +12 -0
  72. package/dist/preferences/schemas.d.ts +38 -12
  73. package/dist/preferences/schemas.d.ts.map +1 -1
  74. package/dist/preferences/schemas.js +10 -0
  75. package/dist/registry/registry.d.ts +4 -44
  76. package/dist/registry/registry.d.ts.map +1 -1
  77. package/dist/runtime/AgentPool.d.ts +2 -2
  78. package/dist/runtime/AgentPool.d.ts.map +1 -1
  79. package/dist/runtime/AgentRuntime.cjs +20 -15
  80. package/dist/runtime/AgentRuntime.d.ts +2 -2
  81. package/dist/runtime/AgentRuntime.d.ts.map +1 -1
  82. package/dist/runtime/AgentRuntime.js +20 -15
  83. package/dist/runtime/approval-delegation.d.ts +2 -2
  84. package/dist/runtime/approval-delegation.d.ts.map +1 -1
  85. package/dist/runtime/schemas.d.ts +1 -1
  86. package/dist/runtime/types.d.ts +2 -1
  87. package/dist/runtime/types.d.ts.map +1 -1
  88. package/dist/{tool-provider → tool-factories/agent-spawner}/error-codes.d.ts +1 -1
  89. package/dist/tool-factories/agent-spawner/error-codes.d.ts.map +1 -0
  90. package/dist/{tool-provider → tool-factories/agent-spawner}/errors.d.ts +1 -1
  91. package/dist/tool-factories/agent-spawner/errors.d.ts.map +1 -0
  92. package/dist/tool-factories/agent-spawner/factory.cjs +290 -0
  93. package/dist/tool-factories/agent-spawner/factory.d.ts +4 -0
  94. package/dist/tool-factories/agent-spawner/factory.d.ts.map +1 -0
  95. package/dist/tool-factories/agent-spawner/factory.js +279 -0
  96. package/dist/{tool-provider → tool-factories/agent-spawner}/index.cjs +9 -9
  97. package/dist/{tool-provider → tool-factories/agent-spawner}/index.d.ts +3 -3
  98. package/dist/tool-factories/agent-spawner/index.d.ts.map +1 -0
  99. package/dist/{tool-provider → tool-factories/agent-spawner}/index.js +4 -4
  100. package/dist/{tool-provider → tool-factories/agent-spawner}/llm-resolution.cjs +1 -1
  101. package/dist/{tool-provider → tool-factories/agent-spawner}/llm-resolution.d.ts +4 -4
  102. package/dist/tool-factories/agent-spawner/llm-resolution.d.ts.map +1 -0
  103. package/dist/{tool-provider → tool-factories/agent-spawner}/llm-resolution.js +1 -1
  104. package/dist/{tool-provider/runtime-service.cjs → tool-factories/agent-spawner/runtime.cjs} +112 -73
  105. package/dist/{tool-provider/runtime-service.d.ts → tool-factories/agent-spawner/runtime.d.ts} +8 -6
  106. package/dist/tool-factories/agent-spawner/runtime.d.ts.map +1 -0
  107. package/dist/{tool-provider/runtime-service.js → tool-factories/agent-spawner/runtime.js} +98 -69
  108. package/dist/{tool-provider → tool-factories/agent-spawner}/schemas.cjs +2 -2
  109. package/dist/{tool-provider → tool-factories/agent-spawner}/schemas.d.ts +4 -4
  110. package/dist/tool-factories/agent-spawner/schemas.d.ts.map +1 -0
  111. package/dist/{tool-provider → tool-factories/agent-spawner}/schemas.js +2 -2
  112. package/dist/{tool-provider → tool-factories/agent-spawner}/spawn-agent-tool.cjs +8 -7
  113. package/dist/tool-factories/agent-spawner/spawn-agent-tool.d.ts +11 -0
  114. package/dist/tool-factories/agent-spawner/spawn-agent-tool.d.ts.map +1 -0
  115. package/dist/{tool-provider → tool-factories/agent-spawner}/spawn-agent-tool.js +8 -7
  116. package/dist/tool-factories/agent-spawner/types.d.ts.map +1 -0
  117. package/dist/utils/api-key-resolver.cjs +1 -1
  118. package/dist/utils/api-key-resolver.js +1 -1
  119. package/dist/utils/feature-flags.cjs +3 -1
  120. package/dist/utils/feature-flags.d.ts +2 -2
  121. package/dist/utils/feature-flags.d.ts.map +1 -1
  122. package/dist/utils/feature-flags.js +3 -1
  123. package/dist/writer.d.ts +2 -1
  124. package/dist/writer.d.ts.map +1 -1
  125. package/package.json +6 -3
  126. package/dist/tool-provider/error-codes.d.ts.map +0 -1
  127. package/dist/tool-provider/errors.d.ts.map +0 -1
  128. package/dist/tool-provider/index.d.ts.map +0 -1
  129. package/dist/tool-provider/llm-resolution.d.ts.map +0 -1
  130. package/dist/tool-provider/runtime-service.d.ts.map +0 -1
  131. package/dist/tool-provider/schemas.d.ts.map +0 -1
  132. package/dist/tool-provider/spawn-agent-tool.d.ts +0 -10
  133. package/dist/tool-provider/spawn-agent-tool.d.ts.map +0 -1
  134. package/dist/tool-provider/tool-provider.cjs +0 -46
  135. package/dist/tool-provider/tool-provider.d.ts +0 -24
  136. package/dist/tool-provider/tool-provider.d.ts.map +0 -1
  137. package/dist/tool-provider/tool-provider.js +0 -22
  138. package/dist/tool-provider/types.d.ts.map +0 -1
  139. /package/dist/{tool-provider → tool-factories/agent-spawner}/error-codes.cjs +0 -0
  140. /package/dist/{tool-provider → tool-factories/agent-spawner}/error-codes.js +0 -0
  141. /package/dist/{tool-provider → tool-factories/agent-spawner}/errors.cjs +0 -0
  142. /package/dist/{tool-provider → tool-factories/agent-spawner}/errors.js +0 -0
  143. /package/dist/{tool-provider → tool-factories/agent-spawner}/types.cjs +0 -0
  144. /package/dist/{tool-provider → tool-factories/agent-spawner}/types.d.ts +0 -0
  145. /package/dist/{tool-provider → tool-factories/agent-spawner}/types.js +0 -0
@@ -0,0 +1,256 @@
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 image_store_exports = {};
30
+ __export(image_store_exports, {
31
+ getDefaultImageStoreDir: () => getDefaultImageStoreDir,
32
+ getImagePackageInstallDir: () => getImagePackageInstallDir,
33
+ getImagePackagesDir: () => getImagePackagesDir,
34
+ getImageRegistryPath: () => getImageRegistryPath,
35
+ isFileLikeImageSpecifier: () => isFileLikeImageSpecifier,
36
+ loadImageRegistry: () => loadImageRegistry,
37
+ parseImageSpecifier: () => parseImageSpecifier,
38
+ removeImageFromStore: () => removeImageFromStore,
39
+ resolveFileLikeImageSpecifierToFileUrl: () => resolveFileLikeImageSpecifierToFileUrl,
40
+ resolveFileLikeImageSpecifierToPath: () => resolveFileLikeImageSpecifierToPath,
41
+ resolveImageEntryFileFromStore: () => resolveImageEntryFileFromStore,
42
+ saveImageRegistry: () => saveImageRegistry,
43
+ setActiveImageVersion: () => setActiveImageVersion
44
+ });
45
+ module.exports = __toCommonJS(image_store_exports);
46
+ var import_path = __toESM(require("path"), 1);
47
+ var import_fs = require("fs");
48
+ var import_fs2 = require("fs");
49
+ var import_os = require("os");
50
+ var import_url = require("url");
51
+ var import_zod = require("zod");
52
+ var import_path2 = require("../utils/path.js");
53
+ const ImageRegistryFileSchema = import_zod.z.object({
54
+ version: import_zod.z.literal(1),
55
+ images: import_zod.z.record(
56
+ import_zod.z.object({
57
+ active: import_zod.z.string().optional(),
58
+ installed: import_zod.z.record(
59
+ import_zod.z.object({
60
+ entryFile: import_zod.z.string(),
61
+ installedAt: import_zod.z.string()
62
+ }).strict()
63
+ )
64
+ }).strict()
65
+ )
66
+ }).strict();
67
+ function getDefaultImageStoreDir() {
68
+ const override = process.env.DEXTO_IMAGE_STORE_DIR?.trim();
69
+ if (override) {
70
+ return override;
71
+ }
72
+ return (0, import_path2.getDextoGlobalPath)("images");
73
+ }
74
+ function getImageRegistryPath(storeDir = getDefaultImageStoreDir()) {
75
+ return import_path.default.join(storeDir, "registry.json");
76
+ }
77
+ function getImagePackagesDir(storeDir = getDefaultImageStoreDir()) {
78
+ return import_path.default.join(storeDir, "packages");
79
+ }
80
+ function getImagePackageInstallDir(imageId, version, storeDir = getDefaultImageStoreDir()) {
81
+ const packagesDir = getImagePackagesDir(storeDir);
82
+ const parts = imageId.startsWith("@") ? imageId.split("/") : [imageId];
83
+ return import_path.default.join(packagesDir, ...parts, version);
84
+ }
85
+ function loadImageRegistry(storeDir = getDefaultImageStoreDir()) {
86
+ const registryPath = getImageRegistryPath(storeDir);
87
+ if (!(0, import_fs.existsSync)(registryPath)) {
88
+ return { version: 1, images: {} };
89
+ }
90
+ try {
91
+ const raw = JSON.parse((0, import_fs.readFileSync)(registryPath, "utf-8"));
92
+ const parsed = ImageRegistryFileSchema.safeParse(raw);
93
+ if (!parsed.success) {
94
+ return { version: 1, images: {} };
95
+ }
96
+ return parsed.data;
97
+ } catch {
98
+ return { version: 1, images: {} };
99
+ }
100
+ }
101
+ async function saveImageRegistry(data, storeDir = getDefaultImageStoreDir()) {
102
+ const registryPath = getImageRegistryPath(storeDir);
103
+ await import_fs2.promises.mkdir(import_path.default.dirname(registryPath), { recursive: true });
104
+ const tempPath = `${registryPath}.tmp.${Date.now()}`;
105
+ try {
106
+ await import_fs2.promises.writeFile(tempPath, JSON.stringify(data, null, 2), {
107
+ encoding: "utf-8",
108
+ mode: 384
109
+ });
110
+ await import_fs2.promises.rename(tempPath, registryPath);
111
+ } catch (error) {
112
+ await import_fs2.promises.rm(tempPath, { force: true }).catch(() => {
113
+ });
114
+ throw error;
115
+ }
116
+ }
117
+ function parseImageSpecifier(specifier) {
118
+ const trimmed = specifier.trim();
119
+ if (!trimmed) {
120
+ throw new Error("Image specifier cannot be empty");
121
+ }
122
+ if (trimmed.startsWith("@")) {
123
+ const slashIndex = trimmed.indexOf("/");
124
+ if (slashIndex === -1) {
125
+ return { id: trimmed };
126
+ }
127
+ const versionIndex2 = trimmed.indexOf("@", slashIndex + 1);
128
+ if (versionIndex2 === -1) {
129
+ return { id: trimmed };
130
+ }
131
+ const version = trimmed.slice(versionIndex2 + 1).trim();
132
+ return {
133
+ id: trimmed.slice(0, versionIndex2),
134
+ ...version.length > 0 ? { version } : {}
135
+ };
136
+ }
137
+ const versionIndex = trimmed.lastIndexOf("@");
138
+ if (versionIndex > 0) {
139
+ const version = trimmed.slice(versionIndex + 1).trim();
140
+ return {
141
+ id: trimmed.slice(0, versionIndex),
142
+ ...version.length > 0 ? { version } : {}
143
+ };
144
+ }
145
+ return { id: trimmed };
146
+ }
147
+ function isFileLikeImageSpecifier(specifier) {
148
+ if (specifier === "." || specifier === "..") return true;
149
+ if (specifier.startsWith("file://")) return true;
150
+ if (specifier.startsWith("~/")) return true;
151
+ if (specifier.startsWith("./") || specifier.startsWith("../")) return true;
152
+ if (import_path.default.isAbsolute(specifier)) return true;
153
+ if (/^[a-zA-Z]:[\\/]/.test(specifier)) return true;
154
+ return false;
155
+ }
156
+ function resolveFileLikeImageSpecifierToPath(specifier, cwd = process.cwd()) {
157
+ if (specifier.startsWith("file://")) {
158
+ return (0, import_url.fileURLToPath)(specifier);
159
+ }
160
+ if (specifier.startsWith("~/")) {
161
+ return import_path.default.join((0, import_os.homedir)(), specifier.slice(2));
162
+ }
163
+ if (import_path.default.isAbsolute(specifier)) {
164
+ return specifier;
165
+ }
166
+ return import_path.default.resolve(cwd, specifier);
167
+ }
168
+ function resolveFileLikeImageSpecifierToFileUrl(specifier, cwd = process.cwd()) {
169
+ if (specifier.startsWith("file://")) {
170
+ return specifier;
171
+ }
172
+ const filePath = resolveFileLikeImageSpecifierToPath(specifier, cwd);
173
+ return (0, import_url.pathToFileURL)(filePath).href;
174
+ }
175
+ async function resolveImageEntryFileFromStore(specifier, storeDir = getDefaultImageStoreDir()) {
176
+ const registry = loadImageRegistry(storeDir);
177
+ const entry = registry.images[specifier.id];
178
+ if (!entry) {
179
+ return null;
180
+ }
181
+ const installedVersions = Object.keys(entry.installed);
182
+ if (installedVersions.length === 0) {
183
+ return null;
184
+ }
185
+ const resolvedVersion = specifier.version ?? entry.active;
186
+ if (!resolvedVersion) {
187
+ if (installedVersions.length === 1) {
188
+ return entry.installed[installedVersions[0] ?? ""]?.entryFile ?? null;
189
+ }
190
+ throw new Error(
191
+ `Image '${specifier.id}' has multiple installed versions but no active version set. Run: dexto image use ${specifier.id}@<version>`
192
+ );
193
+ }
194
+ const resolved = entry.installed[resolvedVersion];
195
+ if (!resolved) {
196
+ throw new Error(
197
+ `Image '${specifier.id}@${resolvedVersion}' is not installed. Run: dexto image install ${specifier.id}@${resolvedVersion}`
198
+ );
199
+ }
200
+ return resolved.entryFile;
201
+ }
202
+ async function setActiveImageVersion(imageId, version, storeDir = getDefaultImageStoreDir()) {
203
+ const registry = loadImageRegistry(storeDir);
204
+ const entry = registry.images[imageId];
205
+ if (!entry || !entry.installed[version]) {
206
+ throw new Error(`Image '${imageId}@${version}' is not installed`);
207
+ }
208
+ entry.active = version;
209
+ await saveImageRegistry(registry, storeDir);
210
+ }
211
+ async function removeImageFromStore(imageId, options = {}) {
212
+ const storeDir = options.storeDir ?? getDefaultImageStoreDir();
213
+ const version = options.version;
214
+ const registry = loadImageRegistry(storeDir);
215
+ const entry = registry.images[imageId];
216
+ if (!entry) {
217
+ return;
218
+ }
219
+ if (version) {
220
+ delete entry.installed[version];
221
+ if (entry.active === version) {
222
+ delete entry.active;
223
+ }
224
+ const installDir = getImagePackageInstallDir(imageId, version, storeDir);
225
+ await import_fs2.promises.rm(installDir, { recursive: true, force: true }).catch(() => {
226
+ });
227
+ if (Object.keys(entry.installed).length === 0) {
228
+ delete registry.images[imageId];
229
+ }
230
+ } else {
231
+ const versions = Object.keys(entry.installed);
232
+ for (const v of versions) {
233
+ const installDir = getImagePackageInstallDir(imageId, v, storeDir);
234
+ await import_fs2.promises.rm(installDir, { recursive: true, force: true }).catch(() => {
235
+ });
236
+ }
237
+ delete registry.images[imageId];
238
+ }
239
+ await saveImageRegistry(registry, storeDir);
240
+ }
241
+ // Annotate the CommonJS export names for ESM import in node:
242
+ 0 && (module.exports = {
243
+ getDefaultImageStoreDir,
244
+ getImagePackageInstallDir,
245
+ getImagePackagesDir,
246
+ getImageRegistryPath,
247
+ isFileLikeImageSpecifier,
248
+ loadImageRegistry,
249
+ parseImageSpecifier,
250
+ removeImageFromStore,
251
+ resolveFileLikeImageSpecifierToFileUrl,
252
+ resolveFileLikeImageSpecifierToPath,
253
+ resolveImageEntryFileFromStore,
254
+ saveImageRegistry,
255
+ setActiveImageVersion
256
+ });
@@ -0,0 +1,70 @@
1
+ import { z } from 'zod';
2
+ declare const ImageRegistryFileSchema: z.ZodObject<{
3
+ version: z.ZodLiteral<1>;
4
+ images: z.ZodRecord<z.ZodString, z.ZodObject<{
5
+ active: z.ZodOptional<z.ZodString>;
6
+ installed: z.ZodRecord<z.ZodString, z.ZodObject<{
7
+ entryFile: z.ZodString;
8
+ installedAt: z.ZodString;
9
+ }, "strict", z.ZodTypeAny, {
10
+ installedAt: string;
11
+ entryFile: string;
12
+ }, {
13
+ installedAt: string;
14
+ entryFile: string;
15
+ }>>;
16
+ }, "strict", z.ZodTypeAny, {
17
+ installed: Record<string, {
18
+ installedAt: string;
19
+ entryFile: string;
20
+ }>;
21
+ active?: string | undefined;
22
+ }, {
23
+ installed: Record<string, {
24
+ installedAt: string;
25
+ entryFile: string;
26
+ }>;
27
+ active?: string | undefined;
28
+ }>>;
29
+ }, "strict", z.ZodTypeAny, {
30
+ version: 1;
31
+ images: Record<string, {
32
+ installed: Record<string, {
33
+ installedAt: string;
34
+ entryFile: string;
35
+ }>;
36
+ active?: string | undefined;
37
+ }>;
38
+ }, {
39
+ version: 1;
40
+ images: Record<string, {
41
+ installed: Record<string, {
42
+ installedAt: string;
43
+ entryFile: string;
44
+ }>;
45
+ active?: string | undefined;
46
+ }>;
47
+ }>;
48
+ export type ImageRegistryFile = z.output<typeof ImageRegistryFileSchema>;
49
+ export interface ImageSpecifierParts {
50
+ id: string;
51
+ version?: string;
52
+ }
53
+ export declare function getDefaultImageStoreDir(): string;
54
+ export declare function getImageRegistryPath(storeDir?: string): string;
55
+ export declare function getImagePackagesDir(storeDir?: string): string;
56
+ export declare function getImagePackageInstallDir(imageId: string, version: string, storeDir?: string): string;
57
+ export declare function loadImageRegistry(storeDir?: string): ImageRegistryFile;
58
+ export declare function saveImageRegistry(data: ImageRegistryFile, storeDir?: string): Promise<void>;
59
+ export declare function parseImageSpecifier(specifier: string): ImageSpecifierParts;
60
+ export declare function isFileLikeImageSpecifier(specifier: string): boolean;
61
+ export declare function resolveFileLikeImageSpecifierToPath(specifier: string, cwd?: string): string;
62
+ export declare function resolveFileLikeImageSpecifierToFileUrl(specifier: string, cwd?: string): string;
63
+ export declare function resolveImageEntryFileFromStore(specifier: ImageSpecifierParts, storeDir?: string): Promise<string | null>;
64
+ export declare function setActiveImageVersion(imageId: string, version: string, storeDir?: string): Promise<void>;
65
+ export declare function removeImageFromStore(imageId: string, options?: {
66
+ version?: string;
67
+ storeDir?: string;
68
+ }): Promise<void>;
69
+ export {};
70
+ //# sourceMappingURL=image-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-store.d.ts","sourceRoot":"","sources":["../../src/images/image-store.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBhB,CAAC;AAEd,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAMhD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,GAAE,MAAkC,GAAG,MAAM,CAEzF;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,MAAkC,GAAG,MAAM,CAExF;AAED,wBAAgB,yBAAyB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAkC,GAC7C,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAkC,GAAG,iBAAiB,CAgBjG;AAED,wBAAsB,iBAAiB,CACnC,IAAI,EAAE,iBAAiB,EACvB,QAAQ,GAAE,MAAkC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAkC1E;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAQnE;AAED,wBAAgB,mCAAmC,CAC/C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAsB,GAC5B,MAAM,CAcR;AAED,wBAAgB,sCAAsC,CAClD,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAsB,GAC5B,MAAM,CAOR;AAED,wBAAsB,8BAA8B,CAChD,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,GAAE,MAAkC,GAC7C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA8BxB;AAED,wBAAsB,qBAAqB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAkC,GAC7C,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,oBAAoB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACtD,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
@@ -0,0 +1,210 @@
1
+ import path from "path";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { promises as fs } from "fs";
4
+ import { homedir } from "os";
5
+ import { fileURLToPath, pathToFileURL } from "url";
6
+ import { z } from "zod";
7
+ import { getDextoGlobalPath } from "../utils/path.js";
8
+ const ImageRegistryFileSchema = z.object({
9
+ version: z.literal(1),
10
+ images: z.record(
11
+ z.object({
12
+ active: z.string().optional(),
13
+ installed: z.record(
14
+ z.object({
15
+ entryFile: z.string(),
16
+ installedAt: z.string()
17
+ }).strict()
18
+ )
19
+ }).strict()
20
+ )
21
+ }).strict();
22
+ function getDefaultImageStoreDir() {
23
+ const override = process.env.DEXTO_IMAGE_STORE_DIR?.trim();
24
+ if (override) {
25
+ return override;
26
+ }
27
+ return getDextoGlobalPath("images");
28
+ }
29
+ function getImageRegistryPath(storeDir = getDefaultImageStoreDir()) {
30
+ return path.join(storeDir, "registry.json");
31
+ }
32
+ function getImagePackagesDir(storeDir = getDefaultImageStoreDir()) {
33
+ return path.join(storeDir, "packages");
34
+ }
35
+ function getImagePackageInstallDir(imageId, version, storeDir = getDefaultImageStoreDir()) {
36
+ const packagesDir = getImagePackagesDir(storeDir);
37
+ const parts = imageId.startsWith("@") ? imageId.split("/") : [imageId];
38
+ return path.join(packagesDir, ...parts, version);
39
+ }
40
+ function loadImageRegistry(storeDir = getDefaultImageStoreDir()) {
41
+ const registryPath = getImageRegistryPath(storeDir);
42
+ if (!existsSync(registryPath)) {
43
+ return { version: 1, images: {} };
44
+ }
45
+ try {
46
+ const raw = JSON.parse(readFileSync(registryPath, "utf-8"));
47
+ const parsed = ImageRegistryFileSchema.safeParse(raw);
48
+ if (!parsed.success) {
49
+ return { version: 1, images: {} };
50
+ }
51
+ return parsed.data;
52
+ } catch {
53
+ return { version: 1, images: {} };
54
+ }
55
+ }
56
+ async function saveImageRegistry(data, storeDir = getDefaultImageStoreDir()) {
57
+ const registryPath = getImageRegistryPath(storeDir);
58
+ await fs.mkdir(path.dirname(registryPath), { recursive: true });
59
+ const tempPath = `${registryPath}.tmp.${Date.now()}`;
60
+ try {
61
+ await fs.writeFile(tempPath, JSON.stringify(data, null, 2), {
62
+ encoding: "utf-8",
63
+ mode: 384
64
+ });
65
+ await fs.rename(tempPath, registryPath);
66
+ } catch (error) {
67
+ await fs.rm(tempPath, { force: true }).catch(() => {
68
+ });
69
+ throw error;
70
+ }
71
+ }
72
+ function parseImageSpecifier(specifier) {
73
+ const trimmed = specifier.trim();
74
+ if (!trimmed) {
75
+ throw new Error("Image specifier cannot be empty");
76
+ }
77
+ if (trimmed.startsWith("@")) {
78
+ const slashIndex = trimmed.indexOf("/");
79
+ if (slashIndex === -1) {
80
+ return { id: trimmed };
81
+ }
82
+ const versionIndex2 = trimmed.indexOf("@", slashIndex + 1);
83
+ if (versionIndex2 === -1) {
84
+ return { id: trimmed };
85
+ }
86
+ const version = trimmed.slice(versionIndex2 + 1).trim();
87
+ return {
88
+ id: trimmed.slice(0, versionIndex2),
89
+ ...version.length > 0 ? { version } : {}
90
+ };
91
+ }
92
+ const versionIndex = trimmed.lastIndexOf("@");
93
+ if (versionIndex > 0) {
94
+ const version = trimmed.slice(versionIndex + 1).trim();
95
+ return {
96
+ id: trimmed.slice(0, versionIndex),
97
+ ...version.length > 0 ? { version } : {}
98
+ };
99
+ }
100
+ return { id: trimmed };
101
+ }
102
+ function isFileLikeImageSpecifier(specifier) {
103
+ if (specifier === "." || specifier === "..") return true;
104
+ if (specifier.startsWith("file://")) return true;
105
+ if (specifier.startsWith("~/")) return true;
106
+ if (specifier.startsWith("./") || specifier.startsWith("../")) return true;
107
+ if (path.isAbsolute(specifier)) return true;
108
+ if (/^[a-zA-Z]:[\\/]/.test(specifier)) return true;
109
+ return false;
110
+ }
111
+ function resolveFileLikeImageSpecifierToPath(specifier, cwd = process.cwd()) {
112
+ if (specifier.startsWith("file://")) {
113
+ return fileURLToPath(specifier);
114
+ }
115
+ if (specifier.startsWith("~/")) {
116
+ return path.join(homedir(), specifier.slice(2));
117
+ }
118
+ if (path.isAbsolute(specifier)) {
119
+ return specifier;
120
+ }
121
+ return path.resolve(cwd, specifier);
122
+ }
123
+ function resolveFileLikeImageSpecifierToFileUrl(specifier, cwd = process.cwd()) {
124
+ if (specifier.startsWith("file://")) {
125
+ return specifier;
126
+ }
127
+ const filePath = resolveFileLikeImageSpecifierToPath(specifier, cwd);
128
+ return pathToFileURL(filePath).href;
129
+ }
130
+ async function resolveImageEntryFileFromStore(specifier, storeDir = getDefaultImageStoreDir()) {
131
+ const registry = loadImageRegistry(storeDir);
132
+ const entry = registry.images[specifier.id];
133
+ if (!entry) {
134
+ return null;
135
+ }
136
+ const installedVersions = Object.keys(entry.installed);
137
+ if (installedVersions.length === 0) {
138
+ return null;
139
+ }
140
+ const resolvedVersion = specifier.version ?? entry.active;
141
+ if (!resolvedVersion) {
142
+ if (installedVersions.length === 1) {
143
+ return entry.installed[installedVersions[0] ?? ""]?.entryFile ?? null;
144
+ }
145
+ throw new Error(
146
+ `Image '${specifier.id}' has multiple installed versions but no active version set. Run: dexto image use ${specifier.id}@<version>`
147
+ );
148
+ }
149
+ const resolved = entry.installed[resolvedVersion];
150
+ if (!resolved) {
151
+ throw new Error(
152
+ `Image '${specifier.id}@${resolvedVersion}' is not installed. Run: dexto image install ${specifier.id}@${resolvedVersion}`
153
+ );
154
+ }
155
+ return resolved.entryFile;
156
+ }
157
+ async function setActiveImageVersion(imageId, version, storeDir = getDefaultImageStoreDir()) {
158
+ const registry = loadImageRegistry(storeDir);
159
+ const entry = registry.images[imageId];
160
+ if (!entry || !entry.installed[version]) {
161
+ throw new Error(`Image '${imageId}@${version}' is not installed`);
162
+ }
163
+ entry.active = version;
164
+ await saveImageRegistry(registry, storeDir);
165
+ }
166
+ async function removeImageFromStore(imageId, options = {}) {
167
+ const storeDir = options.storeDir ?? getDefaultImageStoreDir();
168
+ const version = options.version;
169
+ const registry = loadImageRegistry(storeDir);
170
+ const entry = registry.images[imageId];
171
+ if (!entry) {
172
+ return;
173
+ }
174
+ if (version) {
175
+ delete entry.installed[version];
176
+ if (entry.active === version) {
177
+ delete entry.active;
178
+ }
179
+ const installDir = getImagePackageInstallDir(imageId, version, storeDir);
180
+ await fs.rm(installDir, { recursive: true, force: true }).catch(() => {
181
+ });
182
+ if (Object.keys(entry.installed).length === 0) {
183
+ delete registry.images[imageId];
184
+ }
185
+ } else {
186
+ const versions = Object.keys(entry.installed);
187
+ for (const v of versions) {
188
+ const installDir = getImagePackageInstallDir(imageId, v, storeDir);
189
+ await fs.rm(installDir, { recursive: true, force: true }).catch(() => {
190
+ });
191
+ }
192
+ delete registry.images[imageId];
193
+ }
194
+ await saveImageRegistry(registry, storeDir);
195
+ }
196
+ export {
197
+ getDefaultImageStoreDir,
198
+ getImagePackageInstallDir,
199
+ getImagePackagesDir,
200
+ getImageRegistryPath,
201
+ isFileLikeImageSpecifier,
202
+ loadImageRegistry,
203
+ parseImageSpecifier,
204
+ removeImageFromStore,
205
+ resolveFileLikeImageSpecifierToFileUrl,
206
+ resolveFileLikeImageSpecifierToPath,
207
+ resolveImageEntryFileFromStore,
208
+ saveImageRegistry,
209
+ setActiveImageVersion
210
+ };