Skip to content

feat(skills): add smoke health-check command to int-* skills#95

Open
mt-alarcon wants to merge 1 commit into
evolution-foundation:mainfrom
mt-alarcon:feat/int-skills-smoke-command
Open

feat(skills): add smoke health-check command to int-* skills#95
mt-alarcon wants to merge 1 commit into
evolution-foundation:mainfrom
mt-alarcon:feat/int-skills-smoke-command

Conversation

@mt-alarcon
Copy link
Copy Markdown

@mt-alarcon mt-alarcon commented May 31, 2026

What

Adds a uniform smoke connectivity command to integration skills, with three clean reference implementations: int-stripe, int-linkedin, int-youtube.

Why

There's currently no standard way to ask an int-* skill "are you connected and working?" in a machine-readable way. Ad-hoc connectivity checks (where they exist) log to stderr and can crash or return non-zero, so a caller (CI step, scheduled heartbeat, or a human validating a fresh install) can't reliably distinguish "all good" from "auth failed".

Contract

smoke always exits 0 and prints structured JSON:

{
  "overall": "PASS" | "FAIL",
  "steps": [
    {"step": "auth", "status": "PASS", "duration_ms": 123},
    {"step": "list_charges", "status": "FAIL", "error": "401 Unauthorized", "duration_ms": 45}
  ],
  "duration_ms": 168
}
  • Always exit 0, even on failure — missing/invalid credentials report overall: "FAIL" but never crash and never return non-zero. This lets a caller key off the JSON, not the exit code.
  • Each step is wrapped in try/except; the exception message is captured into the error field.
  • Steps are: (1) auth/client init, (2) a cheap representative read-only call.

Scope

Three skills as reference implementations of the convention. The pattern is intentionally simple so it can be applied incrementally to the rest of the int-* family in follow-ups.

Testing

Each command verified locally — python3 <script> smoke returns exit 0 with valid JSON containing the overall field, both with valid credentials (overall: PASS) and without (overall: FAIL, no crash).

🤖 Generated with Claude Code

Summary by Sourcery

Add a standardized JSON-based smoke health-check command to selected integration skills to report connectivity status without relying on exit codes.

New Features:

  • Introduce a smoke command for the Stripe integration skill to validate API key presence and perform a balance read-only check, always returning structured JSON and exit code 0.
  • Add a smoke command to the LinkedIn integration skill that checks account auth and performs a profile read to report health via structured JSON.
  • Add a smoke command to the YouTube integration skill that validates account auth and performs a lightweight channel stats read, emitting structured JSON health results.

…/youtube

Add a uniform `smoke` connectivity command to three integration skills.
The command runs auth + a representative read-only step, always exits 0,
and emits structured JSON so callers (CI, heartbeats, manual validation)
can distinguish PASS from FAIL without parsing stderr or relying on exit
codes that crash on failure.

Contract:
  {"overall": "PASS"|"FAIL",
   "steps": [{"step": "...", "status": "PASS"|"FAIL", "error": "...", "duration_ms": N}],
   "duration_ms": N}

- Always exits 0, even on failure (missing creds report overall=FAIL, never crash)
- Each step wrapped in try/except; errors captured into the `error` field

int-stripe, int-linkedin and int-youtube are clean reference implementations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 31, 2026

Reviewer's Guide

Implements a standardized smoke health-check command for three integration skills (Stripe, LinkedIn, YouTube), each performing an auth/init step plus a cheap read-only API call, always emitting structured JSON with an overall status and timing info while exiting with code 0.

Sequence diagram for standardized smoke health-check command

sequenceDiagram
    actor Caller
    participant Int_skill as int_*_script
    participant External_API

    Caller->>Int_skill: run smoke
    activate Int_skill

    Int_skill->>Int_skill: [auth step]
    alt auth fails
        Int_skill-->>Caller: JSON {overall: FAIL, steps: [auth FAIL], duration_ms}
        Int_skill->>Caller: exit code 0
    else auth passes
        Int_skill->>External_API: read-only request
        External_API-->>Int_skill: response or error
        Int_skill->>Int_skill: [evaluate API result]
        Int_skill-->>Caller: JSON {overall: PASS or FAIL, steps: [...], duration_ms}
        Int_skill->>Caller: exit code 0
    end
Loading

File-Level Changes

Change Details Files
Add smoke health-check subcommand to the Stripe integration script with explicit auth and balance-check steps and JSON output.
  • Introduce cmd_smoke helper that wraps auth and a /balance read call, capturing timing and errors while guaranteeing process exit 0 with JSON output.
  • Add a smoke subparser to the CLI and dispatch to cmd_smoke when invoked.
  • Ensure exceptions are caught at both step-level and top-level, mapping failures to overall: FAIL in the JSON instead of crashing.
.claude/skills/int-stripe/scripts/stripe_query.py
Add a smoke command path to the LinkedIn integration CLI that validates account loading and performs a representative profile read.
  • Handle smoke in the main command dispatch, orchestrating two steps: _get_accounts for auth and a profile read for a single account.
  • Collect per-step statuses (PASS/FAIL/SKIP), errors, and duration_ms, and compute an overall PASS/FAIL.
  • Print the structured JSON result and explicitly exit 0, independent of step failures.
.claude/skills/int-linkedin/scripts/linkedin_client.py
Add a smoke command path to the YouTube integration CLI that validates account loading and performs a lightweight channel stats read.
  • Handle smoke in the main command dispatch, running _get_accounts as the auth step and channel_stats on the first account as the read-only check.
  • Track each step’s status, error message, and duration_ms, and derive an overall PASS/FAIL outcome.
  • Emit structured JSON with total duration and exit 0 regardless of failures.
.claude/skills/int-youtube/scripts/youtube_client.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The smoke implementations are inconsistent across skills (Stripe wraps the whole routine in a BaseException handler and guarantees JSON output, whereas LinkedIn/YouTube can still raise and exit non‑zero), which can violate the stated contract that smoke always exits 0; consider wrapping the LinkedIn/YouTube blocks in a similar top-level try/except to normalize behavior.
  • The smoke commands currently diverge slightly from the documented contract (e.g., Stripe returns extra fields like currency, LinkedIn/YouTube pretty-print JSON and call sys.exit(0) inline); it might be cleaner to centralize or standardize the JSON schema and exit behavior so all int-* skills behave identically.
  • The Stripe smoke docstring and error messages contain Portuguese phrases while the rest of the file is in English; aligning language and style (and using a consistent time source, e.g., time.monotonic() vs time.time()) across the new smoke implementations would improve readability and maintainability.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `smoke` implementations are inconsistent across skills (Stripe wraps the whole routine in a `BaseException` handler and guarantees JSON output, whereas LinkedIn/YouTube can still raise and exit non‑zero), which can violate the stated contract that `smoke` always exits 0; consider wrapping the LinkedIn/YouTube blocks in a similar top-level try/except to normalize behavior.
- The `smoke` commands currently diverge slightly from the documented contract (e.g., Stripe returns extra fields like `currency`, LinkedIn/YouTube pretty-print JSON and call `sys.exit(0)` inline); it might be cleaner to centralize or standardize the JSON schema and exit behavior so all `int-*` skills behave identically.
- The Stripe `smoke` docstring and error messages contain Portuguese phrases while the rest of the file is in English; aligning language and style (and using a consistent time source, e.g., `time.monotonic()` vs `time.time()`) across the new `smoke` implementations would improve readability and maintainability.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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.

1 participant