Skip to content

Chore#103

Merged
divyeshio merged 5 commits intomainfrom
chore
Mar 5, 2026
Merged

Chore#103
divyeshio merged 5 commits intomainfrom
chore

Conversation

@divyeshio
Copy link
Owner

No description provided.

…schemas, update tool editor and AI parsing components to reflect changes, implement new registry API for fetching tool data, enhance documentation routes, and improve overall code structure and readability.
Copilot AI review requested due to automatic review settings March 5, 2026 13:14
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the “Commandly” tool/registry plumbing by removing Zod-based runtime schemas, switching schema generation to typescript-json-schema, and adding a new /docs section backed by a registry API. It also updates contribution/automation workflows (tool submission and generated-artifact updates) and surfaces build metadata (commit SHA) in the UI.

Changes:

  • Add /docs routes and registry API to browse registry items and view details.
  • Replace Zod schemas/validators with TypeScript interfaces + JSON schema generation via typescript-json-schema.
  • Update CI/workflows for tool PR validation and auto-regeneration of specs/registry artifacts; add COMMIT_SHA define.

Reviewed changes

Copilot reviewed 42 out of 46 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
vite.config.ts Adds /docs prerender and injects COMMIT_SHA build define
src/vite-env.d.ts Declares global COMMIT_SHA type
src/routes/tools/$toolName/index.tsx Replaces Zod search validation + localStorage tool parsing logic
src/routes/tools/$toolName/edit.tsx Replaces Zod search validation + localStorage tool parsing logic
src/routes/index.tsx Shows commit SHA link in footer
src/routes/docs/index.tsx New docs index listing registry items
src/routes/docs/$componentName.tsx New docs detail page for a registry item
src/routes/__root.tsx Updates navbar (Playground/Docs) and root HTML props
src/routeTree.gen.ts Adds generated routes for /docs
src/lib/types.ts Replaces Zod types with TS types + module augmentation for ToolMetadata
src/lib/api/registry.api.ts New API for fetching registry list/items (isomorphic list)
src/components/tool-editor-ui/tool-card.tsx Adjusts link search params construction for newTool
src/components/tool-editor-ui/manual-new-tool.tsx Moves ManualNewTool import to src/lib/types
src/components/tool-editor-ui/import.tsx Removes Zod parse and casts imported JSON to Tool
src/components/tool-editor-ui/ai-parsing.tsx Switches schema source to /specification/flat.json and removes Zod validation
scripts/generate-specification.ts Generates flat/nested JSON Schema from TS types via typescript-json-schema
registry/commandly/tool-editor/tool-editor.tsx Updates “Contribute” flow to open GitHub file editor (new/edit)
registry/commandly/tool-editor/dialogs/tool-details-dialog.tsx Casts metadata updates to ToolMetadata
registry/commandly/tool-editor/dialogs/parameter-details-dialog.tsx Makes longFlag trimming null-safe
registry/commandly/lib/utils/commandly-nested.ts Provides defaults for isDefault/sortOrder when nesting
registry/commandly/lib/types/commandly.ts Replaces Zod schemas with TS interfaces for flat tool model
registry/commandly/lib/types/commandly-nested.ts Replaces Zod schemas with TS interfaces for nested tool model
registry/commandly/tests/json-output.test.tsx Updates casting in test after type changes
registry.json Updates registry dependency lists to remove Zod
public/specification/nested.json Updates generated nested JSON Schema output
public/specification/flat.json Updates generated flat JSON Schema output
public/r/ui.json Updates registry item payload to remove Zod dependency + refresh embedded file contents
public/r/runtime-preview.json Refreshes embedded file contents
public/r/registry.json Updates public registry dependency lists to remove Zod
public/r/json-output.json Refreshes embedded file contents
public/r/generated-command.json Refreshes embedded file contents
public/r/core.json Removes deprecated/duplicate registry item
public/r/commandly-utils.json Refreshes embedded file contents
public/r/commandly-types.json Removes Zod dependency + refreshes embedded file contents
package.json Removes @tanstack/zod-adapter, adds typescript-json-schema
.vscode/tasks.json Adds a “bun dev” task that runs on folder open
.github/workflows/validate-tool-pr.yml Adds PR-time validation for changed public/tools-collection/** JSON files
.github/workflows/tool-submission.yml Removes issue-driven tool submission automation
.github/workflows/pr.yml Regenerates specs/registry during PR checks and attempts to commit/push
.github/workflows/ci-cd.yml Regenerates specs/registry during deploy workflow and attempts to commit/push
.github/PULL_REQUEST_TEMPLATE/tool-submission.md Fixes template table formatting
.github/ISSUE_TEMPLATE/new-tool.yml Removes issue form for new tools
.github/ISSUE_TEMPLATE/edit-tool.yml Removes issue form for tool edits

Comment on lines 76 to 87
const validateJson = useCallback(
(jsonString: string) => {
try {
const parsedTool = ToolSchema.parse(JSON.parse(jsonString));
const parsedTool = JSON.parse(jsonString) as Tool;
const modifiedTool = replaceKey(parsedTool);
setJson(JSON.stringify(modifiedTool, null, 2));
onParseCompleted(modifiedTool);
} catch (error) {
console.error("Error parsing JSON:", error);
onParseCompleted(null);
if (error instanceof z.ZodError) {
toast.error(`Invalid JSON: ${error.name}. Please check the format.`, {
description: z.prettifyError(error),
duration: 5000,
});
} else {
toast.error("Failed to parse JSON. Please check the format.");
}
toast.error("Failed to parse JSON. Please check the format.");
}
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateJson now only checks that the text is valid JSON, then casts to Tool. If the AI returns a JSON object that doesn’t match the Tool shape, this will still be treated as “valid” and can cause downstream runtime errors. Consider adding at least a lightweight structural validation (required fields + array checks) before calling onParseCompleted / replacing keys.

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +78
- name: Commit changes if any
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"

if git diff --quiet; then
echo "No changes to commit"
else
git add .
git commit -m "chore: update generated specifications and registry"
git push origin HEAD:${{ github.head_ref }}
fi
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow pushes commits back to the PR branch (git push) during CI. For PRs from forks, the job will fail because the token can’t push to the contributor’s branch, and even for same-repo PRs it mutates the branch during checks (can invalidate reviews / create surprise commits). Consider making this conditional on !github.event.pull_request.head.repo.fork (or removing the push and instead failing with instructions / using a separate bot workflow).

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +25
const flatProgram = TJS.programFromConfig(tsConfigPath, [
join(process.cwd(), "registry/commandly/lib/types/commandly.ts"),
]);
const flatSchema = TJS.generateSchema(flatProgram, "Tool", settings);
const flatOutputPath = join(process.cwd(), "public", "specification", "flat.json");
writeFileSync(flatOutputPath, JSON.stringify(flatJsonSchema, null, 2));
writeFileSync(flatOutputPath, JSON.stringify(flatSchema, null, 2));

// Generate Nested Specification
const nestedJsonSchema = z.toJSONSchema(NestedToolSchema);
const nestedProgram = TJS.programFromConfig(tsConfigPath, [
join(process.cwd(), "registry/commandly/lib/types/commandly-nested.ts"),
]);
const nestedSchema = TJS.generateSchema(nestedProgram, "NestedTool", settings);
const nestedOutputPath = join(process.cwd(), "public", "specification", "nested.json");
writeFileSync(nestedOutputPath, JSON.stringify(nestedJsonSchema, null, 2));
writeFileSync(nestedOutputPath, JSON.stringify(nestedSchema, null, 2));
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TJS.generateSchema(...) can return null (e.g., if the type name can’t be resolved or the program fails). Currently the script will write null to the schema files and still exit 0, which can silently break downstream consumers (AI parsing, validation, etc.). Add explicit null checks and throw a descriptive error / non-zero exit before writing files.

Copilot uses AI. Check for mistakes.
Comment on lines 26 to 30
try {
const importedData = JSON.parse(jsonInput);
const tool = ToolSchema.parse(importedData);
const tool = importedData as Tool;
onParseCompleted(tool);
setJsonInput("");
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The importer now accepts any valid JSON and casts it to Tool without validating required fields (e.g., name, displayName, commands, parameters). Invalid-but-JSON input will get past this try/catch and likely fail later in the editor/runtime preview. Consider adding minimal shape checks here (or a runtime schema validator) and showing a helpful error before calling onParseCompleted.

Copilot uses AI. Check for mistakes.
Comment on lines 12 to +52
@@ -32,6 +32,25 @@ jobs:
- name: Install dependencies
run: bun install

- name: Generate specifications
run: bun run specification:build

- name: Build registry
run: bun run registry:build

- name: Commit changes if any
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"

if git diff --quiet; then
echo "No changes to commit"
else
git add .
git commit -m "chore: update generated specifications and registry"
git push origin HEAD:main
fi
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deploy workflow commits and pushes generated files back to main as part of a run triggered by push to main. That can cause extra pipeline runs (push → workflow → push → workflow), can fail on protected branches, and makes deployments less deterministic. Consider avoiding pushes from CI (treat generated artifacts as build outputs) or adding guards (e.g., skip if github.actor is the actions bot / use [skip ci] / separate scheduled update workflow).

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +31
const { execSync } = require("child_process");

const changedFiles = execSync(
`git diff --name-only origin/${context.payload.pull_request.base.ref}...HEAD -- "public/tools-collection/"`,
{ encoding: "utf-8" }
).trim().split("\n").filter(Boolean);

Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git diff --name-only origin/${baseRef}...HEAD is likely to fail in Actions because actions/checkout defaults to fetch-depth: 1 and won’t have origin/${baseRef} fetched. Set fetch-depth: 0 (or explicitly fetch the base ref) before running the diff, or use the GitHub API (pulls.listFiles) to get the changed files instead of shelling out to git.

Suggested change
const { execSync } = require("child_process");
const changedFiles = execSync(
`git diff --name-only origin/${context.payload.pull_request.base.ref}...HEAD -- "public/tools-collection/"`,
{ encoding: "utf-8" }
).trim().split("\n").filter(Boolean);
const prNumber = context.payload.pull_request.number;
const files = await github.paginate(
github.rest.pulls.listFiles,
{
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
per_page: 100,
}
);
const changedFiles = files
.map((f) => f.filename)
.filter((name) => name.startsWith("public/tools-collection/"));

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +59
define: {
COMMIT_SHA: `"${process.env.GITHUB_SHA?.slice(0, 7).toString()}"`,
},
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process.env.GITHUB_SHA?.slice(0, 7).toString() will throw at build time when GITHUB_SHA is unset (optional chaining only applies to the slice call; .toString() is still invoked on the possibly-undefined result). Consider safely deriving the value (e.g., const sha = process.env.GITHUB_SHA?.slice(0,7) ?? "") and using JSON.stringify(sha) so local builds/CI without that env don’t crash and COMMIT_SHA is falsy when missing.

Copilot uses AI. Check for mistakes.
Comment on lines 36 to 41
if (newTool) {
const newToolData = localStorage.getItem(`tool-${newTool}`);
if (newToolData) {
const validatedTool = zodValidator(ToolSchema).parse(JSON.parse(newToolData));
return validatedTool;
return JSON.parse(newToolData) as Tool;
} else {
return defaultTool() as Tool;
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON.parse(newToolData) is unguarded here. If localStorage contains invalid JSON (corrupted value, manual edits, older format), the route loader will throw and the page will fail to render. Wrap the parse in a try/catch and fall back to defaultTool() (and optionally clear the bad localStorage entry / show a toast).

Copilot uses AI. Check for mistakes.
Comment on lines 15 to 22
loader: async ({ params: { toolName }, deps: { newTool } }) => {
if (newTool) {
const newToolData = localStorage.getItem(`tool-${newTool}`);
if (newToolData) {
const validatedTool = zodValidator(ToolSchema).parse(JSON.parse(newToolData));
return validatedTool;
return JSON.parse(newToolData) as Tool;
} else {
return defaultTool() as Tool;
}
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON.parse(newToolData) is unguarded here. A corrupted/legacy localStorage value will throw in the loader and break the edit page. Add a try/catch with a safe fallback (e.g., defaultTool() and/or clearing the invalid tool-${newTool} entry).

Copilot uses AI. Check for mistakes.
@divyeshio divyeshio merged commit f29c7c8 into main Mar 5, 2026
3 checks passed
@divyeshio divyeshio deleted the chore branch March 5, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants