toolcraft 0.0.384 → 0.0.386
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
CHANGED
|
@@ -33,7 +33,7 @@ const result = await shell.exec("tools list-users --limit 10 --output json");
|
|
|
33
33
|
await shell.dispose();
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Each root name and
|
|
36
|
+
Each root name, its kebab-case spelling and aliases become virtual commands. Nested groups, command aliases,
|
|
37
37
|
default commands, positional arguments, schema defaults, scalar/enum/array/object/
|
|
38
38
|
record/union inputs and CLI scope filtering reuse Toolcraft's CLI parser. Hidden
|
|
39
39
|
commands are excluded from this surface. Standalone CLI behavior remains unchanged.
|
|
@@ -102,7 +102,11 @@ or overlay filesystem. Library services combine with invocation services, with
|
|
|
102
102
|
invocation-owned services taking precedence on name collisions. Runtime capability
|
|
103
103
|
names are reserved and cannot be replaced through services. Explicitly revoking
|
|
104
104
|
`humanInLoop` also disables a library-configured approval provider.
|
|
105
|
-
Schema pattern validation
|
|
105
|
+
Schema `pattern` and `patternProperties` validation is unsupported in this native
|
|
106
|
+
surface: registration rejects these keywords in parameter and stream-event schemas,
|
|
107
|
+
including nested JSON Schema definitions, instead of using the host regex engine.
|
|
108
|
+
Tools that need regex work can use the injected bounded provider in their handlers.
|
|
109
|
+
CLI-excluded roots are also inaccessible through the public command executor.
|
|
106
110
|
|
|
107
111
|
## What the owner decides
|
|
108
112
|
|
package/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.386",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.386",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/composition.json
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "toolcraft",
|
|
116
|
-
"version": "0.0.
|
|
116
|
+
"version": "0.0.386",
|
|
117
117
|
"license": "MIT"
|
|
118
118
|
},
|
|
119
119
|
{
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"name": "toolcraft-schema",
|
|
126
|
-
"version": "0.0.
|
|
126
|
+
"version": "0.0.386",
|
|
127
127
|
"license": "MIT"
|
|
128
128
|
},
|
|
129
129
|
{
|
package/dist/safe-bash.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { cloneDefaultValue, validate } from "toolcraft-schema";
|
|
2
|
+
import { cloneDefaultValue, toJsonSchema, validate } from "toolcraft-schema";
|
|
3
3
|
import { executeCLICommand, formatCLIName } from "./cli.js";
|
|
4
4
|
import { validateServices } from "./runtime/io.js";
|
|
5
5
|
/** Checks paths, parameter names and values against a library's inferred definitions. */
|
|
@@ -79,11 +79,42 @@ function handlerFileSystem(invocation) {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
+
function assertNativeSchema(schema, commandPath) {
|
|
83
|
+
if (schema === null || typeof schema !== "object" || Array.isArray(schema))
|
|
84
|
+
return;
|
|
85
|
+
const document = schema;
|
|
86
|
+
if (document.pattern !== undefined || document.patternProperties !== undefined) {
|
|
87
|
+
throw new TypeError(`Schema regex validation is unsupported in native Toolcraft commands: ${commandPath}; use the invocation's bounded regex capability in the handler`);
|
|
88
|
+
}
|
|
89
|
+
// Visit schema positions only: parameter names and literal defaults are not keywords.
|
|
90
|
+
for (const key of ["properties", "$defs", "definitions", "dependentSchemas", "dependencies"]) {
|
|
91
|
+
const map = document[key];
|
|
92
|
+
if (map !== null && typeof map === "object" && !Array.isArray(map)) {
|
|
93
|
+
for (const child of Object.values(map))
|
|
94
|
+
assertNativeSchema(child, commandPath);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const key of ["allOf", "anyOf", "oneOf", "prefixItems", "items", "additionalItems", "additionalProperties", "contains", "if", "then", "else", "not", "propertyNames", "unevaluatedItems", "unevaluatedProperties"]) {
|
|
98
|
+
const child = document[key];
|
|
99
|
+
if (Array.isArray(child)) {
|
|
100
|
+
for (const item of child)
|
|
101
|
+
assertNativeSchema(item, commandPath);
|
|
102
|
+
}
|
|
103
|
+
else
|
|
104
|
+
assertNativeSchema(child, commandPath);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
82
107
|
/** Executes already-tokenized argv in process, using the same parser and dispatch as runCLI. */
|
|
83
108
|
export function createToolcraftCommandExecutor(library, options = {}) {
|
|
84
|
-
const roots = Array.isArray(library) ? library : [library]
|
|
109
|
+
const roots = (Array.isArray(library) ? library : [library])
|
|
110
|
+
.filter(root => !root.scope || root.scope.includes("cli"));
|
|
85
111
|
const multiple = Array.isArray(library);
|
|
86
112
|
const commands = new Map(roots.flatMap(root => [...discoverCommands(root, multiple ? `${root.name}/` : "")]));
|
|
113
|
+
for (const [commandPath, command] of commands) {
|
|
114
|
+
assertNativeSchema(toJsonSchema(command.params), commandPath);
|
|
115
|
+
if (command.stream)
|
|
116
|
+
assertNativeSchema(toJsonSchema(command.stream.event), commandPath);
|
|
117
|
+
}
|
|
87
118
|
const defaults = cloneDefaultValue(options.defaults ?? {});
|
|
88
119
|
for (const [commandPath, values] of Object.entries(defaults)) {
|
|
89
120
|
const command = commands.get(commandPath);
|
|
@@ -108,7 +139,7 @@ export function createToolcraftCommandExecutor(library, options = {}) {
|
|
|
108
139
|
const configuredServices = typeof options.services === "function" ? options.services(invocation) : options.services;
|
|
109
140
|
services = { ...configuredServices, ...invocation.services };
|
|
110
141
|
const rootName = multiple ? argv[0] : roots[0]?.name;
|
|
111
|
-
const selectedRoot = multiple ? roots.find(candidate => candidate.name === rootName || candidate.aliases.includes(rootName ?? "")) : roots[0];
|
|
142
|
+
const selectedRoot = multiple ? roots.find(candidate => candidate.name === rootName || formatCLIName(candidate.name, "kebab") === rootName || candidate.aliases.includes(rootName ?? "")) : roots[0];
|
|
112
143
|
if (!selectedRoot)
|
|
113
144
|
throw new TypeError(`Unknown toolcraft root: ${rootName}`);
|
|
114
145
|
root = selectedRoot;
|
|
@@ -173,7 +204,7 @@ export function toolcraftCommands(library, options = {}) {
|
|
|
173
204
|
for (const root of roots) {
|
|
174
205
|
if (root.scope && !root.scope.includes("cli"))
|
|
175
206
|
continue;
|
|
176
|
-
for (const name of [root.name, ...root.aliases]) {
|
|
207
|
+
for (const name of new Set([root.name, formatCLIName(root.name, "kebab"), ...root.aliases])) {
|
|
177
208
|
host.commands.register({
|
|
178
209
|
name,
|
|
179
210
|
description: root.description,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.386",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
"yaml"
|
|
163
163
|
],
|
|
164
164
|
"optionalDependencies": {
|
|
165
|
-
"toolcraft-schema": "0.0.
|
|
165
|
+
"toolcraft-schema": "0.0.386",
|
|
166
166
|
"toolcraft-design": "*",
|
|
167
167
|
"@poe-code/frontmatter": "*",
|
|
168
168
|
"@poe-code/agent-mcp-config": "*",
|