openpets 1.0.5 → 1.0.6

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 (96) hide show
  1. package/dist/data/api.json +3172 -0
  2. package/dist/src/core/ai-client-base/index.d.ts +47 -0
  3. package/dist/src/core/ai-client-base/index.d.ts.map +1 -0
  4. package/dist/src/core/ai-client-base/index.js +168 -0
  5. package/dist/src/core/ai-client-base/index.js.map +1 -0
  6. package/dist/src/core/browser.d.ts +10 -0
  7. package/dist/src/core/browser.d.ts.map +1 -0
  8. package/{browser.ts → dist/src/core/browser.js} +4 -4
  9. package/dist/src/core/browser.js.map +1 -0
  10. package/dist/src/core/build-pet.d.ts +2 -0
  11. package/dist/src/core/build-pet.d.ts.map +1 -0
  12. package/dist/src/core/build-pet.js +364 -0
  13. package/dist/src/core/build-pet.js.map +1 -0
  14. package/dist/src/core/cli.d.ts +3 -0
  15. package/dist/src/core/cli.d.ts.map +1 -0
  16. package/dist/src/core/cli.js +244 -0
  17. package/dist/src/core/cli.js.map +1 -0
  18. package/dist/src/core/config-manager.d.ts +13 -0
  19. package/dist/src/core/config-manager.d.ts.map +1 -0
  20. package/dist/src/core/config-manager.js +59 -0
  21. package/dist/src/core/config-manager.js.map +1 -0
  22. package/dist/src/core/deploy-pet.d.ts +2 -0
  23. package/dist/src/core/deploy-pet.d.ts.map +1 -0
  24. package/dist/src/core/deploy-pet.js +66 -0
  25. package/dist/src/core/deploy-pet.js.map +1 -0
  26. package/dist/src/core/index.d.ts +11 -0
  27. package/dist/src/core/index.d.ts.map +1 -0
  28. package/dist/src/core/index.js +11 -0
  29. package/dist/src/core/index.js.map +1 -0
  30. package/dist/src/core/local-cache.d.ts +69 -0
  31. package/dist/src/core/local-cache.d.ts.map +1 -0
  32. package/dist/src/core/local-cache.js +212 -0
  33. package/dist/src/core/local-cache.js.map +1 -0
  34. package/dist/src/core/logger.d.ts.map +1 -0
  35. package/{logger.js → dist/src/core/logger.js} +8 -9
  36. package/dist/src/core/logger.js.map +1 -0
  37. package/dist/src/core/mcp-factory.d.ts +12 -0
  38. package/dist/src/core/mcp-factory.d.ts.map +1 -0
  39. package/dist/src/core/mcp-factory.js +143 -0
  40. package/dist/src/core/mcp-factory.js.map +1 -0
  41. package/dist/src/core/mcp-server.d.ts +3 -0
  42. package/dist/src/core/mcp-server.d.ts.map +1 -0
  43. package/dist/src/core/mcp-server.js +55 -0
  44. package/dist/src/core/mcp-server.js.map +1 -0
  45. package/dist/src/core/migrate-plugin.d.ts +15 -0
  46. package/dist/src/core/migrate-plugin.d.ts.map +1 -0
  47. package/dist/src/core/migrate-plugin.js +181 -0
  48. package/dist/src/core/migrate-plugin.js.map +1 -0
  49. package/dist/src/core/pets-registry.d.ts +47 -0
  50. package/dist/src/core/pets-registry.d.ts.map +1 -0
  51. package/dist/src/core/pets-registry.js +109 -0
  52. package/dist/src/core/pets-registry.js.map +1 -0
  53. package/dist/src/core/plugin-factory.d.ts +58 -0
  54. package/dist/src/core/plugin-factory.d.ts.map +1 -0
  55. package/dist/src/core/plugin-factory.js +212 -0
  56. package/dist/src/core/plugin-factory.js.map +1 -0
  57. package/dist/src/core/prompt-utils.d.ts +14 -0
  58. package/dist/src/core/prompt-utils.d.ts.map +1 -0
  59. package/dist/src/core/prompt-utils.js +106 -0
  60. package/dist/src/core/prompt-utils.js.map +1 -0
  61. package/dist/src/core/schema-helpers.d.ts +33 -0
  62. package/dist/src/core/schema-helpers.d.ts.map +1 -0
  63. package/dist/src/core/schema-helpers.js +46 -0
  64. package/dist/src/core/schema-helpers.js.map +1 -0
  65. package/dist/src/core/search-pets.d.ts +29 -0
  66. package/dist/src/core/search-pets.d.ts.map +1 -0
  67. package/dist/src/core/search-pets.js +196 -0
  68. package/dist/src/core/search-pets.js.map +1 -0
  69. package/dist/src/core/types.d.ts +63 -0
  70. package/dist/src/core/types.d.ts.map +1 -0
  71. package/dist/src/core/types.js +2 -0
  72. package/dist/src/core/types.js.map +1 -0
  73. package/dist/src/core/validate-pet.d.ts +40 -0
  74. package/dist/src/core/validate-pet.d.ts.map +1 -0
  75. package/dist/src/core/validate-pet.js +650 -0
  76. package/dist/src/core/validate-pet.js.map +1 -0
  77. package/package.json +8 -21
  78. package/ai-client-base/index.ts +0 -229
  79. package/build-pet.ts +0 -429
  80. package/cli.ts +0 -268
  81. package/config-manager.ts +0 -82
  82. package/deploy-pet.ts +0 -91
  83. package/index.ts +0 -10
  84. package/local-cache.ts +0 -280
  85. package/logger.ts +0 -143
  86. package/mcp-factory.ts +0 -180
  87. package/mcp-server.ts +0 -69
  88. package/migrate-plugin.ts +0 -220
  89. package/pets-registry.ts +0 -160
  90. package/plugin-factory.ts +0 -300
  91. package/prompt-utils.ts +0 -130
  92. package/schema-helpers.ts +0 -59
  93. package/search-pets.ts +0 -267
  94. package/types.ts +0 -68
  95. package/validate-pet.ts +0 -749
  96. /package/{logger.d.ts → dist/src/core/logger.d.ts} +0 -0
