@asnd/skill-creator 0.1.2 → 0.1.3
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 +64 -125
- package/dist/cli/dynamic.d.ts +26 -0
- package/dist/cli/dynamic.js +136 -0
- package/dist/cli/dynamic.js.map +1 -0
- package/dist/cli/main.d.ts +2 -4
- package/dist/cli/main.js +376 -1530
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/parse.d.ts +9 -0
- package/dist/cli/parse.js +38 -0
- package/dist/cli/parse.js.map +1 -0
- package/dist/commands/agents.d.ts +96 -0
- package/dist/commands/agents.js +116 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/install.d.ts +12 -0
- package/dist/commands/install.js +229 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/core/cache.d.ts +3 -0
- package/dist/core/cache.js +52 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/coerce.d.ts +8 -0
- package/dist/core/coerce.js +128 -0
- package/dist/core/coerce.js.map +1 -0
- package/dist/core/filter.d.ts +7 -0
- package/dist/core/filter.js +16 -0
- package/dist/core/filter.js.map +1 -0
- package/dist/core/listing.d.ts +11 -0
- package/dist/core/listing.js +31 -0
- package/dist/core/listing.js.map +1 -0
- package/dist/core/names.d.ts +1 -0
- package/dist/core/names.js +7 -0
- package/dist/core/names.js.map +1 -0
- package/dist/core/output.d.ts +12 -0
- package/dist/core/output.js +34 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/secrets.d.ts +1 -0
- package/dist/core/secrets.js +21 -0
- package/dist/core/secrets.js.map +1 -0
- package/dist/core/types.d.ts +37 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage.d.ts +13 -0
- package/dist/core/usage.js +33 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/graphql/execute.d.ts +8 -0
- package/dist/graphql/execute.js +133 -0
- package/dist/graphql/execute.js.map +1 -0
- package/dist/graphql/extract.d.ts +6 -0
- package/dist/graphql/extract.js +109 -0
- package/dist/graphql/extract.js.map +1 -0
- package/dist/graphql/load.d.ts +11 -0
- package/dist/graphql/load.js +95 -0
- package/dist/graphql/load.js.map +1 -0
- package/dist/mcp/extract.d.ts +8 -0
- package/dist/mcp/extract.js +40 -0
- package/dist/mcp/extract.js.map +1 -0
- package/dist/mcp/http.d.ts +8 -0
- package/dist/mcp/http.js +80 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/stdio.d.ts +9 -0
- package/dist/mcp/stdio.js +67 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/openapi/execute.d.ts +12 -0
- package/dist/openapi/execute.js +44 -0
- package/dist/openapi/execute.js.map +1 -0
- package/dist/openapi/extract.d.ts +2 -0
- package/dist/openapi/extract.js +123 -0
- package/dist/openapi/extract.js.map +1 -0
- package/dist/openapi/load.d.ts +11 -0
- package/dist/openapi/load.js +52 -0
- package/dist/openapi/load.js.map +1 -0
- package/dist/openapi/params.d.ts +12 -0
- package/dist/openapi/params.js +47 -0
- package/dist/openapi/params.js.map +1 -0
- package/dist/openapi/refs.d.ts +1 -0
- package/dist/openapi/refs.js +8 -0
- package/dist/openapi/refs.js.map +1 -0
- package/dist/skills/agents.d.ts +77 -0
- package/dist/skills/agents.js +85 -0
- package/dist/skills/agents.js.map +1 -0
- package/dist/skills/generate.d.ts +1 -0
- package/dist/skills/generate.js +494 -0
- package/dist/skills/generate.js.map +1 -0
- package/package.json +7 -10
- package/prompts/skill-creator.md +169 -0
- package/dist/cli/package-SLCRJ4QY.js +0 -89
- package/dist/cli/package-SLCRJ4QY.js.map +0 -1
- package/prompts/generate-skill.md +0 -22
- package/skills/skill-creator/SKILL.md +0 -260
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type JsonSchema = {
|
|
2
|
+
type?: string;
|
|
3
|
+
format?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
enum?: unknown[];
|
|
6
|
+
items?: JsonSchema;
|
|
7
|
+
properties?: Record<string, JsonSchema>;
|
|
8
|
+
required?: string[];
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
export type CliValueType = 'string' | 'integer' | 'number' | 'boolean';
|
|
12
|
+
export type ParamLocation = 'path' | 'query' | 'header' | 'body' | 'file' | 'tool_input' | 'graphql_arg';
|
|
13
|
+
export type ParamDef = {
|
|
14
|
+
/** kebab-case CLI flag name */
|
|
15
|
+
name: string;
|
|
16
|
+
/** original API/tool argument name */
|
|
17
|
+
originalName: string;
|
|
18
|
+
type: CliValueType;
|
|
19
|
+
required?: boolean;
|
|
20
|
+
description?: string;
|
|
21
|
+
choices?: unknown[];
|
|
22
|
+
location?: ParamLocation;
|
|
23
|
+
schema?: JsonSchema;
|
|
24
|
+
};
|
|
25
|
+
export type CommandDef = {
|
|
26
|
+
name: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
params: ParamDef[];
|
|
29
|
+
hasBody?: boolean;
|
|
30
|
+
method?: string;
|
|
31
|
+
path?: string;
|
|
32
|
+
contentType?: string;
|
|
33
|
+
toolName?: string;
|
|
34
|
+
graphqlOperationType?: 'query' | 'mutation';
|
|
35
|
+
graphqlFieldName?: string;
|
|
36
|
+
graphqlReturnType?: unknown;
|
|
37
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type UsageEntry = {
|
|
2
|
+
count: number;
|
|
3
|
+
lastUsed: string;
|
|
4
|
+
};
|
|
5
|
+
export type UsageData = Record<string, Record<string, UsageEntry>>;
|
|
6
|
+
export declare function sourceHashFor(source: string): string;
|
|
7
|
+
export declare class UsageStore {
|
|
8
|
+
private readonly filePath;
|
|
9
|
+
constructor(filePath: string);
|
|
10
|
+
load(): Promise<UsageData>;
|
|
11
|
+
save(data: UsageData): Promise<void>;
|
|
12
|
+
record(sourceHash: string, toolName: string, now?: Date): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
export function sourceHashFor(source) {
|
|
5
|
+
return createHash('sha256').update(source).digest('hex').slice(0, 16);
|
|
6
|
+
}
|
|
7
|
+
export class UsageStore {
|
|
8
|
+
filePath;
|
|
9
|
+
constructor(filePath) {
|
|
10
|
+
this.filePath = filePath;
|
|
11
|
+
}
|
|
12
|
+
async load() {
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(await readFile(this.filePath, 'utf8'));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async save(data) {
|
|
21
|
+
await mkdir(dirname(this.filePath), { recursive: true });
|
|
22
|
+
await writeFile(this.filePath, `${JSON.stringify(data, null, 2)}\n`);
|
|
23
|
+
}
|
|
24
|
+
async record(sourceHash, toolName, now = new Date()) {
|
|
25
|
+
const usage = await this.load();
|
|
26
|
+
usage[sourceHash] ??= {};
|
|
27
|
+
usage[sourceHash][toolName] ??= { count: 0, lastUsed: '' };
|
|
28
|
+
usage[sourceHash][toolName].count += 1;
|
|
29
|
+
usage[sourceHash][toolName].lastUsed = now.toISOString();
|
|
30
|
+
await this.save(usage);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/core/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,OAAO,UAAU;IACQ,QAAQ;IAArC,YAA6B,QAAgB;wBAAhB,QAAQ;IAAW,CAAC;IAEjD,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAc,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAe;QACxB,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,QAAgB,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;QACjE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC3D,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACvC,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACzD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CommandDef } from '../core/types.js';
|
|
2
|
+
export type ExecuteGraphqlOptions = {
|
|
3
|
+
endpoint: string;
|
|
4
|
+
authHeaders?: Array<[string, string]>;
|
|
5
|
+
fields?: string;
|
|
6
|
+
selectionDepth?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function executeGraphql(command: CommandDef, values: Record<string, unknown>, options: ExecuteGraphqlOptions): Promise<unknown>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Kind, OperationTypeNode, parse, print, } from 'graphql';
|
|
2
|
+
import { ClientError, GraphQLClient } from 'graphql-request';
|
|
3
|
+
import { coerceAndValidateValue } from '../core/coerce.js';
|
|
4
|
+
import { buildGraphqlSelectionSet } from './extract.js';
|
|
5
|
+
export async function executeGraphql(command, values, options) {
|
|
6
|
+
const fieldName = command.graphqlFieldName ?? command.name;
|
|
7
|
+
const variables = collectVariables(command, values);
|
|
8
|
+
const query = buildGraphqlOperation(command, fieldName, variables, options.fields, options.selectionDepth ?? 2);
|
|
9
|
+
const client = new GraphQLClient(options.endpoint, {
|
|
10
|
+
headers: Object.fromEntries(options.authHeaders ?? []),
|
|
11
|
+
});
|
|
12
|
+
try {
|
|
13
|
+
const data = await client.request(query, variables);
|
|
14
|
+
if (!isRecord(data))
|
|
15
|
+
return data;
|
|
16
|
+
return data[fieldName];
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw normalizeGraphqlRequestError(error);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function collectVariables(command, values) {
|
|
23
|
+
const variables = {};
|
|
24
|
+
for (const param of command.params) {
|
|
25
|
+
const value = values[param.name] ?? values[param.originalName];
|
|
26
|
+
if (value !== undefined) {
|
|
27
|
+
variables[param.originalName] = coerceAndValidateValue(value, param.schema ?? {}, `--${param.name}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return variables;
|
|
31
|
+
}
|
|
32
|
+
function buildGraphqlOperation(command, fieldName, variables, fields, selectionDepth) {
|
|
33
|
+
const activeParams = command.params.filter((param) => param.required || variables[param.originalName] !== undefined);
|
|
34
|
+
const variableDefinitions = activeParams.map((param) => ({
|
|
35
|
+
kind: Kind.VARIABLE_DEFINITION,
|
|
36
|
+
variable: {
|
|
37
|
+
kind: Kind.VARIABLE,
|
|
38
|
+
name: { kind: Kind.NAME, value: param.originalName },
|
|
39
|
+
},
|
|
40
|
+
type: parseGraphqlType(graphqlParamType(param)),
|
|
41
|
+
}));
|
|
42
|
+
const selectionSet = buildSelectionSetNode(command, fields, selectionDepth);
|
|
43
|
+
const field = {
|
|
44
|
+
kind: Kind.FIELD,
|
|
45
|
+
name: { kind: Kind.NAME, value: fieldName },
|
|
46
|
+
arguments: activeParams.map((param) => ({
|
|
47
|
+
kind: Kind.ARGUMENT,
|
|
48
|
+
name: { kind: Kind.NAME, value: param.originalName },
|
|
49
|
+
value: {
|
|
50
|
+
kind: Kind.VARIABLE,
|
|
51
|
+
name: { kind: Kind.NAME, value: param.originalName },
|
|
52
|
+
},
|
|
53
|
+
})),
|
|
54
|
+
...(selectionSet === undefined ? {} : { selectionSet }),
|
|
55
|
+
};
|
|
56
|
+
const operation = {
|
|
57
|
+
kind: Kind.OPERATION_DEFINITION,
|
|
58
|
+
operation: command.graphqlOperationType === 'mutation'
|
|
59
|
+
? OperationTypeNode.MUTATION
|
|
60
|
+
: OperationTypeNode.QUERY,
|
|
61
|
+
name: { kind: Kind.NAME, value: commandName(command) },
|
|
62
|
+
...(variableDefinitions.length === 0 ? {} : { variableDefinitions }),
|
|
63
|
+
selectionSet: { kind: Kind.SELECTION_SET, selections: [field] },
|
|
64
|
+
};
|
|
65
|
+
const document = { kind: Kind.DOCUMENT, definitions: [operation] };
|
|
66
|
+
return print(document);
|
|
67
|
+
}
|
|
68
|
+
function buildSelectionSetNode(command, fields, selectionDepth) {
|
|
69
|
+
if (command.graphqlReturnType === undefined)
|
|
70
|
+
return undefined;
|
|
71
|
+
const selectionSet = buildGraphqlSelectionSet(command.graphqlReturnType, fields, selectionDepth);
|
|
72
|
+
if (selectionSet.length === 0)
|
|
73
|
+
return undefined;
|
|
74
|
+
return parseSelectionSet(selectionSet);
|
|
75
|
+
}
|
|
76
|
+
function parseGraphqlType(type) {
|
|
77
|
+
const operation = parseSingleOperation(`query __Type($value: ${type}) { __typename }`);
|
|
78
|
+
const variable = operation.variableDefinitions?.[0];
|
|
79
|
+
if (variable === undefined)
|
|
80
|
+
throw new Error(`invalid GraphQL variable type: ${type}`);
|
|
81
|
+
return variable.type;
|
|
82
|
+
}
|
|
83
|
+
function parseSelectionSet(selectionSet) {
|
|
84
|
+
const operation = parseSingleOperation(`query __Selection { _selection ${selectionSet} }`);
|
|
85
|
+
const selection = operation.selectionSet.selections[0];
|
|
86
|
+
if (selection?.kind !== Kind.FIELD || selection.selectionSet === undefined) {
|
|
87
|
+
throw new Error('invalid GraphQL selection set');
|
|
88
|
+
}
|
|
89
|
+
return selection.selectionSet;
|
|
90
|
+
}
|
|
91
|
+
function parseSingleOperation(source) {
|
|
92
|
+
const document = parse(source);
|
|
93
|
+
const definition = document.definitions[0];
|
|
94
|
+
if (definition?.kind !== Kind.OPERATION_DEFINITION) {
|
|
95
|
+
throw new Error('failed to build GraphQL operation');
|
|
96
|
+
}
|
|
97
|
+
return definition;
|
|
98
|
+
}
|
|
99
|
+
function graphqlParamType(param) {
|
|
100
|
+
const type = param.schema?.graphqlType;
|
|
101
|
+
return typeof type === 'string' ? type : jsonSchemaToGraphqlType(param.schema?.type);
|
|
102
|
+
}
|
|
103
|
+
function jsonSchemaToGraphqlType(type) {
|
|
104
|
+
switch (type) {
|
|
105
|
+
case 'integer':
|
|
106
|
+
return 'Int';
|
|
107
|
+
case 'number':
|
|
108
|
+
return 'Float';
|
|
109
|
+
case 'boolean':
|
|
110
|
+
return 'Boolean';
|
|
111
|
+
default:
|
|
112
|
+
return 'String';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function commandName(command) {
|
|
116
|
+
return `${command.graphqlOperationType ?? 'query'}_${command.graphqlFieldName ?? command.name}`.replace(/[^_0-9A-Za-z]/g, '_');
|
|
117
|
+
}
|
|
118
|
+
function normalizeGraphqlRequestError(error) {
|
|
119
|
+
if (error instanceof ClientError) {
|
|
120
|
+
if (error.response.errors !== undefined && error.response.errors.length > 0) {
|
|
121
|
+
return new Error(`GraphQL error: ${formatGraphqlErrors(error.response.errors)}`);
|
|
122
|
+
}
|
|
123
|
+
return new Error(`GraphQL HTTP ${error.response.status}: ${JSON.stringify(error.response, null, 0)}`);
|
|
124
|
+
}
|
|
125
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
126
|
+
}
|
|
127
|
+
function formatGraphqlErrors(errors) {
|
|
128
|
+
return errors.map((error) => error.message ?? 'unknown error').join('; ');
|
|
129
|
+
}
|
|
130
|
+
function isRecord(value) {
|
|
131
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/graphql/execute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type GraphQLInputType, type GraphQLOutputType, type GraphQLSchema, type GraphQLType } from 'graphql';
|
|
2
|
+
import type { CommandDef, JsonSchema } from '../core/types.js';
|
|
3
|
+
export declare function extractGraphqlCommands(schema: GraphQLSchema): CommandDef[];
|
|
4
|
+
export declare function buildGraphqlSelectionSet(type: GraphQLOutputType, fields?: string, depth?: number): string;
|
|
5
|
+
export declare function graphqlInputTypeToJsonSchema(type: GraphQLInputType): JsonSchema;
|
|
6
|
+
export declare function graphqlTypeToString(type: GraphQLType): string;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { getNamedType, isEnumType, isInputObjectType, isInterfaceType, isListType, isNonNullType, isObjectType, isScalarType, } from 'graphql';
|
|
2
|
+
import { schemaTypeToCliType } from '../core/coerce.js';
|
|
3
|
+
import { toKebab } from '../core/names.js';
|
|
4
|
+
export function extractGraphqlCommands(schema) {
|
|
5
|
+
const commands = [];
|
|
6
|
+
addRootFields(commands, schema.getQueryType()?.getFields(), 'query');
|
|
7
|
+
addRootFields(commands, schema.getMutationType()?.getFields(), 'mutation');
|
|
8
|
+
return commands;
|
|
9
|
+
}
|
|
10
|
+
export function buildGraphqlSelectionSet(type, fields, depth = 2) {
|
|
11
|
+
if (fields !== undefined && fields.trim().length > 0)
|
|
12
|
+
return `{ ${fields.trim()} }`;
|
|
13
|
+
return buildDefaultSelectionSet(type, depth, new Set());
|
|
14
|
+
}
|
|
15
|
+
function addRootFields(commands, fields, operationType) {
|
|
16
|
+
if (fields === undefined)
|
|
17
|
+
return;
|
|
18
|
+
for (const field of Object.values(fields)) {
|
|
19
|
+
const description = optionalString(field.description);
|
|
20
|
+
commands.push({
|
|
21
|
+
name: toKebab(field.name),
|
|
22
|
+
...(description === undefined ? {} : { description }),
|
|
23
|
+
params: field.args.map((arg) => graphqlArgToParam(arg.name, arg.type, optionalString(arg.description))),
|
|
24
|
+
graphqlOperationType: operationType,
|
|
25
|
+
graphqlFieldName: field.name,
|
|
26
|
+
graphqlReturnType: field.type,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function graphqlArgToParam(name, type, description) {
|
|
31
|
+
const schema = graphqlInputTypeToJsonSchema(type);
|
|
32
|
+
const cliType = schemaTypeToCliType(schema).type;
|
|
33
|
+
return {
|
|
34
|
+
name: toKebab(name),
|
|
35
|
+
originalName: name,
|
|
36
|
+
type: cliType,
|
|
37
|
+
required: isNonNullType(type),
|
|
38
|
+
...(description === undefined ? {} : { description }),
|
|
39
|
+
location: 'graphql_arg',
|
|
40
|
+
schema,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function graphqlInputTypeToJsonSchema(type) {
|
|
44
|
+
if (isNonNullType(type)) {
|
|
45
|
+
return { ...graphqlInputTypeToJsonSchema(type.ofType), graphqlType: graphqlTypeToString(type) };
|
|
46
|
+
}
|
|
47
|
+
if (isListType(type)) {
|
|
48
|
+
return {
|
|
49
|
+
type: 'array',
|
|
50
|
+
items: graphqlInputTypeToJsonSchema(type.ofType),
|
|
51
|
+
graphqlType: graphqlTypeToString(type),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const namedType = getNamedType(type);
|
|
55
|
+
const base = { graphqlType: graphqlTypeToString(type) };
|
|
56
|
+
if (isEnumType(namedType)) {
|
|
57
|
+
return { ...base, type: 'string', enum: namedType.getValues().map((value) => value.name) };
|
|
58
|
+
}
|
|
59
|
+
if (isInputObjectType(namedType))
|
|
60
|
+
return { ...base, type: 'object' };
|
|
61
|
+
if (isScalarType(namedType)) {
|
|
62
|
+
switch (namedType.name) {
|
|
63
|
+
case 'Int':
|
|
64
|
+
return { ...base, type: 'integer' };
|
|
65
|
+
case 'Float':
|
|
66
|
+
return { ...base, type: 'number' };
|
|
67
|
+
case 'Boolean':
|
|
68
|
+
return { ...base, type: 'boolean' };
|
|
69
|
+
default:
|
|
70
|
+
return { ...base, type: 'string' };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { ...base, type: 'string' };
|
|
74
|
+
}
|
|
75
|
+
export function graphqlTypeToString(type) {
|
|
76
|
+
if (isNonNullType(type))
|
|
77
|
+
return `${graphqlTypeToString(type.ofType)}!`;
|
|
78
|
+
if (isListType(type))
|
|
79
|
+
return `[${graphqlTypeToString(type.ofType)}]`;
|
|
80
|
+
return getNamedType(type).name;
|
|
81
|
+
}
|
|
82
|
+
function optionalString(value) {
|
|
83
|
+
return value ?? undefined;
|
|
84
|
+
}
|
|
85
|
+
function buildDefaultSelectionSet(type, depth, seenTypes) {
|
|
86
|
+
const namedType = getNamedType(type);
|
|
87
|
+
if (isScalarType(namedType) || isEnumType(namedType))
|
|
88
|
+
return '';
|
|
89
|
+
if (depth <= 0)
|
|
90
|
+
return '';
|
|
91
|
+
if (!isObjectType(namedType) && !isInterfaceType(namedType))
|
|
92
|
+
return '{ __typename }';
|
|
93
|
+
if (seenTypes.has(namedType.name))
|
|
94
|
+
return '';
|
|
95
|
+
const nextSeen = new Set(seenTypes);
|
|
96
|
+
nextSeen.add(namedType.name);
|
|
97
|
+
const selections = Object.values(namedType.getFields())
|
|
98
|
+
.filter((field) => field.args.length === 0)
|
|
99
|
+
.map((field) => {
|
|
100
|
+
const fieldNamedType = getNamedType(field.type);
|
|
101
|
+
if (isScalarType(fieldNamedType) || isEnumType(fieldNamedType))
|
|
102
|
+
return field.name;
|
|
103
|
+
const nested = buildDefaultSelectionSet(field.type, depth - 1, nextSeen);
|
|
104
|
+
return nested ? `${field.name} ${nested}` : '';
|
|
105
|
+
})
|
|
106
|
+
.filter((field) => field.length > 0);
|
|
107
|
+
return selections.length === 0 ? '' : `{ ${selections.join(' ')} }`;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/graphql/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type GraphQLSchema } from 'graphql';
|
|
2
|
+
export type LoadGraphqlOptions = {
|
|
3
|
+
authHeaders?: Array<[string, string]>;
|
|
4
|
+
cacheDir?: string;
|
|
5
|
+
cacheKey?: string;
|
|
6
|
+
ttlSeconds?: number;
|
|
7
|
+
refresh?: boolean;
|
|
8
|
+
schemaSource?: string;
|
|
9
|
+
onWarning?: (message: string) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function loadGraphqlSchema(endpoint: string, options?: LoadGraphqlOptions): Promise<GraphQLSchema>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
|
|
2
|
+
import { JsonFileLoader } from '@graphql-tools/json-file-loader';
|
|
3
|
+
import { loadSchema } from '@graphql-tools/load';
|
|
4
|
+
import { UrlLoader } from '@graphql-tools/url-loader';
|
|
5
|
+
import { buildClientSchema, buildSchema, getIntrospectionQuery, introspectionFromSchema, } from 'graphql';
|
|
6
|
+
import { GraphQLClient } from 'graphql-request';
|
|
7
|
+
import ky from 'ky';
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
import { cacheKeyFor, loadCached, saveCache } from '../core/cache.js';
|
|
10
|
+
export async function loadGraphqlSchema(endpoint, options = {}) {
|
|
11
|
+
const authHeaders = options.authHeaders ?? [];
|
|
12
|
+
if (options.schemaSource !== undefined) {
|
|
13
|
+
return loadProvidedGraphqlSchema(options.schemaSource, authHeaders);
|
|
14
|
+
}
|
|
15
|
+
const cacheKey = `graphql-${options.cacheKey ?? cacheKeyFor({ endpoint, authHeaders: options.authHeaders ?? [] })}`;
|
|
16
|
+
const ttlSeconds = options.ttlSeconds ?? 3600;
|
|
17
|
+
if (options.cacheDir !== undefined && !options.refresh) {
|
|
18
|
+
const cached = await loadCached(options.cacheDir, cacheKey, ttlSeconds);
|
|
19
|
+
if (cached !== null)
|
|
20
|
+
return buildClientSchema(cached);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const schema = await loadRemoteGraphqlSchema(endpoint, authHeaders);
|
|
24
|
+
if (options.cacheDir !== undefined) {
|
|
25
|
+
await saveCache(options.cacheDir, cacheKey, introspectionFromSchema(schema));
|
|
26
|
+
}
|
|
27
|
+
return schema;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (options.cacheDir !== undefined) {
|
|
31
|
+
const stale = await loadCached(options.cacheDir, cacheKey, Number.POSITIVE_INFINITY);
|
|
32
|
+
if (stale !== null) {
|
|
33
|
+
options.onWarning?.(`Warning: using stale cached GraphQL schema because introspection failed: ${formatError(error)}`);
|
|
34
|
+
return buildClientSchema(stale);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`GraphQL introspection is disabled or unavailable. Provide a schema with --graphql-schema ./schema.graphql or --graphql-schema ./introspection.json. (${formatError(error)})`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function loadRemoteGraphqlSchema(endpoint, authHeaders) {
|
|
41
|
+
const client = new GraphQLClient(endpoint, {
|
|
42
|
+
headers: Object.fromEntries(authHeaders),
|
|
43
|
+
});
|
|
44
|
+
const introspection = await client.request(getIntrospectionQuery());
|
|
45
|
+
return buildClientSchema(introspection);
|
|
46
|
+
}
|
|
47
|
+
async function loadProvidedGraphqlSchema(source, authHeaders) {
|
|
48
|
+
try {
|
|
49
|
+
const schema = await loadSchema(source, {
|
|
50
|
+
loaders: [new UrlLoader(), new GraphQLFileLoader(), new JsonFileLoader()],
|
|
51
|
+
headers: Object.fromEntries(authHeaders),
|
|
52
|
+
});
|
|
53
|
+
return buildClientSchema(introspectionFromSchema(schema));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return loadProvidedGraphqlSchemaFallback(source, authHeaders);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function loadProvidedGraphqlSchemaFallback(source, authHeaders) {
|
|
60
|
+
const text = await readSchemaSource(source, authHeaders);
|
|
61
|
+
const trimmed = text.trim();
|
|
62
|
+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
63
|
+
const parsed = JSON.parse(trimmed);
|
|
64
|
+
return buildClientSchema(extractIntrospection(parsed));
|
|
65
|
+
}
|
|
66
|
+
return buildSchema(text);
|
|
67
|
+
}
|
|
68
|
+
async function readSchemaSource(source, authHeaders) {
|
|
69
|
+
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
70
|
+
const response = await ky.get(source, {
|
|
71
|
+
headers: Object.fromEntries(authHeaders),
|
|
72
|
+
throwHttpErrors: false,
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok)
|
|
75
|
+
throw new Error(`failed to fetch GraphQL schema: HTTP ${response.status}`);
|
|
76
|
+
return response.text();
|
|
77
|
+
}
|
|
78
|
+
return readFile(source, 'utf8');
|
|
79
|
+
}
|
|
80
|
+
function extractIntrospection(value) {
|
|
81
|
+
if (!isRecord(value))
|
|
82
|
+
throw new Error('GraphQL schema JSON must be an object');
|
|
83
|
+
if (isRecord(value.data))
|
|
84
|
+
return extractIntrospection(value.data);
|
|
85
|
+
if (isRecord(value.__schema))
|
|
86
|
+
return value;
|
|
87
|
+
throw new Error('GraphQL schema JSON must contain an introspection __schema object');
|
|
88
|
+
}
|
|
89
|
+
function formatError(error) {
|
|
90
|
+
return error instanceof Error ? error.message : String(error);
|
|
91
|
+
}
|
|
92
|
+
function isRecord(value) {
|
|
93
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/graphql/load.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { schemaTypeToCliType } from '../core/coerce.js';
|
|
2
|
+
import { toKebab } from '../core/names.js';
|
|
3
|
+
export function extractMcpCommands(tools) {
|
|
4
|
+
return tools.map((tool) => {
|
|
5
|
+
const schema = isJsonSchema(tool.inputSchema) ? tool.inputSchema : {};
|
|
6
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
7
|
+
const properties = getProperties(schema);
|
|
8
|
+
const params = Object.entries(properties).map(([name, propSchema]) => {
|
|
9
|
+
const { type, suffix } = schemaTypeToCliType(propSchema);
|
|
10
|
+
const choices = Array.isArray(propSchema.enum) ? { choices: propSchema.enum } : {};
|
|
11
|
+
return {
|
|
12
|
+
name: toKebab(name),
|
|
13
|
+
originalName: name,
|
|
14
|
+
type,
|
|
15
|
+
required: required.has(name),
|
|
16
|
+
description: `${String(propSchema.description ?? name)}${suffix}`,
|
|
17
|
+
...choices,
|
|
18
|
+
location: 'tool_input',
|
|
19
|
+
schema: propSchema,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
name: toKebab(tool.name),
|
|
24
|
+
description: tool.description ?? '',
|
|
25
|
+
params,
|
|
26
|
+
hasBody: params.length > 0,
|
|
27
|
+
toolName: tool.name,
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function getProperties(schema) {
|
|
32
|
+
const properties = schema.properties;
|
|
33
|
+
if (typeof properties !== 'object' || properties === null || Array.isArray(properties))
|
|
34
|
+
return {};
|
|
35
|
+
return Object.fromEntries(Object.entries(properties).filter((entry) => isJsonSchema(entry[1])));
|
|
36
|
+
}
|
|
37
|
+
function isJsonSchema(value) {
|
|
38
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/mcp/extract.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAQ3C,MAAM,UAAU,kBAAkB,CAAC,KAAoB;IACrD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAc,EAAE;QACpC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAY,EAAE;YAC7E,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;YACzD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,OAAO;gBACL,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;gBACnB,YAAY,EAAE,IAAI;gBAClB,IAAI;gBACJ,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC5B,WAAW,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,MAAM,EAAE;gBACjE,GAAG,OAAO;gBACV,QAAQ,EAAE,YAAY;gBACtB,MAAM,EAAE,UAAU;aACnB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YACxB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,MAAM;YACN,OAAO,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,IAAI;SACpB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,MAAkB;IACvC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACrC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IAClG,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAiC,EAAE,CACzE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACvB,CACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type McpTool } from './stdio.js';
|
|
2
|
+
export type McpHttpTransport = 'auto' | 'streamable' | 'sse';
|
|
3
|
+
export type McpHttpOptions = {
|
|
4
|
+
headers?: Array<[string, string]>;
|
|
5
|
+
transport?: McpHttpTransport;
|
|
6
|
+
};
|
|
7
|
+
export declare function listHttpTools(url: string, optionsOrHeaders?: McpHttpOptions | Array<[string, string]>): Promise<McpTool[]>;
|
|
8
|
+
export declare function callHttpTool(url: string, toolName: string, args: Record<string, unknown>, optionsOrHeaders?: McpHttpOptions | Array<[string, string]>): Promise<unknown>;
|
package/dist/mcp/http.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
3
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
4
|
+
import { extractMcpContent } from './stdio.js';
|
|
5
|
+
export async function listHttpTools(url, optionsOrHeaders = {}) {
|
|
6
|
+
const options = normalizeOptions(optionsOrHeaders);
|
|
7
|
+
return withHttpClient(url, options, async (client) => {
|
|
8
|
+
const result = await client.listTools();
|
|
9
|
+
return result.tools.map((tool) => ({
|
|
10
|
+
name: tool.name,
|
|
11
|
+
...(tool.description === undefined ? {} : { description: tool.description }),
|
|
12
|
+
inputSchema: tool.inputSchema,
|
|
13
|
+
}));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export async function callHttpTool(url, toolName, args, optionsOrHeaders = {}) {
|
|
17
|
+
const options = normalizeOptions(optionsOrHeaders);
|
|
18
|
+
return withHttpClient(url, options, async (client) => {
|
|
19
|
+
const result = await client.callTool({ name: toolName, arguments: args });
|
|
20
|
+
return extractMcpContent(result.content);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function withHttpClient(url, options, fn) {
|
|
24
|
+
if (options.transport === 'auto') {
|
|
25
|
+
try {
|
|
26
|
+
return await withSingleHttpClient(url, { ...options, transport: 'streamable' }, fn);
|
|
27
|
+
}
|
|
28
|
+
catch (streamableError) {
|
|
29
|
+
try {
|
|
30
|
+
return await withSingleHttpClient(url, { ...options, transport: 'sse' }, fn);
|
|
31
|
+
}
|
|
32
|
+
catch (sseError) {
|
|
33
|
+
throw new Error(`failed to connect using streamable HTTP or SSE (${formatError(streamableError)}; ${formatError(sseError)})`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return withSingleHttpClient(url, options, fn);
|
|
38
|
+
}
|
|
39
|
+
async function withSingleHttpClient(url, options, fn) {
|
|
40
|
+
const client = new Client({ name: 'skill-creator', version: '0.1.0' });
|
|
41
|
+
const transport = createTransport(url, options);
|
|
42
|
+
await client.connect(transport);
|
|
43
|
+
try {
|
|
44
|
+
return await fn(client);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
await client.close();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function createTransport(url, options) {
|
|
51
|
+
const headers = Object.fromEntries(options.headers);
|
|
52
|
+
if (options.transport === 'sse') {
|
|
53
|
+
const fetchWithHeaders = (input, init) => fetch(input, { ...init, headers: { ...headers, ...headersToObject(init?.headers) } });
|
|
54
|
+
return new SSEClientTransport(new URL(url), {
|
|
55
|
+
eventSourceInit: { fetch: fetchWithHeaders },
|
|
56
|
+
requestInit: { headers },
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return new StreamableHTTPClientTransport(new URL(url), {
|
|
60
|
+
requestInit: { headers },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function normalizeOptions(optionsOrHeaders) {
|
|
64
|
+
if (Array.isArray(optionsOrHeaders)) {
|
|
65
|
+
return { headers: optionsOrHeaders, transport: 'auto' };
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
headers: optionsOrHeaders.headers ?? [],
|
|
69
|
+
transport: optionsOrHeaders.transport ?? 'auto',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function headersToObject(headers) {
|
|
73
|
+
if (headers === undefined)
|
|
74
|
+
return {};
|
|
75
|
+
return Object.fromEntries(new Headers(headers).entries());
|
|
76
|
+
}
|
|
77
|
+
function formatError(error) {
|
|
78
|
+
return error instanceof Error ? error.message : String(error);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=http.js.map
|