@skillrecordings/cli 0.1.0 → 0.2.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 (136) hide show
  1. package/bin/skill.mjs +27 -0
  2. package/dist/chunk-2NCCVTEE.js +22342 -0
  3. package/dist/chunk-2NCCVTEE.js.map +1 -0
  4. package/dist/chunk-3E3GYSZR.js +7071 -0
  5. package/dist/chunk-3E3GYSZR.js.map +1 -0
  6. package/dist/chunk-F4EM72IH.js +86 -0
  7. package/dist/chunk-F4EM72IH.js.map +1 -0
  8. package/dist/chunk-FGP7KUQW.js +432 -0
  9. package/dist/chunk-FGP7KUQW.js.map +1 -0
  10. package/dist/chunk-H3D6VCME.js +55 -0
  11. package/dist/chunk-H3D6VCME.js.map +1 -0
  12. package/dist/chunk-HK3PEWFD.js +208 -0
  13. package/dist/chunk-HK3PEWFD.js.map +1 -0
  14. package/dist/chunk-KEV3QKXP.js +4495 -0
  15. package/dist/chunk-KEV3QKXP.js.map +1 -0
  16. package/dist/chunk-MG37YDAK.js +882 -0
  17. package/dist/chunk-MG37YDAK.js.map +1 -0
  18. package/dist/chunk-MLNDSBZ4.js +482 -0
  19. package/dist/chunk-MLNDSBZ4.js.map +1 -0
  20. package/dist/chunk-N2WIV2JV.js +22 -0
  21. package/dist/chunk-N2WIV2JV.js.map +1 -0
  22. package/dist/chunk-PWWRCN5W.js +2067 -0
  23. package/dist/chunk-PWWRCN5W.js.map +1 -0
  24. package/dist/chunk-SKHBM3XP.js +7746 -0
  25. package/dist/chunk-SKHBM3XP.js.map +1 -0
  26. package/dist/chunk-WFANXVQG.js +64 -0
  27. package/dist/chunk-WFANXVQG.js.map +1 -0
  28. package/dist/chunk-WYKL32C3.js +275 -0
  29. package/dist/chunk-WYKL32C3.js.map +1 -0
  30. package/dist/chunk-ZNF7XD2S.js +134 -0
  31. package/dist/chunk-ZNF7XD2S.js.map +1 -0
  32. package/dist/config-AUAIYDSI.js +20 -0
  33. package/dist/config-AUAIYDSI.js.map +1 -0
  34. package/dist/fileFromPath-XN7LXIBI.js +134 -0
  35. package/dist/fileFromPath-XN7LXIBI.js.map +1 -0
  36. package/dist/getMachineId-bsd-KW2E7VK3.js +42 -0
  37. package/dist/getMachineId-bsd-KW2E7VK3.js.map +1 -0
  38. package/dist/getMachineId-darwin-ROXJUJX5.js +42 -0
  39. package/dist/getMachineId-darwin-ROXJUJX5.js.map +1 -0
  40. package/dist/getMachineId-linux-KVZEHQSU.js +34 -0
  41. package/dist/getMachineId-linux-KVZEHQSU.js.map +1 -0
  42. package/dist/getMachineId-unsupported-PPRILPPA.js +25 -0
  43. package/dist/getMachineId-unsupported-PPRILPPA.js.map +1 -0
  44. package/dist/getMachineId-win-IIF36LEJ.js +44 -0
  45. package/dist/getMachineId-win-IIF36LEJ.js.map +1 -0
  46. package/dist/index.js +112703 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/lib-R6DEEJCP.js +7623 -0
  49. package/dist/lib-R6DEEJCP.js.map +1 -0
  50. package/dist/pipeline-IAVVAKTU.js +120 -0
  51. package/dist/pipeline-IAVVAKTU.js.map +1 -0
  52. package/dist/query-NTP5NVXN.js +25 -0
  53. package/dist/query-NTP5NVXN.js.map +1 -0
  54. package/dist/routing-BAEPFB7V.js +390 -0
  55. package/dist/routing-BAEPFB7V.js.map +1 -0
  56. package/dist/stripe-lookup-charge-EPRUMZDL.js +56 -0
  57. package/dist/stripe-lookup-charge-EPRUMZDL.js.map +1 -0
  58. package/dist/stripe-payment-history-SJPKA63N.js +67 -0
  59. package/dist/stripe-payment-history-SJPKA63N.js.map +1 -0
  60. package/dist/stripe-subscription-status-L4Z65GB3.js +58 -0
  61. package/dist/stripe-subscription-status-L4Z65GB3.js.map +1 -0
  62. package/dist/stripe-verify-refund-FZDKCIUQ.js +54 -0
  63. package/dist/stripe-verify-refund-FZDKCIUQ.js.map +1 -0
  64. package/dist/support-memory-WSG7SDKG.js +10 -0
  65. package/dist/support-memory-WSG7SDKG.js.map +1 -0
  66. package/package.json +10 -7
  67. package/.env.encrypted +0 -0
  68. package/CHANGELOG.md +0 -35
  69. package/data/tt-archive-dataset.json +0 -1
  70. package/data/validate-test-dataset.json +0 -97
  71. package/docs/CLI-AUTH.md +0 -504
  72. package/preload.ts +0 -18
  73. package/src/__tests__/init.test.ts +0 -74
  74. package/src/alignment-test.ts +0 -64
  75. package/src/check-apps.ts +0 -16
  76. package/src/commands/auth/decrypt.ts +0 -123
  77. package/src/commands/auth/encrypt.ts +0 -81
  78. package/src/commands/auth/index.ts +0 -50
  79. package/src/commands/auth/keygen.ts +0 -41
  80. package/src/commands/auth/status.ts +0 -164
  81. package/src/commands/axiom/forensic.ts +0 -868
  82. package/src/commands/axiom/index.ts +0 -697
  83. package/src/commands/build-dataset.ts +0 -311
  84. package/src/commands/db-status.ts +0 -47
  85. package/src/commands/deploys.ts +0 -219
  86. package/src/commands/eval-local/compare.ts +0 -171
  87. package/src/commands/eval-local/health.ts +0 -212
  88. package/src/commands/eval-local/index.ts +0 -76
  89. package/src/commands/eval-local/real-tools.ts +0 -416
  90. package/src/commands/eval-local/run.ts +0 -1168
  91. package/src/commands/eval-local/score-production.ts +0 -256
  92. package/src/commands/eval-local/seed.ts +0 -276
  93. package/src/commands/eval-pipeline/index.ts +0 -53
  94. package/src/commands/eval-pipeline/real-tools.ts +0 -492
  95. package/src/commands/eval-pipeline/run.ts +0 -1316
  96. package/src/commands/eval-pipeline/seed.ts +0 -395
  97. package/src/commands/eval-prompt.ts +0 -496
  98. package/src/commands/eval.test.ts +0 -253
  99. package/src/commands/eval.ts +0 -108
  100. package/src/commands/faq-classify.ts +0 -460
  101. package/src/commands/faq-cluster.ts +0 -135
  102. package/src/commands/faq-extract.ts +0 -249
  103. package/src/commands/faq-mine.ts +0 -432
  104. package/src/commands/faq-review.ts +0 -426
  105. package/src/commands/front/index.ts +0 -351
  106. package/src/commands/front/pull-conversations.ts +0 -275
  107. package/src/commands/front/tags.ts +0 -825
  108. package/src/commands/front-cache.ts +0 -1277
  109. package/src/commands/front-stats.ts +0 -75
  110. package/src/commands/health.test.ts +0 -82
  111. package/src/commands/health.ts +0 -362
  112. package/src/commands/init.test.ts +0 -89
  113. package/src/commands/init.ts +0 -106
  114. package/src/commands/inngest/client.ts +0 -294
  115. package/src/commands/inngest/events.ts +0 -296
  116. package/src/commands/inngest/investigate.ts +0 -382
  117. package/src/commands/inngest/runs.ts +0 -149
  118. package/src/commands/inngest/signal.ts +0 -143
  119. package/src/commands/kb-sync.ts +0 -498
  120. package/src/commands/memory/find.ts +0 -135
  121. package/src/commands/memory/get.ts +0 -87
  122. package/src/commands/memory/index.ts +0 -97
  123. package/src/commands/memory/stats.ts +0 -163
  124. package/src/commands/memory/store.ts +0 -49
  125. package/src/commands/memory/vote.ts +0 -159
  126. package/src/commands/pipeline.ts +0 -127
  127. package/src/commands/responses.ts +0 -856
  128. package/src/commands/tools.ts +0 -293
  129. package/src/commands/wizard.ts +0 -319
  130. package/src/index.ts +0 -172
  131. package/src/lib/crypto.ts +0 -56
  132. package/src/lib/env-loader.ts +0 -206
  133. package/src/lib/onepassword.ts +0 -137
  134. package/src/test-agent-local.ts +0 -115
  135. package/tsconfig.json +0 -11
  136. package/vitest.config.ts +0 -10
