openpets 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/api.json +6746 -4404
- package/dist/src/core/cli.js +1160 -36
- package/dist/src/core/cli.js.map +1 -1
- package/dist/src/core/discovery.d.ts +130 -0
- package/dist/src/core/discovery.d.ts.map +1 -0
- package/dist/src/core/discovery.js +327 -0
- package/dist/src/core/discovery.js.map +1 -0
- package/dist/src/core/index.d.ts +5 -5
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +7 -5
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/core/mautrix-bridge.d.ts +17 -0
- package/dist/src/core/mautrix-bridge.d.ts.map +1 -1
- package/dist/src/core/mautrix-bridge.js +257 -0
- package/dist/src/core/mautrix-bridge.js.map +1 -1
- package/dist/src/core/pet-config.d.ts +611 -0
- package/dist/src/core/pet-config.d.ts.map +1 -0
- package/dist/src/core/pet-config.js +281 -0
- package/dist/src/core/pet-config.js.map +1 -0
- package/dist/src/core/pet-downloader.d.ts +50 -0
- package/dist/src/core/pet-downloader.d.ts.map +1 -0
- package/dist/src/core/pet-downloader.js +298 -0
- package/dist/src/core/pet-downloader.js.map +1 -0
- package/dist/src/core/pet-scanner.d.ts +14 -0
- package/dist/src/core/pet-scanner.d.ts.map +1 -0
- package/dist/src/core/pet-scanner.js +87 -0
- package/dist/src/core/pet-scanner.js.map +1 -0
- package/dist/src/core/registry-client.d.ts +97 -0
- package/dist/src/core/registry-client.d.ts.map +1 -0
- package/dist/src/core/registry-client.js +283 -0
- package/dist/src/core/registry-client.js.map +1 -0
- package/dist/src/core/search-pets.d.ts.map +1 -1
- package/dist/src/core/search-pets.js +31 -1
- package/dist/src/core/search-pets.js.map +1 -1
- package/dist/src/core/validate-pet.d.ts.map +1 -1
- package/dist/src/core/validate-pet.js +17 -19
- package/dist/src/core/validate-pet.js.map +1 -1
- package/dist/src/sdk/logger.d.ts +32 -0
- package/dist/src/sdk/logger.d.ts.map +1 -0
- package/dist/src/sdk/logger.js +119 -0
- package/dist/src/sdk/logger.js.map +1 -0
- package/dist/src/sdk/plugin-factory.d.ts +104 -0
- package/dist/src/sdk/plugin-factory.d.ts.map +1 -0
- package/dist/src/sdk/plugin-factory.js +540 -0
- package/dist/src/sdk/plugin-factory.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
import { readFileSync, existsSync, writeFileSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { createLogger } from "./logger";
|
|
5
|
+
const logger = createLogger("pet-config");
|
|
6
|
+
const EnvVariableSchema = z.object({
|
|
7
|
+
name: z.string(),
|
|
8
|
+
description: z.string(),
|
|
9
|
+
required: z.boolean().optional().default(false),
|
|
10
|
+
default: z.string().optional(),
|
|
11
|
+
secret: z.boolean().optional().default(false)
|
|
12
|
+
});
|
|
13
|
+
const ProviderSchema = z.object({
|
|
14
|
+
id: z.string().optional(),
|
|
15
|
+
name: z.string(),
|
|
16
|
+
description: z.string().optional(),
|
|
17
|
+
homepage: z.string().url().optional(),
|
|
18
|
+
credentialsUrl: z.string().url().optional(),
|
|
19
|
+
envVariables: z.array(EnvVariableSchema).optional()
|
|
20
|
+
});
|
|
21
|
+
const ToolSchema = z.object({
|
|
22
|
+
name: z.string(),
|
|
23
|
+
description: z.string(),
|
|
24
|
+
inputSchema: z.record(z.unknown()).optional()
|
|
25
|
+
});
|
|
26
|
+
const BuildConfigSchema = z.object({
|
|
27
|
+
entrypoint: z.string().optional().default("index.ts"),
|
|
28
|
+
outDir: z.string().optional().default("dist"),
|
|
29
|
+
target: z.enum(["node", "bun", "browser"]).optional().default("node"),
|
|
30
|
+
format: z.enum(["esm", "cjs"]).optional().default("esm"),
|
|
31
|
+
minify: z.boolean().optional().default(false),
|
|
32
|
+
sourcemap: z.boolean().optional().default(true)
|
|
33
|
+
});
|
|
34
|
+
const RuntimeConfigSchema = z.object({
|
|
35
|
+
runtime: z.enum(["typescript", "bun", "node", "container"]).optional().default("typescript"),
|
|
36
|
+
transport: z.enum(["stdio", "http"]).optional().default("stdio"),
|
|
37
|
+
port: z.number().optional(),
|
|
38
|
+
healthCheck: z.string().optional()
|
|
39
|
+
});
|
|
40
|
+
const ContainerConfigSchema = z.object({
|
|
41
|
+
dockerfile: z.string().optional().default("Dockerfile"),
|
|
42
|
+
dockerBuildPath: z.string().optional().default("."),
|
|
43
|
+
image: z.string().optional(),
|
|
44
|
+
registry: z.string().optional()
|
|
45
|
+
});
|
|
46
|
+
const SessionConfigSchema = z.object({
|
|
47
|
+
configSchema: z.record(z.unknown()).optional(),
|
|
48
|
+
exampleConfig: z.record(z.unknown()).optional()
|
|
49
|
+
});
|
|
50
|
+
export const OpenPetsConfigSchema = z.object({
|
|
51
|
+
$schema: z.string().optional(),
|
|
52
|
+
name: z.string(),
|
|
53
|
+
version: z.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?$/),
|
|
54
|
+
title: z.string().optional(),
|
|
55
|
+
subtitle: z.string().optional(),
|
|
56
|
+
description: z.string(),
|
|
57
|
+
homepage: z.string().url().optional(),
|
|
58
|
+
repository: z.string().url().optional(),
|
|
59
|
+
license: z.string().optional().default("MIT"),
|
|
60
|
+
author: z.union([
|
|
61
|
+
z.string(),
|
|
62
|
+
z.object({ name: z.string(), email: z.string().email().optional() })
|
|
63
|
+
]).optional(),
|
|
64
|
+
categories: z.array(z.string()).optional().default([]),
|
|
65
|
+
keywords: z.array(z.string()).optional().default([]),
|
|
66
|
+
icon: z.string().optional(),
|
|
67
|
+
runtime: RuntimeConfigSchema.optional(),
|
|
68
|
+
build: BuildConfigSchema.optional(),
|
|
69
|
+
container: ContainerConfigSchema.optional(),
|
|
70
|
+
session: SessionConfigSchema.optional(),
|
|
71
|
+
env: z.record(z.string()).optional(),
|
|
72
|
+
envVariables: z.object({
|
|
73
|
+
required: z.array(EnvVariableSchema).optional(),
|
|
74
|
+
optional: z.array(EnvVariableSchema).optional()
|
|
75
|
+
}).optional(),
|
|
76
|
+
providers: z.array(ProviderSchema).optional(),
|
|
77
|
+
tools: z.array(ToolSchema).optional(),
|
|
78
|
+
queries: z.array(z.string()).optional(),
|
|
79
|
+
scenarios: z.record(z.array(z.string())).optional(),
|
|
80
|
+
faq: z.array(z.object({
|
|
81
|
+
question: z.string(),
|
|
82
|
+
answer: z.string()
|
|
83
|
+
})).optional(),
|
|
84
|
+
scripts: z.record(z.string()).optional(),
|
|
85
|
+
dependencies: z.record(z.string()).optional(),
|
|
86
|
+
peerDependencies: z.record(z.string()).optional(),
|
|
87
|
+
devDependencies: z.record(z.string()).optional(),
|
|
88
|
+
publishConfig: z.object({
|
|
89
|
+
access: z.enum(["public", "restricted"]).optional().default("public"),
|
|
90
|
+
registry: z.string().url().optional(),
|
|
91
|
+
tag: z.string().optional().default("latest")
|
|
92
|
+
}).optional(),
|
|
93
|
+
files: z.array(z.string()).optional()
|
|
94
|
+
});
|
|
95
|
+
export function loadPetConfig(petDir) {
|
|
96
|
+
const packageJsonPath = join(petDir, "package.json");
|
|
97
|
+
const openpetsYamlPath = join(petDir, "openpets.yaml");
|
|
98
|
+
const openpetsJsonPath = join(petDir, "openpets.json");
|
|
99
|
+
let config = {};
|
|
100
|
+
if (existsSync(openpetsYamlPath)) {
|
|
101
|
+
try {
|
|
102
|
+
const yaml = require("yaml");
|
|
103
|
+
config = yaml.parse(readFileSync(openpetsYamlPath, "utf-8"));
|
|
104
|
+
logger.debug(`Loaded openpets.yaml from ${petDir}`);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
logger.error(`Failed to parse openpets.yaml: ${error.message}`);
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else if (existsSync(openpetsJsonPath)) {
|
|
112
|
+
try {
|
|
113
|
+
config = JSON.parse(readFileSync(openpetsJsonPath, "utf-8"));
|
|
114
|
+
logger.debug(`Loaded openpets.json from ${petDir}`);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
logger.error(`Failed to parse openpets.json: ${error.message}`);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else if (existsSync(packageJsonPath)) {
|
|
122
|
+
try {
|
|
123
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
124
|
+
config = convertPackageJsonToConfig(packageJson);
|
|
125
|
+
logger.debug(`Loaded config from package.json in ${petDir}`);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
logger.error(`Failed to parse package.json: ${error.message}`);
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
logger.warn(`No configuration file found in ${petDir}`);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
return OpenPetsConfigSchema.parse(config);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
if (error instanceof z.ZodError) {
|
|
141
|
+
logger.error(`Configuration validation failed:`);
|
|
142
|
+
error.errors.forEach(err => {
|
|
143
|
+
logger.error(` - ${err.path.join(".")}: ${err.message}`);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export function savePetConfig(petDir, config, format = "json") {
|
|
150
|
+
try {
|
|
151
|
+
const validated = OpenPetsConfigSchema.parse(config);
|
|
152
|
+
if (format === "yaml") {
|
|
153
|
+
const yaml = require("yaml");
|
|
154
|
+
const yamlPath = join(petDir, "openpets.yaml");
|
|
155
|
+
writeFileSync(yamlPath, yaml.stringify(validated));
|
|
156
|
+
logger.info(`Saved configuration to ${yamlPath}`);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
const jsonPath = join(petDir, "openpets.json");
|
|
160
|
+
writeFileSync(jsonPath, JSON.stringify(validated, null, 2));
|
|
161
|
+
logger.info(`Saved configuration to ${jsonPath}`);
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
logger.error(`Failed to save configuration: ${error.message}`);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function convertPackageJsonToConfig(packageJson) {
|
|
171
|
+
return {
|
|
172
|
+
name: packageJson.name,
|
|
173
|
+
version: packageJson.version || "1.0.0",
|
|
174
|
+
title: packageJson.title,
|
|
175
|
+
subtitle: packageJson.subtitle,
|
|
176
|
+
description: packageJson.description || "",
|
|
177
|
+
homepage: packageJson.homepage,
|
|
178
|
+
repository: typeof packageJson.repository === "string"
|
|
179
|
+
? packageJson.repository
|
|
180
|
+
: packageJson.repository?.url,
|
|
181
|
+
license: packageJson.license,
|
|
182
|
+
author: packageJson.author,
|
|
183
|
+
categories: packageJson.categories,
|
|
184
|
+
keywords: packageJson.keywords,
|
|
185
|
+
icon: packageJson.icon,
|
|
186
|
+
envVariables: packageJson.envVariables,
|
|
187
|
+
providers: packageJson.providers,
|
|
188
|
+
tools: packageJson.tools,
|
|
189
|
+
queries: packageJson.queries,
|
|
190
|
+
scenarios: packageJson.scenarios,
|
|
191
|
+
faq: packageJson.faq,
|
|
192
|
+
scripts: packageJson.scripts,
|
|
193
|
+
dependencies: packageJson.dependencies,
|
|
194
|
+
peerDependencies: packageJson.peerDependencies,
|
|
195
|
+
devDependencies: packageJson.devDependencies,
|
|
196
|
+
publishConfig: packageJson.publishConfig,
|
|
197
|
+
files: packageJson.files
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
export function generateOpenpetsYamlTemplate(options) {
|
|
201
|
+
const yaml = require("yaml");
|
|
202
|
+
const template = {
|
|
203
|
+
$schema: "https://pets.studio/config.yaml.json",
|
|
204
|
+
name: options.name,
|
|
205
|
+
version: "1.0.0",
|
|
206
|
+
description: options.description || `${options.name} plugin for OpenPets`,
|
|
207
|
+
categories: ["general"],
|
|
208
|
+
keywords: ["openpets", "plugin"],
|
|
209
|
+
runtime: {
|
|
210
|
+
runtime: options.runtime || "typescript",
|
|
211
|
+
transport: "stdio"
|
|
212
|
+
},
|
|
213
|
+
build: {
|
|
214
|
+
entrypoint: "index.ts",
|
|
215
|
+
outDir: "dist",
|
|
216
|
+
target: "node",
|
|
217
|
+
format: "esm"
|
|
218
|
+
},
|
|
219
|
+
envVariables: {
|
|
220
|
+
optional: [
|
|
221
|
+
{
|
|
222
|
+
name: "EXAMPLE_API_KEY",
|
|
223
|
+
description: "API key for your service",
|
|
224
|
+
secret: true
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
queries: [
|
|
229
|
+
"example query",
|
|
230
|
+
"another example query"
|
|
231
|
+
],
|
|
232
|
+
scenarios: {
|
|
233
|
+
"basic-test": [
|
|
234
|
+
"example query",
|
|
235
|
+
"another example query"
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
return yaml.stringify(template);
|
|
240
|
+
}
|
|
241
|
+
export function validatePetConfig(config) {
|
|
242
|
+
const errors = [];
|
|
243
|
+
const warnings = [];
|
|
244
|
+
try {
|
|
245
|
+
OpenPetsConfigSchema.parse(config);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
if (error instanceof z.ZodError) {
|
|
249
|
+
error.errors.forEach(err => {
|
|
250
|
+
errors.push(`${err.path.join(".")}: ${err.message}`);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
errors.push(`Unknown validation error: ${error}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (typeof config === "object" && config !== null) {
|
|
258
|
+
const c = config;
|
|
259
|
+
if (!c.description || c.description.length < 10) {
|
|
260
|
+
warnings.push("Description should be at least 10 characters");
|
|
261
|
+
}
|
|
262
|
+
if (!c.categories || c.categories.length === 0) {
|
|
263
|
+
warnings.push("Consider adding categories for better discoverability");
|
|
264
|
+
}
|
|
265
|
+
if (!c.keywords || c.keywords.length === 0) {
|
|
266
|
+
warnings.push("Consider adding keywords for better searchability");
|
|
267
|
+
}
|
|
268
|
+
if (!c.queries || c.queries.length === 0) {
|
|
269
|
+
warnings.push("Consider adding example queries for documentation");
|
|
270
|
+
}
|
|
271
|
+
if (!c.homepage) {
|
|
272
|
+
warnings.push("Consider adding a homepage URL");
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
valid: errors.length === 0,
|
|
277
|
+
errors,
|
|
278
|
+
warnings
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=pet-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-config.js","sourceRoot":"","sources":["../../../pet-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type OpenPetsConfig } from "./pet-config";
|
|
2
|
+
export interface DownloadResult {
|
|
3
|
+
success: boolean;
|
|
4
|
+
message: string;
|
|
5
|
+
packagePath?: string;
|
|
6
|
+
config?: OpenPetsConfig;
|
|
7
|
+
envVariables?: EnvVariableInfo[];
|
|
8
|
+
}
|
|
9
|
+
export interface EnvVariableInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
required: boolean;
|
|
13
|
+
secret: boolean;
|
|
14
|
+
provider?: string;
|
|
15
|
+
currentValue?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AddOptions {
|
|
18
|
+
targetDir?: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
skipConfig?: boolean;
|
|
21
|
+
envValues?: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
export interface OpencodeConfig {
|
|
24
|
+
$schema?: string;
|
|
25
|
+
plugin?: string[];
|
|
26
|
+
env?: Record<string, string>;
|
|
27
|
+
}
|
|
28
|
+
export declare class PetDownloader {
|
|
29
|
+
private cacheDir;
|
|
30
|
+
private petsDir;
|
|
31
|
+
constructor(baseDir?: string);
|
|
32
|
+
private ensureDirs;
|
|
33
|
+
add(packageName: string, options?: AddOptions): Promise<DownloadResult>;
|
|
34
|
+
private downloadPackage;
|
|
35
|
+
private fetchFullPackageInfo;
|
|
36
|
+
private downloadTarball;
|
|
37
|
+
private extractTarball;
|
|
38
|
+
private extractEnvVariables;
|
|
39
|
+
updateOpencodeConfig(targetDir: string, shortName: string, packagePath: string, envValues?: Record<string, string>): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Update .pets/config.json with pet-specific environment variables
|
|
42
|
+
*/
|
|
43
|
+
private updatePetsConfig;
|
|
44
|
+
private getRelativePath;
|
|
45
|
+
getInstalledPetPath(shortName: string): string | null;
|
|
46
|
+
listInstalledPets(): string[];
|
|
47
|
+
removePet(shortName: string): boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare function getPetDownloader(): PetDownloader;
|
|
50
|
+
//# sourceMappingURL=pet-downloader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-downloader.d.ts","sourceRoot":"","sources":["../../../pet-downloader.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAOjE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,OAAO,CAAQ;gBAEX,OAAO,CAAC,EAAE,MAAM;IAO5B,OAAO,CAAC,UAAU;IASZ,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,cAAc,CAAC;YAuCnE,eAAe;YA0Cf,oBAAoB;YAcpB,eAAe;YAUf,cAAc;IAkB5B,OAAO,CAAC,mBAAmB;IAkDrB,oBAAoB,CACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAmChB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoExB,OAAO,CAAC,eAAe;IAmBvB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKrD,iBAAiB,IAAI,MAAM,EAAE;IAS7B,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAOtC;AAID,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, rmSync } from "fs";
|
|
2
|
+
import { join, resolve } from "path";
|
|
3
|
+
import { createGunzip } from "zlib";
|
|
4
|
+
import { extract } from "tar";
|
|
5
|
+
import { createLogger } from "./logger";
|
|
6
|
+
import { getRegistryClient } from "./registry-client";
|
|
7
|
+
import { loadPetConfig } from "./pet-config";
|
|
8
|
+
const logger = createLogger("pet-downloader");
|
|
9
|
+
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
10
|
+
const OPENPETS_SCOPE = "@openpets";
|
|
11
|
+
export class PetDownloader {
|
|
12
|
+
cacheDir;
|
|
13
|
+
petsDir;
|
|
14
|
+
constructor(baseDir) {
|
|
15
|
+
const home = process.env.HOME || process.env.USERPROFILE || "~";
|
|
16
|
+
this.cacheDir = baseDir || join(home, ".openpets", "cache");
|
|
17
|
+
this.petsDir = join(home, ".cache", "opencode", "node_modules", "@openpets");
|
|
18
|
+
this.ensureDirs();
|
|
19
|
+
}
|
|
20
|
+
ensureDirs() {
|
|
21
|
+
if (!existsSync(this.cacheDir)) {
|
|
22
|
+
mkdirSync(this.cacheDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
if (!existsSync(this.petsDir)) {
|
|
25
|
+
mkdirSync(this.petsDir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async add(packageName, options = {}) {
|
|
29
|
+
const { targetDir = process.cwd(), version, skipConfig = false, envValues } = options;
|
|
30
|
+
const fullName = packageName.startsWith(OPENPETS_SCOPE)
|
|
31
|
+
? packageName
|
|
32
|
+
: packageName.startsWith("@")
|
|
33
|
+
? packageName
|
|
34
|
+
: `${OPENPETS_SCOPE}/${packageName}`;
|
|
35
|
+
const shortName = fullName.replace(`${OPENPETS_SCOPE}/`, "").replace("@", "").replace("/", "-");
|
|
36
|
+
logger.info(`Adding pet: ${fullName}`);
|
|
37
|
+
const registryClient = getRegistryClient();
|
|
38
|
+
const pkgInfo = await registryClient.fetchPackageInfo(packageName, version);
|
|
39
|
+
if (!pkgInfo) {
|
|
40
|
+
return { success: false, message: `Package not found: ${fullName}` };
|
|
41
|
+
}
|
|
42
|
+
const downloadResult = await this.downloadPackage(pkgInfo, shortName);
|
|
43
|
+
if (!downloadResult.success) {
|
|
44
|
+
return downloadResult;
|
|
45
|
+
}
|
|
46
|
+
const petConfig = loadPetConfig(downloadResult.packagePath);
|
|
47
|
+
const envVariables = this.extractEnvVariables(petConfig, pkgInfo);
|
|
48
|
+
await this.updateOpencodeConfig(targetDir, shortName, downloadResult.packagePath, envValues);
|
|
49
|
+
return {
|
|
50
|
+
success: true,
|
|
51
|
+
message: `Successfully added ${fullName}@${pkgInfo.version}`,
|
|
52
|
+
packagePath: downloadResult.packagePath,
|
|
53
|
+
config: petConfig || undefined,
|
|
54
|
+
envVariables
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async downloadPackage(pkgInfo, shortName) {
|
|
58
|
+
if (!pkgInfo.dist?.tarball) {
|
|
59
|
+
const fullPkgInfo = await this.fetchFullPackageInfo(pkgInfo.name);
|
|
60
|
+
if (!fullPkgInfo?.dist?.tarball) {
|
|
61
|
+
return { success: false, message: `No tarball URL found for ${pkgInfo.name}` };
|
|
62
|
+
}
|
|
63
|
+
pkgInfo = fullPkgInfo;
|
|
64
|
+
}
|
|
65
|
+
const tarballUrl = pkgInfo.dist.tarball;
|
|
66
|
+
const tarballPath = join(this.cacheDir, `${shortName}-${pkgInfo.version}.tgz`);
|
|
67
|
+
const extractPath = join(this.petsDir, shortName);
|
|
68
|
+
try {
|
|
69
|
+
if (existsSync(extractPath)) {
|
|
70
|
+
const existingPkgPath = join(extractPath, "package.json");
|
|
71
|
+
if (existsSync(existingPkgPath)) {
|
|
72
|
+
const existingPkg = JSON.parse(readFileSync(existingPkgPath, "utf-8"));
|
|
73
|
+
if (existingPkg.version === pkgInfo.version) {
|
|
74
|
+
logger.info(`Package ${pkgInfo.name}@${pkgInfo.version} already exists`);
|
|
75
|
+
return { success: true, message: "Already installed", packagePath: extractPath };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
rmSync(extractPath, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
logger.info(`Downloading ${tarballUrl}`);
|
|
81
|
+
await this.downloadTarball(tarballUrl, tarballPath);
|
|
82
|
+
logger.info(`Extracting to ${extractPath}`);
|
|
83
|
+
mkdirSync(extractPath, { recursive: true });
|
|
84
|
+
await this.extractTarball(tarballPath, extractPath);
|
|
85
|
+
rmSync(tarballPath, { force: true });
|
|
86
|
+
return { success: true, message: "Downloaded successfully", packagePath: extractPath };
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
logger.error(`Download failed: ${error.message}`);
|
|
90
|
+
return { success: false, message: `Download failed: ${error.message}` };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async fetchFullPackageInfo(packageName) {
|
|
94
|
+
const fullName = packageName.startsWith(OPENPETS_SCOPE)
|
|
95
|
+
? packageName
|
|
96
|
+
: `${OPENPETS_SCOPE}/${packageName}`;
|
|
97
|
+
try {
|
|
98
|
+
const response = await fetch(`${NPM_REGISTRY}/${fullName}/latest`);
|
|
99
|
+
if (!response.ok)
|
|
100
|
+
return null;
|
|
101
|
+
return await response.json();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async downloadTarball(url, destPath) {
|
|
108
|
+
const response = await fetch(url);
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
throw new Error(`Failed to download: ${response.statusText}`);
|
|
111
|
+
}
|
|
112
|
+
const buffer = await response.arrayBuffer();
|
|
113
|
+
writeFileSync(destPath, Buffer.from(buffer));
|
|
114
|
+
}
|
|
115
|
+
async extractTarball(tarPath, destPath) {
|
|
116
|
+
return new Promise((resolve, reject) => {
|
|
117
|
+
const extractStream = extract({
|
|
118
|
+
cwd: destPath,
|
|
119
|
+
strip: 1
|
|
120
|
+
});
|
|
121
|
+
const gunzip = createGunzip();
|
|
122
|
+
const fileStream = require("fs").createReadStream(tarPath);
|
|
123
|
+
fileStream
|
|
124
|
+
.pipe(gunzip)
|
|
125
|
+
.pipe(extractStream)
|
|
126
|
+
.on("finish", resolve)
|
|
127
|
+
.on("error", reject);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
extractEnvVariables(config, pkgInfo) {
|
|
131
|
+
const variables = [];
|
|
132
|
+
if (config?.envVariables) {
|
|
133
|
+
const required = config.envVariables.required || [];
|
|
134
|
+
const optional = config.envVariables.optional || [];
|
|
135
|
+
for (const v of required) {
|
|
136
|
+
variables.push({
|
|
137
|
+
name: v.name,
|
|
138
|
+
description: v.description,
|
|
139
|
+
required: true,
|
|
140
|
+
secret: v.secret || false,
|
|
141
|
+
currentValue: process.env[v.name]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
for (const v of optional) {
|
|
145
|
+
variables.push({
|
|
146
|
+
name: v.name,
|
|
147
|
+
description: v.description,
|
|
148
|
+
required: false,
|
|
149
|
+
secret: v.secret || false,
|
|
150
|
+
currentValue: process.env[v.name]
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (config?.providers) {
|
|
155
|
+
for (const provider of config.providers) {
|
|
156
|
+
if (provider.envVariables) {
|
|
157
|
+
for (const v of provider.envVariables) {
|
|
158
|
+
if (!variables.find(existing => existing.name === v.name)) {
|
|
159
|
+
variables.push({
|
|
160
|
+
name: v.name,
|
|
161
|
+
description: v.description,
|
|
162
|
+
required: v.required || false,
|
|
163
|
+
secret: v.secret || false,
|
|
164
|
+
provider: provider.name,
|
|
165
|
+
currentValue: process.env[v.name]
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return variables;
|
|
173
|
+
}
|
|
174
|
+
async updateOpencodeConfig(targetDir, shortName, packagePath, envValues) {
|
|
175
|
+
const opencodeJsonPath = join(targetDir, "opencode.json");
|
|
176
|
+
let config = {
|
|
177
|
+
$schema: "https://opencode.ai/config.json",
|
|
178
|
+
plugin: []
|
|
179
|
+
};
|
|
180
|
+
if (existsSync(opencodeJsonPath)) {
|
|
181
|
+
try {
|
|
182
|
+
config = JSON.parse(readFileSync(opencodeJsonPath, "utf-8"));
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
logger.warn("Could not parse existing opencode.json, creating new one");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!config.plugin) {
|
|
189
|
+
config.plugin = [];
|
|
190
|
+
}
|
|
191
|
+
const pluginEntry = `@openpets/${shortName}`;
|
|
192
|
+
if (!config.plugin.includes(pluginEntry)) {
|
|
193
|
+
config.plugin.push(pluginEntry);
|
|
194
|
+
}
|
|
195
|
+
// Write plugin list to opencode.json (without env vars)
|
|
196
|
+
writeFileSync(opencodeJsonPath, JSON.stringify(config, null, 2));
|
|
197
|
+
logger.info(`Updated opencode.json with plugin: ${pluginEntry}`);
|
|
198
|
+
// Write env values to .pets/config.json (proper location for pet-specific config)
|
|
199
|
+
if (envValues && Object.keys(envValues).length > 0) {
|
|
200
|
+
this.updatePetsConfig(targetDir, shortName, envValues);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Update .pets/config.json with pet-specific environment variables
|
|
205
|
+
*/
|
|
206
|
+
updatePetsConfig(targetDir, petId, envValues) {
|
|
207
|
+
const petsConfigDir = join(targetDir, ".pets");
|
|
208
|
+
const petsConfigPath = join(petsConfigDir, "config.json");
|
|
209
|
+
// Ensure .pets directory exists
|
|
210
|
+
if (!existsSync(petsConfigDir)) {
|
|
211
|
+
mkdirSync(petsConfigDir, { recursive: true });
|
|
212
|
+
logger.debug(`Created .pets directory at ${petsConfigDir}`);
|
|
213
|
+
}
|
|
214
|
+
let petsConfig = {
|
|
215
|
+
enabled: [],
|
|
216
|
+
disabled: [],
|
|
217
|
+
envConfig: {},
|
|
218
|
+
};
|
|
219
|
+
if (existsSync(petsConfigPath)) {
|
|
220
|
+
try {
|
|
221
|
+
const existing = JSON.parse(readFileSync(petsConfigPath, "utf-8"));
|
|
222
|
+
petsConfig = {
|
|
223
|
+
enabled: existing.enabled || [],
|
|
224
|
+
disabled: existing.disabled || [],
|
|
225
|
+
envConfig: existing.envConfig || {},
|
|
226
|
+
...existing
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
logger.warn("Could not parse existing .pets/config.json, creating new structure");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Ensure envConfig structure exists
|
|
234
|
+
if (!petsConfig.envConfig) {
|
|
235
|
+
petsConfig.envConfig = {};
|
|
236
|
+
}
|
|
237
|
+
// Create or update pet-specific env config
|
|
238
|
+
if (!petsConfig.envConfig[petId]) {
|
|
239
|
+
petsConfig.envConfig[petId] = {};
|
|
240
|
+
}
|
|
241
|
+
// Set the environment variables
|
|
242
|
+
for (const [key, value] of Object.entries(envValues)) {
|
|
243
|
+
if (value && value.trim()) {
|
|
244
|
+
petsConfig.envConfig[petId][key] = value.trim();
|
|
245
|
+
logger.debug(`Set ${key} for pet ${petId}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Update timestamp
|
|
249
|
+
petsConfig.last_updated = new Date().toISOString();
|
|
250
|
+
// Write config
|
|
251
|
+
writeFileSync(petsConfigPath, JSON.stringify(petsConfig, null, 2));
|
|
252
|
+
logger.info(`Saved environment variables for ${petId} to .pets/config.json`);
|
|
253
|
+
}
|
|
254
|
+
getRelativePath(from, to) {
|
|
255
|
+
const fromParts = resolve(from).split("/");
|
|
256
|
+
const toParts = resolve(to).split("/");
|
|
257
|
+
let commonLength = 0;
|
|
258
|
+
for (let i = 0; i < Math.min(fromParts.length, toParts.length); i++) {
|
|
259
|
+
if (fromParts[i] === toParts[i]) {
|
|
260
|
+
commonLength++;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const upCount = fromParts.length - commonLength;
|
|
267
|
+
const relativeParts = [...Array(upCount).fill(".."), ...toParts.slice(commonLength)];
|
|
268
|
+
return relativeParts.join("/");
|
|
269
|
+
}
|
|
270
|
+
getInstalledPetPath(shortName) {
|
|
271
|
+
const petPath = join(this.petsDir, shortName);
|
|
272
|
+
return existsSync(petPath) ? petPath : null;
|
|
273
|
+
}
|
|
274
|
+
listInstalledPets() {
|
|
275
|
+
if (!existsSync(this.petsDir))
|
|
276
|
+
return [];
|
|
277
|
+
const { readdirSync } = require("fs");
|
|
278
|
+
return readdirSync(this.petsDir).filter((name) => {
|
|
279
|
+
const pkgPath = join(this.petsDir, name, "package.json");
|
|
280
|
+
return existsSync(pkgPath);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
removePet(shortName) {
|
|
284
|
+
const petPath = join(this.petsDir, shortName);
|
|
285
|
+
if (!existsSync(petPath))
|
|
286
|
+
return false;
|
|
287
|
+
rmSync(petPath, { recursive: true, force: true });
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
let defaultDownloader = null;
|
|
292
|
+
export function getPetDownloader() {
|
|
293
|
+
if (!defaultDownloader) {
|
|
294
|
+
defaultDownloader = new PetDownloader();
|
|
295
|
+
}
|
|
296
|
+
return defaultDownloader;
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=pet-downloader.js.map
|