kbot iterator example: md-ast transformer

This commit is contained in:
lovebird 2025-04-07 17:23:02 +02:00
parent 1991695594
commit 181a655d94
39 changed files with 1912 additions and 35 deletions

View File

@ -0,0 +1,6 @@
/**
* Renders the given Markdown string in a Blessed terminal UI.
*
* @param markdownContent - The Markdown content to display.
*/
export declare function displayMarkdown(markdownContent: string): void;

View File

@ -0,0 +1,51 @@
// src/markdown-blessed.ts
import * as blessed from 'blessed';
import { marked } from 'marked';
/**
* Define a custom renderer where the `image` method
* uses Marked's new signature: image({ href, title, text }: Tokens.Image).
*/
const customRenderer = {
image({ href, title, text }) {
// Provide a textual placeholder instead of an actual image
return `\n[IMAGE: ${text || 'No Alt'}](${href || 'No Href'})\n`;
},
// (Optional) you can override other renderer methods here
};
// We tell Marked to use our custom renderer
// Alternatively, you can pass { renderer: customRenderer } directly to marked().
marked.use({ renderer: customRenderer });
/**
* Renders the given Markdown string in a Blessed terminal UI.
*
* @param markdownContent - The Markdown content to display.
*/
export function displayMarkdown(markdownContent) {
// 1) Create Blessed screen
const screen = blessed.screen({
smartCSR: true,
title: 'Markdown Example with Blessed'
});
// 2) Create a scrollable box for the text
const box = blessed.box({
parent: screen,
top: 'center',
left: 'center',
width: '100%',
height: '100%',
keys: true,
vi: true,
mouse: true,
border: 'none',
alwaysScroll: true,
scrollable: true
});
// 3) Parse the markdown into a string using our renderer
const parsedContent = marked(markdownContent);
// 4) Set the box content
box.setContent(parsedContent);
// 5) Focus and render
box.focus();
screen.render();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvcmVuZGVyZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMEJBQTBCO0FBRTFCLE9BQU8sS0FBSyxPQUFPLE1BQU0sU0FBUyxDQUFBO0FBQ2xDLE9BQU8sRUFBRSxNQUFNLEVBQVUsTUFBTSxRQUFRLENBQUE7QUFDdkM7OztHQUdHO0FBQ0gsTUFBTSxjQUFjLEdBQUc7SUFDckIsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQWdCO1FBQ3ZDLDJEQUEyRDtRQUMzRCxPQUFPLGFBQWEsSUFBSSxJQUFJLFFBQVEsS0FBSyxJQUFJLElBQUksU0FBUyxLQUFLLENBQUM7SUFDbEUsQ0FBQztJQUNELDBEQUEwRDtDQUMzRCxDQUFDO0FBRUYsNENBQTRDO0FBQzVDLGlGQUFpRjtBQUNqRixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7QUFFekM7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsZUFBdUI7SUFDckQsMkJBQTJCO0lBQzNCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDNUIsUUFBUSxFQUFFLElBQUk7UUFDZCxLQUFLLEVBQUUsK0JBQStCO0tBQ3ZDLENBQUMsQ0FBQztJQUVILDBDQUEwQztJQUMxQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3RCLE1BQU0sRUFBRSxNQUFNO1FBQ2QsR0FBRyxFQUFFLFFBQVE7UUFDYixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxNQUFNO1FBQ2IsTUFBTSxFQUFFLE1BQU07UUFDZCxJQUFJLEVBQUUsSUFBSTtRQUNWLEVBQUUsRUFBRSxJQUFJO1FBQ1IsS0FBSyxFQUFFLElBQUk7UUFDWCxNQUFNLEVBQUUsTUFBTTtRQUNkLFlBQVksRUFBRSxJQUFJO1FBQ2xCLFVBQVUsRUFBRSxJQUFJO0tBQ2pCLENBQUMsQ0FBQztJQUVILHlEQUF5RDtJQUN6RCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7SUFFOUMseUJBQXlCO0lBQ3pCLEdBQUcsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7SUFFOUIsc0JBQXNCO0lBQ3RCLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNaLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUVsQixDQUFDIn0=

View File

@ -0,0 +1 @@
export declare function markdownTransformExample(useCache?: boolean): Promise<any>;

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,3 @@
export * from './core/async-iterator-example.js';
export * from './core/iterator-factory-example.js';
export * from './core/iterator-markdown-example.js';

View File

@ -1,4 +1,5 @@
// Export examples
export * from './core/async-iterator-example.js';
export * from './core/iterator-factory-example.js';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXhhbXBsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0JBQWtCO0FBQ2xCLGNBQWMsa0NBQWtDLENBQUM7QUFDakQsY0FBYyxvQ0FBb0MsQ0FBQyJ9
export * from './core/iterator-markdown-example.js';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXhhbXBsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0JBQWtCO0FBQ2xCLGNBQWMsa0NBQWtDLENBQUM7QUFDakQsY0FBYyxvQ0FBb0MsQ0FBQztBQUNuRCxjQUFjLHFDQUFxQyxDQUFDIn0=

View File

@ -11,4 +11,4 @@ export * from './zod_schema.js';
export { E_OPENAI_MODEL } from './models/cache/openai-models.js';
export { E_OPENROUTER_MODEL } from './models/cache/openrouter-models.js';
export { E_OPENROUTER_MODEL_FREE } from './models/cache/openrouter-models-free.js';
export { IKBotTask } from '@polymech/ai-tools';
export type { IKBotTask } from '@polymech/ai-tools';

File diff suppressed because one or more lines are too long

4
packages/kbot/dist-in/merge.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
export declare const deepMerge: (target: string, source: any) => Promise<any>;
export declare const mergers: {
json: (target: string, source: any) => Promise<any>;
};

View File

@ -0,0 +1,30 @@
import { isString } from '@polymech/core/primitives';
import { sync as read } from '@polymech/fs/read';
import { logger } from './index.js';
import { deepmerge as merge } from 'deepmerge-ts';
export const deepMerge = async (target, source) => {
if (!isString(target) || !source) {
logger.error(`Invalid deepmerge parameters:`, target, source);
return source;
}
target = read(target, 'json') || [];
try {
source = isString(source) ? JSON.parse(source) : source;
}
catch (e) {
logger.error('Error parsing completion:', e);
return source;
}
try {
const ret = merge(target, source);
return JSON.stringify(ret, null, 2);
}
catch (error) {
logger.error('Error merging completion:', error);
}
return target;
};
export const mergers = {
json: deepMerge
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbWVyZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVuQyxPQUFPLEVBQUUsU0FBUyxJQUFJLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUNqRCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsS0FBSyxFQUFFLE1BQWMsRUFBRSxNQUFXLEVBQUUsRUFBRTtJQUMzRCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0IsTUFBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDN0QsT0FBTyxNQUFNLENBQUE7SUFDakIsQ0FBQztJQUNELE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBUSxJQUFJLEVBQUUsQ0FBQTtJQUMxQyxJQUFJLENBQUM7UUFDRCxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7SUFDM0QsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQzVDLE9BQU8sTUFBTSxDQUFBO0lBQ2pCLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ3ZDLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNwRCxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQyxDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUNwQjtJQUNJLElBQUksRUFBRSxTQUFTO0NBQ2xCLENBQUEifQ==

View File

@ -0,0 +1,2 @@
export declare enum E_OPENAI_MODEL_FREE {
}

View File

@ -0,0 +1,4 @@
export var E_OPENAI_MODEL_FREE;
(function (E_OPENAI_MODEL_FREE) {
})(E_OPENAI_MODEL_FREE || (E_OPENAI_MODEL_FREE = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLW1vZGVscy1mcmVlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVscy9jYWNoZS9vcGVuYWktbW9kZWxzLWZyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFOLElBQVksbUJBRVg7QUFGRCxXQUFZLG1CQUFtQjtBQUUvQixDQUFDLEVBRlcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQUU5QiJ9

View File

@ -0,0 +1,2 @@
export declare enum E_OPENAI_MODEL {
}

View File

@ -0,0 +1,4 @@
export var E_OPENAI_MODEL;
(function (E_OPENAI_MODEL) {
})(E_OPENAI_MODEL || (E_OPENAI_MODEL = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLW1vZGVscy10b29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2RlbHMvY2FjaGUvb3BlbmFpLW1vZGVscy10b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxjQUVYO0FBRkQsV0FBWSxjQUFjO0FBRTFCLENBQUMsRUFGVyxjQUFjLEtBQWQsY0FBYyxRQUV6QiJ9

View File

@ -0,0 +1,2 @@
export declare enum E_OPENROUTER_MODEL {
}

View File

@ -0,0 +1,4 @@
export var E_OPENROUTER_MODEL;
(function (E_OPENROUTER_MODEL) {
})(E_OPENROUTER_MODEL || (E_OPENROUTER_MODEL = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbnJvdXRlci1tb2RlbHMtdG9vbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9kZWxzL2NhY2hlL29wZW5yb3V0ZXItbW9kZWxzLXRvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUVYO0FBRkQsV0FBWSxrQkFBa0I7QUFFOUIsQ0FBQyxFQUZXLGtCQUFrQixLQUFsQixrQkFBa0IsUUFFN0IifQ==

View File

@ -0,0 +1,7 @@
import { TemplateProps, TemplateContext } from "./kbot-templates.js";
export interface Props extends TemplateProps {
context?: TemplateContext;
}
export declare const filter: (content: string, tpl?: string, opts?: Props) => Promise<any>;
export declare const template_filter: (text: string, template: string, context?: TemplateContext) => Promise<any>;
export declare const getFilterOptions: (content: string, template: any, opts?: Props) => any;

File diff suppressed because one or more lines are too long

1
packages/kbot/dist-in/splitter.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export declare const foo = 2;

View File

@ -0,0 +1,33 @@
export const foo = 2;
/*
import { Document } from "@langchain/core/documents";
import {
CharacterTextSplitter,
LatexTextSplitter,
MarkdownTextSplitter,
RecursiveCharacterTextSplitter,
TokenTextSplitter,
} from "@langchain/textsplitters"
/*
export const splitter_text = async (text: string, options: any) => {
const splitter = new CharacterTextSplitter({
separator: " ",
chunkSize: 7,
chunkOverlap: 3,
});
const output = await splitter.splitText(text);
}
export const splitter_md = async (text: string, options: any) => {
const splitter = new MarkdownTextSplitter({
chunkSize: 60,
chunkOverlap: 3,
});
const output = await splitter.splitText(text);
}
*/
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXR0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3BsaXR0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQTtBQUVwQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBOEJFIn0=

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,25 @@
import { describe, it, expect } from 'vitest';
import { flatten } from '../array';
describe('array utilities', () => {
describe('flatten', () => {
it('should handle undefined input', () => {
expect(flatten(undefined)).toEqual([]);
});
it('should handle string input', () => {
expect(flatten('a,b,c')).toEqual(['a', 'b', 'c']);
});
it('should handle array input', () => {
expect(flatten(['a', 'b,c'])).toEqual(['a', 'b', 'c']);
});
it('should filter out numbers and booleans', () => {
expect(flatten(['a', 'true', '123', 'b'])).toEqual(['a', 'b']);
});
it('should remove duplicates', () => {
expect(flatten('a,b,a,c,b')).toEqual(['a', 'b', 'c']);
});
it('should trim whitespace', () => {
expect(flatten([' a ', ' b , c '])).toEqual(['a', 'b', 'c']);
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXkudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9fX3Rlc3RzX18vYXJyYXkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUVsQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO0lBQy9CLFFBQVEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7WUFDdkMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUN4QyxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7WUFDcEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUNuRCxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7WUFDbkMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3hELENBQUMsQ0FBQyxDQUFBO1FBRUYsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtZQUNoRCxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ2hFLENBQUMsQ0FBQyxDQUFBO1FBRUYsRUFBRSxDQUFDLDBCQUEwQixFQUFFLEdBQUcsRUFBRTtZQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3ZELENBQUMsQ0FBQyxDQUFBO1FBRUYsRUFBRSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtZQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDOUQsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIn0=

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,31 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { readProjectFiles } from '../file';
import { sync as dir } from '@polymech/fs/dir';
import { sync as exists } from '@polymech/fs/exists';
import { filesEx } from '@polymech/commons/_glob';
vi.mock('@polymech/fs/dir');
vi.mock('@polymech/fs/exists');
vi.mock('@polymech/commons/_glob');
vi.mock('@polymech/fs/read');
vi.mock('path', async () => {
const actual = await vi.importActual('path');
return {
...actual,
relative: vi.fn((from, to) => to),
extname: vi.fn((path) => path ? path.includes('.ts') ? '.ts' : '.md' : '')
};
});
describe('file utilities', () => {
beforeEach(() => {
vi.resetAllMocks();
});
describe('readProjectFiles', () => {
it('should create directory if it does not exist', async () => {
vi.mocked(exists).mockReturnValue(false);
await readProjectFiles('/test/path');
expect(dir).toHaveBeenCalledWith('/test/path');
expect(filesEx).not.toHaveBeenCalled();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3V0aWxzL19fdGVzdHNfXy9maWxlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzFDLE9BQU8sRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDOUMsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFFakQsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO0FBQzNCLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQTtBQUM5QixFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUE7QUFDbEMsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0FBQzVCLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM1QyxPQUFPO1FBQ0wsR0FBSSxNQUFjO1FBQ2xCLFFBQVEsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDM0UsQ0FBQTtBQUNILENBQUMsQ0FBQyxDQUFBO0FBRUYsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFBO0lBQ3BCLENBQUMsQ0FBQyxDQUFBO0lBRUYsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtRQUNoQyxFQUFFLENBQUMsOENBQThDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDNUQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7WUFFeEMsTUFBTSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQTtZQUVwQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLENBQUE7WUFDOUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1FBQ3hDLENBQUMsQ0FBQyxDQUFBO0lBR0osQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSJ9

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,77 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { resolveQuery, readStdin } from '../input';
import { detectAndHandle } from '../../commands/handlers';
import { sync as exists } from '@polymech/fs/exists';
import { sync as read } from '@polymech/fs/read';
vi.mock('@polymech/fs/exists');
vi.mock('@polymech/fs/read');
vi.mock('../../commands/handlers');
vi.mock('path', async () => {
const actual = await vi.importActual('path');
return {
...actual,
resolve: vi.fn((p) => p),
extname: vi.fn(() => '.txt')
};
});
describe('input utilities', () => {
let mockStdin;
beforeEach(() => {
vi.resetAllMocks();
mockStdin = {
isTTY: true,
on: vi.fn(),
};
Object.defineProperty(process, 'stdin', {
value: mockStdin,
writable: true
});
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('resolveQuery', () => {
it('should handle file path query', async () => {
const mockOptions = { query: 'test.txt' };
vi.mocked(exists).mockReturnValue(true);
vi.mocked(read).mockReturnValue(Buffer.from('file content'));
vi.mocked(detectAndHandle).mockResolvedValue('processed file content');
const result = await resolveQuery(mockOptions);
expect(result).toBe('processed file content');
expect(detectAndHandle).toHaveBeenCalled();
});
it('should return direct query if not file path', async () => {
const mockOptions = { query: 'direct query' };
vi.mocked(exists).mockReturnValue(false);
const result = await resolveQuery(mockOptions);
expect(result).toBe('direct query');
});
it('should throw error if no query provided', async () => {
await expect(resolveQuery({})).rejects.toThrow('No query provided');
});
});
describe('readStdin', () => {
it('should handle TTY input', async () => {
mockStdin.isTTY = true;
const result = await readStdin();
expect(result).toEqual(Buffer.from(''));
expect(mockStdin.on).not.toHaveBeenCalled();
});
it('should handle non-TTY input', async () => {
mockStdin.isTTY = false;
const mockData = Buffer.from('test input');
// Simulate data events
mockStdin.on.mockImplementation((event, callback) => {
if (event === 'data')
callback(mockData);
if (event === 'end')
callback();
});
const result = await readStdin();
expect(result).toEqual(mockData);
expect(mockStdin.on).toHaveBeenCalledWith('data', expect.any(Function));
expect(mockStdin.on).toHaveBeenCalledWith('end', expect.any(Function));
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9fX3Rlc3RzX18vaW5wdXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDeEUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFBO0FBQ3pELE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDcEQsT0FBTyxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUdoRCxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDOUIsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0FBQzVCLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQTtBQUNsQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLElBQUksRUFBRTtJQUN6QixNQUFNLE1BQU0sR0FBRyxNQUFNLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDNUMsT0FBTztRQUNMLEdBQUcsTUFBYTtRQUNoQixPQUFPLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQztLQUM3QixDQUFBO0FBQ0gsQ0FBQyxDQUFDLENBQUE7QUFFRixRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO0lBQy9CLElBQUks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

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,31 @@
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
import { dumpAsScript } from '../script';
import { sync as write } from '@polymech/fs/write';
vi.mock('@polymech/fs/write');
vi.mock('path', async () => {
const actual = await vi.importActual('path');
return {
...actual,
resolve: vi.fn((...args) => args.join('/'))
};
});
describe('script utilities', () => {
const originalArgv = process.argv;
beforeAll(() => {
process.argv = ['node', 'script.js', 'command', '--option=value', '--dump=output.sh'];
});
afterAll(() => {
process.argv = originalArgv;
});
describe('dumpAsScript', () => {
it('should not create script if dump option is not provided', async () => {
await dumpAsScript({ dump: undefined });
expect(write).not.toHaveBeenCalled();
});
it('should create script file with quoted arguments', async () => {
await dumpAsScript({ dump: 'output.sh' });
expect(write).toHaveBeenCalledWith('output.sh', 'kbot command --option="value"');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyaXB0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvX190ZXN0c19fL3NjcmlwdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ3hDLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFHbEQsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO0FBQzdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM1QyxPQUFPO1FBQ0wsR0FBRyxNQUFhO1FBQ2hCLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDNUMsQ0FBQTtBQUNILENBQUMsQ0FBQyxDQUFBO0FBRUYsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtJQUNoQyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFBO0lBRWpDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYixPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtJQUN2RixDQUFDLENBQUMsQ0FBQTtJQUVGLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDWixPQUFPLENBQUMsSUFBSSxHQUFHLFlBQVksQ0FBQTtJQUM3QixDQUFDLENBQUMsQ0FBQTtJQUVGLFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1FBQzVCLEVBQUUsQ0FBQyx5REFBeUQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN2RSxNQUFNLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFBO1lBQ3ZDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtRQUN0QyxDQUFDLENBQUMsQ0FBQTtRQUVGLEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMvRCxNQUFNLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFBO1lBRXpDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxvQkFBb0IsQ0FDaEMsV0FBVyxFQUNYLCtCQUErQixDQUNoQyxDQUFBO1FBQ0gsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIn0=

View File

@ -1,9 +1,9 @@
{
"model": "openai/chatgpt-4o-latest",
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Analyze this product review and extract key information\n\nText to transform: \"Great selection of fruits with good prices and quality. Some items were out of stock.\""
"content": "Summarize this paragraph in one short sentence (max 15 words).\n\nText to transform: \"A concluding paragraph summarizing the key findings.\""
},
{
"role": "user",

View File

@ -30,9 +30,13 @@
"openai": "4.91.0",
"p-map": "7.0.3",
"p-throttle": "7.0.0",
"remark-parse": "11.0.0",
"remark-stringify": "11.0.0",
"ts-retry": "6.0.0",
"tslog": "^4.9.3",
"turndown": "7.2.0",
"unified": "11.0.5",
"unist-util-visit": "5.0.0",
"yargs": "17.7.2",
"zod": "3.24.2"
},
@ -1723,6 +1727,15 @@
"optional": true,
"peer": true
},
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
"license": "MIT",
"dependencies": {
"@types/ms": "*"
}
},
"node_modules/@types/eslint": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
@ -1759,6 +1772,21 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
"integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
}
},
"node_modules/@types/ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
@ -1809,6 +1837,12 @@
"integrity": "sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w==",
"license": "MIT"
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
@ -2658,6 +2692,16 @@
"proxy-from-env": "^1.1.0"
}
},
"node_modules/bail": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
"integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -2839,6 +2883,16 @@
"node": ">=10"
}
},
"node_modules/character-entities": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
"integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/check-error": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
@ -3172,7 +3226,6 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@ -3186,6 +3239,19 @@
}
}
},
"node_modules/decode-named-character-reference": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
"integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
"license": "MIT",
"dependencies": {
"character-entities": "^2.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/deep-eql": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
@ -3221,6 +3287,28 @@
"node": ">=0.4.0"
}
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/devlop": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
"integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
"license": "MIT",
"dependencies": {
"dequal": "^2.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@ -3641,6 +3729,12 @@
"node": ">=12.0.0"
}
},
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"license": "MIT"
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -4418,6 +4512,18 @@
"node": ">=8"
}
},
"node_modules/is-plain-obj": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
"integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@ -4718,6 +4824,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/longest-streak": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
"integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@ -4837,6 +4953,78 @@
"node": ">= 0.4"
}
},
"node_modules/mdast-util-from-markdown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
"integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"@types/unist": "^3.0.0",
"decode-named-character-reference": "^1.0.0",
"devlop": "^1.0.0",
"mdast-util-to-string": "^4.0.0",
"micromark": "^4.0.0",
"micromark-util-decode-numeric-character-reference": "^2.0.0",
"micromark-util-decode-string": "^2.0.0",
"micromark-util-normalize-identifier": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0",
"unist-util-stringify-position": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-phrasing": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
"integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"unist-util-is": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-to-markdown": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
"integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"@types/unist": "^3.0.0",
"longest-streak": "^3.0.0",
"mdast-util-phrasing": "^4.0.0",
"mdast-util-to-string": "^4.0.0",
"micromark-util-classify-character": "^2.0.0",
"micromark-util-decode-string": "^2.0.0",
"unist-util-visit": "^5.0.0",
"zwitch": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-to-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
"integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -4854,6 +5042,448 @@
"node": ">= 8"
}
},
"node_modules/micromark": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
"integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"@types/debug": "^4.0.0",
"debug": "^4.0.0",
"decode-named-character-reference": "^1.0.0",
"devlop": "^1.0.0",
"micromark-core-commonmark": "^2.0.0",
"micromark-factory-space": "^2.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-chunked": "^2.0.0",
"micromark-util-combine-extensions": "^2.0.0",
"micromark-util-decode-numeric-character-reference": "^2.0.0",
"micromark-util-encode": "^2.0.0",
"micromark-util-normalize-identifier": "^2.0.0",
"micromark-util-resolve-all": "^2.0.0",
"micromark-util-sanitize-uri": "^2.0.0",
"micromark-util-subtokenize": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-core-commonmark": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
"integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"decode-named-character-reference": "^1.0.0",
"devlop": "^1.0.0",
"micromark-factory-destination": "^2.0.0",
"micromark-factory-label": "^2.0.0",
"micromark-factory-space": "^2.0.0",
"micromark-factory-title": "^2.0.0",
"micromark-factory-whitespace": "^2.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-chunked": "^2.0.0",
"micromark-util-classify-character": "^2.0.0",
"micromark-util-html-tag-name": "^2.0.0",
"micromark-util-normalize-identifier": "^2.0.0",
"micromark-util-resolve-all": "^2.0.0",
"micromark-util-subtokenize": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-destination": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
"integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-character": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-label": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
"integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"devlop": "^1.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-space": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
"integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-character": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-title": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
"integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-factory-space": "^2.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-whitespace": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
"integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-factory-space": "^2.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-character": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
"integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-chunked": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
"integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-classify-character": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
"integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-character": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-combine-extensions": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
"integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-chunked": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-decode-numeric-character-reference": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
"integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-decode-string": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
"integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"decode-named-character-reference": "^1.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-decode-numeric-character-reference": "^2.0.0",
"micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-encode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
"integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT"
},
"node_modules/micromark-util-html-tag-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
"integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT"
},
"node_modules/micromark-util-normalize-identifier": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
"integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-resolve-all": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
"integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-sanitize-uri": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
"integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"micromark-util-character": "^2.0.0",
"micromark-util-encode": "^2.0.0",
"micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-subtokenize": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
"integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT",
"dependencies": {
"devlop": "^1.0.0",
"micromark-util-chunked": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-symbol": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
"integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT"
},
"node_modules/micromark-util-types": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
"integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
"funding": [
{
"type": "GitHub Sponsors",
"url": "https://github.com/sponsors/unifiedjs"
},
{
"type": "OpenCollective",
"url": "https://opencollective.com/unified"
}
],
"license": "MIT"
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@ -5717,6 +6347,37 @@
"node": ">= 10.13.0"
}
},
"node_modules/remark-parse": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
"integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"mdast-util-from-markdown": "^2.0.0",
"micromark-util-types": "^2.0.0",
"unified": "^11.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-stringify": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
"integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"mdast-util-to-markdown": "^2.0.0",
"unified": "^11.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@ -6617,6 +7278,16 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/trough": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
"integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/ts-api-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
@ -7365,6 +8036,80 @@
"node": ">=4"
}
},
"node_modules/unified": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
"integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0",
"bail": "^2.0.0",
"devlop": "^1.0.0",
"extend": "^3.0.0",
"is-plain-obj": "^4.0.0",
"trough": "^2.0.0",
"vfile": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-is": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
"integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-stringify-position": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
"integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-visit": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0",
"unist-util-visit-parents": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-visit-parents": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
"integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/universalify": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
@ -7438,6 +8183,34 @@
"dev": true,
"license": "MIT"
},
"node_modules/vfile": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
"integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0",
"vfile-message": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/vfile-message": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
"integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
"license": "MIT",
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-stringify-position": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/vite": {
"version": "5.4.14",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz",
@ -7998,6 +8771,16 @@
"peerDependencies": {
"zod": "^3.24.1"
}
},
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
"integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
}
}
}

View File

@ -37,7 +37,9 @@
"exe:lnx": "cd dist && nexe -i main_node.js -o kbot --build --temp=../../temp-kbot --verbose",
"examples:async-iterator": "node dist-in/examples/core/async-iterator-example.js",
"examples:async-iterator:verbose": "node dist-in/examples/core/async-iterator-example.js --debug",
"examples:iterator-factory": "node dist-in/examples/core/iterator-factory-example.js --debug"
"examples:iterator-factory": "node dist-in/examples/core/iterator-factory-example.js --debug",
"examples:iterator-markdown": "node dist-in/examples/core/iterator-markdown-example.js",
"examples:iterator-markdown:no-cache": "node dist-in/examples/core/iterator-markdown-example.js --no-cache"
},
"dependencies": {
"@polymech/ai-tools": "file:../ai-tools",
@ -62,9 +64,13 @@
"openai": "4.91.0",
"p-map": "7.0.3",
"p-throttle": "7.0.0",
"remark-parse": "11.0.0",
"remark-stringify": "11.0.0",
"ts-retry": "6.0.0",
"tslog": "^4.9.3",
"turndown": "7.2.0",
"unified": "11.0.5",
"unist-util-visit": "5.0.0",
"yargs": "17.7.2",
"zod": "3.24.2"
},

View File

@ -0,0 +1,298 @@
import * as fs from 'fs';
import * as path from 'path';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import { visit } from 'unist-util-visit';
import { sync as write } from "@polymech/fs/write";
import type { IKBotTask } from '@polymech/ai-tools';
import { E_OPENROUTER_MODEL } from '../../models/cache/openrouter-models.js';
import { E_Mode } from '../../zod_schema.js';
import { FieldMapping, transform, IOptions, createLLMTransformer, CacheConfig, ILogger } from '../../iterator.js';
import { OnTransformCallback } from '../../async-iterator.js';
/**
* Notes for LLM modifications
*
* - to test it, use `npm run examples:iterator-markdown` (after adding the script)
* - demonstrates applying the iterator to a Markdown file parsed into an AST (mdast)
* - targets headings, paragraphs, and table cells for transformation
* - uses the 'format' option for structured data extraction
* - uses 'onTransform' callback
*/
const MODEL = E_OPENROUTER_MODEL.MODEL_OPENAI_GPT_4O_MINI; // Corrected model name
const ROUTER = 'openrouter';
const INPUT_MD_PATH = path.resolve('./tests/test-data/core/md-test.md');
const OUTPUT_MD_PATH = path.resolve('./tests/test-data/core/md-test-out.md');
// Basic logger
const logger: ILogger = {
info: (message: string) => console.log(`INFO: ${message}`),
warn: (message: string) => console.log(`WARN: ${message}`),
error: (message: string, error?: any) => console.error(`ERROR: ${message}`, error)
};
// This transformer factory uses the standard createLLMTransformer.
// It assumes the iterator passes the STRING value found at the JSONPath.
// It does NOT handle direct AST node modification for targetPath=null cases,
// because it only receives the string value, not the node context.
// In-place modification of the AST based on primitive value paths is complex
// with this generic iterator and requires a different approach (e.g., post-processing).
// Transformations using targetPath (like analysisResult) will work as expected
// if the JSONPath targets the NODE containing the text.
function getLLMTransformerForMdast(
options: IKBotTask,
baseLogger: ILogger = logger,
cacheConfig?: CacheConfig
): (textValue: string, jsonPath: string) => Promise<string> {
const llmTransformer = createLLMTransformer(options, baseLogger, cacheConfig);
// Just return the basic LLM transformer - it expects a string and returns a string.
return llmTransformer;
}
// Define field mappings for the mdast structure
const fieldMappings: FieldMapping[] = [
{
// Target text value within H1-H5 headings' children
jsonPath: '$.children[?(@.type=="heading" && @.depth <= 5)].children[?(@.type=="text")].value',
targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations)
options: {
prompt: 'Rewrite this heading to be more concise and impactful (max 5 words).'
}
},
{
// Target the specific paragraph NODE in Chapter 4 for structured analysis.
// The transformer will extract text from the node passed to it.
// Using targetPath='analysisResult' stores the LLM output on the node itself.
jsonPath: '$.children[?(@.type=="paragraph" && @.children[0].value.includes("results"))]',
targetPath: 'analysisResult', // Store result in a new property on the paragraph node
options: {
prompt: 'Extract keywords and sentiment from this text.',
format: {
type: "object",
properties: {
sentiment: {
type: "string",
enum: ["positive", "neutral", "negative"],
description: "Overall sentiment"
},
keywords: {
type: "array",
items: { type: "string" },
description: "Main keywords (max 5)"
}
},
required: ["sentiment", "keywords"]
}
}
},
{
// Target text value within paragraphs' children
jsonPath: '$.children[?(@.type=="paragraph")].children[?(@.type=="text")].value',
targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations)
options: {
prompt: 'Summarize this paragraph in one short sentence (max 15 words).'
}
},
{
// Target text value within table cells' children
jsonPath: '$.children[?(@.type=="table")].children[*].children[*].children[?(@.type=="text")].value',
targetPath: null, // Modify in place (NOTE: This likely won't work due to iterator limitations)
options: {
prompt: 'Rephrase this table cell content slightly.'
}
}
];
// Example onTransform callback for Markdown
const mdOnTransform: OnTransformCallback = async (jsonPath, value, options) => {
let textValue = typeof value === 'string' ? value : JSON.stringify(value); // Handle potential node objects if path isn't perfect
console.log(` -> mdOnTransform: Path='${jsonPath}', Original Value='${textValue.substring(0, 50)}...'`);
// No modification needed here, just logging
return textValue; // Must return the string value the LLM transformer expects
};
export async function markdownTransformExample(useCache = true) {
console.log("========================================");
console.log("Starting Markdown transform example");
console.log(`Using cache: ${useCache}`);
console.log("========================================");
try {
// 1. Read Markdown file
const markdownInput = fs.readFileSync(INPUT_MD_PATH, 'utf8');
// 2. Parse Markdown to AST
const processor = unified().use(remarkParse);
const ast = processor.parse(markdownInput);
// Make a deep copy to avoid modifying the original AST if transform fails
// Note: Standard deepClone might not work perfectly with complex AST nodes (position, data fields).
// For this example, JSON stringify/parse is a common workaround, but beware of data loss.
let astToTransform = JSON.parse(JSON.stringify(ast));
// 3. Define global options and iterator options
const globalOptionsMixin: Partial<IKBotTask> = {
model: MODEL,
router: ROUTER,
mode: E_Mode.COMPLETION,
};
const iteratorOptions: IOptions = {
// We provide our custom transformer factory
transformerFactory: (opts) => getLLMTransformerForMdast(opts, logger, { enabled: useCache }),
logger: logger,
cacheConfig: { enabled: useCache, namespace: 'markdown-transforms' },
// onTransform receives the value matched by jsonPath (can be string or node).
// It must return the STRING to be transformed by the LLM.
onTransform: async (jsonPath, value, kbotOptions) => {
let textContent = '';
// Check if the value is a node object or just a string
if (typeof value === 'string') {
textContent = value;
console.log(` -> onTransform String Value: Path='${jsonPath}', Value='${textContent.substring(0, 50)}...'`);
} else if (typeof value === 'object' && value !== null) {
// Attempt to extract text if it's a node (e.g., for the analysisResult mapping)
const node = value as any; // Basic type assertion
if ((node.type === 'heading' || node.type === 'paragraph' || node.type === 'tableCell') && node.children?.length === 1 && node.children[0].type === 'text') {
textContent = node.children[0].value || '';
} else if (node.type === 'text') {
textContent = node.value || '';
} else if (Array.isArray(node.children)) { // Handle complex children
textContent = node.children
.filter((child: any) => child.type === 'text' || child.type === 'inlineCode')
.map((child: any) => child.value)
.join('');
}
console.log(` -> onTransform AST Node: Path='${jsonPath}', Node Type='${node?.type}', Extracted Text='${textContent.substring(0, 50)}...'`);
} else {
console.log(` -> onTransform Unexpected Value Type: Path='${jsonPath}', Type='${typeof value}'`);
}
// Return the extracted string for the LLM transformer
return textContent;
},
errorCallback: (path, value, error) => {
if (error instanceof Error) {
logger.error(`Error processing path ${path}: ${error.message}`, error);
} else {
logger.error(`Error processing path ${path}: ${error}`, error);
}
},
filterCallback: async (value, jsonPath) => {
// Allow transformation if the value is an object (likely an AST node targeted directly)
if (typeof value === 'object' && value !== null) {
return true;
}
// If it's a string, apply the default string filter logic
if (typeof value === 'string') {
// Reuse the default isValidString filter logic for strings
const allow = value.trim() !== '';
if (!allow) {
logger.info(`Filter: Skipping empty string at ${jsonPath}`);
}
return allow;
}
// Skip other types (numbers, booleans, null, undefined)
logger.warn(`Filter: Skipping non-string/non-object value type (${typeof value}) at ${jsonPath}`);
return false;
}
};
// 4. Use the transform function
console.log("Applying transformations to AST...");
// The 'transform' function iterates based on JSONPath and applies the transformerFactory's result
// It modifies the 'astToTransform' object in place.
await transform(
astToTransform, // Pass the AST object
fieldMappings,
globalOptionsMixin,
iteratorOptions
);
// *** Add logging before visit ***
console.log("\n[DEBUG] Inspecting AST before visit call:");
try {
// Attempt to find the specific paragraph node expected to have analysisResult
// NOTE: This relies on index/structure and might be brittle
const potentialNode = astToTransform.children?.find((node: any) =>
node.type === 'paragraph' &&
node.children?.[0]?.value?.includes("results")
);
if (potentialNode) {
console.log("[DEBUG] Found potential node:", JSON.stringify(potentialNode, null, 2));
console.log(`[DEBUG] Does potential node have analysisResult? ${potentialNode.hasOwnProperty('analysisResult')}`);
} else {
console.log("[DEBUG] Could not find the target paragraph node directly before visit.");
}
console.log("---------------------------------------");
} catch (e) {
console.error("[DEBUG] Error during pre-visit inspection:", e);
}
// Retrieve the structured analysis result (if any)
// Note: The 'analysisResult' was added as a new property to the AST node by the mapping.
// We need to find that node again to see the result. This is clumsy.
let analysisData: any = null;
try {
visit(astToTransform, 'paragraph', (node: any) => {
if (node.analysisResult) {
analysisData = node.analysisResult;
// Optional: Remove the temporary property from the AST before stringifying
// delete node.analysisResult;
}
});
if (analysisData) {
console.log("\nStructured Analysis Result:");
// The LLM might return a stringified JSON, try parsing it
try {
const parsedResult = typeof analysisData === 'string' ? JSON.parse(analysisData) : analysisData;
console.log(JSON.stringify(parsedResult, null, 2));
} catch (e) {
console.log("Analysis result (raw):", analysisData);
}
} else {
console.log("\nStructured Analysis Result not found on AST (check targetPath logic and LLM response).");
}
} catch (e) {
logger.error("Error visiting AST for analysis result retrieval:", e)
}
// 5. Stringify the modified AST back to Markdown
console.log("\nStringifying transformed AST...");
const processorStringify = unified().use(remarkStringify);
// Stringify might fail if the AST structure became invalid during transformation
const outputMarkdown = processorStringify.stringify(astToTransform as any);
// 6. Write the output file
console.log(`Writing output to: ${OUTPUT_MD_PATH}`);
const outputDir = path.dirname(OUTPUT_MD_PATH);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
write(OUTPUT_MD_PATH, outputMarkdown);
console.log("Markdown transformation complete.");
return astToTransform; // Return the transformed AST
} catch (error) {
logger.error("ERROR during Markdown transformation:", error);
throw error;
}
}
// Add run logic
if (process.argv[1] && process.argv[1].includes('iterator-markdown-example')) {
const noCache = process.argv.includes('--no-cache');
markdownTransformExample(!noCache)
.then(() => {
console.log("\nMarkdown example finished successfully.");
})
.catch(error => {
console.error("\nMarkdown example failed:", error);
process.exit(1); // Exit with error code
});
}

View File

@ -1,3 +1,4 @@
// Export examples
export * from './core/async-iterator-example.js';
export * from './core/iterator-factory-example.js';
export * from './core/iterator-markdown-example.js';

View File

@ -78,5 +78,4 @@ export * from './zod_schema.js'
export { E_OPENAI_MODEL } from './models/cache/openai-models.js'
export { E_OPENROUTER_MODEL } from './models/cache/openrouter-models.js'
export { E_OPENROUTER_MODEL_FREE } from './models/cache/openrouter-models-free.js'
export { IKBotTask } from '@polymech/ai-tools'
export type { IKBotTask } from '@polymech/ai-tools'

View File

@ -211,8 +211,10 @@ export function createIterator(
return {
createTransformer,
transform: async (mappings: FieldMapping[]): Promise<void> => {
// *** Object Cache Check (Start) ***
let objectCacheKey: any;
if (config.enabled) {
const objectCacheKey = createObjectCacheKey(obj, mappings);
objectCacheKey = createObjectCacheKey(obj, mappings); // Key based on initial state
const cachedObject = await get_cached_object(
{ ca_options: objectCacheKey },
'transformed-objects'
@ -220,20 +222,24 @@ export function createIterator(
if (cachedObject?.content) {
logger.info('Using cached transformed object');
// Clear the original object before merging cache to avoid partial states
Object.keys(obj).forEach(key => delete obj[key]);
deepMerge(obj, cachedObject.content);
return;
}
}
// *** Object Cache Check (End) ***
// If no cache hit or caching disabled, perform the transformations
const transformedObj = JSON.parse(JSON.stringify(obj));
// If no cache hit or caching disabled, perform the transformations directly on 'obj'
// REMOVED: const transformedObj = JSON.parse(JSON.stringify(obj));
for (const mapping of mappings) {
const mergedOptions = { ...optionsMixin, ...mapping.options } as IKBotTask;
const { jsonPath, targetPath = null } = mapping;
const transformer = createTransformer(mergedOptions);
// Call transformObjectWithOptions directly on the original 'obj'
await transformObjectWithOptions(
transformedObj,
obj, // <<< Operate directly on obj
transformer,
{
jsonPath,
@ -248,20 +254,20 @@ export function createIterator(
);
}
// Cache the transformed object
if (config.enabled) {
const objectCacheKey = createObjectCacheKey(obj, mappings);
// *** Object Cache Setting (Start) ***
// Cache the final state of the modified 'obj'
if (config.enabled && objectCacheKey) { // Ensure key was generated
await set_cached_object(
{ ca_options: objectCacheKey },
'transformed-objects',
{ content: transformedObj },
{ content: obj }, // <<< Cache the final obj
{ expiration: config.expiration }
);
logger.info('Cached transformed object');
}
// *** Object Cache Setting (End) ***
// Apply the transformations to the original object
deepMerge(obj, transformedObj);
// REMOVED: deepMerge(obj, transformedObj);
}
};
}

View File

@ -0,0 +1,37 @@
# Intro Chapter
The document introduces topics related to AI and Markdown processing.
## Background Overview
Markdown has an interesting history that we will explore.
### "Early Days"
Early days are described in the details provided.
# Methodology Overview
This chapter describes the employed methods.
## "Markdown Parsing"
User preferences indicate a focus on concise and direct responses.`unified`The paragraph consists only of an empty conjunction and lacks meaningful content.`remark-parse`To manage Markdown formatting.
## Content Transformation
The process entails navigating the AST and implementing LLM transformations.
# Data Representation
The table includes three headers and various data cells, highlighting important content in one cell.
The table displays sample data with transformable cells.
# Structured Output Analysis
The text mentions sunny weather, making it ideal for a park walk.
# Final Thoughts
A summary of the key findings is presented in the concluding paragraph.

View File

@ -0,0 +1,41 @@
# Chapter 1: Introduction
This is the introductory paragraph. It sets the stage for the document. We will discuss various topics related to AI and Markdown processing.
## Section 1.1: Background
Here we provide some background information. The history of Markdown is quite interesting.
### Subsection 1.1.1: Early Days
Details about the early days go here.
# Chapter 2: Methodology
This chapter outlines the methods used.
## Section 2.1: Parsing Markdown
We use `unified` and `remark-parse` to handle Markdown.
## Section 2.2: Transforming Content
The core logic involves traversing the AST and applying LLM transformations.
# Chapter 3: Data Representation
| Header 1 | Header 2 | Header 3 |
|----------|----------|----------|
| Cell 1.1 | Cell 1.2 | Cell 1.3 |
| Cell 2.1 | Cell 2.2 | Cell 2.3: Contains important data |
| Cell 3.1 | Cell 3.2 | Cell 3.3 |
This table shows sample data. Each cell can be targeted for transformation.
# Chapter 4: Analysis with Structured Output
This section discusses the results. We want to extract keywords and sentiment from this text. The weather today is sunny and warm, perfect for a walk in the park.
# Chapter 5: Conclusion
A concluding paragraph summarizing the key findings.

View File

@ -14,6 +14,14 @@
]
}
},
// "include": [
// "src/**/*"
// ],
// "exclude": [
// "node_modules",
// "dist",
// "dist-in"
// ],
"files": [
"src/index.ts",
"src/main.ts",