toolcraft 0.0.117 → 0.0.119
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/composition.json +2 -17
- package/dist/composition.json +2 -17
- package/node_modules/@poe-code/agent-defs/package.json +0 -2
- package/node_modules/@poe-code/agent-human-in-loop/package.json +0 -2
- package/node_modules/@poe-code/agent-mcp-config/package.json +0 -2
- package/node_modules/@poe-code/config-mutations/package.json +0 -2
- package/node_modules/@poe-code/frontmatter/package.json +0 -2
- package/node_modules/@poe-code/process-runner/package.json +0 -2
- package/node_modules/@poe-code/task-list/package.json +0 -2
- package/node_modules/auth-store/package.json +0 -2
- package/node_modules/tiny-mcp-client/package.json +0 -2
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/tiny-stdio-mcp-server/dist/server.js +9 -21
- package/node_modules/tiny-stdio-mcp-server/dist/uri-template.d.ts +6 -0
- package/node_modules/tiny-stdio-mcp-server/dist/uri-template.js +363 -0
- package/node_modules/toolcraft-design/package.json +0 -2
- package/node_modules/toolcraft-schema/package.json +3 -2
- package/package.json +5 -9
- package/node_modules/pct-encode/.travis.yml +0 -7
- package/node_modules/pct-encode/AUTHORS +0 -2
- package/node_modules/pct-encode/LICENSE +0 -11
- package/node_modules/pct-encode/README.md +0 -20
- package/node_modules/pct-encode/index.js +0 -23
- package/node_modules/pct-encode/package.json +0 -23
- package/node_modules/pct-encode/test.js +0 -10
- package/node_modules/uri-template/AUTHORS +0 -2
- package/node_modules/uri-template/LICENSE +0 -19
- package/node_modules/uri-template/README.md +0 -34
- package/node_modules/uri-template/dist/ast.d.ts +0 -28
- package/node_modules/uri-template/dist/ast.js +0 -27
- package/node_modules/uri-template/dist/expander.d.ts +0 -3
- package/node_modules/uri-template/dist/expander.js +0 -165
- package/node_modules/uri-template/dist/grammar.d.ts +0 -13
- package/node_modules/uri-template/dist/grammar.js +0 -749
- package/node_modules/uri-template/dist/index.d.ts +0 -19
- package/node_modules/uri-template/dist/index.js +0 -43
- package/node_modules/uri-template/lib/ast.ts +0 -59
- package/node_modules/uri-template/lib/expander.ts +0 -175
- package/node_modules/uri-template/lib/grammar.js +0 -773
- package/node_modules/uri-template/lib/grammar.pegjs +0 -33
- package/node_modules/uri-template/lib/index.ts +0 -33
- package/node_modules/uri-template/package.json +0 -33
- package/node_modules/uri-template-lite/README.md +0 -86
- package/node_modules/uri-template-lite/index.js +0 -140
- package/node_modules/uri-template-lite/package.json +0 -43
package/composition.json
CHANGED
|
@@ -66,11 +66,6 @@
|
|
|
66
66
|
"version": "3.3.1",
|
|
67
67
|
"license": "MIT"
|
|
68
68
|
},
|
|
69
|
-
{
|
|
70
|
-
"name": "pct-encode",
|
|
71
|
-
"version": "1.0.3",
|
|
72
|
-
"license": "BSD-2-Clause"
|
|
73
|
-
},
|
|
74
69
|
{
|
|
75
70
|
"name": "sisteransi",
|
|
76
71
|
"version": "1.0.5",
|
|
@@ -93,7 +88,7 @@
|
|
|
93
88
|
},
|
|
94
89
|
{
|
|
95
90
|
"name": "toolcraft",
|
|
96
|
-
"version": "0.0.
|
|
91
|
+
"version": "0.0.119",
|
|
97
92
|
"license": "MIT"
|
|
98
93
|
},
|
|
99
94
|
{
|
|
@@ -103,17 +98,7 @@
|
|
|
103
98
|
},
|
|
104
99
|
{
|
|
105
100
|
"name": "toolcraft-schema",
|
|
106
|
-
"version": "0.0.
|
|
107
|
-
"license": "MIT"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"name": "uri-template",
|
|
111
|
-
"version": "2.0.0",
|
|
112
|
-
"license": "MIT"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
"name": "uri-template-lite",
|
|
116
|
-
"version": "23.4.0",
|
|
101
|
+
"version": "0.0.119",
|
|
117
102
|
"license": "MIT"
|
|
118
103
|
},
|
|
119
104
|
{
|
package/dist/composition.json
CHANGED
|
@@ -66,11 +66,6 @@
|
|
|
66
66
|
"version": "3.3.1",
|
|
67
67
|
"license": "MIT"
|
|
68
68
|
},
|
|
69
|
-
{
|
|
70
|
-
"name": "pct-encode",
|
|
71
|
-
"version": "1.0.3",
|
|
72
|
-
"license": "BSD-2-Clause"
|
|
73
|
-
},
|
|
74
69
|
{
|
|
75
70
|
"name": "sisteransi",
|
|
76
71
|
"version": "1.0.5",
|
|
@@ -93,7 +88,7 @@
|
|
|
93
88
|
},
|
|
94
89
|
{
|
|
95
90
|
"name": "toolcraft",
|
|
96
|
-
"version": "0.0.
|
|
91
|
+
"version": "0.0.119",
|
|
97
92
|
"license": "MIT"
|
|
98
93
|
},
|
|
99
94
|
{
|
|
@@ -103,17 +98,7 @@
|
|
|
103
98
|
},
|
|
104
99
|
{
|
|
105
100
|
"name": "toolcraft-schema",
|
|
106
|
-
"version": "0.0.
|
|
107
|
-
"license": "MIT"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"name": "uri-template",
|
|
111
|
-
"version": "2.0.0",
|
|
112
|
-
"license": "MIT"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
"name": "uri-template-lite",
|
|
116
|
-
"version": "23.4.0",
|
|
101
|
+
"version": "0.0.119",
|
|
117
102
|
"license": "MIT"
|
|
118
103
|
},
|
|
119
104
|
{
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as readline from "readline";
|
|
2
2
|
import { compileJsonSchema, formatIssues } from "toolcraft-schema";
|
|
3
|
-
import uriTemplateParser from "uri-template";
|
|
4
|
-
import UriTemplate from "uri-template-lite";
|
|
5
3
|
import { JSON_RPC_ERROR_CODES, ToolError } from "./types.js";
|
|
6
4
|
import { parseMessage, formatSuccessResponse, formatErrorResponse } from "./jsonrpc.js";
|
|
5
|
+
import { parseUriTemplate } from "./uri-template.js";
|
|
7
6
|
import { toContentBlocks } from "./content/convert.js";
|
|
8
7
|
const PROTOCOL_VERSION = "2025-11-25";
|
|
9
8
|
const SUPPORTED_PROTOCOL_VERSIONS = new Set(["2025-03-26", "2025-06-18", PROTOCOL_VERSION]);
|
|
@@ -228,7 +227,7 @@ export function createServer(options) {
|
|
|
228
227
|
if (method === "resources/templates/list") {
|
|
229
228
|
return {
|
|
230
229
|
result: {
|
|
231
|
-
resourceTemplates: [...resourceTemplates.values()].map(({ handler: _handler, ...resourceTemplate }) => resourceTemplate)
|
|
230
|
+
resourceTemplates: [...resourceTemplates.values()].map(({ handler: _handler, template: _template, ...resourceTemplate }) => resourceTemplate)
|
|
232
231
|
}
|
|
233
232
|
};
|
|
234
233
|
}
|
|
@@ -451,12 +450,11 @@ export function createServer(options) {
|
|
|
451
450
|
return server;
|
|
452
451
|
},
|
|
453
452
|
resourceTemplate(definition, handler) {
|
|
454
|
-
|
|
455
|
-
new UriTemplate(definition.uriTemplate);
|
|
453
|
+
const template = parseReadableUriTemplate(definition.uriTemplate);
|
|
456
454
|
if (resourceTemplates.has(definition.uriTemplate)) {
|
|
457
455
|
throw new Error(`Resource template already registered: ${definition.uriTemplate}`);
|
|
458
456
|
}
|
|
459
|
-
resourceTemplates.set(definition.uriTemplate, { ...definition, handler });
|
|
457
|
+
resourceTemplates.set(definition.uriTemplate, { ...definition, handler, template });
|
|
460
458
|
return server;
|
|
461
459
|
},
|
|
462
460
|
method(name, handler) {
|
|
@@ -660,14 +658,12 @@ function assertNonEmptyName(name, message) {
|
|
|
660
658
|
throw new Error(message);
|
|
661
659
|
}
|
|
662
660
|
}
|
|
663
|
-
function
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
get: (_target, property) => (typeof property === "string" ? "value" : undefined)
|
|
667
|
-
}));
|
|
668
|
-
if (typeof expanded !== "string" || !isValidUri(expanded)) {
|
|
661
|
+
function parseReadableUriTemplate(uriTemplate) {
|
|
662
|
+
const template = parseUriTemplate(uriTemplate);
|
|
663
|
+
if (!isValidUri(template.expand({}))) {
|
|
669
664
|
throw new Error(`Invalid resource URI template: ${uriTemplate}`);
|
|
670
665
|
}
|
|
666
|
+
return template;
|
|
671
667
|
}
|
|
672
668
|
function toStringArguments(value) {
|
|
673
669
|
if (value === undefined) {
|
|
@@ -693,15 +689,7 @@ function findReadableResource(uri, resources, resourceTemplates) {
|
|
|
693
689
|
if (resource !== undefined) {
|
|
694
690
|
return resource;
|
|
695
691
|
}
|
|
696
|
-
return [...resourceTemplates.values()].find((template) =>
|
|
697
|
-
}
|
|
698
|
-
function matchesUriTemplate(template, uri) {
|
|
699
|
-
try {
|
|
700
|
-
return new UriTemplate(template).match(uri) !== null;
|
|
701
|
-
}
|
|
702
|
-
catch {
|
|
703
|
-
return false;
|
|
704
|
-
}
|
|
692
|
+
return [...resourceTemplates.values()].find((template) => template.template.match(uri) !== null);
|
|
705
693
|
}
|
|
706
694
|
function isCallToolResult(value) {
|
|
707
695
|
if (!hasContentArray(value) || !value.content.every(isContentItem)) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type UriTemplateValue = string | string[] | Record<string, string>;
|
|
2
|
+
export interface UriTemplate {
|
|
3
|
+
expand(variables: Record<string, UriTemplateValue>): string;
|
|
4
|
+
match(uri: string): Record<string, string> | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function parseUriTemplate(template: string): UriTemplate;
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
const operatorOptions = {
|
|
2
|
+
"": { prefix: "", separator: ",", named: false, ifEmpty: "", allowReserved: false },
|
|
3
|
+
"+": { prefix: "", separator: ",", named: false, ifEmpty: "", allowReserved: true },
|
|
4
|
+
"#": { prefix: "#", separator: ",", named: false, ifEmpty: "", allowReserved: true },
|
|
5
|
+
".": { prefix: ".", separator: ".", named: false, ifEmpty: "", allowReserved: false },
|
|
6
|
+
"/": { prefix: "/", separator: "/", named: false, ifEmpty: "", allowReserved: false },
|
|
7
|
+
";": { prefix: ";", separator: ";", named: true, ifEmpty: "", allowReserved: false },
|
|
8
|
+
"?": { prefix: "?", separator: "&", named: true, ifEmpty: "=", allowReserved: false },
|
|
9
|
+
"&": { prefix: "&", separator: "&", named: true, ifEmpty: "=", allowReserved: false }
|
|
10
|
+
};
|
|
11
|
+
const operators = new Set(["", "+", "#", ".", "/", ";", "?", "&"]);
|
|
12
|
+
const reservedCharacters = new Set(":/?#[]@!$&'()*+,;=".split(""));
|
|
13
|
+
class ParsedUriTemplate {
|
|
14
|
+
segments;
|
|
15
|
+
constructor(segments) {
|
|
16
|
+
this.segments = segments;
|
|
17
|
+
}
|
|
18
|
+
expand(variables) {
|
|
19
|
+
return this.segments
|
|
20
|
+
.map((segment) => segment.kind === "literal" ? segment.value : expandExpression(segment, variables))
|
|
21
|
+
.join("");
|
|
22
|
+
}
|
|
23
|
+
match(uri) {
|
|
24
|
+
return matchSegments(this.segments, uri, 0, 0, {});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function parseUriTemplate(template) {
|
|
28
|
+
if (typeof template !== "string") {
|
|
29
|
+
throw new Error("URI template must be a string.");
|
|
30
|
+
}
|
|
31
|
+
const segments = [];
|
|
32
|
+
let literalStart = 0;
|
|
33
|
+
let index = 0;
|
|
34
|
+
while (index < template.length) {
|
|
35
|
+
const character = template[index];
|
|
36
|
+
if (character === "}") {
|
|
37
|
+
throw syntaxError(template, index, "unmatched closing brace");
|
|
38
|
+
}
|
|
39
|
+
if (character !== "{") {
|
|
40
|
+
index += 1;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (index > literalStart) {
|
|
44
|
+
segments.push({ kind: "literal", value: template.slice(literalStart, index) });
|
|
45
|
+
}
|
|
46
|
+
const closeIndex = template.indexOf("}", index + 1);
|
|
47
|
+
if (closeIndex === -1) {
|
|
48
|
+
throw syntaxError(template, index, "unclosed expression");
|
|
49
|
+
}
|
|
50
|
+
const expression = template.slice(index + 1, closeIndex);
|
|
51
|
+
if (expression.includes("{")) {
|
|
52
|
+
throw syntaxError(template, index, "nested expression");
|
|
53
|
+
}
|
|
54
|
+
segments.push(parseExpression(template, expression, index));
|
|
55
|
+
index = closeIndex + 1;
|
|
56
|
+
literalStart = index;
|
|
57
|
+
}
|
|
58
|
+
if (literalStart < template.length) {
|
|
59
|
+
segments.push({ kind: "literal", value: template.slice(literalStart) });
|
|
60
|
+
}
|
|
61
|
+
if (segments.length === 0) {
|
|
62
|
+
segments.push({ kind: "literal", value: "" });
|
|
63
|
+
}
|
|
64
|
+
return new ParsedUriTemplate(segments);
|
|
65
|
+
}
|
|
66
|
+
function parseExpression(template, expression, offset) {
|
|
67
|
+
if (expression.length === 0) {
|
|
68
|
+
throw syntaxError(template, offset, "empty expression");
|
|
69
|
+
}
|
|
70
|
+
const first = expression[0];
|
|
71
|
+
const operator = operators.has(first) && first !== "" ? first : "";
|
|
72
|
+
const variableList = operator === "" ? expression : expression.slice(1);
|
|
73
|
+
if (variableList.length === 0) {
|
|
74
|
+
throw syntaxError(template, offset, "expression has no variables");
|
|
75
|
+
}
|
|
76
|
+
if (operator === "" && isReservedOperatorCharacter(first)) {
|
|
77
|
+
throw syntaxError(template, offset, `unsupported operator ${first}`);
|
|
78
|
+
}
|
|
79
|
+
const variables = variableList
|
|
80
|
+
.split(",")
|
|
81
|
+
.map((variable) => parseVariableSpec(template, variable, offset));
|
|
82
|
+
return { kind: "expression", operator, variables };
|
|
83
|
+
}
|
|
84
|
+
function parseVariableSpec(template, source, offset) {
|
|
85
|
+
if (source.length === 0) {
|
|
86
|
+
throw syntaxError(template, offset, "empty variable specification");
|
|
87
|
+
}
|
|
88
|
+
const explode = source.endsWith("*");
|
|
89
|
+
const withoutExplode = explode ? source.slice(0, -1) : source;
|
|
90
|
+
const colonIndex = withoutExplode.indexOf(":");
|
|
91
|
+
if (explode && colonIndex !== -1) {
|
|
92
|
+
throw syntaxError(template, offset, "explode and prefix modifiers cannot be combined");
|
|
93
|
+
}
|
|
94
|
+
const name = colonIndex === -1 ? withoutExplode : withoutExplode.slice(0, colonIndex);
|
|
95
|
+
if (!isValidVariableName(name)) {
|
|
96
|
+
throw syntaxError(template, offset, `invalid variable name ${name}`);
|
|
97
|
+
}
|
|
98
|
+
if (colonIndex === -1) {
|
|
99
|
+
return { name, explode };
|
|
100
|
+
}
|
|
101
|
+
const prefixSource = withoutExplode.slice(colonIndex + 1);
|
|
102
|
+
if (!isValidPrefix(prefixSource)) {
|
|
103
|
+
throw syntaxError(template, offset, `invalid prefix modifier ${prefixSource}`);
|
|
104
|
+
}
|
|
105
|
+
return { name, explode: false, prefixLength: Number(prefixSource) };
|
|
106
|
+
}
|
|
107
|
+
function isValidVariableName(name) {
|
|
108
|
+
if (name.length === 0) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
let componentLength = 0;
|
|
112
|
+
for (let index = 0; index < name.length; index += 1) {
|
|
113
|
+
const character = name[index];
|
|
114
|
+
if (character === ".") {
|
|
115
|
+
if (componentLength === 0)
|
|
116
|
+
return false;
|
|
117
|
+
componentLength = 0;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (character === "%") {
|
|
121
|
+
if (!isHex(name[index + 1]) || !isHex(name[index + 2]))
|
|
122
|
+
return false;
|
|
123
|
+
index += 2;
|
|
124
|
+
componentLength += 1;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!isVariableCharacter(character))
|
|
128
|
+
return false;
|
|
129
|
+
componentLength += 1;
|
|
130
|
+
}
|
|
131
|
+
return componentLength > 0;
|
|
132
|
+
}
|
|
133
|
+
function isValidPrefix(value) {
|
|
134
|
+
if (value.length === 0 || value.length > 4 || value[0] === "0") {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
return [...value].every((character) => character >= "0" && character <= "9");
|
|
138
|
+
}
|
|
139
|
+
function isReservedOperatorCharacter(character) {
|
|
140
|
+
return "=,!@|".includes(character);
|
|
141
|
+
}
|
|
142
|
+
function isVariableCharacter(character) {
|
|
143
|
+
return ((character >= "a" && character <= "z") ||
|
|
144
|
+
(character >= "A" && character <= "Z") ||
|
|
145
|
+
(character >= "0" && character <= "9") ||
|
|
146
|
+
character === "_");
|
|
147
|
+
}
|
|
148
|
+
function isHex(character) {
|
|
149
|
+
return (character !== undefined &&
|
|
150
|
+
((character >= "0" && character <= "9") ||
|
|
151
|
+
(character >= "a" && character <= "f") ||
|
|
152
|
+
(character >= "A" && character <= "F")));
|
|
153
|
+
}
|
|
154
|
+
function syntaxError(template, index, detail) {
|
|
155
|
+
return new Error(`Invalid URI template at ${index}: ${detail} (${template})`);
|
|
156
|
+
}
|
|
157
|
+
function expandExpression(expression, variables) {
|
|
158
|
+
const options = operatorOptions[expression.operator];
|
|
159
|
+
const parts = [];
|
|
160
|
+
for (const variable of expression.variables) {
|
|
161
|
+
const value = variables[variable.name];
|
|
162
|
+
if (value === undefined || value === null) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
parts.push(...expandVariable(variable, value, options));
|
|
166
|
+
}
|
|
167
|
+
return parts.length === 0 ? "" : `${options.prefix}${parts.join(options.separator)}`;
|
|
168
|
+
}
|
|
169
|
+
function expandVariable(variable, value, options) {
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
if (variable.prefixLength !== undefined) {
|
|
172
|
+
throw new Error(`Prefix modifier requires a scalar value: ${variable.name}`);
|
|
173
|
+
}
|
|
174
|
+
return expandList(variable, value, options);
|
|
175
|
+
}
|
|
176
|
+
if (isRecord(value)) {
|
|
177
|
+
if (variable.prefixLength !== undefined) {
|
|
178
|
+
throw new Error(`Prefix modifier requires a scalar value: ${variable.name}`);
|
|
179
|
+
}
|
|
180
|
+
return expandAssociative(variable, value, options);
|
|
181
|
+
}
|
|
182
|
+
const original = String(value);
|
|
183
|
+
const scalar = variable.prefixLength === undefined
|
|
184
|
+
? original
|
|
185
|
+
: [...original].slice(0, variable.prefixLength).join("");
|
|
186
|
+
const encoded = encodeValue(scalar, options.allowReserved);
|
|
187
|
+
return [namedValue(variable.name, encoded, options)];
|
|
188
|
+
}
|
|
189
|
+
function expandList(variable, value, options) {
|
|
190
|
+
if (value.length === 0) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const encoded = value.map((item) => encodeValue(String(item), options.allowReserved));
|
|
194
|
+
if (!variable.explode) {
|
|
195
|
+
return [namedValue(variable.name, encoded.join(","), options)];
|
|
196
|
+
}
|
|
197
|
+
if (!options.named) {
|
|
198
|
+
return encoded;
|
|
199
|
+
}
|
|
200
|
+
return encoded.map((item) => namedValue(variable.name, item, options));
|
|
201
|
+
}
|
|
202
|
+
function expandAssociative(variable, value, options) {
|
|
203
|
+
const entries = Object.entries(value);
|
|
204
|
+
if (entries.length === 0) {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
const encoded = entries.map(([key, item]) => [
|
|
208
|
+
encodeValue(key, options.allowReserved),
|
|
209
|
+
encodeValue(String(item), options.allowReserved)
|
|
210
|
+
]);
|
|
211
|
+
if (!variable.explode) {
|
|
212
|
+
return [namedValue(variable.name, encoded.flat().join(","), options)];
|
|
213
|
+
}
|
|
214
|
+
return encoded.map(([key, item]) => `${key}=${item}`);
|
|
215
|
+
}
|
|
216
|
+
function namedValue(name, value, options) {
|
|
217
|
+
if (!options.named) {
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
const encodedName = encodeValue(name, true);
|
|
221
|
+
if (value.length === 0) {
|
|
222
|
+
return `${encodedName}${options.ifEmpty}`;
|
|
223
|
+
}
|
|
224
|
+
return `${encodedName}=${value}`;
|
|
225
|
+
}
|
|
226
|
+
function encodeValue(value, allowReserved) {
|
|
227
|
+
let result = "";
|
|
228
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
229
|
+
const character = value[index];
|
|
230
|
+
if (allowReserved && character === "%" && isHex(value[index + 1]) && isHex(value[index + 2])) {
|
|
231
|
+
result += value.slice(index, index + 3);
|
|
232
|
+
index += 2;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const codePoint = value.codePointAt(index);
|
|
236
|
+
if (codePoint === undefined)
|
|
237
|
+
continue;
|
|
238
|
+
const scalar = String.fromCodePoint(codePoint);
|
|
239
|
+
if (scalar.length === 2)
|
|
240
|
+
index += 1;
|
|
241
|
+
if (isUnreserved(scalar) || (allowReserved && reservedCharacters.has(scalar))) {
|
|
242
|
+
result += scalar;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
for (const byte of new TextEncoder().encode(scalar)) {
|
|
246
|
+
result += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
function isUnreserved(character) {
|
|
252
|
+
return ((character >= "a" && character <= "z") ||
|
|
253
|
+
(character >= "A" && character <= "Z") ||
|
|
254
|
+
(character >= "0" && character <= "9") ||
|
|
255
|
+
"-._~".includes(character));
|
|
256
|
+
}
|
|
257
|
+
function isRecord(value) {
|
|
258
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
259
|
+
}
|
|
260
|
+
function matchSegments(segments, uri, segmentIndex, uriIndex, captures) {
|
|
261
|
+
if (segmentIndex === segments.length) {
|
|
262
|
+
return uriIndex === uri.length ? captures : null;
|
|
263
|
+
}
|
|
264
|
+
const segment = segments[segmentIndex];
|
|
265
|
+
if (segment.kind === "literal") {
|
|
266
|
+
return uri.startsWith(segment.value, uriIndex)
|
|
267
|
+
? matchSegments(segments, uri, segmentIndex + 1, uriIndex + segment.value.length, captures)
|
|
268
|
+
: null;
|
|
269
|
+
}
|
|
270
|
+
for (const endIndex of candidateExpressionEnds(segments, uri, segmentIndex, uriIndex)) {
|
|
271
|
+
const expressionCaptures = matchExpression(segment, uri.slice(uriIndex, endIndex));
|
|
272
|
+
if (expressionCaptures === null)
|
|
273
|
+
continue;
|
|
274
|
+
const result = matchSegments(segments, uri, segmentIndex + 1, endIndex, {
|
|
275
|
+
...captures,
|
|
276
|
+
...expressionCaptures
|
|
277
|
+
});
|
|
278
|
+
if (result !== null)
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
function candidateExpressionEnds(segments, uri, segmentIndex, uriIndex) {
|
|
284
|
+
const next = segments[segmentIndex + 1];
|
|
285
|
+
if (next === undefined) {
|
|
286
|
+
return [uri.length];
|
|
287
|
+
}
|
|
288
|
+
const boundary = next.kind === "literal" ? next.value : operatorOptions[next.operator].prefix;
|
|
289
|
+
if (boundary.length === 0) {
|
|
290
|
+
return descendingRange(uriIndex, uri.length);
|
|
291
|
+
}
|
|
292
|
+
const indices = [];
|
|
293
|
+
let searchIndex = uri.length;
|
|
294
|
+
while (searchIndex >= uriIndex) {
|
|
295
|
+
const found = uri.lastIndexOf(boundary, searchIndex);
|
|
296
|
+
if (found < uriIndex)
|
|
297
|
+
break;
|
|
298
|
+
indices.push(found);
|
|
299
|
+
searchIndex = found - 1;
|
|
300
|
+
}
|
|
301
|
+
return indices;
|
|
302
|
+
}
|
|
303
|
+
function descendingRange(start, end) {
|
|
304
|
+
const values = [];
|
|
305
|
+
for (let value = end; value >= start; value -= 1)
|
|
306
|
+
values.push(value);
|
|
307
|
+
return values;
|
|
308
|
+
}
|
|
309
|
+
function matchExpression(expression, expansion) {
|
|
310
|
+
const options = operatorOptions[expression.operator];
|
|
311
|
+
if (expansion.length === 0) {
|
|
312
|
+
return {};
|
|
313
|
+
}
|
|
314
|
+
if (options.prefix.length > 0 && !expansion.startsWith(options.prefix)) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
const body = options.prefix.length === 0 ? expansion : expansion.slice(options.prefix.length);
|
|
318
|
+
if (options.named) {
|
|
319
|
+
return matchNamedExpression(expression.variables, body, options.separator);
|
|
320
|
+
}
|
|
321
|
+
return matchPositionalExpression(expression.variables, body, options.separator);
|
|
322
|
+
}
|
|
323
|
+
function matchNamedExpression(variables, body, separator) {
|
|
324
|
+
const captures = {};
|
|
325
|
+
const fields = body.length === 0 ? [] : body.split(separator);
|
|
326
|
+
for (const variable of variables) {
|
|
327
|
+
const encodedName = encodeValue(variable.name, true);
|
|
328
|
+
const values = [];
|
|
329
|
+
for (const field of fields) {
|
|
330
|
+
const equalsIndex = field.indexOf("=");
|
|
331
|
+
const key = equalsIndex === -1 ? field : field.slice(0, equalsIndex);
|
|
332
|
+
if (key === encodedName) {
|
|
333
|
+
values.push(equalsIndex === -1 ? "" : field.slice(equalsIndex + 1));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (values.length > 0) {
|
|
337
|
+
captures[variable.name] = decodeValue(values.join(variable.explode ? "," : ""));
|
|
338
|
+
}
|
|
339
|
+
else if (variable.explode && variables.length === 1 && body.length > 0) {
|
|
340
|
+
captures[variable.name] = decodeValue(body);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return captures;
|
|
344
|
+
}
|
|
345
|
+
function matchPositionalExpression(variables, body, separator) {
|
|
346
|
+
if (variables.length === 1) {
|
|
347
|
+
return { [variables[0].name]: decodeValue(body) };
|
|
348
|
+
}
|
|
349
|
+
const captures = {};
|
|
350
|
+
const fields = body.split(separator);
|
|
351
|
+
for (let index = 0; index < variables.length && index < fields.length; index += 1) {
|
|
352
|
+
captures[variables[index].name] = decodeValue(index === variables.length - 1 ? fields.slice(index).join(separator) : fields[index]);
|
|
353
|
+
}
|
|
354
|
+
return captures;
|
|
355
|
+
}
|
|
356
|
+
function decodeValue(value) {
|
|
357
|
+
try {
|
|
358
|
+
return decodeURIComponent(value);
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return value;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft-schema",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.119",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js"
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
12
13
|
}
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.119",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"test": "cd ../.. && vitest run packages/toolcraft/src",
|
|
105
105
|
"test:unit": "cd ../.. && vitest run packages/toolcraft/src",
|
|
106
106
|
"lint": "cd ../.. && eslint packages/toolcraft/src --ext ts && tsc -p packages/toolcraft/tsconfig.json --noEmit",
|
|
107
|
-
"prepack": "node ../../scripts/manage-bundled-workspace-deps.mjs prepare . toolcraft-schema toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client tiny-stdio-mcp-server auth-store fast-string-width fast-wrap-ansi ignore jsonc-parser sisteransi smol-toml
|
|
108
|
-
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-schema toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client tiny-stdio-mcp-server auth-store fast-string-width fast-wrap-ansi ignore jsonc-parser sisteransi smol-toml
|
|
107
|
+
"prepack": "node ../../scripts/manage-bundled-workspace-deps.mjs prepare . toolcraft-schema toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client tiny-stdio-mcp-server auth-store fast-string-width fast-wrap-ansi ignore jsonc-parser sisteransi smol-toml yaml",
|
|
108
|
+
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-schema toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client tiny-stdio-mcp-server auth-store fast-string-width fast-wrap-ansi ignore jsonc-parser sisteransi smol-toml yaml"
|
|
109
109
|
},
|
|
110
110
|
"dependencies": {
|
|
111
111
|
"commander": "^13.1.0",
|
|
@@ -116,8 +116,6 @@
|
|
|
116
116
|
"jsonc-parser": "^3.3.1",
|
|
117
117
|
"sisteransi": "^1.0.5",
|
|
118
118
|
"smol-toml": "^1.3.0",
|
|
119
|
-
"uri-template": "^2.0.0",
|
|
120
|
-
"uri-template-lite": "^23.4.0",
|
|
121
119
|
"yaml": "^2.8.2"
|
|
122
120
|
},
|
|
123
121
|
"files": [
|
|
@@ -153,13 +151,11 @@
|
|
|
153
151
|
"jsonc-parser",
|
|
154
152
|
"sisteransi",
|
|
155
153
|
"smol-toml",
|
|
156
|
-
"uri-template",
|
|
157
|
-
"uri-template-lite",
|
|
158
154
|
"yaml"
|
|
159
155
|
],
|
|
160
156
|
"optionalDependencies": {
|
|
161
|
-
"toolcraft-schema": "0.0.
|
|
162
|
-
"toolcraft-design": "
|
|
157
|
+
"toolcraft-schema": "0.0.119",
|
|
158
|
+
"toolcraft-design": "*",
|
|
163
159
|
"@poe-code/frontmatter": "*",
|
|
164
160
|
"@poe-code/agent-mcp-config": "*",
|
|
165
161
|
"@poe-code/agent-human-in-loop": "*",
|