toolcraft 0.0.40 → 0.0.41
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/dist/number-schema.js +9 -2
- package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.js +1 -1
- package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.js +6 -1
- package/node_modules/@poe-code/agent-defs/dist/agents/cursor.js +1 -1
- package/node_modules/@poe-code/agent-defs/dist/agents/kimi.js +1 -1
- package/node_modules/@poe-code/agent-defs/dist/agents/opencode.js +1 -1
- package/node_modules/@poe-code/agent-defs/dist/specifier.js +15 -6
- package/node_modules/@poe-code/agent-defs/dist/types.d.ts +5 -0
- package/node_modules/@poe-code/agent-mcp-config/dist/apply.js +36 -3
- package/package.json +2 -2
package/dist/number-schema.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
export function isValidNumberSchemaValue(value, schema) {
|
|
2
2
|
return (typeof value === "number" &&
|
|
3
3
|
Number.isFinite(value) &&
|
|
4
|
-
(schema.jsonType !== "integer" || Number.isInteger(value))
|
|
4
|
+
(schema.jsonType !== "integer" || Number.isInteger(value)) &&
|
|
5
|
+
(schema.minimum === undefined || value >= schema.minimum) &&
|
|
6
|
+
(schema.maximum === undefined || value <= schema.maximum));
|
|
5
7
|
}
|
|
6
8
|
export function getExpectedNumberDescription(schema) {
|
|
7
|
-
|
|
9
|
+
const type = schema.jsonType === "integer" ? "an integer" : "a number";
|
|
10
|
+
const bounds = [
|
|
11
|
+
schema.minimum === undefined ? undefined : `greater than or equal to ${schema.minimum}`,
|
|
12
|
+
schema.maximum === undefined ? undefined : `less than or equal to ${schema.maximum}`
|
|
13
|
+
].filter((bound) => bound !== undefined);
|
|
14
|
+
return bounds.length === 0 ? type : `${type} ${bounds.join(" and ")}`;
|
|
8
15
|
}
|
|
@@ -3,7 +3,12 @@ export const claudeDesktopAgent = {
|
|
|
3
3
|
name: "claude-desktop",
|
|
4
4
|
label: "Claude Desktop",
|
|
5
5
|
summary: "Anthropic's official desktop application for Claude",
|
|
6
|
-
configPath: "~/.
|
|
6
|
+
configPath: "~/.config/Claude/claude_desktop_config.json",
|
|
7
|
+
configPaths: {
|
|
8
|
+
darwin: "~/Library/Application Support/Claude/claude_desktop_config.json",
|
|
9
|
+
linux: "~/.config/Claude/claude_desktop_config.json",
|
|
10
|
+
win32: "~/AppData/Roaming/Claude/claude_desktop_config.json"
|
|
11
|
+
},
|
|
7
12
|
branding: {
|
|
8
13
|
colors: {
|
|
9
14
|
dark: "#D97757",
|
|
@@ -2,24 +2,33 @@ import { resolveAgentId } from "./registry.js";
|
|
|
2
2
|
function getOwnModel(specifier) {
|
|
3
3
|
return Object.prototype.hasOwnProperty.call(specifier, "model") ? specifier.model : undefined;
|
|
4
4
|
}
|
|
5
|
+
function requireNonBlank(value, field) {
|
|
6
|
+
const trimmed = value.trim();
|
|
7
|
+
if (trimmed.length === 0) {
|
|
8
|
+
throw new TypeError(`${field} must not be empty`);
|
|
9
|
+
}
|
|
10
|
+
return trimmed;
|
|
11
|
+
}
|
|
5
12
|
export function parseAgentSpecifier(input) {
|
|
6
13
|
const colonIndex = input.indexOf(":");
|
|
7
14
|
if (colonIndex === -1) {
|
|
8
|
-
return { agent: input
|
|
15
|
+
return { agent: requireNonBlank(input, "agent") };
|
|
9
16
|
}
|
|
10
|
-
const agent = input.slice(0, colonIndex)
|
|
17
|
+
const agent = requireNonBlank(input.slice(0, colonIndex), "agent");
|
|
11
18
|
const model = input.slice(colonIndex + 1).trim();
|
|
12
19
|
return {
|
|
13
20
|
agent,
|
|
14
|
-
...(model.length > 0 ? { model } : {})
|
|
21
|
+
...(model.length > 0 ? { model } : {})
|
|
15
22
|
};
|
|
16
23
|
}
|
|
17
24
|
export function formatAgentSpecifier(specifier) {
|
|
25
|
+
const agent = requireNonBlank(specifier.agent, "agent");
|
|
18
26
|
const model = getOwnModel(specifier);
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
const normalizedModel = model?.trim();
|
|
28
|
+
if (normalizedModel) {
|
|
29
|
+
return `${agent}:${normalizedModel}`;
|
|
21
30
|
}
|
|
22
|
-
return
|
|
31
|
+
return agent;
|
|
23
32
|
}
|
|
24
33
|
export function normalizeAgentId(input) {
|
|
25
34
|
const specifier = parseAgentSpecifier(input.trim());
|
|
@@ -14,6 +14,11 @@ export interface AgentDefinition {
|
|
|
14
14
|
readonly apiShapes?: readonly ApiShapeId[];
|
|
15
15
|
readonly otelCapture?: OtelCaptureDefinition;
|
|
16
16
|
configPath: string;
|
|
17
|
+
readonly configPaths?: {
|
|
18
|
+
readonly darwin: string;
|
|
19
|
+
readonly linux: string;
|
|
20
|
+
readonly win32: string;
|
|
21
|
+
};
|
|
17
22
|
branding: {
|
|
18
23
|
colors: {
|
|
19
24
|
dark: string;
|
|
@@ -15,6 +15,32 @@ export class UnsupportedAgentError extends Error {
|
|
|
15
15
|
function isConfigObject(value) {
|
|
16
16
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
17
17
|
}
|
|
18
|
+
function assertNonEmptyString(value, message) {
|
|
19
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
20
|
+
throw new Error(message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function assertHttpUrl(value) {
|
|
24
|
+
assertNonEmptyString(value, "MCP HTTP URL must be a valid http or https URL.");
|
|
25
|
+
let parsed;
|
|
26
|
+
try {
|
|
27
|
+
parsed = new URL(value);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
throw new Error("MCP HTTP URL must be a valid http or https URL.");
|
|
31
|
+
}
|
|
32
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
33
|
+
throw new Error("MCP HTTP URL must be a valid http or https URL.");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function validateServerEntry(server) {
|
|
37
|
+
assertNonEmptyString(server.name, "MCP server name must be a non-empty string.");
|
|
38
|
+
if (server.config.transport === "stdio") {
|
|
39
|
+
assertNonEmptyString(server.config.command, "MCP stdio command must be a non-empty string.");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
assertHttpUrl(server.config.url);
|
|
43
|
+
}
|
|
18
44
|
function resolveServerMap(document, configKey) {
|
|
19
45
|
const value = document[configKey];
|
|
20
46
|
if (value === undefined) {
|
|
@@ -32,12 +58,15 @@ export async function configure(agentId, server, options) {
|
|
|
32
58
|
if (!isSupported(agentId)) {
|
|
33
59
|
throw new UnsupportedAgentError(agentId);
|
|
34
60
|
}
|
|
61
|
+
validateServerEntry(server);
|
|
35
62
|
const config = getAgentConfig(agentId);
|
|
36
63
|
const configPath = resolveConfigPath(config, options.platform);
|
|
37
64
|
const shapeTransformer = getShapeTransformer(config.shape);
|
|
38
65
|
const shaped = shapeTransformer(server);
|
|
66
|
+
const enabledServer = { ...server, enabled: true };
|
|
67
|
+
const enabledShaped = shapeTransformer(enabledServer);
|
|
39
68
|
if (shaped === undefined) {
|
|
40
|
-
await unconfigure(agentId,
|
|
69
|
+
await unconfigure(agentId, enabledServer, options);
|
|
41
70
|
return;
|
|
42
71
|
}
|
|
43
72
|
const configDir = getConfigDirectory(configPath);
|
|
@@ -57,10 +86,13 @@ export async function configure(agentId, server, options) {
|
|
|
57
86
|
? servers[server.name]
|
|
58
87
|
: undefined;
|
|
59
88
|
const shapedServer = shaped;
|
|
89
|
+
const enabledShapedServer = enabledShaped;
|
|
60
90
|
if (existingServer !== undefined && isDeepStrictEqual(existingServer, shapedServer)) {
|
|
61
91
|
return { changed: false, content: document };
|
|
62
92
|
}
|
|
63
|
-
if (existingServer !== undefined &&
|
|
93
|
+
if (existingServer !== undefined &&
|
|
94
|
+
(enabledShapedServer === undefined ||
|
|
95
|
+
!isDeepStrictEqual(existingServer, enabledShapedServer))) {
|
|
64
96
|
throw new Error(`MCP server "${server.name}" already exists with different configuration in ${configPath}.`);
|
|
65
97
|
}
|
|
66
98
|
const newServers = {
|
|
@@ -98,7 +130,8 @@ export async function unconfigure(agentId, server, options) {
|
|
|
98
130
|
if (!Object.hasOwn(servers, serverName)) {
|
|
99
131
|
return { changed: false, content: document };
|
|
100
132
|
}
|
|
101
|
-
if (expectedServer !== undefined &&
|
|
133
|
+
if (expectedServer !== undefined &&
|
|
134
|
+
!isDeepStrictEqual(servers[serverName], expectedServer)) {
|
|
102
135
|
return { changed: false, content: document };
|
|
103
136
|
}
|
|
104
137
|
const newServers = { ...servers };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . 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 mcp-oauth auth-store"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"toolcraft-schema": "0.0.
|
|
50
|
+
"toolcraft-schema": "0.0.41",
|
|
51
51
|
"commander": "^14.0.3",
|
|
52
52
|
"fast-string-width": "^3.0.2",
|
|
53
53
|
"fast-wrap-ansi": "^0.2.0",
|