openpets 1.0.4 → 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 +7 -11
  78. package/ai-client-base/index.ts +0 -117
  79. package/build-pet.ts +0 -429
  80. package/cli.ts +0 -179
  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 -309
  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 -594
  96. /package/{logger.d.ts → dist/src/core/logger.d.ts} +0 -0
package/pets-registry.ts DELETED
@@ -1,160 +0,0 @@
1
- import { readdirSync, existsSync, readFileSync } from "fs"
2
- import { join, resolve } from "path"
3
- import { createLogger } from "./logger"
4
-
5
- const logger = createLogger("pets-registry")
6
-
7
- export interface PetMetadata {
8
- id: string
9
- name: string
10
- description: string
11
- version: string
12
- keywords: string[]
13
- author?: string
14
- repository?: {
15
- type: string
16
- url: string
17
- directory?: string
18
- }
19
- queries?: string[]
20
- scenarios?: Record<string, string[]>
21
- envVariables?: {
22
- required?: Array<{ name: string; description: string; provider?: string }>
23
- optional?: Array<{ name: string; description: string; provider?: string }>
24
- }
25
- utils?: {
26
- dependencies?: string[]
27
- paths?: string[]
28
- }
29
- }
30
-
31
- export class PetsRegistry {
32
- private pets: Map<string, PetMetadata> = new Map()
33
- private petsDir: string
34
-
35
- constructor(petsDir?: string) {
36
- this.petsDir = petsDir || resolve(__dirname, "../../pets")
37
- this.loadPets()
38
- }
39
-
40
- private loadPets(): void {
41
- try {
42
- if (!existsSync(this.petsDir)) {
43
- logger.warn(`Pets directory not found: ${this.petsDir}`)
44
- return
45
- }
46
-
47
- const entries = readdirSync(this.petsDir, { withFileTypes: true })
48
-
49
- for (const entry of entries) {
50
- if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === 'node_modules') {
51
- continue
52
- }
53
-
54
- const petDir = join(this.petsDir, entry.name)
55
- const packageJsonPath = join(petDir, 'package.json')
56
-
57
- if (!existsSync(packageJsonPath)) {
58
- continue
59
- }
60
-
61
- try {
62
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
63
-
64
- const metadata: PetMetadata = {
65
- id: entry.name,
66
- name: packageJson.name || entry.name,
67
- description: packageJson.description || '',
68
- version: packageJson.version || '1.0.0',
69
- keywords: packageJson.keywords || [],
70
- author: packageJson.author,
71
- repository: packageJson.repository,
72
- queries: packageJson.queries,
73
- scenarios: packageJson.scenarios,
74
- envVariables: packageJson.envVariables,
75
- utils: packageJson.utils
76
- }
77
-
78
- this.pets.set(entry.name, metadata)
79
- logger.debug(`Loaded pet: ${entry.name}`)
80
- } catch (error: any) {
81
- logger.error(`Failed to load pet ${entry.name}: ${error.message}`)
82
- }
83
- }
84
-
85
- logger.info(`Loaded ${this.pets.size} pets`)
86
- } catch (error: any) {
87
- logger.error(`Failed to load pets: ${error.message}`)
88
- }
89
- }
90
-
91
- getAllPets(): PetMetadata[] {
92
- return Array.from(this.pets.values())
93
- }
94
-
95
- getPet(id: string): PetMetadata | undefined {
96
- return this.pets.get(id)
97
- }
98
-
99
- searchPets(query: string): PetMetadata[] {
100
- if (!query || query.trim() === '') {
101
- return this.getAllPets()
102
- }
103
-
104
- const normalizedQuery = query.toLowerCase().trim()
105
- const results: PetMetadata[] = []
106
-
107
- for (const pet of this.pets.values()) {
108
- const searchableText = [
109
- pet.id,
110
- pet.name,
111
- pet.description,
112
- ...(pet.keywords || []),
113
- pet.author || '',
114
- ].join(' ').toLowerCase()
115
-
116
- if (searchableText.includes(normalizedQuery)) {
117
- results.push(pet)
118
- }
119
- }
120
-
121
- return results
122
- }
123
-
124
- getPetsByCategory(keywords: string[]): PetMetadata[] {
125
- return this.getAllPets().filter(pet =>
126
- keywords.some(keyword =>
127
- pet.keywords?.some(k => k.toLowerCase().includes(keyword.toLowerCase()))
128
- )
129
- )
130
- }
131
-
132
- reload(): void {
133
- this.pets.clear()
134
- this.loadPets()
135
- }
136
- }
137
-
138
- let defaultRegistry: PetsRegistry | null = null
139
-
140
- export function getPetsRegistry(petsDir?: string): PetsRegistry {
141
- if (!defaultRegistry) {
142
- defaultRegistry = new PetsRegistry(petsDir)
143
- }
144
- return defaultRegistry
145
- }
146
-
147
- export function searchPetsInRegistry(query: string, petsDir?: string): PetMetadata[] {
148
- const registry = getPetsRegistry(petsDir)
149
- return registry.searchPets(query)
150
- }
151
-
152
- export function getAllPetsFromRegistry(petsDir?: string): PetMetadata[] {
153
- const registry = getPetsRegistry(petsDir)
154
- return registry.getAllPets()
155
- }
156
-
157
- export function getPetFromRegistry(id: string, petsDir?: string): PetMetadata | undefined {
158
- const registry = getPetsRegistry(petsDir)
159
- return registry.getPet(id)
160
- }
package/plugin-factory.ts DELETED
@@ -1,309 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin"
2
- import { readFileSync, existsSync } from "fs"
3
- import { resolve, dirname } from "path"
4
- import { createLogger } from "./logger"
5
- import { config } from "dotenv"
6
- import type * as z from "zod"
7
- import * as zodRuntime from "zod"
8
-
9
- // ============================================================================
10
- // CRITICAL: SCHEMA FORMAT REQUIREMENTS
11
- // ============================================================================
12
- //
13
- // 1. ALWAYS use tool.schema for the Zod instance (not direct "zod" import)
14
- // This ensures the same Zod version as OpenCode
15
- //
16
- // 2. SIMPLE TYPES ONLY - Do NOT use nested schemas
17
- // ✅ ALLOWED:
18
- // - z.string()
19
- // - z.number()
20
- // - z.boolean()
21
- // - z.array(z.string())
22
- // - z.array(z.number())
23
- // - z.object({ field: z.string() })
24
- //
25
- // ❌ NOT ALLOWED (will cause runtime errors):
26
- // - z.array(z.object({...})) // Nested object in array
27
- // - z.object({ nested: z.object({...}) }) // Nested object in object
28
- // - z.record(z.string()) // Record with any nested type
29
- // - z.union([z.object({...}), ...]) // Union with nested types
30
- //
31
- // 3. WORKAROUND for complex data structures:
32
- // Use z.string() with JSON serialization
33
- // Example:
34
- // schema: z.object({
35
- // dataJson: z.string().describe("JSON string of data array")
36
- // }),
37
- // execute(args) {
38
- // const data = JSON.parse(args.dataJson)
39
- // // ... process data
40
- // }
41
- //
42
- // ============================================================================
43
-
44
- export { tool }
45
- export { zodRuntime as z }
46
-
47
- const logger = createLogger("plugin-factory")
48
-
49
- export interface ToolDefinition<T extends Record<string, any> = any> {
50
- name: string
51
- description: string
52
- schema: z.ZodType<any, any, any>
53
- execute: (args: T, context?: any) => Promise<string>
54
- }
55
-
56
- export interface ProviderSpec {
57
- name: string
58
- displayName: string
59
- envVars: {
60
- required: Array<{
61
- name: string
62
- description: string
63
- example?: string
64
- }>
65
- }
66
- capabilities: string[]
67
- comingSoon?: string[]
68
- credentialsUrl?: string
69
- credentialsDocUrl?: string
70
- }
71
-
72
- export interface ProviderValidationResult {
73
- provider: string
74
- configured: boolean
75
- missingVars: string[]
76
- spec?: ProviderSpec
77
- }
78
-
79
- export interface ProviderValidationReport {
80
- hasRequiredProvider: boolean
81
- requiredResults: ProviderValidationResult[]
82
- optionalResults: ProviderValidationResult[]
83
- errors: string[]
84
- }
85
-
86
- export type ToolRecord = Record<string, {
87
- description: string
88
- args: z.ZodObject<any>
89
- execute: (args: any, context?: any) => Promise<string>
90
- }>
91
-
92
- export function createPlugin(tools: ToolDefinition[]): { tool: ToolRecord } {
93
- const toolRecord: ToolRecord = {}
94
-
95
- for (const toolDef of tools) {
96
- const schema = toolDef.schema as any
97
- toolRecord[toolDef.name] = tool({
98
- description: toolDef.description,
99
- args: schema.shape || schema,
100
- execute: toolDef.execute
101
- })
102
- }
103
-
104
- return { tool: toolRecord }
105
- }
106
-
107
- export function createSingleTool<T extends Record<string, any>>(
108
- definition: Omit<ToolDefinition<T>, 'name'>
109
- ): {
110
- description: string
111
- args: z.ZodObject<any>
112
- execute: (args: T, context?: any) => Promise<string>
113
- } {
114
- const schema = definition.schema as any
115
- return tool({
116
- description: definition.description,
117
- args: schema.shape || schema,
118
- execute: definition.execute
119
- })
120
- }
121
-
122
- function loadProviderSpec(providerPath: string, pluginDir: string): ProviderSpec | null {
123
- try {
124
- let packagePath: string
125
-
126
- if (providerPath.startsWith('openpets/')) {
127
- const petName = providerPath.replace('openpets/', '')
128
- packagePath = resolve(pluginDir, `../${petName}/package.json`)
129
- } else if (providerPath.startsWith('@/utils/')) {
130
- const normalizedPath = providerPath.replace('@/utils/', '')
131
- packagePath = resolve(pluginDir, `../../src/utils/${normalizedPath}/package.json`)
132
- } else {
133
- logger.debug(`Unknown provider path format: ${providerPath}`)
134
- return null
135
- }
136
-
137
- const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'))
138
-
139
- if (packageJson.provider) {
140
- return packageJson.provider
141
- }
142
-
143
- if (packageJson.envVariables?.required) {
144
- return {
145
- name: packageJson.name || providerPath,
146
- displayName: packageJson.description?.split('-')[0]?.trim() || providerPath,
147
- envVars: {
148
- required: packageJson.envVariables.required.map((env: any) => ({
149
- name: env.name,
150
- description: env.description,
151
- example: env.example
152
- }))
153
- },
154
- capabilities: packageJson.keywords?.filter((k: string) => k !== 'opencode' && k !== 'plugin') || []
155
- }
156
- }
157
-
158
- return null
159
- } catch (error: any) {
160
- logger.debug(`Could not load provider spec for ${providerPath}: ${error.message}`)
161
- return null
162
- }
163
- }
164
-
165
- function validateProvider(providerPath: string, pluginDir: string): ProviderValidationResult {
166
- const spec = loadProviderSpec(providerPath, pluginDir)
167
-
168
- if (!spec) {
169
- return {
170
- provider: providerPath,
171
- configured: false,
172
- missingVars: [],
173
- spec: undefined
174
- }
175
- }
176
-
177
- const missingVars: string[] = []
178
-
179
- for (const envVar of spec.envVars.required) {
180
- if (!process.env[envVar.name]) {
181
- missingVars.push(envVar.name)
182
- }
183
- }
184
-
185
- return {
186
- provider: providerPath,
187
- configured: missingVars.length === 0,
188
- missingVars,
189
- spec
190
- }
191
- }
192
-
193
- export function validateProviders(packageJson: any, pluginDir: string): ProviderValidationReport {
194
- const errors: string[] = []
195
- const requiredResults: ProviderValidationResult[] = []
196
- const optionalResults: ProviderValidationResult[] = []
197
-
198
- if (!packageJson.providers) {
199
- return { hasRequiredProvider: true, requiredResults, optionalResults, errors }
200
- }
201
-
202
- const anyProviders = packageJson.providers.any || []
203
- const requiredProviders = packageJson.providers.required || []
204
- const optionalProviders = packageJson.providers.optional || []
205
-
206
- const allProviders = [...anyProviders, ...requiredProviders]
207
-
208
- for (const providerPath of allProviders) {
209
- const result = validateProvider(providerPath, pluginDir)
210
- requiredResults.push(result)
211
- }
212
-
213
- for (const providerPath of optionalProviders) {
214
- const result = validateProvider(providerPath, pluginDir)
215
- optionalResults.push(result)
216
- }
217
-
218
- const hasRequiredProvider = requiredResults.length === 0 || requiredResults.some(r => r.configured)
219
-
220
- if (!hasRequiredProvider && requiredResults.length > 0) {
221
- const providerNames = requiredResults
222
- .map(r => r.spec?.displayName || r.provider)
223
- .join(', ')
224
-
225
- errors.push(`At least one provider must be configured. Available providers: ${providerNames}`)
226
- errors.push(`\nConfigure any one of the following:\n`)
227
-
228
- for (const result of requiredResults) {
229
- if (result.spec) {
230
- errors.push(`${result.spec.displayName}:`)
231
- for (const envVar of result.spec.envVars.required) {
232
- errors.push(` - ${envVar.name}: ${envVar.description}`)
233
- if (envVar.example) {
234
- errors.push(` Example: ${envVar.example}`)
235
- }
236
- }
237
- errors.push('')
238
- }
239
- }
240
- }
241
-
242
- return { hasRequiredProvider, requiredResults, optionalResults, errors }
243
- }
244
-
245
- export interface EnvConfig {
246
- [key: string]: string
247
- }
248
-
249
- export function loadEnv(petId?: string): EnvConfig {
250
- const envVars: EnvConfig = {}
251
-
252
- try {
253
- const projectRoot = resolve(process.cwd())
254
- const dotenvPath = resolve(projectRoot, '.env')
255
- const petsConfigPath = resolve(projectRoot, '.pets', 'config.json')
256
-
257
- logger.debug(`Loading env vars for pet: ${petId || 'global'}`)
258
-
259
- if (petId && existsSync(petsConfigPath)) {
260
- try {
261
- const petsConfig = JSON.parse(readFileSync(petsConfigPath, 'utf-8'))
262
- const petEnvConfig = petsConfig.envConfig?.[petId] || {}
263
-
264
- for (const [key, value] of Object.entries(petEnvConfig)) {
265
- if (typeof value === 'string' && value.length > 0) {
266
- envVars[key] = value
267
- logger.debug(`Loaded from .pets/config.json: ${key}`)
268
- }
269
- }
270
- } catch (error: any) {
271
- logger.debug(`Failed to load pet config: ${error.message}`)
272
- }
273
- }
274
-
275
- if (existsSync(dotenvPath)) {
276
- const dotenvResult = config({ path: dotenvPath })
277
-
278
- if (dotenvResult.parsed) {
279
- for (const [key, value] of Object.entries(dotenvResult.parsed)) {
280
- if (value && value.length > 0) {
281
- envVars[key] = value
282
- logger.debug(`Loaded from .env (overriding if exists): ${key}`)
283
- }
284
- }
285
- }
286
- }
287
-
288
- for (const [key, value] of Object.entries(process.env)) {
289
- if (value && value.length > 0) {
290
- if (!envVars[key]) {
291
- envVars[key] = value
292
- logger.debug(`Loaded from process.env: ${key}`)
293
- }
294
- }
295
- }
296
-
297
- logger.info(`Loaded ${Object.keys(envVars).length} environment variables`)
298
-
299
- } catch (error: any) {
300
- logger.error(`Error loading environment variables: ${error.message}`)
301
- }
302
-
303
- return envVars
304
- }
305
-
306
- export function getEnv(key: string, petId?: string): string | undefined {
307
- const envVars = loadEnv(petId)
308
- return envVars[key]
309
- }
package/prompt-utils.ts DELETED
@@ -1,130 +0,0 @@
1
- import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'fs'
2
- import { join, dirname } from 'path'
3
-
4
- interface PetPrompt {
5
- name: string
6
- content: string
7
- description: string
8
- }
9
-
10
- export function extractPetPrompts(agentsMdPath: string, enabledPets: string[]): PetPrompt[] {
11
- if (!existsSync(agentsMdPath)) {
12
- console.warn(`AGENTS.md not found at ${agentsMdPath}`)
13
- return []
14
- }
15
-
16
- const agentsContent = readFileSync(agentsMdPath, 'utf-8')
17
- const prompts: PetPrompt[] = []
18
-
19
- for (const pet of enabledPets) {
20
- const petName = pet.replace('openpets/', '')
21
- const prompt = extractPromptForPet(agentsContent, petName)
22
- if (prompt) {
23
- prompts.push(prompt)
24
- }
25
- }
26
-
27
- return prompts
28
- }
29
-
30
- function extractPromptForPet(content: string, petName: string): PetPrompt | null {
31
- // Simple regex to find plugin section
32
- const pattern = '### [^\\n]*`pets/' + petName + '`'
33
- const pluginRegex = new RegExp(pattern, 'i')
34
- const match = content.match(pluginRegex)
35
-
36
- if (!match) {
37
- console.warn(`No section found for pet: ${petName}`)
38
- return null
39
- }
40
-
41
- const startIndex = match.index!
42
- const afterHeader = content.substring(startIndex + match[0].length)
43
-
44
- // Find next ### section or end of file
45
- const nextSectionMatch = afterHeader.match(/### /)
46
- const endIndex = nextSectionMatch ? startIndex + match[0].length + nextSectionMatch.index! : content.length
47
-
48
- const sectionContent = content.substring(startIndex, endIndex).trim()
49
-
50
- // Extract description (first paragraph)
51
- const lines = sectionContent.split('\\n')
52
- let description = ''
53
- for (let i = 0; i < lines.length; i++) {
54
- if (lines[i].trim() && !lines[i].startsWith('**') && !lines[i].startsWith('*')) {
55
- description = lines[i].trim()
56
- break
57
- }
58
- }
59
-
60
- if (!description) {
61
- description = `System prompt for ${petName} plugin`
62
- }
63
-
64
- // Build simple system prompt
65
- const systemPrompt = `# ${petName.charAt(0).toUpperCase() + petName.slice(1)} Plugin
66
-
67
- ${description}
68
-
69
- ## Usage Guidance
70
-
71
- This plugin provides tools for interacting with ${petName} services.
72
-
73
- ## Important Notes
74
-
75
- - Always check for required environment variables before using tools
76
- - Read tool descriptions carefully to understand parameters
77
- - Handle errors gracefully and provide helpful feedback to users
78
- `
79
-
80
- return {
81
- name: petName,
82
- content: systemPrompt,
83
- description
84
- }
85
- }
86
-
87
- export function writePetPrompts(prompts: PetPrompt[], outputDir: string): void {
88
- if (!existsSync(outputDir)) {
89
- mkdirSync(outputDir, { recursive: true })
90
- }
91
-
92
- for (const prompt of prompts) {
93
- const promptPath = join(outputDir, `${prompt.name}.md`)
94
- writeFileSync(promptPath, prompt.content, 'utf-8')
95
- console.log(`Wrote prompt: ${promptPath}`)
96
- }
97
- }
98
-
99
- export function readPetsConfig(configPath: string): { enabled: string[], disabled: string[] } {
100
- if (!existsSync(configPath)) {
101
- return { enabled: [], disabled: [] }
102
- }
103
-
104
- try {
105
- const config = JSON.parse(readFileSync(configPath, 'utf-8'))
106
- return {
107
- enabled: config.enabled || [],
108
- disabled: config.disabled || []
109
- }
110
- } catch (error) {
111
- console.warn(`Error reading pets config: ${error}`)
112
- return { enabled: [], disabled: [] }
113
- }
114
- }
115
-
116
- export function writePetsConfig(configPath: string, enabled: string[], disabled: string[]): void {
117
- const configDir = dirname(configPath)
118
- if (!existsSync(configDir)) {
119
- mkdirSync(configDir, { recursive: true })
120
- }
121
-
122
- const config = {
123
- enabled,
124
- disabled,
125
- lastUpdated: new Date().toISOString()
126
- }
127
-
128
- writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8')
129
- console.log(`Wrote pets config: ${configPath}`)
130
- }
package/schema-helpers.ts DELETED
@@ -1,59 +0,0 @@
1
- import { z } from "zod"
2
-
3
- export const commonSchemas = {
4
- id: z.string().describe("Unique identifier"),
5
- url: z.string().url().describe("URL"),
6
- email: z.string().email().describe("Email address"),
7
-
8
- pagination: {
9
- perPage: z.number().optional().describe("Number of results per page (default: 20, max: 100)"),
10
- page: z.number().optional().describe("Page number")
11
- },
12
-
13
- search: z.string().optional().describe("Search query"),
14
-
15
- state: (values: string[]) => z.enum(values as [string, ...string[]]).optional().describe("Filter by state")
16
- }
17
-
18
- export function withPagination<T extends z.ZodRawShape>(shape: T) {
19
- return z.object({
20
- ...shape,
21
- ...commonSchemas.pagination
22
- })
23
- }
24
-
25
- export function optional<T extends z.ZodTypeAny>(schema: T) {
26
- return schema.optional()
27
- }
28
-
29
- export function arrayOf<T extends z.ZodTypeAny>(schema: T) {
30
- return z.array(schema)
31
- }
32
-
33
- export function stringEnum(...values: string[]) {
34
- return z.enum(values as [string, ...string[]])
35
- }
36
-
37
- export function stringField(description: string) {
38
- return z.string().describe(description)
39
- }
40
-
41
- export function optionalString(description: string) {
42
- return z.string().optional().describe(description)
43
- }
44
-
45
- export function numberField(description: string) {
46
- return z.number().describe(description)
47
- }
48
-
49
- export function optionalNumber(description: string) {
50
- return z.number().optional().describe(description)
51
- }
52
-
53
- export function booleanField(description: string) {
54
- return z.boolean().describe(description)
55
- }
56
-
57
- export function optionalBoolean(description: string) {
58
- return z.boolean().optional().describe(description)
59
- }