@n1k1t/pipelain 0.1.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 (2) hide show
  1. package/README.md +575 -0
  2. package/package.json +113 -0
package/README.md ADDED
@@ -0,0 +1,575 @@
1
+ <div align='center'>
2
+ <h1>PipelAIn</h1>
3
+ <p>Type-safe AI-powered execution pipelines</p>
4
+
5
+ <img src="https://raw.githubusercontent.com/n1k1t/pipelain/refs/heads/master/images/preview.png?raw=true" />
6
+
7
+ <br />
8
+ <br />
9
+
10
+ ![License](https://img.shields.io/badge/License-MIT-yellow.svg)
11
+ ![npm version](https://badge.fury.io/js/@n1k1t%2Fpipelain.svg)
12
+ ![Dynamic XML Badge](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fgithub.com%2Fn1k1t%2Fpipelain%2Fblob%2Fmaster%2Fcoverage%2Fcobertura-coverage.xml%3Fraw%3Dtrue&query=round(%2Fcoverage%2F%40line-rate%20*%201000)%20div%201000&label=coverage)
13
+ </div>
14
+
15
+ Powerful utility to build and execute type-safe AI pipelines with structured outputs and tool integration.
16
+
17
+ - [Features](#features)
18
+ - [Installation](#installation)
19
+ - [First Steps](#first-steps)
20
+ - [Simple Example](#simple-example)
21
+ - [Environment Variables](#environment-variables)
22
+ - [Pipeline Step Utilities](#pipeline-step-utilities)
23
+ - [factory](#factory)
24
+ - [utils](#utils)
25
+ - [context](#context)
26
+ - [utils.content (ContentFactory)](#utilscontent-contentfactory)
27
+ - [factory.tools (LlmToolsFactory)](#factorytools-llmtoolsfactory)
28
+ - [factory.skills (LlmSkillsFactory)](#factoryskills-llmskillsfactory)
29
+ - [Usage](#usage)
30
+ - [Logging and Events](#logging-and-events)
31
+ - [Structured Prompt Content](#structured-prompt-content)
32
+ - [AI Step with LLM Configuration](#ai-step-with-llm-configuration)
33
+ - [Debugging AI Steps](#debugging-ai-steps)
34
+ - [Combining self and ai Steps](#combining-self-and-ai-steps)
35
+ - [Parallel Execution with swarm](#parallel-execution-with-swarm)
36
+ - [Iterative Execution with loop](#iterative-execution-with-loop)
37
+ - [Multi-Provider Pipelines](#multi-provider-pipelines)
38
+ - [MCP (Model Context Protocol) Integration](#mcp-model-context-protocol-integration)
39
+ - [Using Skills](#using-skills)
40
+ - [Extensions](#extensions)
41
+ - [Custom LLM Tools](#custom-llm-tools)
42
+ - [Custom LLM Skills](#custom-llm-skills)
43
+ - [Registering Skills from Markdown](#registering-skills-from-markdown)
44
+ - [License](#license)
45
+
46
+ ## Features
47
+
48
+ - **Type-safe**: Built with TypeScript and Zod for full type safety of inputs, outputs, and intermediate states.
49
+ - **Structured Outputs**: Enforce AI responses to match specific Zod schemas.
50
+ - **Tool Integration**: Easily provide tools (web search, file system, etc.) to the AI.
51
+ - **Step-by-step Execution**: Define complex workflows as a series of steps.
52
+ - **Context-aware**: Shared context and state across all pipeline steps.
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ npm install @n1k1t/pipelain zod
58
+ ```
59
+
60
+ ## First Steps
61
+
62
+ To use the library, you need to provide an API key for the LLM provider. Create a `.env` file in your project root and add your key:
63
+
64
+ ```env
65
+ PIPELAIN_API_KEY=your_api_key_here
66
+ ```
67
+
68
+ ## Simple Example
69
+
70
+ A basic pipeline that translates text and returns a structured response:
71
+
72
+ ```ts
73
+ import z from 'zod/v3';
74
+ import { PipelineCompiler } from '@n1k1t/pipelain';
75
+
76
+ const translate = PipelineCompiler
77
+ .build('Translator')
78
+ .input(z.string())
79
+ .step('translated', ({ factory, context }) => factory
80
+ .ai('Translating')
81
+ .schema(z.object({
82
+ ru: z.string().describe('Russian translation'),
83
+ es: z.string().describe('Spanish translation'),
84
+ en: z.string().describe('English translation'),
85
+ }))
86
+ .prompt([
87
+ `Translate this text to Russian, Spanish and English: ${context.input}`,
88
+ ])
89
+ );
90
+
91
+ (async () => {
92
+ const compiled = await translate.compile();
93
+ const result = await compiled.run('Hello');
94
+
95
+ console.log(result.translated.es); // Hola
96
+ })();
97
+ ```
98
+
99
+ ## Environment Variables
100
+
101
+ The following environment variables are supported:
102
+
103
+ | Variable | Description | Default |
104
+ | --- | --- | --- |
105
+ | `PIPELAIN_API_KEY` | API key for the LLM provider. | - |
106
+ | `PIPELAIN_API_URL` | Custom API URL for the LLM provider. | - |
107
+ | `PIPELAIN_SKILLS_DIR` | Directory path where LLM skills are stored. | `~/.agents/skills` |
108
+ | `PIPELAIN_MODEL` | Default LLM model to use. | `gemini-flash-latest` |
109
+ | `PIPELAIN_PROVIDER` | LLM provider name (e.g., `google`, `openai`). | - |
110
+
111
+ ## Pipeline Step Utilities
112
+
113
+ Each pipeline step receives a set of utilities to interact with the environment, AI, and context.
114
+
115
+ ### `factory`
116
+ Used to create different types of steps:
117
+ - `ai(description?)`: Creates a step that executes on the AI side.
118
+ - `self(description?)`: Creates a step that executes on the local machine.
119
+ - `swarm(description?)`: Executes multiple steps or pipelines in parallel.
120
+ - `loop(description?)`: Creates a loop of steps.
121
+ - `tools`: Access to LLM tools factory (e.g., `factory.tools.web()`).
122
+ - `skills`: Access to LLM skills factory (e.g., `factory.skills.all()`).
123
+
124
+ ### `utils`
125
+ General-purpose utilities:
126
+ - `content`: `ContentFactory` instance to create structured prompt content (articles, tasks, rules, attachments).
127
+ - `bash`: Execute shell commands on the local machine.
128
+ - `log`: Emit log events for the current pipeline session.
129
+
130
+ ### `context`
131
+ Shared state and configuration:
132
+ - `input`: The input data provided to the pipeline.
133
+ - `state`: Shared state across all steps.
134
+ - `llm`: Current LLM provider configuration.
135
+ - `project`: Information about the current project.
136
+
137
+ ### `utils.content` (ContentFactory)
138
+ Used to create structured prompt content. These methods are available via `utils.content` in pipeline steps.
139
+
140
+ | Method | Description | Example |
141
+ | --- | --- | --- |
142
+ | `article(title, content)` | Creates a `## Title` section with nested markdown content. | `utils.content.article('Context', [{ p: 'Some text' }])` |
143
+ | `rules(list)` | Creates a bulleted list of rules/constraints. | `utils.content.rules(['Use JSON', 'Be concise'])` |
144
+ | `tasks(list)` | Creates a numbered list of tasks for the AI. | `utils.content.tasks(['Analyze data', 'Write summary'])` |
145
+ | `sources(list)` | Creates a list of source links. | `utils.content.sources(['https://google.com'])` |
146
+ | `attachment(title, payload)` | Attaches data (object, string) as a file-like block. | `utils.content.attachment('Data', { content: { id: 1 } })` |
147
+ | `file(title, path)` | Reads a local file and attaches it as context. | `await utils.content.file('Config', 'package.json')` |
148
+ | `glob(title, pattern)` | Reads multiple files by pattern and attaches them. | `await utils.content.glob('Source', 'src/**/*.ts')` |
149
+ | `plain(text)` | Adds raw markdown text. | `utils.content.plain('### Subtitle\nText')` |
150
+
151
+ ### `factory.tools` (LlmToolsFactory)
152
+ Used to provide tools to the AI. These methods are available via `factory.tools` in pipeline steps.
153
+
154
+ | Method | Description | Included Tools |
155
+ | --- | --- | --- |
156
+ | `web()` | Tools for web interaction. | `search`, `fetch` |
157
+ | `files('read')` | Read-only file system tools. | `read`, `grep`, `glob`, `ls` |
158
+ | `files('read-write')` | Read and write file system tools. | `read`, `grep`, `glob`, `ls`, `mkdir`, `write`, `edit`, `rm` |
159
+ | `commands(['npm', 'npx'])` | Package manager tools. | `npm`, `npx` |
160
+ | `all()` | Includes all available tools. | All of the above |
161
+ | `custom(tools)` | Includes custom tool implementations. | - |
162
+ | `all()` | Includes all available tools. | All of the above |
163
+
164
+ ### `factory.skills` (LlmSkillsFactory)
165
+ Used to provide domain-specific instructions and workflows to the AI. These methods are available via `factory.skills` in pipeline steps.
166
+
167
+ | Method | Description |
168
+ | --- | --- |
169
+ | `all()` | Includes all registered skills. |
170
+ | `match(pattern)` | Includes skills matching a minimatch pattern. |
171
+ | `register(raw)` | Registers a new skill from raw markdown content (with frontmatter). |
172
+ | `custom(skills)` | Includes custom skill objects. |
173
+ | `provide()` | Returns the list of included skills for LLM configuration. |
174
+
175
+ ---
176
+
177
+ ## Usage
178
+
179
+ ### Logging and Events
180
+
181
+ You can use `stdout.console` to output pipeline progress and logs to `stdout`:
182
+
183
+ ```ts
184
+ import { stdout } from '@n1k1t/pipelain';
185
+
186
+ (async () => {
187
+ const compiled = await translate.compile({ stdout: stdout.console });
188
+ await compiled.run('Hello');
189
+ })();
190
+ ```
191
+
192
+ To use a custom logger or override specific event handlers, use `PipelineStdout`:
193
+
194
+ ```ts
195
+ import { PipelineStdout } from '@n1k1t/pipelain';
196
+
197
+ const customStdout = PipelineStdout
198
+ .build(console) // Pass any logger with .info and .warn methods
199
+ .override('log', (event) => {
200
+ console.log(`[CUSTOM LOG] ${event.message}`);
201
+ })
202
+ .override('step:run', (event) => {
203
+ if (event.meta.state === 'SUCCESS') {
204
+ console.log(`Step ${event.step.title} finished in ${event.meta.spent}ms`);
205
+ }
206
+ });
207
+
208
+ (async () => {
209
+ const compiled = await translate.compile({ stdout: customStdout });
210
+ await compiled.run('Hello');
211
+ })();
212
+ ```
213
+
214
+ ### Structured Prompt Content
215
+
216
+ You can combine multiple content types to create a rich, structured prompt for the AI:
217
+
218
+ ```ts
219
+ .step('complex_task', async ({ factory, utils, context }) => factory
220
+ .ai('Complex Processing')
221
+ .prompt([
222
+ // 1. Global rules for the AI
223
+ utils.content.rules([
224
+ 'Use professional tone',
225
+ 'Output must be valid JSON'
226
+ ]),
227
+
228
+ // 2. Structured article with nested content
229
+ utils.content.article('Project Overview', [
230
+ { p: 'This project is a type-safe pipeline builder.' },
231
+ { h2: 'Key Goals' },
232
+ { ul: ['Safety', 'Performance', 'Flexibility'] }
233
+ ]),
234
+
235
+ // 3. Attachments (data or files)
236
+ utils.content.attachment('User Data', {
237
+ content: { id: 1, name: 'John Doe' }
238
+ }),
239
+
240
+ // 4. Local files and glob patterns
241
+ await utils.content.file('Package Info', 'package.json'),
242
+ await utils.content.glob('Source Code', 'src/utils/*.ts'),
243
+
244
+ // 5. External sources
245
+ utils.content.sources(['https://github.com/n1k1t/pipelain']),
246
+
247
+ // 6. Raw markdown
248
+ utils.content.plain('> Note: This is a critical task.'),
249
+
250
+ // 7. Specific tasks for the AI to complete
251
+ utils.content.tasks([
252
+ 'Review the `Project Overview` article',
253
+ 'Analyze `User Data` and `Source Code`',
254
+ 'Generate a summary based on the rules'
255
+ ])
256
+ ])
257
+ )
258
+ ```
259
+
260
+ ### AI Step with LLM Configuration
261
+
262
+ You can customize the LLM behavior for a specific step, such as changing the temperature or providing tools. You can also restrict file tools to specific paths using `allowed` patterns:
263
+
264
+ ```ts
265
+ .step('research', ({ factory, context, utils }) => factory
266
+ .ai('Researching')
267
+ .llm(({ context }) => context.llm.assign({
268
+ temperature: 0.7,
269
+ limit: 10, // Max tool execution attempts
270
+ tools: factory.tools
271
+ .web()
272
+ .files('read-write', {
273
+ allowed: {
274
+ // Restrict 'write' tool to specific directory
275
+ write: ['src/generated/*.ts'],
276
+ // Restrict 'edit' tool to all TypeScript files
277
+ edit: ['src/**/*.ts'],
278
+ // Restrict 'rm' tool to temporary files
279
+ rm: ['temp/**/*']
280
+ }
281
+ })
282
+ .provide(),
283
+ }))
284
+ .schema(z.object({
285
+ summary: z.string(),
286
+ links: z.array(z.string())
287
+ }))
288
+ .prompt([
289
+ utils.content.tasks([
290
+ `Find information about: ${context.input}`,
291
+ 'Summarize findings and provide source links'
292
+ ])
293
+ ])
294
+ )
295
+ ```
296
+
297
+ ### Debugging AI Steps
298
+
299
+ You can use the `.debug()` method to inspect the prompts sent to the AI. When debug mode is enabled, the step will mock the AI response and save the generated prompt into a markdown file in the `.pipelain` directory:
300
+
301
+ ```ts
302
+ .step('debug_example', ({ factory }) => factory
303
+ .ai('Debugging Step')
304
+ .debug() // Enables debug mode for this step
305
+ .schema(z.object({ result: z.string() }))
306
+ .prompt(['Analyze this complex data...'])
307
+ )
308
+ ```
309
+
310
+ The prompt will be saved to: `.pipelain/${timestamp}-${session-id}/${step-title}.md`.
311
+
312
+ ### Combining `self` and `ai` Steps
313
+
314
+ You can use `self` steps to perform local computations, logging, or data transformation between AI steps:
315
+
316
+ ```ts
317
+ const pipeline = PipelineCompiler
318
+ .build('Data Processor')
319
+ .input(z.string())
320
+ .step('extracted', ({ factory, context }) => factory
321
+ .ai('Extracting data')
322
+ .schema(z.object({
323
+ items: z.array(z.string())
324
+ }))
325
+ .prompt([`Extract items from: ${context.input}`])
326
+ )
327
+ // Local step to process data or log progress
328
+ .step(({ context, utils }) => {
329
+ utils.log(`Extracted ${context.state.extracted.items.length} items`);
330
+
331
+ // You can also modify the state or context here
332
+ context.merge({
333
+ state: {
334
+ processedCount: context.state.extracted.items.length
335
+ }
336
+ });
337
+ })
338
+ .step('summary', ({ factory, context }) => factory
339
+ .ai('Summarizing')
340
+ .schema(z.object({ text: z.string() }))
341
+ .prompt([
342
+ `Summarize these ${context.state.processedCount} items:`,
343
+ context.state.extracted.items.join(', ')
344
+ ])
345
+ );
346
+ ```
347
+
348
+ ### Parallel Execution with `swarm`
349
+
350
+ Use `swarm` to execute multiple AI tasks in parallel. You can define subtasks using the `subtasks` method:
351
+
352
+ ```ts
353
+ .step('analysis', ({ factory }) => factory
354
+ .swarm('Parallel Analysis')
355
+ .subtasks([
356
+ factory
357
+ .ai('Sentiment Analysis')
358
+ .schema(z.object({ score: z.number() }))
359
+ .prompt(({ context }) => [`Analyze sentiment of: ${context.input}`]),
360
+
361
+ factory
362
+ .ai('Keyword Extraction')
363
+ .schema(z.object({ tags: z.array(z.string()) }))
364
+ .prompt(({ context }) => [`Extract keywords from: ${context.input}`]),
365
+ ])
366
+ .limit(2) // Optional: limit parallel executions
367
+ )
368
+ // Results will be available in context.state.analysis as an array of PromiseSettledResult
369
+ ```
370
+
371
+ ### Iterative Execution with `loop`
372
+
373
+ Use `loop` for tasks that require multiple iterations or validation, such as self-correction:
374
+
375
+ ```ts
376
+ .step('refined_answer', ({ factory }) => factory
377
+ .loop('Self-Correction Loop')
378
+ .limit(3) // Max 3 attempts
379
+ .action(({ factory, context, verdict }) => factory
380
+ .ai('Answering')
381
+ .schema(z.object({
382
+ answer: z.string(),
383
+ isCorrect: z.boolean().describe('Self-check result')
384
+ }))
385
+ .prompt([
386
+ `Question: ${context.input}`,
387
+ // If this is a retry, include previous feedback
388
+ verdict.status === 'pending' ? verdict.content : ''
389
+ ])
390
+ )
391
+ .condition(({ result }) => {
392
+ if (result.isCorrect) {
393
+ return { status: 'fulfilled' };
394
+ }
395
+
396
+ return {
397
+ status: 'pending',
398
+ content: 'Your previous answer was incorrect. Please try again and be more specific.'
399
+ };
400
+ })
401
+ )
402
+ // Result will contain { status: 'fulfilled' | 'voided', value: { answer, isCorrect } }
403
+ ```
404
+
405
+ ### Multi-Provider Pipelines
406
+
407
+ You can use different LLM providers for different steps in the same pipeline:
408
+
409
+ ```ts
410
+ import { PipelineCompiler, llm } from '@n1k1t/pipelain';
411
+
412
+ const pipeline = PipelineCompiler
413
+ .build('Multi-Provider')
414
+ .input(z.string())
415
+ .step('initial_analysis', ({ factory }) => factory
416
+ .ai('Google Analysis')
417
+ .llm(() => llm.providers.LlmGoogleProvider.build('gemini-1.5-flash', {
418
+ connection: { key: process.env.GOOGLE_API_KEY! }
419
+ }))
420
+ .prompt(({ context }) => [`Analyze this: ${context.input}`])
421
+ )
422
+ .step('final_summary', ({ factory }) => factory
423
+ .ai('Anthropic Summary')
424
+ .llm(() => llm.providers.LlmAnthropicProvider.build('claude-3-5-sonnet-20240620', {
425
+ connection: { key: process.env.ANTHROPIC_API_KEY! }
426
+ }))
427
+ .prompt(({ context }) => [
428
+ `Summarize the analysis: ${context.state.initial_analysis}`
429
+ ])
430
+ );
431
+ ```
432
+
433
+ ### MCP (Model Context Protocol) Integration
434
+
435
+ You can integrate MCP servers into your pipeline steps. This allows the AI to use tools provided by external MCP servers. You can also filter which tools are enabled:
436
+
437
+ ```ts
438
+ import { LlmMcp } from '@n1k1t/pipelain';
439
+
440
+ pipeline.step('mcp_research', ({ factory, context }) => factory
441
+ .ai('Researching with MCP')
442
+ .llm(({ context }) => context.llm.assign({
443
+ mcp: [
444
+ LlmMcp.build({
445
+ transport: {
446
+ type: 'stdio',
447
+ command: 'npx',
448
+ args: ['-y', '@modelcontextprotocol/server-gdrive'],
449
+ },
450
+ tools: {
451
+ // Enable only specific tools using names or minimatch patterns
452
+ enabled: ['list-files', 'read-file'],
453
+ // Or disable specific tools
454
+ // disabled: ['delete-file'],
455
+ },
456
+ }),
457
+ ],
458
+ }))
459
+ .prompt(['List my recent files in Google Drive and summarize them.'])
460
+ );
461
+ ```
462
+
463
+ ### Using Skills
464
+
465
+ Skills allow you to inject reusable domain-specific instructions or workflows into your AI steps. You can manage them via `factory.skills`:
466
+
467
+ ```ts
468
+ .step('specialized_task', ({ factory, context }) => factory
469
+ .ai('Executing with skills')
470
+ .llm(({ context }) => context.llm.assign({
471
+ // Include all registered skills from PIPELAIN_SKILLS_DIR
472
+ skills: factory.skills.all().provide(),
473
+
474
+ // OR: Include only specific skills by pattern
475
+ // skills: factory.skills.match('coding-*').provide(),
476
+ }))
477
+ .prompt([
478
+ `Perform this task using available skills: ${context.input}`
479
+ ])
480
+ )
481
+ ```
482
+
483
+ ## Extensions
484
+
485
+ ### Custom LLM Tools
486
+
487
+ You can create custom tools for the AI using `LlmToolCompiler`. This allows the AI to interact with your own services or perform specialized tasks:
488
+
489
+ ```ts
490
+ import z from 'zod/v3';
491
+ import { LlmToolCompiler } from '@n1k1t/pipelain';
492
+
493
+ // 1. Define the tool
494
+ const weatherTool = LlmToolCompiler
495
+ .build('Get current weather for a location')
496
+ .input(z.object({
497
+ city: z.string().describe('The city name')
498
+ }))
499
+ .output(z.object({
500
+ temperature: z.number(),
501
+ condition: z.string()
502
+ }))
503
+ .execute(() => async ({ city }) => {
504
+ // Your implementation here
505
+ return { temperature: 22, condition: 'Sunny' };
506
+ });
507
+
508
+ // 2. Use it in a step
509
+ pipeline.step('weather_report', ({ factory, context }) => factory
510
+ .ai('Checking weather')
511
+ .llm(({ context }) => context.llm.assign({
512
+ tools: factory.tools
513
+ .web() // Include standard web tools
514
+ .custom({ weather: weatherTool }) // Add your custom tool
515
+ .provide()
516
+ }))
517
+ .prompt([`Check weather in ${context.input}`])
518
+ );
519
+ ```
520
+
521
+ ### Custom LLM Skills
522
+
523
+ You can also provide custom skills programmatically:
524
+
525
+ ```ts
526
+ pipeline.step('custom_skills', ({ factory, context }) => factory
527
+ .ai('Using custom skills')
528
+ .llm(({ context }) => context.llm.assign({
529
+ skills: factory.skills
530
+ // Provide custom skill objects
531
+ .custom([{
532
+ name: 'manual-skill',
533
+ description: 'Manually defined skill',
534
+ content: 'Manual skill content'
535
+ }])
536
+ .provide()
537
+ }))
538
+ .prompt(['...'])
539
+ );
540
+ ```
541
+
542
+ ### Registering Skills from Markdown
543
+
544
+ You can register new skills from raw markdown content (with frontmatter) using `LlmSkillsFactory`:
545
+
546
+ ```ts
547
+ import { LlmSkillsFactory } from '@n1k1t/pipelain';
548
+
549
+ const rawSkill = `---
550
+ name: custom-skill
551
+ description: A custom skill description
552
+ ---
553
+ Skill content goes here.`;
554
+
555
+ // 1. Create a skills factory (optionally with existing skills)
556
+ const skills = LlmSkillsFactory.build();
557
+
558
+ // 2. Register new skills from raw markdown
559
+ skills.register(rawSkill);
560
+
561
+ // 3. Use in a pipeline step
562
+ pipeline.step('specialized_task', ({ factory, context }) => factory
563
+ .ai('Executing with registered skill')
564
+ .llm(({ context }) => context.llm.assign({
565
+ skills: skills.all().provide(),
566
+ }))
567
+ .prompt(['...'])
568
+ );
569
+ ```
570
+
571
+ ---
572
+
573
+ ## License
574
+
575
+ MIT
package/package.json ADDED
@@ -0,0 +1,113 @@
1
+ {
2
+ "name": "@n1k1t/pipelain",
3
+ "version": "0.1.0",
4
+ "description": "Powerful utility to build and execute type-safe AI pipelines with structured outputs and tool integration",
5
+ "main": "lib/src/index.js",
6
+ "types": "lib/src/index.d.ts",
7
+ "scripts": {
8
+ "test": "NODE_ENV=test jest --silent",
9
+ "test:coverage": "NODE_ENV=test jest --coverage",
10
+ "start:dev:main": "npx ts-node -r ./src/opentelemetry.ts test/index.ts",
11
+ "start:dev:skill": "npx ts-node -r ./src/opentelemetry.ts test/skill.ts",
12
+ "build": "rm -rf lib && npx tsc",
13
+ "build:check": "npx tsc --noEmit",
14
+ "prepare": "husky",
15
+ "preversion": "npm run build:check && npm test",
16
+ "version": "git add -A .",
17
+ "postversion": "npm run build && git push && git push --tags"
18
+ },
19
+ "jest": {
20
+ "preset": "ts-jest",
21
+ "passWithNoTests": true,
22
+ "testEnvironment": "node",
23
+ "testMatch": [
24
+ "<rootDir>/src/**/*.spec.ts"
25
+ ],
26
+ "coverageReporters": [
27
+ "cobertura",
28
+ "text"
29
+ ],
30
+ "collectCoverageFrom": [
31
+ "<rootDir>/src/**/*.ts"
32
+ ],
33
+ "setupFilesAfterEnv": [
34
+ "jest-extended/all"
35
+ ],
36
+ "setupFiles": [],
37
+ "transform": {
38
+ ".+\\.ts?$": [
39
+ "ts-jest",
40
+ {
41
+ "isolatedModules": true
42
+ }
43
+ ]
44
+ }
45
+ },
46
+ "engines": {
47
+ "node": ">=20.16.0"
48
+ },
49
+ "keywords": [
50
+ "ai",
51
+ "pipeline",
52
+ "llm",
53
+ "type-safe",
54
+ "zod",
55
+ "structured-outputs",
56
+ "mcp",
57
+ "agents",
58
+ "automation",
59
+ "typescript"
60
+ ],
61
+ "homepage": "https://github.com/n1k1t/pipelain",
62
+ "author": "n1k1t",
63
+ "license": "MIT",
64
+ "devDependencies": {
65
+ "@langfuse/otel": "4.6.1",
66
+ "@n1k1t/unit-generator": "1.1.3",
67
+ "@opentelemetry/sdk-node": "0.213.0",
68
+ "@types/cheerio": "0.22.35",
69
+ "@types/commander": "2.12.2",
70
+ "@types/jest": "29.5.11",
71
+ "@types/jsdom": "28.0.1",
72
+ "@types/json2md": "1.5.4",
73
+ "@types/lodash": "4.14.184",
74
+ "@types/minimatch": "5.1.2",
75
+ "@types/node": "22.13.14",
76
+ "@types/proper-lockfile": "4.1.4",
77
+ "@types/turndown": "5.0.6",
78
+ "@types/uuid": "8.3.4",
79
+ "husky": "9.1.7",
80
+ "jest": "29.7.0",
81
+ "jest-extended": "4.0.2",
82
+ "ts-jest": "29.1.1",
83
+ "ts-node": "10.9.2",
84
+ "typescript": "5.7.2"
85
+ },
86
+ "dependencies": {
87
+ "@ai-sdk/anthropic": "3.0.48",
88
+ "@ai-sdk/google": "3.0.33",
89
+ "@ai-sdk/mcp": "1.0.43",
90
+ "@ai-sdk/mistral": "3.0.20",
91
+ "@ai-sdk/openai": "3.0.36",
92
+ "@ai-sdk/openai-compatible": "2.0.47",
93
+ "@ast-grep/napi": "0.42.0",
94
+ "ai": "6.0.103",
95
+ "colors": "1.4.0",
96
+ "commander": "9.4.0",
97
+ "dotenv": "16.4.7",
98
+ "fast-glob": "3.3.3",
99
+ "fast-xml-parser": "4.5.0",
100
+ "gray-matter": "4.0.3",
101
+ "json2md": "2.0.3",
102
+ "lodash": "4.17.21",
103
+ "minimatch": "5.1.0",
104
+ "proper-lockfile": "4.1.2",
105
+ "reflect-metadata": "0.2.1",
106
+ "string-argv": "0.3.2",
107
+ "turndown": "7.2.2",
108
+ "uuid": "9.0.0",
109
+ "yaml": "2.8.0",
110
+ "zocker": "3.0.0",
111
+ "zod": "4.3.6"
112
+ }
113
+ }