Skip to content

Validate iterate watch scheduling options#746

Merged
ralyodio merged 2 commits into
profullstack:masterfrom
rissrice2105-agent:codex/sh1pt-iterate-quiet-hours
Jun 14, 2026
Merged

Validate iterate watch scheduling options#746
ralyodio merged 2 commits into
profullstack:masterfrom
rissrice2105-agent:codex/sh1pt-iterate-quiet-hours

Conversation

@rissrice2105-agent

@rissrice2105-agent rissrice2105-agent commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #745.

Changes

  • validate iterate watch --quiet-hours before configuration is persisted
  • require start-end format with both local hours in the 0-23 range
  • require --interval to be a positive safe integer before generating cron configuration
  • keep parsers dependency-light so focused tests run without optional workspace packages
  • add regression tests

Verification

  • corepack pnpm vitest run packages/cli/src/commands/iterate.test.ts (18 passed)
  • corepack pnpm --filter @profullstack/sh1pt typecheck attempted; it still fails on existing workspace/module-resolution errors unrelated to this PR

@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds CLI-level input validation for the iterate watch --quiet-hours and --interval options by extracting two focused parser functions (parseQuietHours, parsePositiveSafeInteger) into a new iterate-options.ts module and wiring them as Commander argument parsers. Bad values now surface as InvalidArgumentError before the watch config is persisted.

  • parseQuietHours enforces the start-end regex and bounds-checks both hours against 0–23; parsePositiveSafeInteger rejects non-integer, non-positive, and out-of-safe-range values for --interval.
  • New test file iterate.test.ts covers valid inputs, format errors, and out-of-range values for both parsers without importing workspace-private packages.
  • Existing quiet-hours enforcement (the inQuietHours helper) is unchanged; this PR is scoped to validation on write.

Confidence Score: 5/5

Safe to merge — the change is additive validation only; no existing data paths are altered.

Both parsers are implemented correctly, the regex tightly constrains inputs to digit-only groups before numeric conversion, and the tests cover valid inputs, format errors, and out-of-range values. The wiring in iterate.ts is minimal and correct.

No files require special attention.

Important Files Changed

Filename Overview
packages/cli/src/commands/iterate-options.ts New module with parseQuietHours and parsePositiveSafeInteger; logic is correct and the regex correctly constrains inputs to 1–2 digit groups only.
packages/cli/src/commands/iterate.test.ts Focused unit tests for both parsers; covers valid ranges, format errors, and out-of-range values without workspace dependencies.
packages/cli/src/commands/iterate.ts Wires the two new parsers into the Commander option definitions for --interval and --quiet-hours; all other behaviour is unchanged.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["sh1pt iterate watch --interval N --quiet-hours S-E"] --> B["Commander parses --interval"]
    B --> C{"parsePositiveSafeInteger(N)"}
    C -- valid --> D[interval stored as number]
    C -- invalid --> E["InvalidArgumentError: must be a positive safe integer"]
    A --> F["Commander parses --quiet-hours"]
    F --> G{"parseQuietHours(S-E)"}
    G -- regex fails --> H["InvalidArgumentError: must use start-end format"]
    G -- regex ok --> I{"start > 23 or end > 23?"}
    I -- yes --> J["InvalidArgumentError: hours must be between 0 and 23"]
    I -- no --> K["returns original string value"]
    D --> L["WatchConfig persisted to iterate-watch.json"]
    K --> L
    L --> M["iterate watch --status reads config"]
    M --> N["inQuietHours(spec) called for display only"]
Loading

Reviews (2): Last reviewed commit: "Validate iterate watch interval" | Re-trigger Greptile

Comment on lines +10 to +12

export function parseQuietHours(value: string): string {
const match = value.match(/^(\d{1,2})-(\d{1,2})$/);

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.

P2 start === end accepted but creates a permanently-silent quiet window

When start equals end (e.g., 10-10), the validator passes (both values ≤ 23), but inQuietHours evaluates hour >= 10 && hour < 10 — a contradiction that is never true. The watch daemon will never pause, with no error or warning surfaced to the user. Adding if (start === end) throw new InvalidArgumentError('start and end hours must differ'); before returning value would close this gap.

@rissrice2105-agent rissrice2105-agent changed the title Validate iterate watch quiet-hours ranges Validate iterate watch scheduling options Jun 14, 2026
@rissrice2105-agent

Copy link
Copy Markdown
Contributor Author

CI is green after expanding this PR to validate both --quiet-hours and --interval.

Verification:

  • corepack pnpm vitest run packages/cli/src/commands/iterate.test.ts (18 passed)
  • corepack pnpm --filter @profullstack/sh1pt typecheck was attempted and still fails on existing workspace/module-resolution errors unrelated to this PR.

uGig invoice evidence will be sent after the retry window expires.

@ralyodio ralyodio merged commit 05ea5cf into profullstack:master Jun 14, 2026
5 checks passed
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.

iterate watch accepts invalid quiet-hours ranges

2 participants