Conversation
…nal fields - Updated JSON schemas for subfinder, urlfinder, and yt-dlp to remove unnecessary fields and make enumValues, dependencies, and validations optional. - Modified commandly nested and main types to reflect optional properties for enumValues, validations, and dependencies. - Enhanced UI components to safely access optional properties, preventing potential runtime errors. - Adjusted tool editor dialogs to accommodate changes in parameter handling, ensuring smooth updates and rendering of enum values. - Cleaned up manual new tool component by removing unused state properties.
There was a problem hiding this comment.
Pull request overview
This PR appears to relax the Commandly tool JSON shape (making several fields optional) and update the tool editor/export pipeline and sample tool definitions to tolerate missing/empty properties.
Changes:
- Make multiple
commandly/commandly-nestedschema fields optional (e.g.,metadata,exclusionGroups, enum-related fields). - Add null-safe access patterns in the tool editor UI/store for optional arrays/metadata.
- Update structured/nested JSON specifications and multiple
public/tools-collection/*.jsonfiles to omit empty arrays; add tests around omission behavior.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/components/tool-editor-ui/manual-new-tool.tsx | Adjusts manual tool creation state initialization (now omits some optional fields). |
| registry/commandly/tool-editor/tool-editor.store.ts | Makes exclusion group handling tolerant of undefined exclusionGroups. |
| registry/commandly/tool-editor/help-menu.tsx | Makes enum value printing tolerant of undefined enumValues. |
| registry/commandly/tool-editor/dialogs/tool-details-dialog.tsx | Makes metadata access null-safe for supported input/output defaults. |
| registry/commandly/tool-editor/dialogs/parameter-details-dialog.tsx | Makes enumValues handling tolerant of undefined and updates enum value add behavior. |
| registry/commandly/runtime-preview.tsx | Makes enumValues rendering tolerant of undefined. |
| registry/commandly/lib/utils/commandly.ts | Updates default/tool creation + import flattening + command sorting behavior to align with optional fields. |
| registry/commandly/lib/utils/commandly-nested.ts | Updates nested conversion to tolerate optional validations/dependencies/exclusionGroups. |
| registry/commandly/lib/types/commandly.ts | Updates Zod schemas/types to make several fields optional. |
| registry/commandly/lib/types/commandly-nested.ts | Updates nested schemas/types to make enum/validation/dependency arrays optional. |
| registry/commandly/tests/json-output.test.tsx | Adds tests asserting structured/nested output omits empty optional fields. |
| public/tools-collection/yt-dlp.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/urlfinder.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/subfinder.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/shuffledns.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/katana.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/httpx.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/dnsx.json | Removes empty arrays/fields (incl. empty metadata) to match updated optional schema. |
| public/tools-collection/cdncheck.json | Removes empty arrays/fields to match updated optional schema. |
| public/tools-collection/asnmap.json | Removes empty arrays/fields to match updated optional schema. |
| public/specification/nested.json | Updates JSON Schema required-fields rules to reflect new optionality/nullability. |
| public/specification/flat.json | Updates JSON Schema required-fields rules to reflect new optionality. |
Comments suppressed due to low confidence (1)
registry/commandly/runtime-preview.tsx:131
- With the updated
Parametertype makingdescriptionoptional, this component still passesparameter.descriptionintoParameterLabelProps.description, which is typed as a requiredstring. This should fail understrictNullChecksand/or cause undefined descriptions at runtime. Consider makingParameterLabelProps.descriptionoptional (and rendering a fallback) or passingparameter.description ?? ""everywhereParameterLabelis used.
{parameter.enumValues?.map((enumValue) => (
<SelectItem
key={enumValue.key}
value={enumValue.value}
>
| }; | ||
|
|
||
| export const createNewParameter = (isGlobal: boolean, commandKey?: string): Parameter => { | ||
| return { | ||
| key: "", | ||
| name: "", | ||
| commandKey: isGlobal ? undefined : commandKey, | ||
| description: "", | ||
| parameterType: "Option", | ||
| dataType: "String", | ||
| isRequired: false, | ||
| isRepeatable: false, | ||
| isGlobal, | ||
| defaultValue: "", | ||
| shortFlag: "", | ||
| longFlag: "", |
There was a problem hiding this comment.
createNewParameter now omits defaults like description, defaultValue, shortFlag, separators, and arrays. Several UI inputs bind directly to these fields (e.g. value={parameter.description} / value={parameter.shortFlag}), so newly-created parameters will start as undefined and can trigger controlled/uncontrolled warnings or break nested export where description is required. Consider restoring safe defaults (empty strings / default separators / empty arrays) or ensure the UI always coalesces undefined to appropriate defaults.
| @@ -9,9 +9,6 @@ export function ManualNewToolComponent({ onSubmit }: { onSubmit: (tool: Tool | n | |||
| const [manualNewTool, setManualTool] = useState<ManualNewTool>({ | |||
| name: "", | |||
| displayName: "", | |||
There was a problem hiding this comment.
manualNewTool state no longer initializes version, url, and description, but the inputs/text area still bind value={manualNewTool.version/url/description}. This will make those fields undefined initially and can cause React controlled/uncontrolled warnings (and potentially broken editing depending on the underlying Input/Textarea implementation). Initialize these fields to empty strings again or use nullish coalescing in the value props (e.g., value={manualNewTool.version ?? ""}).
| displayName: "", | |
| displayName: "", | |
| version: "", | |
| url: "", | |
| description: "", |
| preview += `${indent} ${" ".repeat(18)} Values: ${arg.enumValues | ||
| .map((e) => e.value) | ||
| .join(", ")}\n`; | ||
| preview += `${indent} ${" ".repeat(18)} Values: ${arg.enumValues?.map((e) => e.value).join(", ")}\n`; |
There was a problem hiding this comment.
When arg.enumValues is undefined, this interpolation prints Values: undefined in the generated help preview. Consider defaulting to an empty string (or only adding the line when there are values) so the preview output stays clean.
| preview += `${indent} ${" ".repeat(18)} Values: ${arg.enumValues?.map((e) => e.value).join(", ")}\n`; | |
| const valuesString = (arg.enumValues ?? []).map((e) => e.value).join(", "); | |
| if (valuesString) { | |
| preview += `${indent} ${" ".repeat(18)} Values: ${valuesString}\n`; | |
| } |
|
|
||
| export const buildCommandHierarchy = (commands: Command[]): Command[] => { | ||
| return commands.sort((a, b) => a.sortOrder - b.sortOrder); | ||
| return commands.sort( |
There was a problem hiding this comment.
The sort comparator uses commands.indexOf(a/b) as a fallback when sortOrder is missing. Because Array.prototype.sort mutates commands while sorting, indexOf can change during the sort, producing a non-transitive comparator and potentially inconsistent ordering. Prefer capturing original indices before sorting (or sorting a copied array) and using those cached indices as a stable tie-breaker.
| return commands.sort( | |
| const originalIndex = new Map<Command, number>(); | |
| commands.forEach((cmd, index) => { | |
| originalIndex.set(cmd, index); | |
| }); | |
| return commands.sort((a, b) => { | |
| const aOrder = a.sortOrder ?? originalIndex.get(a) ?? 0; | |
| const bOrder = b.sortOrder ?? originalIndex.get(b) ?? 0; | |
| return aOrder - bOrder; | |
| }); |
| }; | ||
|
|
||
| export const flattenImportedData = (importedData: Record<string, unknown>): Tool => { | ||
| const { | ||
| name, | ||
| displayName, | ||
| parameters = [], | ||
| commands = [], | ||
| exclusionGroups = [], | ||
| metadata = { | ||
| supportedInput: [], | ||
| supportedOutput: [], | ||
| }, | ||
| } = importedData as { | ||
| name: string; | ||
| displayName?: string; | ||
| parameters?: Parameter[]; | ||
| commands?: Record<string, unknown>[]; | ||
| exclusionGroups?: ExclusionGroup[]; | ||
| metadata?: Tool["metadata"]; | ||
| }; | ||
|
|
There was a problem hiding this comment.
flattenImportedData no longer includes top-level parameters from importedData (it initializes allParameters to [] and never appends the root parameters). If the imported JSON is already in the flat format (with parameters at the root), those parameters will be silently dropped. Consider restoring the previous behavior (seed allParameters from parameters) or remove parameters from the accepted input shape if this function is intended to only flatten nested command parameters.
| @@ -287,32 +278,22 @@ | |||
| key: slugify(name), | |||
There was a problem hiding this comment.
createNewCommand no longer sets a default description. Downstream code (help preview, nested export schema, etc.) expects a string description and will end up rendering/serializing undefined or failing schema validation. Provide a default description (even an empty string) to keep newly-created commands compatible with the rest of the tool editor/export pipeline.
| key: slugify(name), | |
| name, | |
| description: "", |
No description provided.