@@ -1,492 +0,0 @@
1
- /**
2
- * Real tool implementations for eval-pipeline CLI
3
- *
4
- * Unlike mock tools, these actually hit Docker MySQL and Qdrant
5
- * for production-like eval behavior.
6
- */
7
-
8
- import {
9
- type OllamaClient,
10
- createOllamaClient,
11
- } from '@skillrecordings/core/adapters/ollama'
12
- import {
13
- type QdrantClient,
14
- createQdrantClient,
15
- } from '@skillrecordings/core/adapters/qdrant'
16
- import { tool } from 'ai'
17
- import type { Pool } from 'mysql2/promise'
18
- import { createPool } from 'mysql2/promise'
19
- import { z } from 'zod'
20
-
21
- let mysqlPool: Pool | null = null
22
- let qdrantClient: QdrantClient | null = null
23
- let ollamaClient: OllamaClient | null = null
24
-
25
- export interface RealToolsConfig {
26
- mysql?: {
27
- host: string
28
- port: number
29
- user: string
30
- password: string
31
- database: string
32
- }
33
- qdrant?: {
34
- url: string
35
- collection: string
36
- }
37
- ollama?: {
38
- url: string
39
- model: string
40
- }
41
- }
42
-
43
- const DEFAULT_CONFIG: RealToolsConfig = {
44
- mysql: {
45
- host: process.env.MYSQL_HOST || 'localhost',
46
- port: parseInt(process.env.MYSQL_PORT || '3306', 10),
47
- user: process.env.MYSQL_USER || 'eval_user',
48
- password: process.env.MYSQL_PASSWORD || 'eval_pass',
49
- database: process.env.MYSQL_DATABASE || 'support_eval',
50
- },
51
- qdrant: {
52
- url: process.env.QDRANT_URL || 'http://localhost:6333',
53
- collection: process.env.QDRANT_COLLECTION || 'support_eval',
54
- },
55
- ollama: {
56
- url: process.env.OLLAMA_BASE_URL || 'http://localhost:11434',
57
- model: process.env.EMBEDDING_MODEL || 'nomic-embed-text',
58
- },
59
- }
60
-
61
- /**
62
- * Initialize connections to Docker services
63
- */
64
- export async function initRealTools(
65
- config: RealToolsConfig = DEFAULT_CONFIG,
66
- verbose = false
67
- ): Promise<{ mysql: boolean; qdrant: boolean; ollama: boolean }> {
68
- const status = { mysql: false, qdrant: false, ollama: false }
69
-
70
- // MySQL
71
- if (config.mysql) {
72
- try {
73
- mysqlPool = createPool({
74
- ...config.mysql,
75
- waitForConnections: true,
76
- connectionLimit: 5,
77
- })
78
- const conn = await mysqlPool.getConnection()
79
- await conn.ping()
80
- conn.release()
81
- status.mysql = true
82
- if (verbose) console.log(' ✅ MySQL connected')
83
- } catch (error) {
84
- if (verbose)
85
- console.log(
86
- ` ❌ MySQL: ${error instanceof Error ? error.message : 'failed'}`
87
- )
88
- }
89
- }
90
-
91
- // Qdrant
92
- if (config.qdrant) {
93
- try {
94
- qdrantClient = createQdrantClient()
95
- const info = await qdrantClient.getCollectionInfo()
96
- status.qdrant = info.status !== 'not_found'
97
- if (verbose)
98
- console.log(` ✅ Qdrant connected (${info.pointsCount} points)`)
99
- } catch (error) {
100
- if (verbose)
101
- console.log(
102
- ` ❌ Qdrant: ${error instanceof Error ? error.message : 'failed'}`
103
- )
104
- }
105
- }
106
-
107
- // Ollama (for embeddings)
108
- if (config.ollama) {
109
- try {
110
- ollamaClient = createOllamaClient()
111
- const healthy = await ollamaClient.healthCheck()
112
- if (healthy) {
113
- const available = await ollamaClient.isModelAvailable()
114
- if (available) {
115
- status.ollama = true
116
- if (verbose) console.log(' ✅ Ollama connected')
117
- } else {
118
- if (verbose) console.log(' ⚠️ Ollama healthy but model not available')
119
- }
120
- }
121
- } catch (error) {
122
- if (verbose)
123
- console.log(
124
- ` ❌ Ollama: ${error instanceof Error ? error.message : 'failed'}`
125
- )
126
- }
127
- }
128
-
129
- return status
130
- }
131
-
132
- /**
133
- * Clean up connections
134
- */
135
- export async function cleanupRealTools(): Promise<void> {
136
- if (mysqlPool) {
137
- await mysqlPool.end()
138
- mysqlPool = null
139
- }
140
- qdrantClient = null
141
- ollamaClient = null
142
- }
143
-
144
- /**
145
- * Get embedding for text using Ollama
146
- */
147
- async function embed(text: string): Promise<number[]> {
148
- if (!ollamaClient) {
149
- throw new Error('Ollama client not initialized')
150
- }
151
- return ollamaClient.embed(text)
152
- }
153
-
154
- /**
155
- * Create real tools that query Docker services
156
- */
157
- export function createRealTools(scenario: {
158
- appId?: string
159
- customerEmail?: string
160
- }) {
161
- const appId = scenario.appId || 'total-typescript'
162
- const customerEmail = scenario.customerEmail || '[EMAIL]'
163
-
164
- return {
165
- lookupUser: tool({
166
- description: 'Look up user by email in the product database',
167
- inputSchema: z.object({
168
- email: z.string().describe('Customer email address'),
169
- appId: z.string().describe('App/product identifier'),
170
- }),
171
- execute: async ({ email, appId: queryAppId }) => {
172
- if (!mysqlPool) {
173
- return { found: false, error: 'MySQL not connected' }
174
- }
175
-
176
- try {
177
- // Look up customer in conversations table
178
- const [convRows] = (await mysqlPool.query(
179
- `SELECT DISTINCT customer_email, customer_name
180
- FROM SUPPORT_conversations
181
- WHERE customer_email = ? AND (app_id = ? OR app_id IS NULL)
182
- LIMIT 1`,
183
- [email, queryAppId]
184
- )) as any[]
185
-
186
- if (convRows.length > 0) {
187
- return {
188
- found: true,
189
- user: {
190
- id: `user_${email.split('@')[0]}`,
191
- email: convRows[0].customer_email,
192
- name: convRows[0].customer_name || 'Customer',
193
- },
194
- purchases: [
195
- {
196
- id: `purch_${Date.now()}`,
197
- product:
198
- queryAppId === 'ai-hero'
199
- ? 'AI Hero Workshop'
200
- : 'Total TypeScript',
201
- date: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
202
- .toISOString()
203
- .split('T')[0],
204
- status: 'active',
205
- },
206
- ],
207
- }
208
- }
209
-
210
- return {
211
- found: false,
212
- user: null,
213
- purchases: [],
214
- }
215
- } catch (error) {
216
- console.error('lookupUser error:', error)
217
- return { found: false, error: String(error) }
218
- }
219
- },
220
- }),
221
-
222
- searchKnowledge: tool({
223
- description: 'Search the knowledge base for relevant information',
224
- inputSchema: z.object({
225
- query: z.string().describe('Search query'),
226
- appId: z.string().describe('App/product identifier'),
227
- }),
228
- execute: async ({ query, appId: queryAppId }) => {
229
- if (!qdrantClient || !ollamaClient) {
230
- return { similarTickets: [], knowledge: [], goodResponses: [] }
231
- }
232
-
233
- try {
234
- const queryVector = await embed(query)
235
-
236
- // Search with app filter
237
- const results = await qdrantClient.search(queryVector, 5, {
238
- should: [
239
- { key: 'app', match: { value: queryAppId } },
240
- { key: 'app', match: { value: 'general' } },
241
- ],
242
- })
243
-
244
- return {
245
- similarTickets: results
246
- .filter((r) => r.payload?.type === 'ticket')
247
- .map((r) => ({
248
- data: r.payload?.content as string,
249
- score: r.score,
250
- })),
251
- knowledge: results
252
- .filter(
253
- (r) =>
254
- r.payload?.type === 'knowledge' ||
255
- r.payload?.type === 'general' ||
256
- r.payload?.type === 'faq'
257
- )
258
- .map((r) => ({
259
- data: r.payload?.content as string,
260
- score: r.score,
261
- })),
262
- goodResponses: results
263
- .filter((r) => r.payload?.type === 'response')
264
- .map((r) => ({
265
- data: r.payload?.content as string,
266
- score: r.score,
267
- })),
268
- }
269
- } catch (error) {
270
- console.error('searchKnowledge error:', error)
271
- return { similarTickets: [], knowledge: [], goodResponses: [] }
272
- }
273
- },
274
- }),
275
-
276
- searchProductContent: tool({
277
- description: 'Search product content (courses, tutorials, etc)',
278
- inputSchema: z.object({
279
- query: z.string().describe('Search query'),
280
- }),
281
- execute: async ({ query }) => {
282
- if (!qdrantClient || !ollamaClient) {
283
- return { results: [] }
284
- }
285
-
286
- try {
287
- const queryVector = await embed(query)
288
- const results = await qdrantClient.search(queryVector, 3)
289
-
290
- return {
291
- results: results
292
- .filter((r) => r.payload?.type === 'content')
293
- .map((r) => ({
294
- title: r.payload?.title as string,
295
- type: (r.payload?.content_type as string) || 'course',
296
- url: r.payload?.url as string,
297
- })),
298
- }
299
- } catch {
300
- return { results: [] }
301
- }
302
- },
303
- }),
304
-
305
- draftResponse: tool({
306
- description: 'Draft a response to send to the customer',
307
- inputSchema: z.object({
308
- body: z.string().describe('The response body to draft'),
309
- }),
310
- execute: async ({ body }) => {
311
- return { drafted: true, body }
312
- },
313
- }),
314
-
315
- escalateToHuman: tool({
316
- description: 'Escalate the conversation to human support',
317
- inputSchema: z.object({
318
- reason: z.string().describe('Reason for escalation'),
319
- urgency: z.enum(['low', 'medium', 'high']).describe('Urgency level'),
320
- }),
321
- execute: async ({ reason, urgency }) => {
322
- return { escalated: true, reason, urgency }
323
- },
324
- }),
325
-
326
- assignToInstructor: tool({
327
- description:
328
- 'Assign conversation to instructor for personal correspondence',
329
- inputSchema: z.object({
330
- conversationId: z.string(),
331
- reason: z.string(),
332
- }),
333
- execute: async ({ conversationId, reason }) => ({
334
- status: 'pending_approval',
335
- conversationId,
336
- reason,
337
- message: 'Instructor assignment submitted for approval',
338
- }),
339
- }),
340
-
341
- processRefund: tool({
342
- description: 'Process a refund for a purchase',
343
- inputSchema: z.object({
344
- purchaseId: z.string(),
345
- appId: z.string(),
346
- reason: z.string(),
347
- }),
348
- execute: async ({ purchaseId, reason }) => ({
349
- status: 'pending_approval',
350
- purchaseId,
351
- reason,
352
- message: 'Refund submitted for approval',
353
- }),
354
- }),
355
-
356
- transferPurchase: tool({
357
- description: 'Transfer purchase to another email',
358
- inputSchema: z.object({
359
- purchaseId: z.string(),
360
- appId: z.string(),
361
- fromUserId: z.string(),
362
- toEmail: z.string(),
363
- reason: z.string(),
364
- }),
365
- execute: async () => ({
366
- status: 'pending_approval',
367
- message: 'Transfer submitted for approval',
368
- }),
369
- }),
370
-
371
- getPaymentHistory: tool({
372
- description: 'Get payment history from Stripe',
373
- inputSchema: z.object({
374
- customerEmail: z.string(),
375
- limit: z.number().optional(),
376
- }),
377
- execute: async ({ customerEmail: email }) => {
378
- if (!mysqlPool) {
379
- return { charges: [] }
380
- }
381
-
382
- try {
383
- const [rows] = (await mysqlPool.query(
384
- `SELECT 1 FROM SUPPORT_conversations WHERE customer_email = ? LIMIT 1`,
385
- [email]
386
- )) as any[]
387
-
388
- if (rows.length > 0) {
389
- return {
390
- charges: [
391
- {
392
- id: `ch_eval_${Date.now()}`,
393
- amount: 24900,
394
- status: 'succeeded',
395
- created: Date.now() - 7 * 24 * 60 * 60 * 1000,
396
- },
397
- ],
398
- }
399
- }
400
-
401
- return { charges: [] }
402
- } catch {
403
- return { charges: [] }
404
- }
405
- },
406
- }),
407
-
408
- check_product_availability: tool({
409
- description: 'Check if product is available or sold out',
410
- inputSchema: z.object({
411
- productId: z.string().optional(),
412
- appId: z.string(),
413
- }),
414
- execute: async () => ({
415
- soldOut: false,
416
- quantityRemaining: -1,
417
- enrollmentOpen: true,
418
- }),
419
- }),
420
-
421
- memory_search: tool({
422
- description: 'Search semantic memory',
423
- inputSchema: z.object({ query: z.string() }),
424
- execute: async () => ({ results: [], total: 0 }),
425
- }),
426
-
427
- memory_store: tool({
428
- description: 'Store learning in memory',
429
- inputSchema: z.object({
430
- content: z.string(),
431
- tags: z.array(z.string()).optional(),
432
- }),
433
- execute: async () => ({ stored: true, id: 'mem_eval_1' }),
434
- }),
435
-
436
- memory_vote: tool({
437
- description: 'Vote on memory usefulness',
438
- inputSchema: z.object({
439
- memoryId: z.string(),
440
- vote: z.enum(['up', 'down']),
441
- }),
442
- execute: async () => ({ success: true }),
443
- }),
444
-
445
- memory_cite: tool({
446
- description: 'Cite a memory as used',
447
- inputSchema: z.object({ memoryId: z.string() }),
448
- execute: async () => ({ cited: true }),
449
- }),
450
-
451
- getSubscriptionStatus: tool({
452
- description: 'Get subscription status',
453
- inputSchema: z.object({
454
- customerId: z.string(),
455
- stripeAccountId: z.string(),
456
- }),
457
- execute: async () => ({ subscription: null }),
458
- }),
459
-
460
- lookupCharge: tool({
461
- description: 'Look up specific charge',
462
- inputSchema: z.object({ chargeId: z.string() }),
463
- execute: async ({ chargeId }) => ({
464
- charge: {
465
- id: chargeId,
466
- amount: 24900,
467
- status: 'succeeded',
468
- refunded: false,
469
- },
470
- }),
471
- }),
472
-
473
- verifyRefund: tool({
474
- description: 'Verify refund status',
475
- inputSchema: z.object({ refundId: z.string() }),
476
- execute: async ({ refundId }) => ({
477
- refund: {
478
- id: refundId,
479
- status: 'succeeded',
480
- amount: 24900,
481
- },
482
- }),
483
- }),
484
- }
485
- }
486
-
487
- /**
488
- * Check if real tools are available
489
- */
490
- export function isRealToolsAvailable(): boolean {
491
- return mysqlPool !== null && qdrantClient !== null
492
- }