Skip to content

Skills commands to wrap npm's skills#10528

Draft
christhompsongoogle wants to merge 2 commits into
mainfrom
skills-commands
Draft

Skills commands to wrap npm's skills#10528
christhompsongoogle wants to merge 2 commits into
mainfrom
skills-commands

Conversation

@christhompsongoogle
Copy link
Copy Markdown
Contributor

No description provided.

@wiz-9635d3485b
Copy link
Copy Markdown

Wiz Scan Summary

Scanner Findings
Vulnerability Finding Vulnerabilities -
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings 10 Medium
Software Management Finding Software Management Findings -
Total 10 Medium

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new 'skills' command set to the CLI, including functionality to add, update, and delete skills. The implementation includes a manifest system for tracking local file hashes and transformations, as well as a registry for synchronizing with remote updates. Feedback focuses on improving type safety by removing 'any' casts, enhancing the robustness of CLI argument parsing for multiple flags, addressing potential regex injection vulnerabilities during template replacement, and optimizing I/O operations during bulk updates.

set.transformName = transformName;
}

await installSkill(path, path, { ...options, set } as any);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

There are two issues here:

  1. Casting to any violates the repository style guide regarding type safety.
  2. Using the raw path as the skillName is problematic when path is a local file path (e.g., ./myskill.ts). This leads to the manifest using the path as a key and installSkill generating filenames like .agent/skills/./myskill.ts.ts. Consider deriving a clean name from the path or requiring an alias for local files.
References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

Comment thread src/skills/api.ts
for (const [key, value] of Object.entries(options.set)) {
transformations[key] = value;
// Simple template replacement
content = content.replace(new RegExp(`{{${key}}}`, "g"), String(value));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Using new RegExp with an unescaped variable (key) can lead to regex injection or unexpected behavior if the key contains special characters (e.g., ., *, or {). Since this is a simple template replacement, using split().join() is safer and more performant.

Suggested change
content = content.replace(new RegExp(`{{${key}}}`, "g"), String(value));
content = content.split(`{{${key}}}`).join(String(value));

Comment on lines +12 to +17
if (typeof options.set === "string") {
const [key, value] = options.set.split("=");
if (key && value) {
set[key] = value;
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The current logic only handles a single --set flag if it is passed as a string. In many CLI configurations, providing multiple --set flags results in an array. This implementation would skip processing entirely if options.set is an array, preventing users from applying multiple transformations.

Suggested change
if (typeof options.set === "string") {
const [key, value] = options.set.split("=");
if (key && value) {
set[key] = value;
}
}
const set: Record<string, string> = {};
const setArgs = Array.isArray(options.set) ? options.set : (typeof options.set === "string" ? [options.set] : []);
for (const s of setArgs) {
const [key, value] = s.split("=");
if (key && value) {
set[key] = value;
}
}

Comment thread src/skills/api.ts
Comment on lines +163 to +167
await installSkill(skillName, entry.source, {
...options,
alias: entry.transformations?.alias,
set: entry.transformations
} as any);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Calling installSkill inside a loop is inefficient because installSkill performs individual manifest loads and saves (I/O) for every item. For bulk updates, it is better to update the manifest in memory and perform a single save operation at the end of the process.

Comment thread src/skills/types.ts
localFileHash: string;
transformations?: {
alias?: string;
[key: string]: any;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Avoid using any as an escape hatch for transformation values. Define a more specific type (e.g., string | number | boolean) to adhere to the style guide and ensure type safety.

References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

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