@@ -0,0 +1,47 @@
1
+ export interface AIImageResult {
2
+ success: boolean;
3
+ images?: Array<{
4
+ url: string;
5
+ width?: number;
6
+ height?: number;
7
+ }>;
8
+ error?: string;
9
+ metadata?: Record<string, any>;
10
+ requestId?: string;
11
+ credits?: Record<string, any>;
12
+ }
13
+ export interface AIVideoResult {
14
+ success: boolean;
15
+ videos?: Array<{
16
+ url: string;
17
+ duration?: number;
18
+ width?: number;
19
+ height?: number;
20
+ }>;
21
+ error?: string;
22
+ metadata?: Record<string, any>;
23
+ requestId?: string;
24
+ credits?: Record<string, any>;
25
+ }
26
+ export interface BaseAIClientConfig {
27
+ apiKey: string;
28
+ baseUrl?: string;
29
+ debug?: boolean;
30
+ }
31
+ export declare abstract class BaseAIClient {
32
+ protected apiKey: string;
33
+ protected baseUrl?: string;
34
+ protected debug: boolean;
35
+ constructor(config: BaseAIClientConfig);
36
+ abstract get providerName(): string;
37
+ protected log(message: string, level?: "info" | "warn" | "error" | "debug"): void;
38
+ protected ensureApiKey(envVarName: string): void;
39
+ protected downloadMedia(url: string, outputDir: string, prefix: string): Promise<string>;
40
+ protected openInDefaultViewer(filepath: string): Promise<void>;
41
+ protected getMimeType(filename: string): string;
42
+ protected downloadAndOpen<T extends AIImageResult | AIVideoResult>(result: T, mediaType: "image" | "video", fileExtension: string, openInViewer?: boolean): Promise<T & {
43
+ localPath?: string;
44
+ }>;
45
+ protected extractCreditsFromResponse(response: any): any;
46
+ }
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../ai-client-base/index.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,8BAAsB,YAAY;IAChC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,KAAK,EAAE,OAAO,CAAA;gBAEZ,MAAM,EAAE,kBAAkB;IAMtC,QAAQ,KAAK,YAAY,IAAI,MAAM,CAAA;IAEnC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAgB,GAAG,IAAI;IAqBzF,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;cAMhC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;cA6B9E,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBpE,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;cAgB/B,eAAe,CAAC,CAAC,SAAS,aAAa,GAAG,aAAa,EACrE,MAAM,EAAE,CAAC,EACT,SAAS,EAAE,OAAO,GAAG,OAAO,EAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,GAAE,OAAc,GAC3B,OAAO,CAAC,CAAC,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsDtC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;CA+BzD"}
@@ -0,0 +1,168 @@
1
+ import { createLogger } from "../logger";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import { exec } from "child_process";
5
+ import { promisify } from "util";
6
+ const execAsync = promisify(exec);
7
+ const logger = createLogger("base-ai-client");
8
+ export class BaseAIClient {
9
+ apiKey;
10
+ baseUrl;
11
+ debug;
12
+ constructor(config) {
13
+ this.apiKey = config.apiKey;
14
+ this.baseUrl = config.baseUrl;
15
+ this.debug = config.debug || false;
16
+ }
17
+ log(message, level = "info") {
18
+ if (!this.debug && level === "debug")
19
+ return;
20
+ const timestamp = new Date().toISOString();
21
+ const prefix = `[${this.providerName.toUpperCase()}] ${timestamp}`;
22
+ switch (level) {
23
+ case "error":
24
+ console.error(`${prefix} ERROR:`, message);
25
+ break;
26
+ case "warn":
27
+ console.warn(`${prefix} WARN:`, message);
28
+ break;
29
+ case "debug":
30
+ console.debug(`${prefix} DEBUG:`, message);
31
+ break;
32
+ default:
33
+ console.log(`${prefix} INFO:`, message);
34
+ }
35
+ }
36
+ ensureApiKey(envVarName) {
37
+ if (!this.apiKey || this.apiKey.trim() === "") {
38
+ throw new Error(`${envVarName} environment variable is required but not set`);
39
+ }
40
+ }
41
+ async downloadMedia(url, outputDir, prefix) {
42
+ try {
43
+ if (!fs.existsSync(outputDir)) {
44
+ fs.mkdirSync(outputDir, { recursive: true });
45
+ }
46
+ const timestamp = Date.now();
47
+ const extension = url.includes('.mp4') || url.includes('video') ? 'mp4' : 'png';
48
+ const filename = `${prefix}-${timestamp}.${extension}`;
49
+ const filepath = path.join(outputDir, filename);
50
+ logger.info(`Downloading media from ${url}`);
51
+ const response = await fetch(url);
52
+ if (!response.ok) {
53
+ throw new Error(`Failed to download: ${response.statusText}`);
54
+ }
55
+ const buffer = await response.arrayBuffer();
56
+ fs.writeFileSync(filepath, Buffer.from(buffer));
57
+ logger.info(`Media saved to ${filepath}`);
58
+ return filepath;
59
+ }
60
+ catch (error) {
61
+ logger.error(`Failed to download media: ${error.message}`);
62
+ throw error;
63
+ }
64
+ }
65
+ async openInDefaultViewer(filepath) {
66
+ try {
67
+ const platform = process.platform;
68
+ let command;
69
+ if (platform === "darwin") {
70
+ command = `open "${filepath}"`;
71
+ }
72
+ else if (platform === "win32") {
73
+ command = `start "" "${filepath}"`;
74
+ }
75
+ else {
76
+ command = `xdg-open "${filepath}"`;
77
+ }
78
+ await execAsync(command);
79
+ logger.info(`Opened ${filepath} in default viewer`);
80
+ }
81
+ catch (error) {
82
+ logger.warn(`Failed to open in viewer: ${error.message}`);
83
+ }
84
+ }
85
+ getMimeType(filename) {
86
+ const ext = path.extname(filename).toLowerCase();
87
+ const mimeTypes = {
88
+ '.jpg': 'image/jpeg',
89
+ '.jpeg': 'image/jpeg',
90
+ '.png': 'image/png',
91
+ '.gif': 'image/gif',
92
+ '.webp': 'image/webp',
93
+ '.mp4': 'video/mp4',
94
+ '.mov': 'video/quicktime',
95
+ '.avi': 'video/x-msvideo',
96
+ '.webm': 'video/webm'
97
+ };
98
+ return mimeTypes[ext] || 'application/octet-stream';
99
+ }
100
+ async downloadAndOpen(result, mediaType, fileExtension, openInViewer = true) {
101
+ if (!result.success) {
102
+ return result;
103
+ }
104
+ const mediaArray = mediaType === "image"
105
+ ? result.images
106
+ : result.videos;
107
+ if (!mediaArray || mediaArray.length === 0) {
108
+ return result;
109
+ }
110
+ try {
111
+ const downloadsDir = path.join(process.cwd(), "output");
112
+ if (!fs.existsSync(downloadsDir)) {
113
+ fs.mkdirSync(downloadsDir, { recursive: true });
114
+ }
115
+ const timestamp = Date.now();
116
+ const filename = `${this.providerName}-${mediaType}-${timestamp}.${fileExtension}`;
117
+ const localPath = path.join(downloadsDir, filename);
118
+ const response = await fetch(mediaArray[0].url);
119
+ if (!response.ok) {
120
+ throw new Error(`Failed to download: ${response.statusText}`);
121
+ }
122
+ const buffer = await response.arrayBuffer();
123
+ fs.writeFileSync(localPath, Buffer.from(buffer));
124
+ logger.info(`${mediaType} saved to ${localPath}`);
125
+ if (openInViewer) {
126
+ await this.openInDefaultViewer(localPath);
127
+ }
128
+ return {
129
+ ...result,
130
+ localPath
131
+ };
132
+ }
133
+ catch (error) {
134
+ this.log(`${mediaType.charAt(0).toUpperCase() + mediaType.slice(1)} generated successfully but post-processing failed: ${error.message}`, "error");
135
+ return {
136
+ ...result,
137
+ localPath: undefined
138
+ };
139
+ }
140
+ }
141
+ extractCreditsFromResponse(response) {
142
+ const credits = {};
143
+ if (response?.credits !== undefined) {
144
+ credits.balance = response.credits.balance;
145
+ credits.cost = response.credits.cost;
146
+ credits.currency = response.credits.currency;
147
+ credits.remaining = response.credits.remaining;
148
+ credits.limit = response.credits.limit;
149
+ credits.used = response.credits.used;
150
+ }
151
+ if (response?.billing !== undefined) {
152
+ credits.balance = response.billing.balance;
153
+ credits.cost = response.billing.cost;
154
+ credits.currency = response.billing.currency;
155
+ credits.remaining = response.billing.remaining;
156
+ }
157
+ if (response?.usage !== undefined) {
158
+ credits.used = response.usage.total_tokens || response.usage.used;
159
+ credits.limit = response.usage.limit;
160
+ credits.remaining = response.usage.remaining;
161
+ }
162
+ if (Object.keys(credits).length === 0) {
163
+ return undefined;
164
+ }
165
+ return credits;
166
+ }
167
+ }
168
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../ai-client-base/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Browser-safe exports from openpets
3
+ *
4
+ * This module only exports code that doesn't use Node.js APIs like fs, path, etc.
5
+ * Use this entry point when importing from browser/frontend code.
6
+ */
7
+ export * from './types';
8
+ export * from './search-pets';
9
+ export * from './schema-helpers';
10
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../browser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA"}
@@ -4,7 +4,7 @@
4
4
  * This module only exports code that doesn't use Node.js APIs like fs, path, etc.
5
5
  * Use this entry point when importing from browser/frontend code.
6
6
  */
7
-
8
- export * from './types'
9
- export * from './search-pets'
10
- export * from './schema-helpers'
7
+ export * from './types';
8
+ export * from './search-pets';
9
+ export * from './schema-helpers';
10
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../browser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function buildPet(petName?: string): Promise<void>;
2
+ //# sourceMappingURL=build-pet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-pet.d.ts","sourceRoot":"","sources":["../../../build-pet.ts"],"names":[],"mappings":"AAmQA,wBAAsB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyK9D"}
@@ -0,0 +1,364 @@
1
+ import { join, dirname } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs';
4
+ import { pathToFileURL } from 'url';
5
+ import { PluginValidator } from './validate-pet.js';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+ const projectRoot = dirname(dirname(__dirname));
9
+ const DEBUG = process.env.PETS_DEBUG === 'true';
10
+ function debug(...msgs) {
11
+ if (DEBUG) {
12
+ console.log('[BUILD-PET]', ...msgs);
13
+ }
14
+ }
15
+ async function extractToolsFromIndexFile(indexPath) {
16
+ debug('=== EXTRACTING TOOLS FROM INDEX FILE ===');
17
+ debug('Index path:', indexPath);
18
+ debug('File exists:', existsSync(indexPath));
19
+ try {
20
+ const indexUrl = pathToFileURL(indexPath).href;
21
+ debug('Index URL:', indexUrl);
22
+ debug('Attempting dynamic import...');
23
+ const indexModule = await import(/* @vite-ignore */ indexUrl);
24
+ debug('Import successful');
25
+ debug('Module keys:', Object.keys(indexModule));
26
+ if (indexModule.toolsMetadata && Array.isArray(indexModule.toolsMetadata)) {
27
+ console.log(` Found ${indexModule.toolsMetadata.length} tools from exported toolsMetadata`);
28
+ debug('Tools metadata:', JSON.stringify(indexModule.toolsMetadata, null, 2));
29
+ return indexModule.toolsMetadata;
30
+ }
31
+ else {
32
+ debug('toolsMetadata not found or not an array');
33
+ debug('indexModule.toolsMetadata:', indexModule.toolsMetadata);
34
+ }
35
+ }
36
+ catch (error) {
37
+ console.warn(` ⚠️ Could not import toolsMetadata, falling back to file parsing`);
38
+ console.warn(` Error: ${error instanceof Error ? error.message : String(error)}`);
39
+ debug('Import error details:', {
40
+ name: error instanceof Error ? error.name : 'Unknown',
41
+ message: error instanceof Error ? error.message : String(error),
42
+ stack: error instanceof Error ? error.stack : 'No stack trace'
43
+ });
44
+ }
45
+ debug('Falling back to file parsing');
46
+ return extractToolsFromIndexFileByParsing(indexPath);
47
+ }
48
+ function extractToolsFromIndexFileByParsing(indexPath) {
49
+ const content = readFileSync(indexPath, 'utf8');
50
+ const toolsMatch = content.match(/const\s+tools:\s*ToolDefinition\[\]\s*=\s*\[([\s\S]*?)\n\s*\]/m);
51
+ if (!toolsMatch) {
52
+ console.warn('⚠️ Could not find tools array in index.ts');
53
+ return [];
54
+ }
55
+ const toolsArray = toolsMatch[1];
56
+ const toolNames = [];
57
+ const toolsSeparated = toolsArray.split(/\n\s*\{/).filter(part => part.includes('name:'));
58
+ const toolBlocks = toolsSeparated.map((part, idx) => {
59
+ if (idx === 0)
60
+ return part;
61
+ return '{' + part;
62
+ });
63
+ for (const block of toolBlocks) {
64
+ const nameMatch = block.match(/name:\s*["']([^"']+)["']/);
65
+ const descMatch = block.match(/description:\s*["']([^"']+)["']/);
66
+ const schemaMatch = block.match(/schema:\s*z\.object\(\{([\s\S]*?)\}\),?\s*(?:async\s+execute|$)/);
67
+ if (nameMatch && descMatch) {
68
+ let schemaProperties = {};
69
+ if (schemaMatch) {
70
+ const schemaContent = schemaMatch[1];
71
+ const lines = schemaContent.split('\n').filter(l => l.trim() && !l.trim().startsWith('//'));
72
+ for (const line of lines) {
73
+ const propMatch = line.match(/^\s*(\w+):\s*z\.(.+?),?\s*$/);
74
+ if (!propMatch)
75
+ continue;
76
+ const [, propName, zodDef] = propMatch;
77
+ let propSchema = {};
78
+ if (zodDef.includes('string(')) {
79
+ propSchema.type = 'string';
80
+ }
81
+ else if (zodDef.includes('number(')) {
82
+ propSchema.type = 'number';
83
+ const minMatch = zodDef.match(/\.min\((\d+)\)/);
84
+ const maxMatch = zodDef.match(/\.max\((\d+)\)/);
85
+ if (minMatch)
86
+ propSchema.minimum = parseInt(minMatch[1]);
87
+ if (maxMatch)
88
+ propSchema.maximum = parseInt(maxMatch[1]);
89
+ }
90
+ else if (zodDef.includes('boolean(')) {
91
+ propSchema.type = 'boolean';
92
+ }
93
+ else if (zodDef.includes('enum(')) {
94
+ propSchema.type = 'string';
95
+ const enumMatch = zodDef.match(/enum\(\[([^\]]+)\]\)/);
96
+ if (enumMatch) {
97
+ const enumValues = enumMatch[1].match(/["']([^"']+)["']/g)?.map(v => v.replace(/["']/g, ''));
98
+ if (enumValues)
99
+ propSchema.enum = enumValues;
100
+ }
101
+ }
102
+ else if (zodDef.includes('array(')) {
103
+ propSchema.type = 'array';
104
+ const arrayTypeMatch = zodDef.match(/array\(z\.(\w+)\(\)\)/);
105
+ if (arrayTypeMatch) {
106
+ propSchema.items = { type: arrayTypeMatch[1].toLowerCase() };
107
+ }
108
+ }
109
+ if (zodDef.includes('.optional()')) {
110
+ propSchema.optional = true;
111
+ }
112
+ const descMatch = zodDef.match(/\.describe\(["']([^"']+)["']\)/);
113
+ if (descMatch) {
114
+ propSchema.description = descMatch[1];
115
+ }
116
+ schemaProperties[propName] = propSchema;
117
+ }
118
+ }
119
+ toolNames.push({
120
+ name: nameMatch[1],
121
+ description: descMatch[1],
122
+ schema: {
123
+ type: 'object',
124
+ properties: schemaProperties
125
+ }
126
+ });
127
+ }
128
+ }
129
+ console.log(` Found ${toolNames.length} tools in index.ts`);
130
+ return toolNames;
131
+ }
132
+ function formatZodSchema(schema, depth = 0) {
133
+ if (!schema || !schema._def) {
134
+ return { type: 'object', properties: {} };
135
+ }
136
+ const def = schema._def;
137
+ const zodType = def.typeName || def.type || schema.constructor?.name || 'unknown';
138
+ if (zodType === 'ZodObject' || zodType === 'object') {
139
+ const properties = {};
140
+ const shapeObj = typeof def.shape === 'function' ? def.shape() : def.shape || {};
141
+ for (const [key, value] of Object.entries(shapeObj)) {
142
+ properties[key] = formatZodSchema(value, depth + 1);
143
+ }
144
+ return {
145
+ type: 'object',
146
+ properties
147
+ };
148
+ }
149
+ if (zodType === 'ZodString' || zodType === 'string') {
150
+ return { type: 'string' };
151
+ }
152
+ if (zodType === 'ZodNumber' || zodType === 'number') {
153
+ const result = { type: 'number' };
154
+ if (def.checks) {
155
+ for (const check of def.checks) {
156
+ if (check.kind === 'min')
157
+ result.minimum = check.value;
158
+ if (check.kind === 'max')
159
+ result.maximum = check.value;
160
+ }
161
+ }
162
+ return result;
163
+ }
164
+ if (zodType === 'ZodBoolean' || zodType === 'boolean') {
165
+ return { type: 'boolean' };
166
+ }
167
+ if (zodType === 'ZodArray' || zodType === 'array') {
168
+ return {
169
+ type: 'array',
170
+ items: formatZodSchema(def.type, depth + 1)
171
+ };
172
+ }
173
+ if (zodType === 'ZodEnum' || zodType === 'enum') {
174
+ let values = def.values;
175
+ if (!values && schema._def?.values) {
176
+ values = schema._def.values;
177
+ }
178
+ if (!values && schema.options) {
179
+ values = schema.options;
180
+ }
181
+ const enumArray = Array.isArray(values) ? values : Object.values(values || {});
182
+ return {
183
+ type: 'string',
184
+ enum: enumArray
185
+ };
186
+ }
187
+ if (zodType === 'ZodOptional' || zodType === 'optional') {
188
+ return {
189
+ ...formatZodSchema(def.innerType, depth + 1),
190
+ optional: true
191
+ };
192
+ }
193
+ return { type: zodType };
194
+ }
195
+ function generateToolsMetadata(tools) {
196
+ return tools.map(tool => ({
197
+ name: tool.name,
198
+ description: tool.description,
199
+ schema: tool.schema._def ? formatZodSchema(tool.schema) : tool.schema
200
+ }));
201
+ }
202
+ function generateScriptsFromTools(tools, petName) {
203
+ const scripts = {
204
+ build: 'pets build',
205
+ 'build:tsc': 'tsc',
206
+ quickstart: `opencode run "list available ${petName} commands"`,
207
+ };
208
+ for (const tool of tools) {
209
+ let scriptName = tool.name;
210
+ if (scriptName.startsWith(`${petName}-`)) {
211
+ scriptName = scriptName.replace(new RegExp(`^${petName}-`), 'test:');
212
+ }
213
+ else {
214
+ scriptName = `test:${scriptName}`;
215
+ }
216
+ const command = `opencode run "${tool.description}"`;
217
+ scripts[scriptName] = command;
218
+ }
219
+ scripts['test:all'] = 'echo "Run individual test scripts to test specific tools"';
220
+ return scripts;
221
+ }
222
+ export async function buildPet(petName) {
223
+ debug('=== BUILD PET STARTING ===');
224
+ debug('Initial petName:', petName);
225
+ debug('CWD:', process.cwd());
226
+ debug('Project root:', projectRoot);
227
+ if (!petName) {
228
+ const cwd = process.cwd();
229
+ const petsDir = join(projectRoot, 'pets');
230
+ debug('Auto-detecting pet from CWD:', cwd);
231
+ debug('Pets directory:', petsDir);
232
+ if (cwd.includes('/pets/')) {
233
+ petName = cwd.split('/pets/')[1].split('/')[0];
234
+ console.log(`📦 Auto-detected pet: ${petName}`);
235
+ debug('Auto-detected pet:', petName);
236
+ }
237
+ if (!petName) {
238
+ console.error('Usage: pets build <pet-name>');
239
+ console.error('Example: pets build postgres');
240
+ console.error('');
241
+ console.error('Available pets:');
242
+ if (existsSync(petsDir)) {
243
+ const pets = readdirSync(petsDir).filter(dir => {
244
+ const petPath = join(petsDir, dir);
245
+ return statSync(petPath).isDirectory() && dir !== '_TEMPLATE_';
246
+ });
247
+ pets.forEach(pet => console.error(` - ${pet}`));
248
+ debug('Available pets:', pets);
249
+ }
250
+ else {
251
+ debug('Pets directory does not exist:', petsDir);
252
+ }
253
+ process.exit(1);
254
+ }
255
+ }
256
+ const petDir = join(projectRoot, 'pets', petName);
257
+ const packageJsonPath = join(petDir, 'package.json');
258
+ const indexPath = join(petDir, 'index.ts');
259
+ debug('Pet directory:', petDir);
260
+ debug('Package.json path:', packageJsonPath);
261
+ debug('Index.ts path:', indexPath);
262
+ if (!existsSync(petDir)) {
263
+ console.error(`❌ Pet '${petName}' not found in pets/ directory`);
264
+ debug('Pet directory does not exist:', petDir);
265
+ process.exit(1);
266
+ }
267
+ if (!existsSync(packageJsonPath)) {
268
+ console.error(`❌ package.json not found for pet '${petName}'`);
269
+ debug('Package.json does not exist:', packageJsonPath);
270
+ process.exit(1);
271
+ }
272
+ if (!existsSync(indexPath)) {
273
+ console.error(`❌ index.ts not found for pet '${petName}'`);
274
+ debug('Index.ts does not exist:', indexPath);
275
+ process.exit(1);
276
+ }
277
+ console.log(`🔨 Building ${petName}...`);
278
+ debug('All required files found, proceeding with build');
279
+ const packageJsonContent = readFileSync(packageJsonPath, 'utf8');
280
+ debug('Package.json content length:', packageJsonContent.length);
281
+ const packageJson = JSON.parse(packageJsonContent);
282
+ debug('Package.json parsed successfully');
283
+ debug('Package name:', packageJson.name);
284
+ debug('Package version:', packageJson.version);
285
+ // Auto-generate repository field if missing
286
+ if (!packageJson.repository) {
287
+ packageJson.repository = {
288
+ type: 'git',
289
+ url: `https://github.com/raggle-ai/pets/pets/${petName}`
290
+ };
291
+ debug('Auto-generated repository field:', packageJson.repository.url);
292
+ }
293
+ console.log(` Name: ${packageJson.name}`);
294
+ console.log(` Version: ${packageJson.version}`);
295
+ console.log(` Description: ${packageJson.description || 'No description'}`);
296
+ console.log(`\n🔍 Validating plugin structure...`);
297
+ const validator = new PluginValidator();
298
+ const validation = validator.validatePlugin(petDir);
299
+ if (validation.result.errors.length > 0) {
300
+ console.log(`\n❌ Validation failed with ${validation.result.errors.length} error(s):`);
301
+ validation.result.errors.forEach(error => {
302
+ console.log(` ❌ ${error}`);
303
+ });
304
+ console.log(`\n💥 Build aborted due to validation errors.`);
305
+ process.exit(1);
306
+ }
307
+ if (validation.result.warnings.length > 0) {
308
+ console.log(`\n⚠️ Found ${validation.result.warnings.length} warning(s):`);
309
+ validation.result.warnings.forEach(warning => {
310
+ console.log(` ⚠️ ${warning}`);
311
+ });
312
+ }
313
+ if (validation.result.codePatternWarnings && validation.result.codePatternWarnings.length > 0) {
314
+ console.log(`\n📋 Code pattern analysis:`);
315
+ validation.result.codePatternWarnings.forEach(warning => {
316
+ console.log(` ${warning}`);
317
+ });
318
+ }
319
+ if (validation.result.errors.length === 0 && validation.result.warnings.length === 0 && (!validation.result.codePatternWarnings || validation.result.codePatternWarnings.length === 0)) {
320
+ console.log(` ✓ All validation checks passed`);
321
+ }
322
+ debug('Extracting tools from index file...');
323
+ const tools = await extractToolsFromIndexFile(indexPath);
324
+ debug(`Extracted ${tools.length} tools`);
325
+ if (tools.length > 0) {
326
+ console.log(`\n📝 Generating scripts and metadata for ${tools.length} tools...`);
327
+ debug('Tools extracted:', tools.map(t => t.name));
328
+ const scripts = generateScriptsFromTools(tools, petName);
329
+ debug('Generated scripts:', Object.keys(scripts));
330
+ const toolsMetadata = generateToolsMetadata(tools);
331
+ debug('Generated tools metadata count:', toolsMetadata.length);
332
+ packageJson.scripts = scripts;
333
+ delete packageJson.tools;
334
+ const commandsJsonPath = join(petDir, 'commands.json');
335
+ debug('Commands.json path:', commandsJsonPath);
336
+ const commandsData = {
337
+ name: packageJson.name,
338
+ version: packageJson.version,
339
+ description: packageJson.description,
340
+ tools: toolsMetadata,
341
+ generatedAt: new Date().toISOString()
342
+ };
343
+ debug('Writing package.json...');
344
+ writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8');
345
+ debug('Package.json written successfully');
346
+ debug('Writing commands.json...');
347
+ writeFileSync(commandsJsonPath, JSON.stringify(commandsData, null, 2) + '\n', 'utf8');
348
+ debug('Commands.json written successfully');
349
+ console.log(` ✓ Updated package.json with ${Object.keys(scripts).length} scripts`);
350
+ console.log(` ✓ Generated commands.json with ${tools.length} tools`);
351
+ console.log(`\n🔧 Generated test scripts:`);
352
+ Object.entries(scripts).forEach(([name, cmd]) => {
353
+ if (name.startsWith('test:')) {
354
+ console.log(` - npm run ${name}`);
355
+ }
356
+ });
357
+ }
358
+ else {
359
+ debug('No tools found in index file');
360
+ }
361
+ console.log(`\n✅ ${petName} built successfully!`);
362
+ debug('=== BUILD COMPLETE ===');
363
+ }
364
+ //# sourceMappingURL=build-pet.js.map