Skip to content

fix(skills): reject invalid listing prices#472

Open
Jorel97 wants to merge 4 commits into
profullstack:masterfrom
Jorel97:codex/fix-skills-price-validation-457
Open

fix(skills): reject invalid listing prices#472
Jorel97 wants to merge 4 commits into
profullstack:masterfrom
Jorel97:codex/fix-skills-price-validation-457

Conversation

@Jorel97
Copy link
Copy Markdown

@Jorel97 Jorel97 commented May 29, 2026

Fixes #457.

sh1pt skills new --price now validates listing prices before the manifest is written:

  • accepts only non-negative integer sat amounts such as 0 or 25
  • rejects negative, fractional, and non-numeric values
  • reuses the parsed value for both sh1pt.skill.json and generated marketplace commands so they cannot diverge
  • adds regression coverage for valid price persistence and invalid price rejection before file creation

Verification: the change is limited to the CLI command and its Vitest coverage. I could not run the repo test suite in this projectless workspace because the full sh1pt dependency checkout is not present here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 29, 2026

Greptile Summary

This PR adds input validation to sh1pt skills new --price, replacing the silent parseInt(...) || 0 fallback with a dedicated parseListingPrice helper that rejects non-numeric, fractional, and negative values, and also guards against integers exceeding Number.MAX_SAFE_INTEGER. The parsed value is now reused for both the manifest and marketplace command generation, eliminating any possible divergence between the two.

  • parseListingPrice applies a ^\\d+$ regex check followed by a Number.isSafeInteger check, throwing a descriptive error before any file I/O on invalid input.
  • Tests cover valid price persistence and regex-based rejection (-5, 1.9, abc), but the isSafeInteger branch has no corresponding test case.

Confidence Score: 5/5

Safe to merge — the validation logic is correct, file writes are guarded, and the parsed value is consistently reused.

The change is narrowly scoped to input validation in a single CLI action handler. Both guard conditions (^\d+$ and isSafeInteger) are correct, the error is thrown before any file I/O, and the single parsed value is threaded through to both the manifest and marketplace commands, removing the previous divergence risk. The new tests cover the main happy path and the three regex-rejected cases.

No files require special attention.

Important Files Changed

Filename Overview
packages/cli/src/commands/skills.ts Adds parseListingPrice helper with regex + isSafeInteger guard; replaces the silent `parseInt(...)
packages/cli/src/commands/skills.test.ts Adds two new test cases: one for valid price persistence, one parametrised for regex-rejected inputs (-5, 1.9, abc). The isSafeInteger rejection path (e.g. "99999999999999999999") has no corresponding test case.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["sh1pt skills new --price <value>"] --> B["parseListingPrice(value)"]
    B --> C{"^\\d+$ test\non value.trim()"}
    C -- fail --> D["throw: --price must be a\nnon-negative integer sat amount"]
    C -- pass --> E["Number.parseInt(normalized, 10)"]
    E --> F{"Number.isSafeInteger(price)?"}
    F -- false --> G["throw: --price must be ≤ Number.MAX_SAFE_INTEGER"]
    F -- true --> H["return price"]
    H --> I["Build manifest + marketplace commands using price"]
    I --> J["Write sh1pt.skill.json"]
Loading

Reviews (2): Last reviewed commit: "test(skills): cover unsafe price values" | Re-trigger Greptile

Comment thread packages/cli/src/commands/skills.ts
Comment thread packages/cli/src/commands/skills.ts
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.

skills new accepts invalid listing prices

1 participant