Conversation
📝 WalkthroughWalkthroughAdds a TeaPie Cursor AI skill: extensive documentation, HTTP templates, and four Python CLI utilities for parsing, discovering, renumbering, and inserting gaps in TeaPie test cases. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as "find-tests-for-api.py"
participant FS as "FileSystem (.http, env.json)"
participant Parser as "HTTP parser & variable resolver"
participant Matcher as "Endpoint matcher"
User->>CLI: run with endpoint, collection, (env)
CLI->>FS: read .http files and optional env.json
CLI->>Parser: parse files, resolve variables
Parser-->>CLI: list of HttpRequest objects
CLI->>Matcher: compare requests to target endpoint/method
Matcher-->>CLI: matched requests
CLI-->>User: print text or JSON results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 Fix all issues with AI agents
In @.cursor/skills/skill-creator/scripts/init_skill.py:
- Around line 5-12: Update the script's top-level docstring usage line in
init_skill.py to show the required positional skill name and the path option
(e.g., change "init_skill.py --path" to "init_skill.py <skill_name> --path
<path>") so it matches the argument parsing and the example lines below; ensure
the usage line mirrors the examples like "init_skill.py my-new-skill --path
skills/public".
In @.cursor/skills/skill-creator/scripts/package_skill.py:
- Around line 5-11: Update the top docstring/usage text in package_skill.py to
reflect the actual CLI signature that requires a skill_path argument and to
reference the correct directory (scripts/ instead of utils/); change the
help/examples (both the initial Usage/Example block and the later occurrences
around the same docstring at lines ~86-90) to show the real invocation: "python
scripts/package_skill.py <skill_path> [output-directory]" and concrete examples
like "python scripts/package_skill.py skills/public/my-skill" and "python
scripts/package_skill.py skills/public/my-skill ./dist" so the usage matches the
script's parameter names and location.
- Around line 64-75: The zip loop can accidentally include the generated archive
when output_path is inside skill_path; update the loop that iterates "for
file_path in skill_path.rglob('*')" to skip the output archive by comparing
file_path to skill_filename (use resolved paths or samefile) and continue when
they match so zipf.write is not called for the generated .skill file; reference
"skill_filename", "skill_path", "output_path", "file_path", and "zipf.write"
when making the change.
In @.cursor/skills/skill-creator/scripts/quick_validate.py:
- Around line 88-91: The usage message in the __main__ block of
quick_validate.py doesn't specify the required skill path argument; update the
check that inspects sys.argv (the if len(sys.argv) != 2 block and the subsequent
print call) so the printed usage string explicitly shows the required argument
(e.g., "Usage: python quick_validate.py <skill_path>") before sys.exit(1),
ensuring callers know to pass the skill path.
In @.cursor/skills/skill-creator/SKILL.md:
- Line 112: Replace the misspelled word "auxilary" with the correct spelling
"auxiliary" in the SKILL.md content (look for the phrase "It should not contain
auxilary context" and update it to "It should not contain auxiliary context").
In @.cursor/skills/teapie/references/project-analysis.md:
- Around line 45-51: The example passed to tp.RegisterTestDirective references
an undefined variable negation in the human-readable message; update the snippet
so the message is copy-pastable by either defining a local variable (e.g., var
negation = parameters.GetBool("MyBool") ? "" : "not ";) before calling
tp.RegisterTestDirective or replace {negation} inline with the desired literal
("" or "not ") in the string returned by the lambda; ensure you edit the lambda
that builds the message for the "SUCCESSFUL-STATUS" directive so it no longer
references an undeclared symbol.
In @.cursor/skills/teapie/references/test-mapping-patterns.md:
- Line 17: Replace the typo in the sentence fragment "If the project doesn't
exist yet, choose based on project needs (see "Choosing an Approach" section) or
ask for user." by changing "ask for user" to "ask the user" so the line reads
"...or ask the user."; locate the sentence in the test-mapping-patterns.md
content (the line containing "Choosing an Approach") and update the text
accordingly.
In @.cursor/skills/teapie/scripts/find-tests-for-api.py:
- Around line 48-60: The JSON output in the to_dict method uses 'request_name'
whereas other tools (parse-http-file.py) use 'name'; update the to_dict method
on the same class to standardize the key to 'name' (or include both keys for
backward compatibility). Specifically, in the to_dict function, replace or add
the 'request_name' entry so the dict includes 'name': self.name (and optionally
also keep 'request_name': self.name) and ensure any consumers of
resolved_uri/file remain unchanged; verify callers that expect 'request_name'
are updated or still supported if you keep the alias.
- Around line 239-245: The final startswith check `if
normalized_path.startswith(normalized_target):` is redundant and causes false
positives (e.g., "/car" matching "/cars"); remove this check and rely on the
existing exact-equality and `normalized_path.startswith(normalized_target +
'/')` checks so only exact matches or proper subpaths (with a trailing slash)
are considered—locate the checks around `normalized_path` and
`normalized_target` and delete the loose `startswith(normalized_target)` branch.
- Around line 157-175: The docstring for normalize_endpoint claims it converts
slug IDs like "/cars/abc" to "/cars/{id}" but the implementation only handles
numeric and UUID segments; either update the docstring to remove/adjust the slug
example or extend the normalization regex to also replace slug-like path
segments (e.g., add a rule alongside the numeric and UUID replacements such as
matching r'/[A-Za-z0-9_-]{3,}' or similar to avoid short path words) so
normalize_endpoint's behavior and docs match; update the function's
docstring/examples if you choose the doc-only route or add the new re.sub call
(with flags=re.IGNORECASE if needed) referencing normalize_endpoint to perform
slug replacement.
In @.cursor/skills/teapie/scripts/insert-gap.py:
- Around line 148-150: The print statement in insert-gap.py uses an unnecessary
f-string when there are no placeholders; update the print in the gap_size check
(the block that checks "if gap_size < 1") to use a normal string literal (remove
the leading "f") so it prints "❌ Error: Gap size must be at least 1" without an
f-string.
In @.cursor/skills/teapie/scripts/renumber-tests.py:
- Line 270: The print statement uses an unnecessary f-string prefix; replace
print(f"✅ Successfully renumbered items") with a plain string call print("✅
Successfully renumbered items") to remove the extraneous f-string; locate the
statement by searching for the exact text "✅ Successfully renumbered items" in
renumber-tests.py and update the print invocation accordingly.
- Line 9: Update the module docstring in renumber-tests.py so the usage and
example match the implemented CLI flags: replace the usage clause that currently
shows "--insert <number> <name>" with "--insert <number> --insert-name <name>"
(or show both flags separately), and update the example invocation (around the
current example line) to use --insert and --insert-name as separate flags;
ensure any descriptive text in the docstring referencing the insert parameters
matches the names used by the implemented argument parser.
🧹 Nitpick comments (12)
.cursor/skills/README.md (3)
11-11: Consider clarifying "from this directory."The phrase "download it from this directory" might be ambiguous—users could interpret it as referring to a local directory. Consider rephrasing to "download it from the TeaPie repository" or "download it from the skills directory in the GitHub repository" for clarity.
18-30: Consider adding guidance on handling existing directories.The prompt template doesn't specify what should happen if the target directory already exists. Consider adding a note about whether to merge, overwrite, or skip existing files.
📝 Suggested addition
After line 29, consider adding:
Download the entire teapie directory (including SKILL.md and all subdirectories with their contents: references/, scripts/, templates/) from the GitHub repository and copy it to the correct target location in the project. + +If the directory already exists, merge the contents and overwrite any existing files with newer versions.
18-30: Consider adding versioning guidance.The documentation instructs users to download from the
masterbranch, which could lead to compatibility issues as the TeaPie framework evolves. Consider adding guidance about version compatibility or suggesting users download from specific release tags for production use.📝 Suggested addition
After line 22, consider adding:
The skill is located at: https://github.com/Kros-sk/TeaPie/tree/master/.cursor/skills/teapie/ + +Note: For production use, consider downloading from a specific release tag to ensure compatibility with your TeaPie version: +https://github.com/Kros-sk/TeaPie/tree/v{version}/.cursor/skills/teapie/.cursor/skills/skill-creator/SKILL.md (1)
51-62: Consider adding language identifier to fenced code blocks.The directory structure examples could use
textas the language identifier to satisfy markdown linters, though this is purely cosmetic.📝 Example fix for first occurrence
-``` +```text skill-name/ ├── SKILL.md (required).cursor/skills/skill-creator/scripts/init_skill.py (1)
273-288: Consider validating skill name format.The usage documentation specifies skill name requirements (hyphen-case, lowercase, max 40 chars) but
init_skill()doesn't validate these constraints. Invalid names could cause downstream issues.🛡️ Proposed validation
+import re + +def validate_skill_name(skill_name: str) -> bool: + """Validate skill name meets requirements.""" + if len(skill_name) > 40: + return False + return bool(re.match(r'^[a-z0-9]+(-[a-z0-9]+)*$', skill_name)) + def main(): if len(sys.argv) < 4 or sys.argv[2] != '--path': # ... existing usage message ... sys.exit(1) skill_name = sys.argv[1] path = sys.argv[3] + if not validate_skill_name(skill_name): + print(f"❌ Error: Invalid skill name '{skill_name}'") + print("Skill name must be hyphen-case with lowercase letters, digits, and hyphens only (max 40 chars)") + sys.exit(1) + print(f"🚀 Initializing skill: {skill_name}").cursor/skills/teapie/templates/with-auth.http (1)
1-5: Consider adding an Authorization header placeholder for template clarity.The authenticated request template relies on
AUTH-PROVIDER: OAuth2directive but doesn't demonstrate how the authorization header would appear. For educational purposes in a skills template, consider adding a placeholder header to show the expected structure:### Authenticated Request # `@name` AuthenticatedRequest ## AUTH-PROVIDER: OAuth2 ## TEST-EXPECT-STATUS: [200] GET {{ApiBaseUrl}}/{{ResourcePath}} +Authorization: Bearer {{AccessToken}}This would help users understand the complete request structure when OAuth2 is configured.
docs/docs/ai-agent-skills.md (1)
38-42: Consider clarifying "standard conventions" for other IDEs.The guidance for "other IDEs" is vague. Users might not know what "standard conventions" means for their specific IDE. Consider either listing a few more common IDEs or providing a fallback suggestion:
- For Cursor: .cursor/skills/teapie/ - For VS Code: .github/skills/teapie/ -- For other IDEs: use standard conventions for that IDE +- For other IDEs: use `.skills/teapie/` or a similar location appropriate for that IDEThis provides a concrete fallback path when IDE-specific conventions are unknown.
.cursor/skills/teapie/references/variables-functions.md (1)
9-18: Clarify variable precedence wording to avoid ambiguity.The list says “priority order” with Global first, but the next paragraph says lower levels override higher levels. Consider rewording to explicitly state precedence and resolution order so it’s unambiguous.
.cursor/skills/teapie/scripts/find-tests-for-api.py (2)
32-34: Avoid duplicated parsing helpers to reduce drift.This script reimplements the same parsing helpers as
parse-http-file.py, which makes future fixes inconsistent. Consider extracting shared helpers into a small module and importing from both scripts.
63-81: Catch JSON/IO errors explicitly instead ofException.Catching everything can hide programmer errors. Consider narrowing to
OSErrorandjson.JSONDecodeError(and let unexpected errors surface).Proposed change
- except Exception as e: + except (OSError, json.JSONDecodeError) as e: print(f"Warning: Could not load env file {env_file}: {e}", file=sys.stderr) return {}.cursor/skills/teapie/scripts/parse-http-file.py (2)
59-90: Catch JSON/IO errors explicitly instead ofException.A blanket catch hides programmer errors. Consider narrowing to
OSErrorandjson.JSONDecodeError, letting unexpected errors surface.Proposed change
- except Exception as e: + except (OSError, json.JSONDecodeError) as e: print(f"Warning: Could not load env file {env_file}: {e}", file=sys.stderr) return {}
141-141: Drop unusedline_numto satisfy lint.
line_numis unused, so it trips lint and adds noise.Proposed change
- for line_num, line in enumerate(lines, 1): + for _line_num, line in enumerate(lines, 1):
| Usage: | ||
| init_skill.py --path | ||
|
|
||
| Examples: | ||
| init_skill.py my-new-skill --path skills/public | ||
| init_skill.py my-api-helper --path skills/private | ||
| init_skill.py custom-skill --path /custom/location | ||
| """ |
There was a problem hiding this comment.
Docstring usage line is incomplete.
Line 6 shows init_skill.py --path but should show init_skill.py <skill_name> --path <path> to match the actual argument parsing and examples below.
📝 Proposed fix
Usage:
- init_skill.py --path
+ init_skill.py <skill_name> --path <path>🤖 Prompt for AI Agents
In @.cursor/skills/skill-creator/scripts/init_skill.py around lines 5 - 12,
Update the script's top-level docstring usage line in init_skill.py to show the
required positional skill name and the path option (e.g., change "init_skill.py
--path" to "init_skill.py <skill_name> --path <path>") so it matches the
argument parsing and the example lines below; ensure the usage line mirrors the
examples like "init_skill.py my-new-skill --path skills/public".
| Usage: | ||
| python utils/package_skill.py [output-directory] | ||
|
|
||
| Example: | ||
| python utils/package_skill.py skills/public/my-skill | ||
| python utils/package_skill.py skills/public/my-skill ./dist | ||
| """ |
There was a problem hiding this comment.
Update usage text to match the actual CLI signature and path.
The help text omits the required skill_path and references utils/, but the file lives under scripts/. Please align the usage and examples with the real invocation.
📝 Suggested wording
-Usage:
- python utils/package_skill.py [output-directory]
+Usage:
+ python scripts/package_skill.py <skill-path> [output-directory]
Example:
- python utils/package_skill.py skills/public/my-skill
- python utils/package_skill.py skills/public/my-skill ./dist
+ python scripts/package_skill.py skills/public/my-skill
+ python scripts/package_skill.py skills/public/my-skill ./distAlso applies to: 86-90
🤖 Prompt for AI Agents
In @.cursor/skills/skill-creator/scripts/package_skill.py around lines 5 - 11,
Update the top docstring/usage text in package_skill.py to reflect the actual
CLI signature that requires a skill_path argument and to reference the correct
directory (scripts/ instead of utils/); change the help/examples (both the
initial Usage/Example block and the later occurrences around the same docstring
at lines ~86-90) to show the real invocation: "python scripts/package_skill.py
<skill_path> [output-directory]" and concrete examples like "python
scripts/package_skill.py skills/public/my-skill" and "python
scripts/package_skill.py skills/public/my-skill ./dist" so the usage matches the
script's parameter names and location.
| skill_filename = output_path / f"{skill_name}.skill" | ||
|
|
||
| # Create the .skill file (zip format) | ||
| try: | ||
| with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: | ||
| # Walk through the skill directory | ||
| for file_path in skill_path.rglob('*'): | ||
| if file_path.is_file(): | ||
| # Calculate the relative path within the zip | ||
| arcname = file_path.relative_to(skill_path.parent) | ||
| zipf.write(file_path, arcname) | ||
| print(f" Added: {arcname}") |
There was a problem hiding this comment.
Avoid packaging the output .skill file when it’s inside the skill folder.
If output_dir is under skill_path, the newly created archive is included in itself. Skip the output file to prevent recursion/corruption.
💡 Proposed fix
skill_filename = output_path / f"{skill_name}.skill"
+output_file = skill_filename.resolve()
# Create the .skill file (zip format)
try:
with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
# Walk through the skill directory
for file_path in skill_path.rglob('*'):
if file_path.is_file():
+ if file_path.resolve() == output_file:
+ continue
# Calculate the relative path within the zip
arcname = file_path.relative_to(skill_path.parent)
zipf.write(file_path, arcname)🧰 Tools
🪛 Ruff (0.14.14)
[warning] 68-68: Expected an indented block after try statement
(invalid-syntax)
[warning] 70-70: Expected an indented block after with statement
(invalid-syntax)
[warning] 71-71: Expected an indented block after for statement
(invalid-syntax)
[warning] 73-73: Expected an indented block after if statement
(invalid-syntax)
🤖 Prompt for AI Agents
In @.cursor/skills/skill-creator/scripts/package_skill.py around lines 64 - 75,
The zip loop can accidentally include the generated archive when output_path is
inside skill_path; update the loop that iterates "for file_path in
skill_path.rglob('*')" to skip the output archive by comparing file_path to
skill_filename (use resolved paths or samefile) and continue when they match so
zipf.write is not called for the generated .skill file; reference
"skill_filename", "skill_path", "output_path", "file_path", and "zipf.write"
when making the change.
| if __name__ == "__main__": | ||
| if len(sys.argv) != 2: | ||
| print("Usage: python quick_validate.py ") | ||
| sys.exit(1) |
There was a problem hiding this comment.
Clarify required CLI argument in usage text.
The usage line is missing the skill path argument.
📝 Suggested wording
-if len(sys.argv) != 2:
- print("Usage: python quick_validate.py ")
+if len(sys.argv) != 2:
+ print("Usage: python quick_validate.py <skill-path>")🧰 Tools
🪛 Ruff (0.14.14)
[warning] 90-90: Expected an indented block after if statement
(invalid-syntax)
🤖 Prompt for AI Agents
In @.cursor/skills/skill-creator/scripts/quick_validate.py around lines 88 - 91,
The usage message in the __main__ block of quick_validate.py doesn't specify the
required skill path argument; update the check that inspects sys.argv (the if
len(sys.argv) != 2 block and the subsequent print call) so the printed usage
string explicitly shows the required argument (e.g., "Usage: python
quick_validate.py <skill_path>") before sys.exit(1), ensuring callers know to
pass the skill path.
| - CHANGELOG.md | ||
| - etc. | ||
|
|
||
| The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxilary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion. |
There was a problem hiding this comment.
Fix typo: "auxilary" → "auxiliary"
✏️ Proposed fix
-The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxilary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion.
+The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxiliary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxilary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion. | |
| The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxiliary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion. |
🧰 Tools
🪛 LanguageTool
[grammar] ~112-~112: Ensure spelling is correct
Context: ... the job at hand. It should not contain auxilary context about the process that went int...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In @.cursor/skills/skill-creator/SKILL.md at line 112, Replace the misspelled
word "auxilary" with the correct spelling "auxiliary" in the SKILL.md content
(look for the phrase "It should not contain auxilary context" and update it to
"It should not contain auxiliary context").
| def normalize_endpoint(uri: str) -> str: | ||
| """ | ||
| Normalize endpoint by replacing ID values with {id} pattern. | ||
|
|
||
| Examples: | ||
| "/cars/123" -> "/cars/{id}" | ||
| "/cars/abc" -> "/cars/{id}" | ||
| "/customers/456/details" -> "/customers/{id}/details" | ||
| """ | ||
| # Remove base URL if present (http://, https://) | ||
| normalized = re.sub(r'^https?://[^/]+', '', uri) | ||
|
|
||
| # Remove query parameters | ||
| normalized = normalized.split('?')[0] | ||
|
|
||
| # Replace numeric or alphanumeric segments that look like IDs with {id} | ||
| # Pattern: segments that are likely IDs (numbers, UUIDs, etc.) | ||
| normalized = re.sub(r'/\d+', '/{id}', normalized) | ||
| normalized = re.sub(r'/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}', '/{id}', normalized, flags=re.IGNORECASE) |
There was a problem hiding this comment.
Align normalization docs with current behavior (slug IDs).
The docstring claims /cars/abc becomes /cars/{id}, but the regex only normalizes numeric/UUID segments. Either update the docs or extend the regex to actually cover slug IDs to avoid mismatched expectations.
Doc-only alignment (minimal change)
- "/cars/abc" -> "/cars/{id}"
+ # (example removed: slug IDs are not normalized by current regex)
@@
- # Replace numeric or alphanumeric segments that look like IDs with {id}
- # Pattern: segments that are likely IDs (numbers, UUIDs, etc.)
+ # Replace numeric segments and UUIDs that look like IDs with {id}
+ # Pattern: numbers and UUIDs are treated as IDs📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def normalize_endpoint(uri: str) -> str: | |
| """ | |
| Normalize endpoint by replacing ID values with {id} pattern. | |
| Examples: | |
| "/cars/123" -> "/cars/{id}" | |
| "/cars/abc" -> "/cars/{id}" | |
| "/customers/456/details" -> "/customers/{id}/details" | |
| """ | |
| # Remove base URL if present (http://, https://) | |
| normalized = re.sub(r'^https?://[^/]+', '', uri) | |
| # Remove query parameters | |
| normalized = normalized.split('?')[0] | |
| # Replace numeric or alphanumeric segments that look like IDs with {id} | |
| # Pattern: segments that are likely IDs (numbers, UUIDs, etc.) | |
| normalized = re.sub(r'/\d+', '/{id}', normalized) | |
| normalized = re.sub(r'/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}', '/{id}', normalized, flags=re.IGNORECASE) | |
| def normalize_endpoint(uri: str) -> str: | |
| """ | |
| Normalize endpoint by replacing ID values with {id} pattern. | |
| Examples: | |
| "/cars/123" -> "/cars/{id}" | |
| "/customers/456/details" -> "/customers/{id}/details" | |
| """ | |
| # Remove base URL if present (http://, https://) | |
| normalized = re.sub(r'^https?://[^/]+', '', uri) | |
| # Remove query parameters | |
| normalized = normalized.split('?')[0] | |
| # Replace numeric segments and UUIDs that look like IDs with {id} | |
| # Pattern: numbers and UUIDs are treated as IDs | |
| normalized = re.sub(r'/\d+', '/{id}', normalized) | |
| normalized = re.sub(r'/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}', '/{id}', normalized, flags=re.IGNORECASE) |
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/find-tests-for-api.py around lines 157 - 175,
The docstring for normalize_endpoint claims it converts slug IDs like
"/cars/abc" to "/cars/{id}" but the implementation only handles numeric and UUID
segments; either update the docstring to remove/adjust the slug example or
extend the normalization regex to also replace slug-like path segments (e.g.,
add a rule alongside the numeric and UUID replacements such as matching
r'/[A-Za-z0-9_-]{3,}' or similar to avoid short path words) so
normalize_endpoint's behavior and docs match; update the function's
docstring/examples if you choose the doc-only route or add the new re.sub call
(with flags=re.IGNORECASE if needed) referencing normalize_endpoint to perform
slug replacement.
| if normalized_path.startswith(normalized_target + '/'): | ||
| return True | ||
|
|
||
| # Also check if target is a prefix (e.g., "/cars" matches "/cars/bulk") | ||
| if normalized_path.startswith(normalized_target): | ||
| return True | ||
|
|
There was a problem hiding this comment.
Remove redundant prefix match to avoid false positives.
The final startswith check makes /car match /cars. Equality and the normalized_target + '/' check already cover intended cases, so this adds noise.
Proposed change
- # Also check if target is a prefix (e.g., "/cars" matches "/cars/bulk")
- if normalized_path.startswith(normalized_target):
- return True
-
return False📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if normalized_path.startswith(normalized_target + '/'): | |
| return True | |
| # Also check if target is a prefix (e.g., "/cars" matches "/cars/bulk") | |
| if normalized_path.startswith(normalized_target): | |
| return True | |
| if normalized_path.startswith(normalized_target + '/'): | |
| return True | |
| return False |
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/find-tests-for-api.py around lines 239 - 245,
The final startswith check `if normalized_path.startswith(normalized_target):`
is redundant and causes false positives (e.g., "/car" matching "/cars"); remove
this check and rely on the existing exact-equality and
`normalized_path.startswith(normalized_target + '/')` checks so only exact
matches or proper subpaths (with a trailing slash) are considered—locate the
checks around `normalized_path` and `normalized_target` and delete the loose
`startswith(normalized_target)` branch.
| if gap_size < 1: | ||
| print(f"❌ Error: Gap size must be at least 1") | ||
| sys.exit(1) |
There was a problem hiding this comment.
Remove unnecessary f-string prefix.
Line 149 uses an f-string without any placeholders.
📝 Proposed fix
if gap_size < 1:
- print(f"❌ Error: Gap size must be at least 1")
+ print("❌ Error: Gap size must be at least 1")
sys.exit(1)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if gap_size < 1: | |
| print(f"❌ Error: Gap size must be at least 1") | |
| sys.exit(1) | |
| if gap_size < 1: | |
| print("❌ Error: Gap size must be at least 1") | |
| sys.exit(1) |
🧰 Tools
🪛 Ruff (0.14.14)
[error] 149-149: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/insert-gap.py around lines 148 - 150, The
print statement in insert-gap.py uses an unnecessary f-string when there are no
placeholders; update the print in the gap_size check (the block that checks "if
gap_size < 1") to use a normal string literal (remove the leading "f") so it
prints "❌ Error: Gap size must be at least 1" without an f-string.
| and numbered directories as a group to preserve test case integrity. | ||
|
|
||
| Usage: | ||
| python renumber-tests.py --directory <path> [--start <number>] [--insert <number> <name>] |
There was a problem hiding this comment.
Docstring usage doesn't match actual CLI arguments.
The docstring shows --insert <number> <name> suggesting both values follow --insert, but the actual implementation uses --insert <number> and --insert-name <name> as separate flags.
📝 Proposed fix to align docstring with implementation
- python renumber-tests.py --directory <path> [--start <number>] [--insert <number> <name>]
+ python renumber-tests.py --directory <path> [--start <number>] [--insert <number> --insert-name <name>]And update the example at line 19:
- python renumber-tests.py --directory ./Tests/002-Cars --insert 003 MyNewTest
+ python renumber-tests.py --directory ./Tests/002-Cars --insert 003 --insert-name MyNewTest🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/renumber-tests.py at line 9, Update the module
docstring in renumber-tests.py so the usage and example match the implemented
CLI flags: replace the usage clause that currently shows "--insert <number>
<name>" with "--insert <number> --insert-name <name>" (or show both flags
separately), and update the example invocation (around the current example line)
to use --insert and --insert-name as separate flags; ensure any descriptive text
in the docstring referencing the insert parameters matches the names used by the
implemented argument parser.
| sys.exit(1) | ||
|
|
||
| if file_rename_plan or dir_rename_plan: | ||
| print(f"✅ Successfully renumbered items") |
There was a problem hiding this comment.
Remove extraneous f-string prefix.
The f-string has no placeholders. Use a regular string instead.
🔧 Proposed fix
- print(f"✅ Successfully renumbered items")
+ print("✅ Successfully renumbered items")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| print(f"✅ Successfully renumbered items") | |
| print("✅ Successfully renumbered items") |
🧰 Tools
🪛 Ruff (0.14.14)
[error] 270-270: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/renumber-tests.py at line 270, The print
statement uses an unnecessary f-string prefix; replace print(f"✅ Successfully
renumbered items") with a plain string call print("✅ Successfully renumbered
items") to remove the extraneous f-string; locate the statement by searching for
the exact text "✅ Successfully renumbered items" in renumber-tests.py and update
the print invocation accordingly.
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Fix all issues with AI agents
In @.cursor/skills/README.md:
- Around line 20-29: The README currently hard-codes a branched URL to the
teapie folder; change it to be branch‑agnostic by instructing the agent to
either clone the repository (git clone https://github.com/Kros-sk/TeaPie.git)
and copy the .cursor/skills/teapie/ directory (including SKILL.md and
subdirectories references/, scripts/, templates/) into the correct target
location (.cursor/skills/teapie/ for Cursor, .github/skills/teapie/ for VS Code,
or the IDE-specific path for others), or call the GitHub API to fetch the
repository's default_branch before constructing a /tree/{default_branch}/.
Ensure README text and the sample link mention cloning or resolving the default
branch rather than embedding a fixed branch name.
In @.cursor/skills/teapie/references/project-analysis.md:
- Around line 46-52: The example for tp.RegisterTestDirective uses an undefined
variable negation in the interpolation; fix by deriving negation from the
incoming parameters (e.g., inspect the boolean parameter from
TestDirectivePatternBuilder via the parameters dictionary) or simplify the
lambda to a static string; update the description lambda passed to
tp.RegisterTestDirective (the third argument) so it computes var negation =
parameters["MyBool"] == false ? "not " : ""; and then returns $"Response status
code should {negation}be successful." to ensure negation is defined and tied to
the AddBooleanParameter("MyBool") value.
In @.cursor/skills/teapie/references/test-design.md:
- Around line 256-261: The example uses the wrong argument order for
JsonContains; update the "Basic usage" and the test example that calls
JsonContains(expectedJson, actualJson) so it follows the function signature and
other examples: JsonContains(container, contained, ...). Specifically swap the
two JsonElement arguments so the response/actual JSON is passed first
(container) and the expected/request JSON is passed second (contained) to the
JsonContains call referenced in the test and any surrounding examples.
In @.cursor/skills/teapie/references/test-mapping-patterns.md:
- Around line 146-150: Fix the Markdown table pipes to satisfy MD060 by ensuring
a single space exists on both sides of each pipe and consistent column alignment
for all rows; update the header row and each data row (the line starting with "|
**Direct URL**" and the following two data rows and the separator row
"|----------|-------------|") so that pipes are spaced like "| Approach | When
to Use |" and matching spacing is applied to every line in the table to produce
a consistent, lint-compliant table.
In @.cursor/skills/teapie/references/variables-functions.md:
- Around line 165-171: The Markdown table rows for the variables ($guid, $now,
$rand, $randomInt) violate MD060 due to inconsistent pipe spacing; update every
table row (header and body) so each cell has a single space before and after the
pipe delimiter (e.g., "| Name | Signature | Description | Example |") and ensure
the separator row ("|---|---|---|---|") uses the same consistent spacing style
to satisfy markdownlint.
In @.cursor/skills/teapie/scripts/find-tests-for-api.py:
- Around line 239-246: The extra broad match using
normalized_path.startswith(normalized_target) causes false positives; replace it
with an exact equality check so only exact endpoint matches or proper sub-paths
match. Concretely, in the match routine that uses normalized_path and
normalized_target, keep the existing
normalized_path.startswith(normalized_target + '/') check for sub-paths and
change the subsequent startswith(normalized_target) branch to a strict equality
check (normalized_path == normalized_target) so `/cars` will match `/cars` and
`/cars/...` but not `/carsales`.
In @.cursor/skills/teapie/scripts/insert-gap.py:
- Around line 148-150: The print statement inside the gap size check uses an
unnecessary f-string prefix; update the conditional block that checks gap_size
(the "if gap_size < 1:" branch) to call print without the leading "f" (i.e.,
change print(f"❌ Error: Gap size must be at least 1") to a normal string) and
keep the sys.exit(1) behavior unchanged.
In @.cursor/skills/teapie/scripts/parse-http-file.py:
- Line 141: The loop in parse-http-file.py declares an unused variable line_num
in "for line_num, line in enumerate(lines, 1):"; change the loop to either use a
throwaway name or drop enumeration — e.g., replace with "for _, line in
enumerate(lines, 1):" or simply "for line in lines:" — so the unused variable is
removed; update any surrounding logic that assumed line_num accordingly (no
other changes required if the line number isn't used).
In @.cursor/skills/teapie/scripts/renumber-tests.py:
- Around line 269-270: The print statement inside the conditional checking
file_rename_plan or dir_rename_plan uses an unnecessary f-string; update the
print call in the block that contains the conditional (the code referencing
file_rename_plan and dir_rename_plan) to remove the leading "f" so it becomes a
normal string literal (e.g., change print(f"✅ Successfully renumbered items") to
a plain string print statement).
In `@docs/docs/getting-started.md`:
- Around line 26-32: The docs hard-code a branch in the TeaPie download URL
which will break if the default branch changes—update the URL referenced in the
diff (the GitHub link) to be branch‑agnostic or replace it with a note saying
“use the repository’s default branch” and keep the rest of the instruction
intact; ensure the skill path references (.cursor/skills/teapie/ and
.github/skills/teapie/) and the instruction to download the entire teapie
directory (SKILL.md, references/, scripts/, templates/) remain unchanged so
users still know where to place the files.
🧹 Nitpick comments (5)
.cursor/skills/teapie/references/openapi-to-tests.md (1)
5-8: Optional readability tweak (avoid split infinitive).✍️ Suggested edit
-TeaPie doesn't have built-in OpenAPI integration. This guide shows how to manually create test cases from OpenAPI specs. +TeaPie doesn't have built-in OpenAPI integration. This guide shows how to create test cases manually from OpenAPI specs..cursor/skills/teapie/scripts/insert-gap.py (2)
26-128: Consider extracting shared utilities to a common module.The functions
extract_test_case_info,extract_directory_info,find_numbered_directories,find_test_cases, andformat_numberare duplicated verbatim inrenumber-tests.py. Consider extracting these into a shared module (e.g.,teapie_utils.py) to reduce duplication and ease maintenance.
207-212: Catching broadExceptionis acceptable here but could be more specific.While catching
Exceptionduring file/directory rename operations is pragmatic (various OS-specific errors can occur), you could consider catchingOSErrorfor more precise error handling. This is a minor improvement and can be deferred.Also applies to: 224-229
.cursor/skills/teapie/scripts/parse-http-file.py (1)
34-56: Consider extractingHttpRequestclass to a shared module.The
HttpRequestclass is duplicated infind-tests-for-api.pywith slight variations (e.g.,file_pathattribute,to_dictoutput keys). Extracting this to a shared module would reduce duplication and ensure consistent behavior..cursor/skills/teapie/scripts/find-tests-for-api.py (1)
32-34: Address code duplication rather than documenting it.The comment acknowledges duplication but doesn't resolve it. Consider importing from
parse-http-file.pyor extracting shared code to a common module. This would eliminate ~120 lines of duplicated code.
| Download the TeaPie skill from the GitHub repository into this project. | ||
|
|
||
| The skill is located at: https://github.com/Kros-sk/TeaPie/tree/master/.cursor/skills/teapie/ | ||
|
|
||
| The agent should determine the target location based on the IDE it's working in: | ||
| - For Cursor: .cursor/skills/teapie/ | ||
| - For VS Code: .github/skills/teapie/ | ||
| - For other IDEs: use standard conventions for that IDE | ||
|
|
||
| Download the entire teapie directory (including SKILL.md and all subdirectories with their contents: references/, scripts/, templates/) from the GitHub repository and copy it to the correct target location in the project. |
There was a problem hiding this comment.
Avoid hard‑coding the branch in the download URL.
If the default branch changes, the link will go stale. Consider a branch-agnostic reference or wording.
🔧 Suggested doc tweak
-The skill is located at: https://github.com/Kros-sk/TeaPie/tree/master/.cursor/skills/teapie/
+The skill is located at: https://github.com/Kros-sk/TeaPie/tree/<default-branch>/.cursor/skills/teapie/🤖 Prompt for AI Agents
In @.cursor/skills/README.md around lines 20 - 29, The README currently
hard-codes a branched URL to the teapie folder; change it to be branch‑agnostic
by instructing the agent to either clone the repository (git clone
https://github.com/Kros-sk/TeaPie.git) and copy the .cursor/skills/teapie/
directory (including SKILL.md and subdirectories references/, scripts/,
templates/) into the correct target location (.cursor/skills/teapie/ for Cursor,
.github/skills/teapie/ for VS Code, or the IDE-specific path for others), or
call the GitHub API to fetch the repository's default_branch before constructing
a /tree/{default_branch}/. Ensure README text and the sample link mention
cloning or resolving the default branch rather than embedding a fixed branch
name.
| tp.RegisterTestDirective( | ||
| "SUCCESSFUL-STATUS", | ||
| TestDirectivePatternBuilder.Create("SUCCESSFUL-STATUS").AddBooleanParameter("MyBool").Build(), | ||
| (parameters) => $"Response status code should {negation}be successful.", | ||
| async (response, parameters) => { /* test logic */ } | ||
| ); | ||
| ``` |
There was a problem hiding this comment.
Example references undefined variable {negation}.
The string interpolation uses {negation} but this variable is not defined or explained in the example. Consider either defining it or simplifying the example.
📝 Suggested fix
tp.RegisterTestDirective(
"SUCCESSFUL-STATUS",
TestDirectivePatternBuilder.Create("SUCCESSFUL-STATUS").AddBooleanParameter("MyBool").Build(),
- (parameters) => $"Response status code should {negation}be successful.",
+ (parameters) => $"Response status code should be successful.",
async (response, parameters) => { /* test logic */ }
);Alternatively, if negation is intentional, add context showing how it's derived from parameters:
tp.RegisterTestDirective(
"SUCCESSFUL-STATUS",
TestDirectivePatternBuilder.Create("SUCCESSFUL-STATUS").AddBooleanParameter("MyBool").Build(),
(parameters) => {
var negation = parameters["MyBool"] == false ? "not " : "";
return $"Response status code should {negation}be successful.";
},
async (response, parameters) => { /* test logic */ }
);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| tp.RegisterTestDirective( | |
| "SUCCESSFUL-STATUS", | |
| TestDirectivePatternBuilder.Create("SUCCESSFUL-STATUS").AddBooleanParameter("MyBool").Build(), | |
| (parameters) => $"Response status code should {negation}be successful.", | |
| async (response, parameters) => { /* test logic */ } | |
| ); | |
| ``` | |
| tp.RegisterTestDirective( | |
| "SUCCESSFUL-STATUS", | |
| TestDirectivePatternBuilder.Create("SUCCESSFUL-STATUS").AddBooleanParameter("MyBool").Build(), | |
| (parameters) => $"Response status code should be successful.", | |
| async (response, parameters) => { /* test logic */ } | |
| ); |
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/references/project-analysis.md around lines 46 - 52,
The example for tp.RegisterTestDirective uses an undefined variable negation in
the interpolation; fix by deriving negation from the incoming parameters (e.g.,
inspect the boolean parameter from TestDirectivePatternBuilder via the
parameters dictionary) or simplify the lambda to a static string; update the
description lambda passed to tp.RegisterTestDirective (the third argument) so it
computes var negation = parameters["MyBool"] == false ? "not " : ""; and then
returns $"Response status code should {negation}be successful." to ensure
negation is defined and tied to the AddBooleanParameter("MyBool") value.
| }); | ||
| ``` | ||
|
|
||
| 2. **Use JsonElement for precise comparison:** | ||
| ```csharp | ||
| await tp.Test("Retrieved product should match created product.", async () => |
There was a problem hiding this comment.
Inconsistent argument order in JsonContains example.
The "Basic usage" example shows JsonContains(expectedJson, actualJson), but all other examples in this document (lines 54, 62, 88, 229, 232) and the function signature on line 223 show the pattern JsonContains(container, contained, ...) where the response (container) comes first and the request (contained) comes second.
📝 Suggested fix
// Basic usage
-JsonContains(expectedJson, actualJson);
+JsonContains(actualJson, expectedJson);
// Exclude server-generated properties from comparison
JsonContains(responseBody, requestBody, "id", "createdAt");🤖 Prompt for AI Agents
In @.cursor/skills/teapie/references/test-design.md around lines 256 - 261, The
example uses the wrong argument order for JsonContains; update the "Basic usage"
and the test example that calls JsonContains(expectedJson, actualJson) so it
follows the function signature and other examples: JsonContains(container,
contained, ...). Specifically swap the two JsonElement arguments so the
response/actual JSON is passed first (container) and the expected/request JSON
is passed second (contained) to the JsonContains call referenced in the test and
any surrounding examples.
| | Approach | When to Use | | ||
| |----------|-------------| | ||
| | **Direct URL** | Simple projects, single environment, clear/readable tests, quick prototyping | | ||
| | **Variable-based** | Multi-environment setups, paths differ between environments, centralized path management | | ||
| | **Hybrid** | Base URL in env (`ApiBaseUrl`), paths directly in HTTP files - best of both worlds | |
There was a problem hiding this comment.
Fix table pipe spacing to satisfy markdownlint (MD060).
🔧 Suggested fix
-| Approach | When to Use |
-|----------|-------------|
+| Approach | When to Use |
+| -------- | ----------- |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | Approach | When to Use | | |
| |----------|-------------| | |
| | **Direct URL** | Simple projects, single environment, clear/readable tests, quick prototyping | | |
| | **Variable-based** | Multi-environment setups, paths differ between environments, centralized path management | | |
| | **Hybrid** | Base URL in env (`ApiBaseUrl`), paths directly in HTTP files - best of both worlds | | |
| | Approach | When to Use | | |
| | -------- | ----------- | | |
| | **Direct URL** | Simple projects, single environment, clear/readable tests, quick prototyping | | |
| | **Variable-based** | Multi-environment setups, paths differ between environments, centralized path management | | |
| | **Hybrid** | Base URL in env (`ApiBaseUrl`), paths directly in HTTP files - best of both worlds | |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 147-147: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 147-147: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 147-147: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 147-147: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/references/test-mapping-patterns.md around lines 146 -
150, Fix the Markdown table pipes to satisfy MD060 by ensuring a single space
exists on both sides of each pipe and consistent column alignment for all rows;
update the header row and each data row (the line starting with "| **Direct
URL**" and the following two data rows and the separator row
"|----------|-------------|") so that pipes are spaced like "| Approach | When
to Use |" and matching spacing is applied to every line in the table to produce
a consistent, lint-compliant table.
| | Name | Signature | Description | Example | | ||
| |------|-----------|-------------|---------| | ||
| | `$guid` | `Guid $guid()` | Generates a new GUID | `{{$guid}}` | | ||
| | `$now` | `string $now(string? format)` | Current local time formatted via `DateTime.ToString(format)`. Default formatting if format omitted. | `{{$now "yyyy-MM-dd"}}` | | ||
| | `$rand` | `double $rand()` | Random double in range [0, 1) | `{{$rand}}` | | ||
| | `$randomInt` | `int $randomInt(int min, int max)` | Random integer in range [min, max) | `{{$randomInt 1 100}}` | | ||
|
|
There was a problem hiding this comment.
Fix table pipe spacing to satisfy markdownlint (MD060).
🔧 Suggested fix
-| Name | Signature | Description | Example |
-|------|-----------|-------------|---------|
+| Name | Signature | Description | Example |
+| ---- | --------- | ----------- | ------- |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | Name | Signature | Description | Example | | |
| |------|-----------|-------------|---------| | |
| | `$guid` | `Guid $guid()` | Generates a new GUID | `{{$guid}}` | | |
| | `$now` | `string $now(string? format)` | Current local time formatted via `DateTime.ToString(format)`. Default formatting if format omitted. | `{{$now "yyyy-MM-dd"}}` | | |
| | `$rand` | `double $rand()` | Random double in range [0, 1) | `{{$rand}}` | | |
| | `$randomInt` | `int $randomInt(int min, int max)` | Random integer in range [min, max) | `{{$randomInt 1 100}}` | | |
| | Name | Signature | Description | Example | | |
| | ---- | --------- | ----------- | ------- | | |
| | `$guid` | `Guid $guid()` | Generates a new GUID | `{{$guid}}` | | |
| | `$now` | `string $now(string? format)` | Current local time formatted via `DateTime.ToString(format)`. Default formatting if format omitted. | `{{$now "yyyy-MM-dd"}}` | | |
| | `$rand` | `double $rand()` | Random double in range [0, 1) | `{{$rand}}` | | |
| | `$randomInt` | `int $randomInt(int min, int max)` | Random integer in range [min, max) | `{{$randomInt 1 100}}` | |
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 166-166: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 166-166: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/references/variables-functions.md around lines 165 -
171, The Markdown table rows for the variables ($guid, $now, $rand, $randomInt)
violate MD060 due to inconsistent pipe spacing; update every table row (header
and body) so each cell has a single space before and after the pipe delimiter
(e.g., "| Name | Signature | Description | Example |") and ensure the separator
row ("|---|---|---|---|") uses the same consistent spacing style to satisfy
markdownlint.
| if normalized_path.startswith(normalized_target + '/'): | ||
| return True | ||
|
|
||
| # Also check if target is a prefix (e.g., "/cars" matches "/cars/bulk") | ||
| if normalized_path.startswith(normalized_target): | ||
| return True | ||
|
|
||
| return False |
There was a problem hiding this comment.
Overly broad endpoint matching may produce false positives.
The startswith check on line 243 can match unintended endpoints. For example, searching for /cars would incorrectly match /carsales or /carservices.
🔧 Suggested fix
# Partial match: target "/cars" matches "/cars/{id}"
if normalized_target.endswith('/'):
normalized_target = normalized_target[:-1]
if normalized_path.startswith(normalized_target + '/'):
return True
- # Also check if target is a prefix (e.g., "/cars" matches "/cars/bulk")
- if normalized_path.startswith(normalized_target):
- return True
-
return FalseThe existing check startswith(normalized_target + '/') already handles sub-paths like /cars/bulk. The additional startswith(normalized_target) without the trailing slash is redundant for valid sub-paths and introduces false positives for paths that merely share a prefix.
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/find-tests-for-api.py around lines 239 - 246,
The extra broad match using normalized_path.startswith(normalized_target) causes
false positives; replace it with an exact equality check so only exact endpoint
matches or proper sub-paths match. Concretely, in the match routine that uses
normalized_path and normalized_target, keep the existing
normalized_path.startswith(normalized_target + '/') check for sub-paths and
change the subsequent startswith(normalized_target) branch to a strict equality
check (normalized_path == normalized_target) so `/cars` will match `/cars` and
`/cars/...` but not `/carsales`.
| if gap_size < 1: | ||
| print(f"❌ Error: Gap size must be at least 1") | ||
| sys.exit(1) |
There was a problem hiding this comment.
Remove unnecessary f-string prefix.
This f-string has no placeholders, so the f prefix is unnecessary.
🔧 Suggested fix
if gap_size < 1:
- print(f"❌ Error: Gap size must be at least 1")
+ print("❌ Error: Gap size must be at least 1")
sys.exit(1)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if gap_size < 1: | |
| print(f"❌ Error: Gap size must be at least 1") | |
| sys.exit(1) | |
| if gap_size < 1: | |
| print("❌ Error: Gap size must be at least 1") | |
| sys.exit(1) |
🧰 Tools
🪛 Ruff (0.14.14)
[error] 149-149: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/insert-gap.py around lines 148 - 150, The
print statement inside the gap size check uses an unnecessary f-string prefix;
update the conditional block that checks gap_size (the "if gap_size < 1:"
branch) to call print without the leading "f" (i.e., change print(f"❌ Error: Gap
size must be at least 1") to a normal string) and keep the sys.exit(1) behavior
unchanged.
| with open(http_file, 'r', encoding='utf-8') as f: | ||
| lines = f.readlines() | ||
|
|
||
| for line_num, line in enumerate(lines, 1): |
There was a problem hiding this comment.
Unused loop variable line_num.
The line_num variable is declared but never used in the loop body. Rename it to _ to indicate it's intentionally unused.
🔧 Suggested fix
- for line_num, line in enumerate(lines, 1):
+ for _, line in enumerate(lines, 1):Or simply iterate directly since the line number isn't needed:
- for line_num, line in enumerate(lines, 1):
+ for line in lines:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for line_num, line in enumerate(lines, 1): | |
| for _, line in enumerate(lines, 1): |
🧰 Tools
🪛 Ruff (0.14.14)
[warning] 141-141: Loop control variable line_num not used within loop body
Rename unused line_num to _line_num
(B007)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/parse-http-file.py at line 141, The loop in
parse-http-file.py declares an unused variable line_num in "for line_num, line
in enumerate(lines, 1):"; change the loop to either use a throwaway name or drop
enumeration — e.g., replace with "for _, line in enumerate(lines, 1):" or simply
"for line in lines:" — so the unused variable is removed; update any surrounding
logic that assumed line_num accordingly (no other changes required if the line
number isn't used).
| if file_rename_plan or dir_rename_plan: | ||
| print(f"✅ Successfully renumbered items") |
There was a problem hiding this comment.
Remove unnecessary f-string prefix.
This f-string has no placeholders, so the f prefix is unnecessary.
🔧 Suggested fix
if file_rename_plan or dir_rename_plan:
- print(f"✅ Successfully renumbered items")
+ print("✅ Successfully renumbered items")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if file_rename_plan or dir_rename_plan: | |
| print(f"✅ Successfully renumbered items") | |
| if file_rename_plan or dir_rename_plan: | |
| print("✅ Successfully renumbered items") |
🧰 Tools
🪛 Ruff (0.14.14)
[error] 270-270: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/scripts/renumber-tests.py around lines 269 - 270, The
print statement inside the conditional checking file_rename_plan or
dir_rename_plan uses an unnecessary f-string; update the print call in the block
that contains the conditional (the code referencing file_rename_plan and
dir_rename_plan) to remove the leading "f" so it becomes a normal string literal
(e.g., change print(f"✅ Successfully renumbered items") to a plain string print
statement).
| 1. Download the TeaPie skill from the GitHub repository into this project. | ||
| - Skill location: https://github.com/Kros-sk/TeaPie/tree/master/.cursor/skills/teapie/ | ||
| - Determine the target location based on the IDE: | ||
| * For Cursor: .cursor/skills/teapie/ | ||
| * For VS Code: .github/skills/teapie/ | ||
| * For other IDEs: use standard conventions for that IDE | ||
| - Download the entire teapie directory (including SKILL.md and all subdirectories with their contents: references/, scripts/, templates/) and copy it to the correct target location. |
There was a problem hiding this comment.
Avoid hard‑coding the branch in the download URL.
If the default branch changes, this link breaks. Prefer a branch-agnostic URL (or mention “default branch”) to keep the prompt durable.
🔧 Suggested doc tweak
- - Skill location: https://github.com/Kros-sk/TeaPie/tree/master/.cursor/skills/teapie/
+ - Skill location: https://github.com/Kros-sk/TeaPie/tree/<default-branch>/.cursor/skills/teapie/🤖 Prompt for AI Agents
In `@docs/docs/getting-started.md` around lines 26 - 32, The docs hard-code a
branch in the TeaPie download URL which will break if the default branch
changes—update the URL referenced in the diff (the GitHub link) to be
branch‑agnostic or replace it with a note saying “use the repository’s default
branch” and keep the rest of the instruction intact; ensure the skill path
references (.cursor/skills/teapie/ and .github/skills/teapie/) and the
instruction to download the entire teapie directory (SKILL.md, references/,
scripts/, templates/) remain unchanged so users still know where to place the
files.
|
|
||
| ```http | ||
| ### Get Car | ||
| GET {{ApiBaseUrl}}{{ApiCarsSection}}/{{AddCarRequest.response.body.$.Id}} |
There was a problem hiding this comment.
Should this be here? It is something from .http file and this file describes characteristics of .csx file.
|
|
||
| ```csharp | ||
| #load "./Definitions/GenerateNewCar.csx" | ||
| #load "$teapie/Definitions/Helper.csx" |
There was a problem hiding this comment.
Add explanation for $teapie wildcard (it points to .teapie folder).
|
|
||
| - **Environments:** `$shared`, `local`, `production` | ||
| - **Variables per environment:** List all variables defined | ||
| - **Variable values:** Show values (mask secrets if tagged) |
There was a problem hiding this comment.
Do we have support for masking secrets by tagging them?
|
|
||
| Variables are resolved in this order: | ||
| 1. Global (`$shared` environment) | ||
| 2. Environment (collection-specific) |
There was a problem hiding this comment.
Shouldn't it be environment-specific instead of collection-specific?
| # @name RetryRequest | ||
| ## RETRY-STRATEGY: Default retry | ||
| ## RETRY-UNTIL-STATUS: [200, 201] | ||
| ## TEST-EXPECT-STATUS: [200, 201] |
There was a problem hiding this comment.
Is it necessary to have both retry-until-status and test-expect-status?
| @@ -0,0 +1,398 @@ | |||
| --- | |||
| Multi-level variable system (priority order): | ||
|
|
||
| 1. Global (`$shared` environment) | ||
| 2. Environment (collection-specific) |
There was a problem hiding this comment.
Shouldn't it be environment-specific instead of collection-specific?
…clarify path wildcards, and refine variable value descriptions in project analysis. Adjust test mapping patterns for better clarity on environment specificity. Remove unnecessary comment in HTTP template.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.cursor/skills/teapie/references/csx-scripting.md:
- Around line 255-261: The examples for JsonContains are using inconsistent
parameter semantics (first example uses expectedJson, actualJson while the
second calls JsonContains(responseBody, requestBody) where the response is the
superset and the request is the subset), so update the example to make the
argument roles explicit: rename the parameters in the first example to something
like supersetJson, subsetJson or add a short inline note that the first
parameter is the JSON that should contain the second, ensuring the
JsonContains(...) examples consistently reflect that the first argument is the
container/superset and the second is the subset to check.
🧹 Nitpick comments (1)
.cursor/skills/teapie/references/csx-scripting.md (1)
220-226: Fragile string-based ID lookup in array example.The pattern
responseBody.Contains($"\"id\":{itemId}")is brittle — it won't match if the server serializes with different whitespace, or if a property like"itemId"partially matches. Since this is a "simple validations" example intended as guidance for an AI agent, consider adding a brief caveat noting the limitation, or switching to theJsonElementdeserialization approach shown below for ID lookups.
| ```csharp | ||
| // Basic usage | ||
| JsonContains(expectedJson, actualJson); | ||
|
|
||
| // Exclude server-generated properties from comparison | ||
| JsonContains(responseBody, requestBody, "id", "createdAt"); | ||
| ``` |
There was a problem hiding this comment.
Potentially misleading parameter names in JsonContains example.
On line 257, the parameters are named expectedJson, actualJson, but on line 260 the call is JsonContains(responseBody, requestBody, ...) — where the response (actual) is first and the request (expected subset) is second. This appears to swap the semantic meaning between the two examples, which could confuse an AI agent (or human) about the correct argument order.
Consider aligning the variable names on line 257 to match the actual semantics (e.g., JsonContains(supersetJson, subsetJson)), or add a brief inline note clarifying which parameter is the "contains" side.
🤖 Prompt for AI Agents
In @.cursor/skills/teapie/references/csx-scripting.md around lines 255 - 261,
The examples for JsonContains are using inconsistent parameter semantics (first
example uses expectedJson, actualJson while the second calls
JsonContains(responseBody, requestBody) where the response is the superset and
the request is the subset), so update the example to make the argument roles
explicit: rename the parameters in the first example to something like
supersetJson, subsetJson or add a short inline note that the first parameter is
the JSON that should contain the second, ensuring the JsonContains(...) examples
consistently reflect that the first argument is the container/superset and the
second is the subset to check.

Add AI Agent Skills Support for TeaPie
Summary
Added AI Agent Skills support to enable AI agents to work more effectively with TeaPie projects. The skill provides comprehensive knowledge about the TeaPie framework, its syntax, CLI commands, and best practices.
Primary Changes: AI Agent Skills Creation
TeaPie Skill Structure
Created a complete TeaPie skill in
.cursor/skills/teapie/containing:SKILL.md — Main skill file with:
references/ — 9 reference documents:
scripts/ — 4 Python utility scripts:
find-tests-for-api.py— Find tests for API endpointsrenumber-tests.py— Renumber test casesinsert-gap.py— Create gaps in numberingparse-http-file.py— Parse HTTP filestemplates/ — 6 HTTP templates:
Documentation Updates
Updated documentation:
docs/docs/ai-agent-skills.md)docs/docs/toc.yml)Summary by CodeRabbit
Documentation
New Features
Getting Started