@silkweave/core 2.6.0 → 3.0.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.
- package/README.md +1 -1
- package/build/index.d.mts +30 -1
- package/build/index.d.mts.map +1 -1
- package/build/index.mjs +78 -18
- package/build/index.mjs.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -121,5 +121,5 @@ type AdapterFactory<T = void> = (options: T) => AdapterGenerator
|
|
|
121
121
|
- [`@silkweave/mcp`](https://www.npmjs.com/package/@silkweave/mcp) - MCP stdio and HTTP adapters
|
|
122
122
|
- [`@silkweave/fastify`](https://www.npmjs.com/package/@silkweave/fastify) - Fastify REST adapter
|
|
123
123
|
- [`@silkweave/cli`](https://www.npmjs.com/package/@silkweave/cli) - CLI adapter
|
|
124
|
-
- [`@silkweave/
|
|
124
|
+
- [`@silkweave/edge`](https://www.npmjs.com/package/@silkweave/edge) - Web-Standard edge/serverless adapter (Cloudflare Workers, Vercel, Bun, Deno)
|
|
125
125
|
- [`@silkweave/typegen`](https://www.npmjs.com/package/@silkweave/typegen) - Build-time type generation
|
package/build/index.d.mts
CHANGED
|
@@ -116,6 +116,13 @@ interface SilkweaveOptions {
|
|
|
116
116
|
name: string;
|
|
117
117
|
description: string;
|
|
118
118
|
version: string;
|
|
119
|
+
/**
|
|
120
|
+
* Run the dev-time action linter on `start()` (warns about missing/short tool
|
|
121
|
+
* descriptions and undescribed input params - mistakes that degrade agent
|
|
122
|
+
* tool-use). Warnings go to stderr via `console.warn`. Default `true`; set
|
|
123
|
+
* `false` to silence in production.
|
|
124
|
+
*/
|
|
125
|
+
lint?: boolean;
|
|
119
126
|
}
|
|
120
127
|
interface Adapter {
|
|
121
128
|
context: SilkweaveContext;
|
|
@@ -186,6 +193,28 @@ interface ActionInputSources {
|
|
|
186
193
|
*/
|
|
187
194
|
declare function resolveActionInput(action: Action, sources: ActionInputSources): Record<string, unknown>;
|
|
188
195
|
//#endregion
|
|
196
|
+
//#region src/util/lint.d.ts
|
|
197
|
+
type ActionLintCode = 'missing-description' | 'short-description' | 'undescribed-params' | 'some-undescribed-params';
|
|
198
|
+
interface ActionLintWarning {
|
|
199
|
+
action: string;
|
|
200
|
+
code: ActionLintCode;
|
|
201
|
+
message: string;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Static checks for agent-hostile action definitions - the cheap mistakes that
|
|
205
|
+
* quietly degrade tool-use: a missing or throwaway description (the model reads
|
|
206
|
+
* it to decide when to call the tool) and undescribed input parameters (the
|
|
207
|
+
* model guesses what to pass). Pure + side-effect-free; `reportActionLint` wires
|
|
208
|
+
* it to a warn sink, and `silkweave().start()` runs it automatically.
|
|
209
|
+
*/
|
|
210
|
+
declare function lintActions(actions: Action[]): ActionLintWarning[];
|
|
211
|
+
/**
|
|
212
|
+
* Run `lintActions` and emit each warning through `warn` (default `console.warn`,
|
|
213
|
+
* which goes to stderr - safe even for the stdio MCP transport). Returns the
|
|
214
|
+
* warnings so callers can also inspect or suppress them.
|
|
215
|
+
*/
|
|
216
|
+
declare function reportActionLint(actions: Action[], warn?: (message: string) => void): ActionLintWarning[];
|
|
217
|
+
//#endregion
|
|
189
218
|
//#region src/util/streaming.d.ts
|
|
190
219
|
/**
|
|
191
220
|
* Drive a streaming action's async generator. Calls `onChunk` once per yielded
|
|
@@ -208,5 +237,5 @@ interface UnwrapResult {
|
|
|
208
237
|
}
|
|
209
238
|
declare function unwrap(type: z.ZodTypeAny, result?: UnwrapResult): [z.ZodTypeAny, UnwrapResult];
|
|
210
239
|
//#endregion
|
|
211
|
-
export { Action, ActionInputSources, ActionKind, ActionRun, ActionStreamRun, Adapter, AdapterFactory, AdapterGenerator, HttpMethod, NonStreamingActionInput, Silkweave, SilkweaveContext, SilkweaveError, type SilkweaveOptions, StreamingActionInput, UnwrapResult, actionMethod, badRequest, createAction, createContext, forbidden, internal, isStreamingAction, methodHasBody, notFound, pathParamNames, resolveActionInput, runStreamingAction, silkweave, unwrap, validateActionRouting };
|
|
240
|
+
export { Action, ActionInputSources, ActionKind, ActionLintCode, ActionLintWarning, ActionRun, ActionStreamRun, Adapter, AdapterFactory, AdapterGenerator, HttpMethod, NonStreamingActionInput, Silkweave, SilkweaveContext, SilkweaveError, type SilkweaveOptions, StreamingActionInput, UnwrapResult, actionMethod, badRequest, createAction, createContext, forbidden, internal, isStreamingAction, lintActions, methodHasBody, notFound, pathParamNames, reportActionLint, resolveActionInput, runStreamingAction, silkweave, unwrap, validateActionRouting };
|
|
212
241
|
//# sourceMappingURL=index.d.mts.map
|
package/build/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/util/context.ts","../src/util/action.ts","../src/util/adapter.ts","../src/lib/silkweave.ts","../src/util/error.ts","../src/util/http.ts","../src/util/streaming.ts","../src/util/zod.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/util/context.ts","../src/util/action.ts","../src/util/adapter.ts","../src/lib/silkweave.ts","../src/util/error.ts","../src/util/http.ts","../src/util/lint.ts","../src/util/streaming.ts","../src/util/zod.ts"],"mappings":"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"}
|
package/build/index.mjs
CHANGED
|
@@ -28,6 +28,82 @@ function createContext(store = {}) {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
|
+
//#region src/util/zod.ts
|
|
32
|
+
function unwrap(type, result = {}) {
|
|
33
|
+
if (type instanceof z.ZodOptional) {
|
|
34
|
+
result.isOptional = true;
|
|
35
|
+
return unwrap(type.unwrap(), result);
|
|
36
|
+
} else if (type instanceof z.ZodNullable) {
|
|
37
|
+
result.isNullable = true;
|
|
38
|
+
return unwrap(type.unwrap(), result);
|
|
39
|
+
} else if (type instanceof z.ZodReadonly) {
|
|
40
|
+
result.isReadOnly = true;
|
|
41
|
+
return unwrap(type.def.innerType, result);
|
|
42
|
+
} else if (type instanceof z.ZodDefault) {
|
|
43
|
+
result.defaultValue = typeof type.def.defaultValue === "function" ? type.def.defaultValue() : type.def.defaultValue;
|
|
44
|
+
return unwrap(type.unwrap(), result);
|
|
45
|
+
} else return [type, result];
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/util/lint.ts
|
|
49
|
+
/** A description shorter than this reads as a placeholder to an agent picking a tool. */
|
|
50
|
+
const MIN_DESCRIPTION_LENGTH = 12;
|
|
51
|
+
/** A field's `.describe()` text, looking through optional/default/nullable/readonly wrappers. */
|
|
52
|
+
function describedText(field) {
|
|
53
|
+
if (field.description) return field.description;
|
|
54
|
+
const [base] = unwrap(field);
|
|
55
|
+
return base.description;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Static checks for agent-hostile action definitions - the cheap mistakes that
|
|
59
|
+
* quietly degrade tool-use: a missing or throwaway description (the model reads
|
|
60
|
+
* it to decide when to call the tool) and undescribed input parameters (the
|
|
61
|
+
* model guesses what to pass). Pure + side-effect-free; `reportActionLint` wires
|
|
62
|
+
* it to a warn sink, and `silkweave().start()` runs it automatically.
|
|
63
|
+
*/
|
|
64
|
+
function lintActions(actions) {
|
|
65
|
+
const warnings = [];
|
|
66
|
+
for (const action of actions) {
|
|
67
|
+
const description = action.description?.trim() ?? "";
|
|
68
|
+
if (!description) warnings.push({
|
|
69
|
+
action: action.name,
|
|
70
|
+
code: "missing-description",
|
|
71
|
+
message: `Action "${action.name}" has no description - MCP clients show it to the model to decide when to call the tool. Add a clear, specific sentence.`
|
|
72
|
+
});
|
|
73
|
+
else if (description.length < MIN_DESCRIPTION_LENGTH) warnings.push({
|
|
74
|
+
action: action.name,
|
|
75
|
+
code: "short-description",
|
|
76
|
+
message: `Action "${action.name}" description is very short ("${description}"). A fuller sentence helps agents choose the right tool.`
|
|
77
|
+
});
|
|
78
|
+
const shape = action.input?.shape ?? {};
|
|
79
|
+
const params = Object.keys(shape);
|
|
80
|
+
const undescribed = params.filter((name) => !describedText(shape[name]));
|
|
81
|
+
if (params.length > 0 && undescribed.length === params.length) warnings.push({
|
|
82
|
+
action: action.name,
|
|
83
|
+
code: "undescribed-params",
|
|
84
|
+
message: `Action "${action.name}" has no described input parameters (${params.join(", ")}). Add .describe() to each field so agents pass correct values.`
|
|
85
|
+
});
|
|
86
|
+
else if (undescribed.length > 0) warnings.push({
|
|
87
|
+
action: action.name,
|
|
88
|
+
code: "some-undescribed-params",
|
|
89
|
+
message: `Action "${action.name}" input fields lack descriptions: ${undescribed.join(", ")}. Add .describe() for better agent tool-use.`
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return warnings;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Run `lintActions` and emit each warning through `warn` (default `console.warn`,
|
|
96
|
+
* which goes to stderr - safe even for the stdio MCP transport). Returns the
|
|
97
|
+
* warnings so callers can also inspect or suppress them.
|
|
98
|
+
*/
|
|
99
|
+
function reportActionLint(actions, warn = (message) => {
|
|
100
|
+
console.warn(message);
|
|
101
|
+
}) {
|
|
102
|
+
const warnings = lintActions(actions);
|
|
103
|
+
for (const warning of warnings) warn(`[silkweave] ${warning.message}`);
|
|
104
|
+
return warnings;
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
31
107
|
//#region src/lib/silkweave.ts
|
|
32
108
|
function silkweave(options) {
|
|
33
109
|
const adapters = [];
|
|
@@ -51,6 +127,7 @@ function silkweave(options) {
|
|
|
51
127
|
return builder;
|
|
52
128
|
},
|
|
53
129
|
start: async () => {
|
|
130
|
+
if (options.lint !== false) reportActionLint(actions);
|
|
54
131
|
await Promise.all(adapters.map((adapter) => {
|
|
55
132
|
const filtered = adapter.allActions ? actions : actions.filter((action) => {
|
|
56
133
|
if (!action.isEnabled) return true;
|
|
@@ -99,23 +176,6 @@ function internal(message = "Internal error") {
|
|
|
99
176
|
return new SilkweaveError(message, "internal", 500);
|
|
100
177
|
}
|
|
101
178
|
//#endregion
|
|
102
|
-
//#region src/util/zod.ts
|
|
103
|
-
function unwrap(type, result = {}) {
|
|
104
|
-
if (type instanceof z.ZodOptional) {
|
|
105
|
-
result.isOptional = true;
|
|
106
|
-
return unwrap(type.unwrap(), result);
|
|
107
|
-
} else if (type instanceof z.ZodNullable) {
|
|
108
|
-
result.isNullable = true;
|
|
109
|
-
return unwrap(type.unwrap(), result);
|
|
110
|
-
} else if (type instanceof z.ZodReadonly) {
|
|
111
|
-
result.isReadOnly = true;
|
|
112
|
-
return unwrap(type.def.innerType, result);
|
|
113
|
-
} else if (type instanceof z.ZodDefault) {
|
|
114
|
-
result.defaultValue = typeof type.def.defaultValue === "function" ? type.def.defaultValue() : type.def.defaultValue;
|
|
115
|
-
return unwrap(type.unwrap(), result);
|
|
116
|
-
} else return [type, result];
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
179
|
//#region src/util/http.ts
|
|
120
180
|
const PATH_PARAM_RE = /:([A-Za-z0-9_]+)/g;
|
|
121
181
|
/**
|
|
@@ -231,6 +291,6 @@ async function runStreamingAction(action, input, context, onChunk) {
|
|
|
231
291
|
return chunks;
|
|
232
292
|
}
|
|
233
293
|
//#endregion
|
|
234
|
-
export { SilkweaveError, actionMethod, badRequest, createAction, createContext, forbidden, internal, isStreamingAction, methodHasBody, notFound, pathParamNames, resolveActionInput, runStreamingAction, silkweave, unwrap, validateActionRouting };
|
|
294
|
+
export { SilkweaveError, actionMethod, badRequest, createAction, createContext, forbidden, internal, isStreamingAction, lintActions, methodHasBody, notFound, pathParamNames, reportActionLint, resolveActionInput, runStreamingAction, silkweave, unwrap, validateActionRouting };
|
|
235
295
|
|
|
236
296
|
//# sourceMappingURL=index.mjs.map
|
package/build/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/util/context.ts","../src/lib/silkweave.ts","../src/util/action.ts","../src/util/error.ts","../src/util/zod.ts","../src/util/http.ts","../src/util/streaming.ts"],"sourcesContent":["export interface SilkweaveContext {\n keys: () => string[]\n has: (key: string) => boolean\n get: <T>(key: string) => T\n getOptional: <T>(key: string) => T | undefined\n set: <T>(key: string, value: T) => void\n fork: (store?: Record<string, unknown>) => SilkweaveContext\n}\n\nexport function createContext(store: Record<string, unknown> = {}): SilkweaveContext {\n return {\n keys: () => {\n return Object.keys(store)\n },\n has: (key: string): boolean => {\n return store[key] != null\n },\n get: <T>(key: string): T => {\n const value = store[key]\n if (value == null) { throw new Error(`Invalid context key: ${key}`) }\n return value as T\n },\n getOptional: <T>(key: string): T | undefined => {\n return store[key] as T | undefined\n },\n set: <T>(key: string, value: T) => {\n store[key] = value\n },\n fork: (value?: Record<string, unknown>) => {\n return createContext({ ...store, ...value })\n }\n }\n}\n","import { Action } from '../util/action.js'\nimport { Adapter, AdapterGenerator, SilkweaveOptions } from '../util/adapter.js'\nimport { createContext } from '../util/context.js'\n\nexport type { SilkweaveOptions } from '../util/adapter.js'\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface Silkweave<Actions extends Record<string, Action> = {}> {\n set: <T>(key: string, value: T) => Silkweave<Actions>\n adapter: (generator: AdapterGenerator) => Silkweave<Actions>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: <A extends Action<any, any, string, any>>(\n action: A\n ) => Silkweave<Actions & Record<A['name'], A>>\n actions: <Arr extends readonly Action[]>(\n actions: Arr\n ) => Silkweave<Actions & { [K in Arr[number] as K['name']]: K }>\n start: () => Promise<Silkweave<Actions>>\n}\n\nexport function silkweave(options: SilkweaveOptions): Silkweave {\n const adapters: Adapter[] = []\n const actions: Action[] = []\n const context = createContext()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const builder: Silkweave<any> = {\n set: (key, value) => {\n context.set(key, value)\n return builder\n },\n adapter: (generator) => {\n adapters.push(generator(options, context))\n return builder\n },\n action: (value) => {\n actions.push(value)\n return builder\n },\n actions: (values) => {\n actions.push(...values)\n return builder\n },\n start: async () => {\n await Promise.all(adapters.map((adapter) => {\n const filtered = adapter.allActions\n ? actions\n : actions.filter((action) => {\n if (!action.isEnabled) { return true }\n return action.isEnabled(adapter.context)\n })\n return adapter.start(filtered)\n }))\n return builder\n }\n }\n return builder\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { type CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport z from 'zod/v4'\nimport { SilkweaveContext } from './context.js'\n\nexport type ActionKind = 'query' | 'mutation'\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'\n\nexport type ActionRun<I, O> = (input: I, context: SilkweaveContext) => Promise<O>\nexport type ActionStreamRun<I, C> = (input: I, context: SilkweaveContext) => AsyncGenerator<C, void, void>\n\nexport interface Action<\n I extends object = any,\n O extends object = any,\n N extends string = string,\n K extends ActionKind = ActionKind,\n C = any\n> {\n name: N\n description: string\n input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }\n output?: z.ZodType<O> & { shape: Record<string, z.ZodTypeAny> }\n /**\n * Schema for individual chunks yielded by a streaming `run`. Required when\n * `run` is an async generator; adapters detect streaming actions by checking\n * `isStreamingAction(action)` at runtime, but type-aware tooling (inferRouter,\n * typegen) uses the presence of this field.\n */\n chunk?: z.ZodType<C>\n kind?: K\n /**\n * HTTP verb for REST-style adapters (fastify, nestjs `rest`). Defaults to\n * `POST`, or `GET` when `kind` is `'query'`. An explicit `method` always wins.\n */\n method?: HttpMethod\n /**\n * Route path for REST-style adapters. May contain `:param` placeholders\n * (e.g. `'spaces/:spaceId/users'`); each placeholder must be a key of the\n * input schema and is resolved from the URL path at runtime. When unset, the\n * adapter derives the path from `name`.\n */\n path?: string\n /**\n * Input fields sourced from the URL query string instead of the request body\n * (e.g. `['offset', 'limit']`). Each must be a key of the input schema; their\n * required/optional status is validated by the input schema as usual.\n */\n queryParams?: (keyof I)[]\n args?: (keyof I)[]\n /**\n * Default MCP result disposition for this action - `'json'` formats the\n * response with `jsonToolResult` (compact JSON text), `'smart'` (the default\n * when unset) uses `smartToolResult` (inlines small payloads, offloads large\n * ones to an embedded resource). This is only a default: a client that sends\n * `_meta.disposition` on the tool call always wins. Ignored by non-MCP\n * adapters.\n */\n disposition?: 'json' | 'smart'\n isEnabled?: (context: SilkweaveContext) => boolean\n run: ActionRun<I, O> | ActionStreamRun<I, C>\n toolResult?: (response: O, context: SilkweaveContext) => CallToolResult | undefined\n}\n\nexport interface NonStreamingActionInput<I extends object, O extends object, N extends string, K extends ActionKind> {\n name: N\n description: string\n input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }\n output?: z.ZodType<O> & { shape: Record<string, z.ZodTypeAny> }\n kind?: K\n method?: HttpMethod\n path?: string\n queryParams?: (keyof I)[]\n args?: (keyof I)[]\n disposition?: 'json' | 'smart'\n isEnabled?: (context: SilkweaveContext) => boolean\n run: ActionRun<I, O>\n toolResult?: (response: O, context: SilkweaveContext) => CallToolResult | undefined\n}\n\nexport interface StreamingActionInput<I extends object, C, N extends string, K extends ActionKind> {\n name: N\n description: string\n input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }\n chunk: z.ZodType<C>\n kind?: K\n method?: HttpMethod\n path?: string\n queryParams?: (keyof I)[]\n args?: (keyof I)[]\n disposition?: 'json' | 'smart'\n isEnabled?: (context: SilkweaveContext) => boolean\n run: ActionStreamRun<I, C>\n toolResult?: (response: C[], context: SilkweaveContext) => CallToolResult | undefined\n}\n\nexport function createAction<\n I extends object,\n C,\n N extends string,\n K extends ActionKind = 'mutation'\n>(action: StreamingActionInput<I, C, N, K>): StreamingActionInput<I, C, N, K>\nexport function createAction<\n I extends object,\n O extends object,\n N extends string,\n K extends ActionKind = 'mutation'\n>(action: NonStreamingActionInput<I, O, N, K>): NonStreamingActionInput<I, O, N, K>\nexport function createAction(action: Action): Action {\n return action\n}\n\n/**\n * Returns `true` when `action.run` is an async generator function (declared\n * with `async function*`). Adapters use this to switch between buffered\n * request/response and streaming chunk delivery.\n */\nexport function isStreamingAction(action: Action): boolean {\n return action.run?.constructor?.name === 'AsyncGeneratorFunction'\n}\n","export class SilkweaveError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode = 500\n ) {\n super(message)\n this.name = 'SilkweaveError'\n }\n}\n\nexport function notFound(message = 'Not found') {\n return new SilkweaveError(message, 'not_found', 404)\n}\n\nexport function badRequest(message = 'Bad request') {\n return new SilkweaveError(message, 'bad_request', 400)\n}\n\nexport function forbidden(message = 'Forbidden') {\n return new SilkweaveError(message, 'forbidden', 403)\n}\n\nexport function internal(message = 'Internal error') {\n return new SilkweaveError(message, 'internal', 500)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from 'zod/v4'\n\nexport interface UnwrapResult {\n defaultValue?: any\n isOptional?: boolean\n isNullable?: boolean\n isReadOnly?: boolean\n}\n\nexport function unwrap(\n type: z.ZodTypeAny,\n result: UnwrapResult = {}\n): [z.ZodTypeAny, UnwrapResult] {\n if (type instanceof z.ZodOptional) {\n result.isOptional = true\n return unwrap(type.unwrap() as z.ZodTypeAny, result)\n } else if (type instanceof z.ZodNullable) {\n result.isNullable = true\n return unwrap(type.unwrap() as z.ZodTypeAny, result)\n } else if (type instanceof z.ZodReadonly) {\n result.isReadOnly = true\n return unwrap(type.def.innerType as z.ZodTypeAny, result)\n } else if (type instanceof z.ZodDefault) {\n result.defaultValue = typeof type.def.defaultValue === 'function'\n ? type.def.defaultValue()\n : type.def.defaultValue\n return unwrap(type.unwrap() as z.ZodTypeAny, result)\n } else {\n return [type, result]\n }\n}\n","import type z from 'zod/v4'\nimport { type Action, type HttpMethod } from './action.js'\nimport { SilkweaveError } from './error.js'\nimport { unwrap } from './zod.js'\n\nconst PATH_PARAM_RE = /:([A-Za-z0-9_]+)/g\n\n/**\n * Resolve the HTTP verb for an action. An explicit `method` always wins;\n * otherwise `kind: 'query'` maps to `GET` and everything else to `POST`.\n */\nexport function actionMethod(action: Pick<Action, 'method' | 'kind'>): HttpMethod {\n if (action.method) { return action.method }\n return action.kind === 'query' ? 'GET' : 'POST'\n}\n\n/** Whether a request with this method carries a body (everything except GET). */\nexport function methodHasBody(method: HttpMethod): boolean {\n return method !== 'GET'\n}\n\n/** Extract the `:param` placeholder names from a route path template. */\nexport function pathParamNames(path: string | undefined): string[] {\n if (!path) { return [] }\n return [...path.matchAll(PATH_PARAM_RE)].map((match) => match[1])\n}\n\n/**\n * Assert that every `:param` in `action.path` and every `queryParams` entry is a\n * field of the input schema. Throws a `SilkweaveError` at registration time so\n * misconfigured routing fails fast instead of silently dropping values.\n */\nexport function validateActionRouting(action: Action): void {\n const shape = action.input.shape\n for (const param of pathParamNames(action.path)) {\n if (!(param in shape)) {\n throw new SilkweaveError(\n `Action \"${action.name}\" path \"${action.path}\" references \":${param}\" but the input schema has no \"${param}\" field`,\n 'invalid_action_routing'\n )\n }\n }\n for (const key of action.queryParams ?? []) {\n if (!(String(key) in shape)) {\n throw new SilkweaveError(\n `Action \"${action.name}\" lists query param \"${String(key)}\" but the input schema has no such field`,\n 'invalid_action_routing'\n )\n }\n }\n}\n\n/**\n * Coerce a raw string (from the URL path or query string) to the primitive the\n * field's schema expects. Non-string values pass through untouched (REST\n * frameworks like Fastify may have already coerced via JSON Schema), and a\n * failed coercion returns the original value so Zod surfaces a proper error.\n */\nfunction coerceScalar(field: z.ZodTypeAny | undefined, value: unknown): unknown {\n if (!field || typeof value !== 'string') { return value }\n const [base] = unwrap(field)\n const type = (base as { def?: { type?: string } }).def?.type\n if (type === 'number') {\n const num = Number(value)\n return value.trim() === '' || Number.isNaN(num) ? value : num\n }\n if (type === 'boolean') {\n if (value === 'true') { return true }\n if (value === 'false') { return false }\n return value\n }\n if (type === 'bigint') {\n try { return BigInt(value) } catch { return value }\n }\n return value\n}\n\nexport interface ActionInputSources {\n /** Path parameters keyed by `:param` name (e.g. Express/Fastify `req.params`). */\n params?: Record<string, string | undefined>\n /** Parsed query string (string values, or arrays/coerced values from a framework). */\n query?: Record<string, unknown>\n /** Parsed request body (already-typed JSON for body methods). */\n body?: unknown\n}\n\n/**\n * Merge an action's path params, query params, and body into a single input\n * object honouring its `method`/`path`/`queryParams` routing config:\n *\n * - body fields form the base layer (only for body-carrying methods),\n * - declared query params override (on bodyless GET requests every input field\n * that is not a path param is read from the query string),\n * - path params override last.\n *\n * String values from the path/query are coerced to the primitive their schema\n * expects. The result is not validated here - callers pass it to\n * `action.input.parse()` (or let a framework validate it).\n */\nexport function resolveActionInput(action: Action, sources: ActionInputSources): Record<string, unknown> {\n const shape = action.input.shape\n const method = actionMethod(action)\n const hasBody = methodHasBody(method)\n const params = sources.params ?? {}\n const query = sources.query ?? {}\n const pathParams = new Set(pathParamNames(action.path))\n const queryKeys = new Set((action.queryParams ?? []).map(String))\n\n const merged: Record<string, unknown> = {}\n\n if (hasBody && sources.body && typeof sources.body === 'object') {\n Object.assign(merged, sources.body as Record<string, unknown>)\n }\n\n for (const [key, raw] of Object.entries(query)) {\n if (raw === undefined) { continue }\n const declared = hasBody ? queryKeys.has(key) : (key in shape && !pathParams.has(key))\n if (!declared) { continue }\n merged[key] = Array.isArray(raw) ? raw : coerceScalar(shape[key], raw)\n }\n\n for (const key of pathParams) {\n const raw = params[key]\n if (raw === undefined) { continue }\n merged[key] = coerceScalar(shape[key], raw)\n }\n\n return merged\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Action, ActionStreamRun, isStreamingAction } from './action.js'\nimport { SilkweaveContext } from './context.js'\n\n/**\n * Drive a streaming action's async generator. Calls `onChunk` once per yielded\n * value and awaits it before pulling the next value from the generator - this\n * is what wires transport-level backpressure (SSE drain, stdout flush, tRPC\n * subscription consumer) back to the action.\n *\n * Returns the buffered array of all chunks. Use this for non-streaming\n * adapters or when a client has opted out of streaming (e.g. no MCP\n * `progressToken`). Pass `onChunk` to also emit each chunk on the wire.\n */\nexport async function runStreamingAction<C>(\n action: Action<any, any, string, any, C>,\n input: object,\n context: SilkweaveContext,\n onChunk?: (chunk: C, index: number) => void | Promise<void>\n): Promise<C[]> {\n if (!isStreamingAction(action)) {\n throw new Error(`Action ${action.name} is not a streaming action`)\n }\n const run = action.run as ActionStreamRun<object, C>\n const iter = run(input, context)\n const chunks: C[] = []\n let index = 0\n for await (const chunk of iter) {\n chunks.push(chunk)\n if (onChunk) { await onChunk(chunk, index) }\n index += 1\n }\n return chunks\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/util/context.ts","../src/util/zod.ts","../src/util/lint.ts","../src/lib/silkweave.ts","../src/util/action.ts","../src/util/error.ts","../src/util/http.ts","../src/util/streaming.ts"],"sourcesContent":["export interface SilkweaveContext {\n keys: () => string[]\n has: (key: string) => boolean\n get: <T>(key: string) => T\n getOptional: <T>(key: string) => T | undefined\n set: <T>(key: string, value: T) => void\n fork: (store?: Record<string, unknown>) => SilkweaveContext\n}\n\nexport function createContext(store: Record<string, unknown> = {}): SilkweaveContext {\n return {\n keys: () => {\n return Object.keys(store)\n },\n has: (key: string): boolean => {\n return store[key] != null\n },\n get: <T>(key: string): T => {\n const value = store[key]\n if (value == null) { throw new Error(`Invalid context key: ${key}`) }\n return value as T\n },\n getOptional: <T>(key: string): T | undefined => {\n return store[key] as T | undefined\n },\n set: <T>(key: string, value: T) => {\n store[key] = value\n },\n fork: (value?: Record<string, unknown>) => {\n return createContext({ ...store, ...value })\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { z } from 'zod/v4'\n\nexport interface UnwrapResult {\n defaultValue?: any\n isOptional?: boolean\n isNullable?: boolean\n isReadOnly?: boolean\n}\n\nexport function unwrap(\n type: z.ZodTypeAny,\n result: UnwrapResult = {}\n): [z.ZodTypeAny, UnwrapResult] {\n if (type instanceof z.ZodOptional) {\n result.isOptional = true\n return unwrap(type.unwrap() as z.ZodTypeAny, result)\n } else if (type instanceof z.ZodNullable) {\n result.isNullable = true\n return unwrap(type.unwrap() as z.ZodTypeAny, result)\n } else if (type instanceof z.ZodReadonly) {\n result.isReadOnly = true\n return unwrap(type.def.innerType as z.ZodTypeAny, result)\n } else if (type instanceof z.ZodDefault) {\n result.defaultValue = typeof type.def.defaultValue === 'function'\n ? type.def.defaultValue()\n : type.def.defaultValue\n return unwrap(type.unwrap() as z.ZodTypeAny, result)\n } else {\n return [type, result]\n }\n}\n","import { z } from 'zod/v4'\nimport { Action } from './action.js'\nimport { unwrap } from './zod.js'\n\nexport type ActionLintCode =\n | 'missing-description'\n | 'short-description'\n | 'undescribed-params'\n | 'some-undescribed-params'\n\nexport interface ActionLintWarning {\n action: string\n code: ActionLintCode\n message: string\n}\n\n/** A description shorter than this reads as a placeholder to an agent picking a tool. */\nconst MIN_DESCRIPTION_LENGTH = 12\n\n/** A field's `.describe()` text, looking through optional/default/nullable/readonly wrappers. */\nfunction describedText(field: z.ZodTypeAny): string | undefined {\n if (field.description) { return field.description }\n const [base] = unwrap(field)\n return base.description\n}\n\n/**\n * Static checks for agent-hostile action definitions - the cheap mistakes that\n * quietly degrade tool-use: a missing or throwaway description (the model reads\n * it to decide when to call the tool) and undescribed input parameters (the\n * model guesses what to pass). Pure + side-effect-free; `reportActionLint` wires\n * it to a warn sink, and `silkweave().start()` runs it automatically.\n */\nexport function lintActions(actions: Action[]): ActionLintWarning[] {\n const warnings: ActionLintWarning[] = []\n for (const action of actions) {\n const description = action.description?.trim() ?? ''\n if (!description) {\n warnings.push({\n action: action.name,\n code: 'missing-description',\n message: `Action \"${action.name}\" has no description - MCP clients show it to the model to decide when to call the tool. Add a clear, specific sentence.`\n })\n } else if (description.length < MIN_DESCRIPTION_LENGTH) {\n warnings.push({\n action: action.name,\n code: 'short-description',\n message: `Action \"${action.name}\" description is very short (\"${description}\"). A fuller sentence helps agents choose the right tool.`\n })\n }\n\n const shape = action.input?.shape ?? {}\n const params = Object.keys(shape)\n const undescribed = params.filter((name) => !describedText(shape[name]))\n if (params.length > 0 && undescribed.length === params.length) {\n warnings.push({\n action: action.name,\n code: 'undescribed-params',\n message: `Action \"${action.name}\" has no described input parameters (${params.join(', ')}). Add .describe() to each field so agents pass correct values.`\n })\n } else if (undescribed.length > 0) {\n warnings.push({\n action: action.name,\n code: 'some-undescribed-params',\n message: `Action \"${action.name}\" input fields lack descriptions: ${undescribed.join(', ')}. Add .describe() for better agent tool-use.`\n })\n }\n }\n return warnings\n}\n\n/**\n * Run `lintActions` and emit each warning through `warn` (default `console.warn`,\n * which goes to stderr - safe even for the stdio MCP transport). Returns the\n * warnings so callers can also inspect or suppress them.\n */\nexport function reportActionLint(\n actions: Action[],\n warn: (message: string) => void = (message) => { console.warn(message) }\n): ActionLintWarning[] {\n const warnings = lintActions(actions)\n for (const warning of warnings) {\n warn(`[silkweave] ${warning.message}`)\n }\n return warnings\n}\n","import { Action } from '../util/action.js'\nimport { Adapter, AdapterGenerator, SilkweaveOptions } from '../util/adapter.js'\nimport { createContext } from '../util/context.js'\nimport { reportActionLint } from '../util/lint.js'\n\nexport type { SilkweaveOptions } from '../util/adapter.js'\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface Silkweave<Actions extends Record<string, Action> = {}> {\n set: <T>(key: string, value: T) => Silkweave<Actions>\n adapter: (generator: AdapterGenerator) => Silkweave<Actions>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: <A extends Action<any, any, string, any>>(\n action: A\n ) => Silkweave<Actions & Record<A['name'], A>>\n actions: <Arr extends readonly Action[]>(\n actions: Arr\n ) => Silkweave<Actions & { [K in Arr[number] as K['name']]: K }>\n start: () => Promise<Silkweave<Actions>>\n}\n\nexport function silkweave(options: SilkweaveOptions): Silkweave {\n const adapters: Adapter[] = []\n const actions: Action[] = []\n const context = createContext()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const builder: Silkweave<any> = {\n set: (key, value) => {\n context.set(key, value)\n return builder\n },\n adapter: (generator) => {\n adapters.push(generator(options, context))\n return builder\n },\n action: (value) => {\n actions.push(value)\n return builder\n },\n actions: (values) => {\n actions.push(...values)\n return builder\n },\n start: async () => {\n if (options.lint !== false) { reportActionLint(actions) }\n await Promise.all(adapters.map((adapter) => {\n const filtered = adapter.allActions\n ? actions\n : actions.filter((action) => {\n if (!action.isEnabled) { return true }\n return action.isEnabled(adapter.context)\n })\n return adapter.start(filtered)\n }))\n return builder\n }\n }\n return builder\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { type CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport z from 'zod/v4'\nimport { SilkweaveContext } from './context.js'\n\nexport type ActionKind = 'query' | 'mutation'\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'\n\nexport type ActionRun<I, O> = (input: I, context: SilkweaveContext) => Promise<O>\nexport type ActionStreamRun<I, C> = (input: I, context: SilkweaveContext) => AsyncGenerator<C, void, void>\n\nexport interface Action<\n I extends object = any,\n O extends object = any,\n N extends string = string,\n K extends ActionKind = ActionKind,\n C = any\n> {\n name: N\n description: string\n input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }\n output?: z.ZodType<O> & { shape: Record<string, z.ZodTypeAny> }\n /**\n * Schema for individual chunks yielded by a streaming `run`. Required when\n * `run` is an async generator; adapters detect streaming actions by checking\n * `isStreamingAction(action)` at runtime, but type-aware tooling (inferRouter,\n * typegen) uses the presence of this field.\n */\n chunk?: z.ZodType<C>\n kind?: K\n /**\n * HTTP verb for REST-style adapters (fastify, nestjs `rest`). Defaults to\n * `POST`, or `GET` when `kind` is `'query'`. An explicit `method` always wins.\n */\n method?: HttpMethod\n /**\n * Route path for REST-style adapters. May contain `:param` placeholders\n * (e.g. `'spaces/:spaceId/users'`); each placeholder must be a key of the\n * input schema and is resolved from the URL path at runtime. When unset, the\n * adapter derives the path from `name`.\n */\n path?: string\n /**\n * Input fields sourced from the URL query string instead of the request body\n * (e.g. `['offset', 'limit']`). Each must be a key of the input schema; their\n * required/optional status is validated by the input schema as usual.\n */\n queryParams?: (keyof I)[]\n args?: (keyof I)[]\n /**\n * Default MCP result disposition for this action - `'json'` formats the\n * response with `jsonToolResult` (compact JSON text), `'smart'` (the default\n * when unset) uses `smartToolResult` (inlines small payloads, offloads large\n * ones to an embedded resource). This is only a default: a client that sends\n * `_meta.disposition` on the tool call always wins. Ignored by non-MCP\n * adapters.\n */\n disposition?: 'json' | 'smart'\n isEnabled?: (context: SilkweaveContext) => boolean\n run: ActionRun<I, O> | ActionStreamRun<I, C>\n toolResult?: (response: O, context: SilkweaveContext) => CallToolResult | undefined\n}\n\nexport interface NonStreamingActionInput<I extends object, O extends object, N extends string, K extends ActionKind> {\n name: N\n description: string\n input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }\n output?: z.ZodType<O> & { shape: Record<string, z.ZodTypeAny> }\n kind?: K\n method?: HttpMethod\n path?: string\n queryParams?: (keyof I)[]\n args?: (keyof I)[]\n disposition?: 'json' | 'smart'\n isEnabled?: (context: SilkweaveContext) => boolean\n run: ActionRun<I, O>\n toolResult?: (response: O, context: SilkweaveContext) => CallToolResult | undefined\n}\n\nexport interface StreamingActionInput<I extends object, C, N extends string, K extends ActionKind> {\n name: N\n description: string\n input: z.ZodType<I> & { shape: Record<string, z.ZodTypeAny> }\n chunk: z.ZodType<C>\n kind?: K\n method?: HttpMethod\n path?: string\n queryParams?: (keyof I)[]\n args?: (keyof I)[]\n disposition?: 'json' | 'smart'\n isEnabled?: (context: SilkweaveContext) => boolean\n run: ActionStreamRun<I, C>\n toolResult?: (response: C[], context: SilkweaveContext) => CallToolResult | undefined\n}\n\nexport function createAction<\n I extends object,\n C,\n N extends string,\n K extends ActionKind = 'mutation'\n>(action: StreamingActionInput<I, C, N, K>): StreamingActionInput<I, C, N, K>\nexport function createAction<\n I extends object,\n O extends object,\n N extends string,\n K extends ActionKind = 'mutation'\n>(action: NonStreamingActionInput<I, O, N, K>): NonStreamingActionInput<I, O, N, K>\nexport function createAction(action: Action): Action {\n return action\n}\n\n/**\n * Returns `true` when `action.run` is an async generator function (declared\n * with `async function*`). Adapters use this to switch between buffered\n * request/response and streaming chunk delivery.\n */\nexport function isStreamingAction(action: Action): boolean {\n return action.run?.constructor?.name === 'AsyncGeneratorFunction'\n}\n","export class SilkweaveError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode = 500\n ) {\n super(message)\n this.name = 'SilkweaveError'\n }\n}\n\nexport function notFound(message = 'Not found') {\n return new SilkweaveError(message, 'not_found', 404)\n}\n\nexport function badRequest(message = 'Bad request') {\n return new SilkweaveError(message, 'bad_request', 400)\n}\n\nexport function forbidden(message = 'Forbidden') {\n return new SilkweaveError(message, 'forbidden', 403)\n}\n\nexport function internal(message = 'Internal error') {\n return new SilkweaveError(message, 'internal', 500)\n}\n","import type z from 'zod/v4'\nimport { type Action, type HttpMethod } from './action.js'\nimport { SilkweaveError } from './error.js'\nimport { unwrap } from './zod.js'\n\nconst PATH_PARAM_RE = /:([A-Za-z0-9_]+)/g\n\n/**\n * Resolve the HTTP verb for an action. An explicit `method` always wins;\n * otherwise `kind: 'query'` maps to `GET` and everything else to `POST`.\n */\nexport function actionMethod(action: Pick<Action, 'method' | 'kind'>): HttpMethod {\n if (action.method) { return action.method }\n return action.kind === 'query' ? 'GET' : 'POST'\n}\n\n/** Whether a request with this method carries a body (everything except GET). */\nexport function methodHasBody(method: HttpMethod): boolean {\n return method !== 'GET'\n}\n\n/** Extract the `:param` placeholder names from a route path template. */\nexport function pathParamNames(path: string | undefined): string[] {\n if (!path) { return [] }\n return [...path.matchAll(PATH_PARAM_RE)].map((match) => match[1])\n}\n\n/**\n * Assert that every `:param` in `action.path` and every `queryParams` entry is a\n * field of the input schema. Throws a `SilkweaveError` at registration time so\n * misconfigured routing fails fast instead of silently dropping values.\n */\nexport function validateActionRouting(action: Action): void {\n const shape = action.input.shape\n for (const param of pathParamNames(action.path)) {\n if (!(param in shape)) {\n throw new SilkweaveError(\n `Action \"${action.name}\" path \"${action.path}\" references \":${param}\" but the input schema has no \"${param}\" field`,\n 'invalid_action_routing'\n )\n }\n }\n for (const key of action.queryParams ?? []) {\n if (!(String(key) in shape)) {\n throw new SilkweaveError(\n `Action \"${action.name}\" lists query param \"${String(key)}\" but the input schema has no such field`,\n 'invalid_action_routing'\n )\n }\n }\n}\n\n/**\n * Coerce a raw string (from the URL path or query string) to the primitive the\n * field's schema expects. Non-string values pass through untouched (REST\n * frameworks like Fastify may have already coerced via JSON Schema), and a\n * failed coercion returns the original value so Zod surfaces a proper error.\n */\nfunction coerceScalar(field: z.ZodTypeAny | undefined, value: unknown): unknown {\n if (!field || typeof value !== 'string') { return value }\n const [base] = unwrap(field)\n const type = (base as { def?: { type?: string } }).def?.type\n if (type === 'number') {\n const num = Number(value)\n return value.trim() === '' || Number.isNaN(num) ? value : num\n }\n if (type === 'boolean') {\n if (value === 'true') { return true }\n if (value === 'false') { return false }\n return value\n }\n if (type === 'bigint') {\n try { return BigInt(value) } catch { return value }\n }\n return value\n}\n\nexport interface ActionInputSources {\n /** Path parameters keyed by `:param` name (e.g. Express/Fastify `req.params`). */\n params?: Record<string, string | undefined>\n /** Parsed query string (string values, or arrays/coerced values from a framework). */\n query?: Record<string, unknown>\n /** Parsed request body (already-typed JSON for body methods). */\n body?: unknown\n}\n\n/**\n * Merge an action's path params, query params, and body into a single input\n * object honouring its `method`/`path`/`queryParams` routing config:\n *\n * - body fields form the base layer (only for body-carrying methods),\n * - declared query params override (on bodyless GET requests every input field\n * that is not a path param is read from the query string),\n * - path params override last.\n *\n * String values from the path/query are coerced to the primitive their schema\n * expects. The result is not validated here - callers pass it to\n * `action.input.parse()` (or let a framework validate it).\n */\nexport function resolveActionInput(action: Action, sources: ActionInputSources): Record<string, unknown> {\n const shape = action.input.shape\n const method = actionMethod(action)\n const hasBody = methodHasBody(method)\n const params = sources.params ?? {}\n const query = sources.query ?? {}\n const pathParams = new Set(pathParamNames(action.path))\n const queryKeys = new Set((action.queryParams ?? []).map(String))\n\n const merged: Record<string, unknown> = {}\n\n if (hasBody && sources.body && typeof sources.body === 'object') {\n Object.assign(merged, sources.body as Record<string, unknown>)\n }\n\n for (const [key, raw] of Object.entries(query)) {\n if (raw === undefined) { continue }\n const declared = hasBody ? queryKeys.has(key) : (key in shape && !pathParams.has(key))\n if (!declared) { continue }\n merged[key] = Array.isArray(raw) ? raw : coerceScalar(shape[key], raw)\n }\n\n for (const key of pathParams) {\n const raw = params[key]\n if (raw === undefined) { continue }\n merged[key] = coerceScalar(shape[key], raw)\n }\n\n return merged\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Action, ActionStreamRun, isStreamingAction } from './action.js'\nimport { SilkweaveContext } from './context.js'\n\n/**\n * Drive a streaming action's async generator. Calls `onChunk` once per yielded\n * value and awaits it before pulling the next value from the generator - this\n * is what wires transport-level backpressure (SSE drain, stdout flush, tRPC\n * subscription consumer) back to the action.\n *\n * Returns the buffered array of all chunks. Use this for non-streaming\n * adapters or when a client has opted out of streaming (e.g. no MCP\n * `progressToken`). Pass `onChunk` to also emit each chunk on the wire.\n */\nexport async function runStreamingAction<C>(\n action: Action<any, any, string, any, C>,\n input: object,\n context: SilkweaveContext,\n onChunk?: (chunk: C, index: number) => void | Promise<void>\n): Promise<C[]> {\n if (!isStreamingAction(action)) {\n throw new Error(`Action ${action.name} is not a streaming action`)\n }\n const run = action.run as ActionStreamRun<object, C>\n const iter = run(input, context)\n const chunks: C[] = []\n let index = 0\n for await (const chunk of iter) {\n chunks.push(chunk)\n if (onChunk) { await onChunk(chunk, index) }\n index += 1\n }\n return chunks\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silkweave/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Silkweave Core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.silkweave.dev",
|
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
30
|
-
"@silkweave/logger": "2.6.0"
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
31
30
|
},
|
|
32
31
|
"peerDependencies": {
|
|
33
32
|
"zod": "^3.25.0"
|
|
@@ -43,6 +42,7 @@
|
|
|
43
42
|
"tsx": "^4.21.0",
|
|
44
43
|
"typescript": "^5.9.3",
|
|
45
44
|
"typescript-eslint": "^8.56.1",
|
|
45
|
+
"vitest": "^4.1.9",
|
|
46
46
|
"zod": "^3.25.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"watch": "tsdown --watch",
|
|
52
52
|
"typecheck": "tsc --noEmit",
|
|
53
53
|
"lint": "eslint",
|
|
54
|
-
"check": "pnpm lint && pnpm typecheck"
|
|
54
|
+
"check": "pnpm lint && pnpm typecheck",
|
|
55
|
+
"test": "vitest run"
|
|
55
56
|
}
|
|
56
57
|
}
|