iflow-mcp_modelcontextinterface-mcix 1.1.1.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.copier-answers.yml +10 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.cursor/rules/general.mdc +72 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.cursor/rules/python.mdc +290 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.github/copilot-instructions.md +203 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.github/workflows/ci.yml +63 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.github/workflows/copilot-setup-steps.yml +40 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.github/workflows/publish.yml +44 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.gitignore +187 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/.vscode/mcp.json +26 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/LICENSE +21 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/Makefile +46 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/PKG-INFO +931 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/PLAN.md +852 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/PRD.md +371 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/README.md +902 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/development.md +478 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/devtools/lint.py +53 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/docs/architecture.md +445 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/installation.md +27 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/language.json +1 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci/.gitignore +1 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci/example_toolset.mci.json +37 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/adapter/basic-usage.mdx +799 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/adapter/execution-types.mdx +680 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/adapter/mcp_integration.mdx +384 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/adapter/quickstart.mdx +214 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/api-reference.mdx +1882 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/concepts/mcp_servers.mdx +615 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/concepts/structure.mdx +583 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/concepts/templates.mdx +707 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/concepts/tools.mdx +685 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/concepts/toolsets.mdx +635 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci-docs/python/schema-reference.mdx +1429 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mci.json +38 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/mcp-server-docs.md +378 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/package_name +1 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/publishing.md +71 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/pyproject.toml +184 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/__init__.py +10 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/assets/example_toolset.mci.json +37 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/assets/example_toolset.mci.yaml +23 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/assets/gitignore +1 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/assets/mci.json +29 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/assets/mci.yaml +19 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/__init__.py +8 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/add.py +108 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/envs.py +257 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/formatters/__init__.py +12 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/formatters/env_formatter.py +83 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/formatters/json_formatter.py +93 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/formatters/table_formatter.py +138 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/formatters/yaml_formatter.py +93 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/install.py +147 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/list.py +153 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/run.py +125 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/cli/validate.py +113 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/__init__.py +8 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/config.py +144 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/dynamic_server.py +187 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/file_finder.py +105 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/mci_client.py +196 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/mcp_server.py +240 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/schema_editor.py +284 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/tool_converter.py +119 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/tool_manager.py +118 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/core/validator.py +162 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/mci.py +39 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/py.typed +0 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/__init__.py +8 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/dotenv.py +170 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/env_scanner.py +84 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/error_formatter.py +165 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/error_handler.py +174 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/timestamp.py +50 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/src/mci/utils/validation.py +92 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_add_command.py +329 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_cli_help.py +49 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_config_loading.py +234 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_dotenv_loading.py +193 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_envs_command.py +339 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_install_command.py +213 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_list_command.py +231 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_mci_integration.py +337 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_mcp_server_creation.py +379 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_run_command.py +270 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/test_validate_command.py +233 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/formatters/test_json_formatter.py +259 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/formatters/test_table_formatter.py +247 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/formatters/test_yaml_formatter.py +229 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/test_add.py +262 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/test_envs.py +305 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/test_install.py +304 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/test_list.py +391 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/test_run.py +285 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/cli/test_validate.py +171 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_config.py +402 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_dynamic_server.py +356 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_env_vars_in_execution.py +159 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_file_finder.py +182 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_mci_client.py +267 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_mcp_server.py +264 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_schema_editor.py +348 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_tool_converter.py +310 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_tool_manager.py +263 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/core/test_validator.py +207 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/test_cli_init.py +32 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/test_imports.py +55 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/utils/test_dotenv.py +462 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/utils/test_env_scanner.py +154 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/utils/test_error_formatter.py +147 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/utils/test_error_handler.py +180 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/utils/test_timestamp.py +108 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/tests/unit/utils/test_validation.py +128 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_add.py +279 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_annotations_in_mcp.py +182 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_dotenv_autoload.py +293 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_envs_demo.py +251 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_install.py +232 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_list_output.py +297 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_mcp_server.py +176 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_mcp_server_annotations.py +247 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_run_stdio.py +259 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_tool_loading.py +334 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/testsManual/test_validate.py +251 -0
- iflow_mcp_modelcontextinterface_mcix-1.1.1.dev0/uv.lock +1271 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changes here will be overwritten by Copier. Do not edit manually.
|
|
2
|
+
_commit: v0.2.19
|
|
3
|
+
_src_path: gh:jlevy/simple-modern-uv
|
|
4
|
+
package_author_email: revaz@usemci.dev
|
|
5
|
+
package_author_name: maestroerror
|
|
6
|
+
package_description: 'CLI tool designed to manage MCI (Model Context Interface) schemas
|
|
7
|
+
and dynamically run MCP servers using defined MCI toolsets '
|
|
8
|
+
package_github_org: Model-Context-Interface
|
|
9
|
+
package_module: mci
|
|
10
|
+
package_name: mci
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: General Guidelines
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
# Assistant Rules
|
|
7
|
+
|
|
8
|
+
**Your fundamental responsibility:** Remember you are a senior engineer and have a
|
|
9
|
+
serious responsibility to be clear, factual, think step by step and be systematic,
|
|
10
|
+
express expert opinion, and make use of the user’s attention wisely.
|
|
11
|
+
|
|
12
|
+
**Rules must be followed:** It is your responsibility to carefully read these rules as
|
|
13
|
+
well as Python or other language-specific rules included here.
|
|
14
|
+
|
|
15
|
+
Therefore:
|
|
16
|
+
|
|
17
|
+
- Be concise. State answers or responses directly, without extra commentary.
|
|
18
|
+
Or (if it is clear) directly do what is asked.
|
|
19
|
+
|
|
20
|
+
- If instructions are unclear or there are two or more ways to fulfill the request that
|
|
21
|
+
are substantially different, make a tentative plan (or offer options) and ask for
|
|
22
|
+
confirmation.
|
|
23
|
+
|
|
24
|
+
- If you can think of a much better approach that the user requests, be sure to mention
|
|
25
|
+
it. It’s your responsibility to suggest approaches that lead to better, simpler
|
|
26
|
+
solutions.
|
|
27
|
+
|
|
28
|
+
- Give thoughtful opinions on better/worse approaches, but NEVER say “great idea!”
|
|
29
|
+
or “good job” or other compliments, encouragement, or non-essential banter.
|
|
30
|
+
Your job is to give expert opinions and to solve problems, not to motivate the user.
|
|
31
|
+
|
|
32
|
+
- Avoid gratuitous enthusiasm or generalizations.
|
|
33
|
+
Use thoughtful comparisons like saying which code is “cleaner” but don’t congratulate
|
|
34
|
+
yourself. Avoid subjective descriptions.
|
|
35
|
+
For example, don’t say “I’ve meticulously improved the code and it is in great shape!”
|
|
36
|
+
That is useless generalization.
|
|
37
|
+
Instead, specifically say what you’ve done, e.g., "I’ve added types, including
|
|
38
|
+
generics, to all the methods in `Foo` and fixed all linter errors."
|
|
39
|
+
|
|
40
|
+
# General Coding Guidelines
|
|
41
|
+
|
|
42
|
+
## Using Comments
|
|
43
|
+
|
|
44
|
+
- Keep all comments concise and clear and suitable for inclusion in final production.
|
|
45
|
+
|
|
46
|
+
- DO use comments whenever the intent of a given piece of code is subtle or confusing or
|
|
47
|
+
avoids a bug or is not obvious from the code itself.
|
|
48
|
+
|
|
49
|
+
- DO NOT repeat in comments what is obvious from the names of functions or variables or
|
|
50
|
+
types.
|
|
51
|
+
|
|
52
|
+
- DO NOT include comments that reflect what you did, such as “Added this function” as
|
|
53
|
+
this is meaningless to anyone reading the code later.
|
|
54
|
+
(Instead, describe in your message to the user any other contextual information.)
|
|
55
|
+
|
|
56
|
+
- DO NOT use fancy or needlessly decorated headings like “===== MIGRATION TOOLS =====”
|
|
57
|
+
in comments
|
|
58
|
+
|
|
59
|
+
- DO NOT number steps in comments.
|
|
60
|
+
These are hard to maintain if the code changes.
|
|
61
|
+
NEVER DO THIS: “// Step 3: Fetch the data from the cache”\
|
|
62
|
+
This is fine: “// Now fetch the data from the cache”
|
|
63
|
+
|
|
64
|
+
- DO NOT use emojis or special unicode characters like ① or • or – or — in comments.
|
|
65
|
+
|
|
66
|
+
- Use emojis in output if it enhances the clarity and can be done consistently.
|
|
67
|
+
You may use ✔︎ and ✘ to indicate success and failure, and ∆ and ‼︎ for user-facing
|
|
68
|
+
warnings and errors, for example, but be sure to do it consistently.
|
|
69
|
+
DO NOT use emojis gratuitously in comments or output.
|
|
70
|
+
You may use then ONLY when they have clear meanings (like success or failure).
|
|
71
|
+
Unless the user says otherwise, avoid emojis and Unicode in comments as clutters the
|
|
72
|
+
output with little benefit.
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Python Coding Guidelines
|
|
3
|
+
globs: *.py,pyproject.toml
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Python Coding Guidelines
|
|
7
|
+
|
|
8
|
+
These are rules for a modern Python project using uv.
|
|
9
|
+
|
|
10
|
+
## Python Version
|
|
11
|
+
|
|
12
|
+
Write for Python 3.11-3.13. Do NOT write code to support earlier versions of Python.
|
|
13
|
+
Always use modern Python practices appropriate for Python 3.11-3.13.
|
|
14
|
+
|
|
15
|
+
Always use full type annotations, generics, and other modern practices.
|
|
16
|
+
|
|
17
|
+
## Project Setup and Developer Workflows
|
|
18
|
+
|
|
19
|
+
- Important: BE SURE you read and understand the project setup by reading the
|
|
20
|
+
pyproject.toml file and the Makefile.
|
|
21
|
+
|
|
22
|
+
- ALWAYS use uv for running all code and managing dependencies.
|
|
23
|
+
Never use direct `pip` or `python` commands.
|
|
24
|
+
|
|
25
|
+
- Use modern uv commands: `uv sync`, `uv run ...`, etc.
|
|
26
|
+
Prefer `uv add` over `uv pip install`.
|
|
27
|
+
|
|
28
|
+
- You may use the following shortcuts
|
|
29
|
+
```shell
|
|
30
|
+
|
|
31
|
+
# Install all dependencies:
|
|
32
|
+
make install
|
|
33
|
+
|
|
34
|
+
# Run linting (with ruff) and type checking (with basedpyright).
|
|
35
|
+
# Note when you run this, ruff will auto-format and sort imports, resolving any
|
|
36
|
+
# linter warnings about import ordering:
|
|
37
|
+
make lint
|
|
38
|
+
|
|
39
|
+
# Run tests:
|
|
40
|
+
make test
|
|
41
|
+
|
|
42
|
+
# Run uv sync, lint, and test in one command:
|
|
43
|
+
make
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- The usual `make test` like standard pytest does not show test output.
|
|
47
|
+
Run individual tests and see output with `uv run pytest -s some/file.py`.
|
|
48
|
+
|
|
49
|
+
- Always run `make lint` and `make test` to check your code after changes.
|
|
50
|
+
|
|
51
|
+
- You must verify there are zero linter warnings/errors or test failures before
|
|
52
|
+
considering any task complete.
|
|
53
|
+
|
|
54
|
+
## General Development Practices
|
|
55
|
+
|
|
56
|
+
- Be sure to resolve the pyright (basedpyright) linter errors as you develop and make
|
|
57
|
+
changes.
|
|
58
|
+
|
|
59
|
+
- If type checker errors are hard to resolve, you may add a comment `# pyright: ignore`
|
|
60
|
+
to disable Pyright warnings or errors but ONLY if you know they are not a real problem
|
|
61
|
+
and are difficult to fix.
|
|
62
|
+
|
|
63
|
+
- In special cases you may consider disabling it globally it in pyproject.toml but YOU
|
|
64
|
+
MUST ASK FOR CONFIRMATION from the user before globally disabling lint or type checker
|
|
65
|
+
rules.
|
|
66
|
+
|
|
67
|
+
- Never change an existing comment, pydoc, or a log statement, unless it is directly
|
|
68
|
+
fixing the issue you are changing, or the user has asked you to clean up the code.
|
|
69
|
+
Do not drop existing comments when editing code!
|
|
70
|
+
And do not delete or change logging statements.
|
|
71
|
+
|
|
72
|
+
## Coding Conventions and Imports
|
|
73
|
+
|
|
74
|
+
- Always use full, absolute imports for paths.
|
|
75
|
+
do NOT use `from .module1.module2 import ...`. Such relative paths make it hard to
|
|
76
|
+
refactor. Use `from toplevel_pkg.module1.modlule2 import ...` instead.
|
|
77
|
+
|
|
78
|
+
- Be sure to import things like `Callable` and other types from the right modules,
|
|
79
|
+
remembering that many are now in `collections.abc` or `typing_extensions`. For
|
|
80
|
+
example: `from collections.abc import Callable, Coroutine`
|
|
81
|
+
|
|
82
|
+
- Use `typing_extensions` for things like `@override` (you need to use this, and not
|
|
83
|
+
`typing` since we want to support Python 3.11).
|
|
84
|
+
|
|
85
|
+
- Add `from __future__ import annotations` on files with types whenever applicable.
|
|
86
|
+
|
|
87
|
+
- Use pathlib `Path` instead of strings.
|
|
88
|
+
Use `Path(filename).read_text()` instead of two-line `with open(...)` blocks.
|
|
89
|
+
|
|
90
|
+
- Use strif’s `atomic_output_file` context manager when writing files to ensure output
|
|
91
|
+
files are written atomically.
|
|
92
|
+
|
|
93
|
+
## Use Modern Python Practices
|
|
94
|
+
|
|
95
|
+
- ALWAYS use `@override` decorators to override methods from base classes.
|
|
96
|
+
This is a modern Python practice and helps avoid bugs.
|
|
97
|
+
|
|
98
|
+
## Testing
|
|
99
|
+
|
|
100
|
+
- For longer tests put them in a file like `tests/test_somename.py` in the `tests/`
|
|
101
|
+
directory (or `tests/module_name/test_somename.py` file for a submodule).
|
|
102
|
+
|
|
103
|
+
- For simple tests, prefer inline functions in the original code file below a `## Tests`
|
|
104
|
+
comment. This keeps the tests easy to maintain and close to the code.
|
|
105
|
+
Inline tests should NOT import pytest or pytest fixtures as we do not want runtime
|
|
106
|
+
dependency on pytest.
|
|
107
|
+
|
|
108
|
+
- DO NOT write one-off test code in extra files that are throwaway.
|
|
109
|
+
|
|
110
|
+
- DO NOT put `if __name__ == "__main__":` just for quick testing.
|
|
111
|
+
Instead use the inline function tests and run them with `uv run pytest`.
|
|
112
|
+
|
|
113
|
+
- You can run such individual tests with `uv run pytest -s src/.../path/to/test`
|
|
114
|
+
|
|
115
|
+
- Don’t add docs to assertions unless it’s not obvious what they’re checking - the
|
|
116
|
+
assertion appears in the stack trace.
|
|
117
|
+
Do NOT write `assert x == 5, "x should be 5"`. Do NOT write `assert x == 5 # Check if
|
|
118
|
+
x is 5`. That is redundant.
|
|
119
|
+
Just write `assert x == 5`.
|
|
120
|
+
|
|
121
|
+
- DO NOT write trivial or obvious tests that are evident directly from code, such as
|
|
122
|
+
assertions that confirm the value of a constant setting.
|
|
123
|
+
|
|
124
|
+
- NEVER write `assert False`. If a test reaches an unexpected branch and must fail
|
|
125
|
+
explicitly, `raise AssertionError("Some explanation")` instead.
|
|
126
|
+
This is best typical best practice in Python since assertions can be removed with
|
|
127
|
+
optimization.
|
|
128
|
+
|
|
129
|
+
- DO NOT use pytest fixtures like parameterized tests or expected exception decorators
|
|
130
|
+
unless absolutely necessary in more complex tests.
|
|
131
|
+
It is typically simpler to use simple assertions and put the checks inside the test.
|
|
132
|
+
This is also preferable because then simple tests have no explicit pytest dependencies
|
|
133
|
+
and can be placed in code anywhere.
|
|
134
|
+
|
|
135
|
+
- DO NOT write trivial tests that test something we know already works, like
|
|
136
|
+
instantiating a Pydantic object.
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
class Link(BaseModel):
|
|
140
|
+
url: str
|
|
141
|
+
title: str = None
|
|
142
|
+
|
|
143
|
+
# DO NOT write tests like this. They are trivial and only create clutter!
|
|
144
|
+
def test_link_model():
|
|
145
|
+
link = Link(url="https://example.com", title="Example")
|
|
146
|
+
assert link.url == "https://example.com"
|
|
147
|
+
assert link.title == "Example"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Types and Type Annotations
|
|
151
|
+
|
|
152
|
+
- Use modern union syntax: `str | None` instead of `Optional[str]`, `dict[str]` instead
|
|
153
|
+
of `Dict[str]`, `list[str]` instead of `List[str]`, etc.
|
|
154
|
+
|
|
155
|
+
- Never use/import `Optional` for new code.
|
|
156
|
+
|
|
157
|
+
- Use modern enums like `StrEnum` if appropriate.
|
|
158
|
+
|
|
159
|
+
- One exception to common practice on enums: If an enum has many values that are
|
|
160
|
+
strings, and they have a literal value as a string (like in a JSON protocol), it’s
|
|
161
|
+
fine to use lower_snake_case for enum values to match the actual value.
|
|
162
|
+
This is more readable than LONG_ALL_CAPS_VALUES, and you can simply set the value to
|
|
163
|
+
be the same as the name for each.
|
|
164
|
+
For example:
|
|
165
|
+
```python
|
|
166
|
+
class MediaType(Enum):
|
|
167
|
+
"""
|
|
168
|
+
Media types. For broad categories only, to determine what processing
|
|
169
|
+
is possible.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
text = "text"
|
|
173
|
+
image = "image"
|
|
174
|
+
audio = "audio"
|
|
175
|
+
video = "video"
|
|
176
|
+
webpage = "webpage"
|
|
177
|
+
binary = "binary"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Guidelines for Literal Strings
|
|
181
|
+
|
|
182
|
+
- For multi-line strings NEVER put multi-line strings flush against the left margin.
|
|
183
|
+
ALWAYS use a `dedent()` function to make it more readable.
|
|
184
|
+
You may wish to add a `strip()` as well.
|
|
185
|
+
Example:
|
|
186
|
+
```python
|
|
187
|
+
from textwrap import dedent
|
|
188
|
+
markdown_content = dedent("""
|
|
189
|
+
# Title 1
|
|
190
|
+
Some text.
|
|
191
|
+
## Subtitle 1.1
|
|
192
|
+
More text.
|
|
193
|
+
""").strip()
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Guidelines for Comments
|
|
197
|
+
|
|
198
|
+
- Comments should be EXPLANATORY: Explain *WHY* something is done a certain way and not
|
|
199
|
+
just *what* is done.
|
|
200
|
+
|
|
201
|
+
- Comments should be CONCISE: Remove all extraneous words.
|
|
202
|
+
|
|
203
|
+
- DO NOT use comments to state obvious things or repeat what is evident from the code.
|
|
204
|
+
Here is an example of a comment that SHOULD BE REMOVED because it simply repeats the
|
|
205
|
+
code, which is distracting and adds no value:
|
|
206
|
+
```python
|
|
207
|
+
if self.failed == 0:
|
|
208
|
+
# All successful
|
|
209
|
+
return "All tasks finished successfully"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Guidelines for Docstrings
|
|
213
|
+
|
|
214
|
+
- Here is an example of the correct style for docstrings:
|
|
215
|
+
```python
|
|
216
|
+
def check_if_url(
|
|
217
|
+
text: UnresolvedLocator, only_schemes: list[str] | None = None
|
|
218
|
+
) -> ParseResult | None:
|
|
219
|
+
"""
|
|
220
|
+
Convenience function to check if a string or Path is a URL and if so return
|
|
221
|
+
the `urlparse.ParseResult`.
|
|
222
|
+
|
|
223
|
+
Also returns false for Paths, so that it's easy to use local paths and URLs
|
|
224
|
+
(`Locator`s) interchangeably. Can provide `HTTP_ONLY` or `HTTP_OR_FILE` to
|
|
225
|
+
restrict to only certain schemes.
|
|
226
|
+
"""
|
|
227
|
+
# Function body
|
|
228
|
+
|
|
229
|
+
def is_url(text: UnresolvedLocator, only_schemes: list[str] | None = None) -> bool:
|
|
230
|
+
"""
|
|
231
|
+
Check if a string is a URL. For convenience, also returns false for
|
|
232
|
+
Paths, so that it's easy to use local paths and URLs interchangeably.
|
|
233
|
+
"""
|
|
234
|
+
return check_if_url(text, only_schemes) is not None
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
- Use concise pydoc strings with triple quotes on their own lines.
|
|
238
|
+
|
|
239
|
+
- Use `backticks` around variable names and inline code excerpts.
|
|
240
|
+
|
|
241
|
+
- Use plain fences (```) around code blocks inside of pydocs.
|
|
242
|
+
|
|
243
|
+
- For classes with many methods, use a concise docstring on the class that explains all
|
|
244
|
+
the common information, and avoid repeating the same information on every method.
|
|
245
|
+
|
|
246
|
+
- Docstrings should provide context or as concisely as possible explain “why”, not
|
|
247
|
+
obvious details evident from the class names, function names, parameter names, and
|
|
248
|
+
type annotations.
|
|
249
|
+
|
|
250
|
+
- Docstrings *should* mention any key rationale or pitfalls when using the class or
|
|
251
|
+
function.
|
|
252
|
+
|
|
253
|
+
- Avoid obvious or repetitive docstrings.
|
|
254
|
+
Do NOT add pydocs that just repeat in English facts that are obvious from the function
|
|
255
|
+
name, variable name, or types.
|
|
256
|
+
That is silly and obvious and makes the code longer for no reason.
|
|
257
|
+
|
|
258
|
+
- Do NOT list args and return values if they’re obvious.
|
|
259
|
+
In the above examples, you do not need and `Arguments:` or `Returns:` section, since
|
|
260
|
+
sections as it is obvious from context.
|
|
261
|
+
do list these if there are many arguments and their meaning isn’t clear.
|
|
262
|
+
If it returns a less obvious type like a tuple, do explain in the pydoc.
|
|
263
|
+
|
|
264
|
+
- Exported/public variables, functions, or methods SHOULD have concise docstrings.
|
|
265
|
+
Internal/local variables, functions, and methods DO NOT need docstrings unless their
|
|
266
|
+
purpose is not obvious.
|
|
267
|
+
|
|
268
|
+
## General Clean Coding Practices
|
|
269
|
+
|
|
270
|
+
- Avoid writing trivial wrapper functions.
|
|
271
|
+
For example, when writing a class DO NOT blindly make delegation methods around public
|
|
272
|
+
member variables. DO NOT write methods like this:
|
|
273
|
+
```python
|
|
274
|
+
def reassemble(self) -> str:
|
|
275
|
+
"""Call the original reassemble method."""
|
|
276
|
+
return self.paragraph.reassemble()
|
|
277
|
+
```
|
|
278
|
+
In general, the user can just call the enclosed objects methods, reducing code bloat.
|
|
279
|
+
|
|
280
|
+
- If a function does not use a parameter, but it should still be present, you can use `#
|
|
281
|
+
pyright: ignore[reportUnusedParameter]` in a comment to suppress the linter warning.
|
|
282
|
+
|
|
283
|
+
## Guidelines for Backward Compatibility
|
|
284
|
+
|
|
285
|
+
- When changing code in a library or general function, if a change to an API or library
|
|
286
|
+
will break backward compatibility, MENTION THIS to the user.
|
|
287
|
+
|
|
288
|
+
- DO NOT implement additional code for backward compatiblity (such as extra methods or
|
|
289
|
+
variable aliases or comments about backward compatibility) UNLESS the user has
|
|
290
|
+
confirmed that it is necessary.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Copilot Instructions for mci-py
|
|
2
|
+
|
|
3
|
+
## Project Context
|
|
4
|
+
|
|
5
|
+
- **Check `PRD.md`** for overall project context, goals, and requirements
|
|
6
|
+
- **Check `PLAN.md`** for full implementation plan and design decisions
|
|
7
|
+
- **Check `development.md`** for testing and linting commands
|
|
8
|
+
- **Check `installation.md`** for setup and installation instructions
|
|
9
|
+
|
|
10
|
+
## Code Documentation Standards
|
|
11
|
+
|
|
12
|
+
### File-Level Comments
|
|
13
|
+
|
|
14
|
+
Write explanation comments at the start of each file that describe:
|
|
15
|
+
|
|
16
|
+
- The purpose of the file
|
|
17
|
+
- What functionality it provides
|
|
18
|
+
- How it fits into the overall project
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
"""
|
|
24
|
+
mcipy.py - Main entry point for the MCI Python adapter
|
|
25
|
+
|
|
26
|
+
This module provides the core functionality for loading and executing
|
|
27
|
+
MCI tool definitions from JSON schema files.
|
|
28
|
+
"""
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Function/Class Documentation
|
|
32
|
+
|
|
33
|
+
Write explanation comments for each function, class, and method that explain:
|
|
34
|
+
|
|
35
|
+
- What the function/class does
|
|
36
|
+
- Why it exists (not just what it does)
|
|
37
|
+
- Any important implementation details or gotchas
|
|
38
|
+
- Parameters and return values (if not obvious from type hints)
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
def execute_tool(tool_def: dict, properties: dict) -> dict:
|
|
44
|
+
"""
|
|
45
|
+
Execute an MCI tool definition with the provided properties.
|
|
46
|
+
|
|
47
|
+
Handles templating of environment variables and property values,
|
|
48
|
+
then dispatches to the appropriate executor (HTTP, CLI, or file).
|
|
49
|
+
Returns a structured result with error handling.
|
|
50
|
+
"""
|
|
51
|
+
# Implementation
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Testing Strategy
|
|
55
|
+
|
|
56
|
+
### Coverage Goal
|
|
57
|
+
|
|
58
|
+
**Target: 90%+ test coverage** across all modules
|
|
59
|
+
|
|
60
|
+
### Test Types
|
|
61
|
+
|
|
62
|
+
#### 1. Unit Tests
|
|
63
|
+
|
|
64
|
+
Test every function involved in processing:
|
|
65
|
+
|
|
66
|
+
- **JSON Schema Validation**: Test schema loading, validation, and error handling
|
|
67
|
+
- **Templating Engine**: Test placeholder replacement for `{{env.VAR}}`, `{{props.name}}`, `{{input.field}}`
|
|
68
|
+
- **Execution Dispatchers**: Test each executor (HTTP, CLI, file) in isolation
|
|
69
|
+
- **Authentication Handlers**: Test API key, OAuth2, basic auth parsing and application
|
|
70
|
+
- **Error Handling**: Test error detection, formatting, and propagation
|
|
71
|
+
- **Utility Functions**: Test all helper functions for parsing, formatting, and validation
|
|
72
|
+
- **Others**
|
|
73
|
+
|
|
74
|
+
Example unit test structure:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
def test_template_replacement():
|
|
78
|
+
"""Test that environment variables are correctly replaced in templates."""
|
|
79
|
+
template = "Hello {{env.USER}}"
|
|
80
|
+
env = {"USER": "TestUser"}
|
|
81
|
+
result = replace_template(template, env=env)
|
|
82
|
+
assert result == "Hello TestUser"
|
|
83
|
+
|
|
84
|
+
def test_template_missing_variable():
|
|
85
|
+
"""Test error handling when template variable is missing."""
|
|
86
|
+
template = "Hello {{env.MISSING}}"
|
|
87
|
+
with pytest.raises(TemplateError):
|
|
88
|
+
replace_template(template, env={})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### 2. Feature Tests
|
|
92
|
+
|
|
93
|
+
Test full features end-to-end:
|
|
94
|
+
|
|
95
|
+
- **Tool Loading**: Load JSON context file and parse all tools
|
|
96
|
+
- **HTTP Execution**: Make real HTTP requests to test endpoints (use mocking where appropriate)
|
|
97
|
+
- **CLI Execution**: Execute command-line tools and capture output
|
|
98
|
+
- **File Reading**: Read and parse files with template replacement
|
|
99
|
+
- **Error Scenarios**: Test network failures, timeouts, invalid inputs
|
|
100
|
+
|
|
101
|
+
Example feature test:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
def test_execute_http_tool_with_api_key():
|
|
105
|
+
"""Test executing an HTTP tool with API key authentication."""
|
|
106
|
+
tool_def = {
|
|
107
|
+
"name": "get_weather",
|
|
108
|
+
"execution": {
|
|
109
|
+
"type": "http",
|
|
110
|
+
"method": "GET",
|
|
111
|
+
"url": "https://api.example.com/weather",
|
|
112
|
+
"auth": {
|
|
113
|
+
"type": "apiKey",
|
|
114
|
+
"in": "header",
|
|
115
|
+
"name": "X-API-Key",
|
|
116
|
+
"value": "{{env.API_KEY}}"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
env = {"API_KEY": "test-key-123"}
|
|
121
|
+
result = execute_tool(tool_def, env=env, props={})
|
|
122
|
+
assert result["success"] is True
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### 3. Manual Tests
|
|
126
|
+
|
|
127
|
+
Create manual test files for large features that should be run individually via terminal with clear output.
|
|
128
|
+
|
|
129
|
+
**Location**: `testsManual/`
|
|
130
|
+
|
|
131
|
+
**Requirements**:
|
|
132
|
+
|
|
133
|
+
- Each test file should be standalone and executable
|
|
134
|
+
- Provide clear, human-readable output showing what is being tested
|
|
135
|
+
- Include setup instructions in comments at the top of each file
|
|
136
|
+
- Use only the implemented modules directly, not mocks or any other deps
|
|
137
|
+
- Show both success and failure cases
|
|
138
|
+
- Avoid using private properties or methods in feature tests
|
|
139
|
+
|
|
140
|
+
### Test Organization
|
|
141
|
+
|
|
142
|
+
Organize tests in the `tests/` directory: Unit tests in `tests/unit/` mimicking `src/` directory structure; place feature tests directly under `tests/` directory.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
tests/
|
|
148
|
+
├── test_schema.py # Feature tests for JSON schema validation
|
|
149
|
+
├── test_templating.py # Feature tests for template engine
|
|
150
|
+
└── unit/
|
|
151
|
+
├── test_mcipy.py
|
|
152
|
+
├── test_init.py
|
|
153
|
+
└── tools/
|
|
154
|
+
├── test_http_executor.py
|
|
155
|
+
└── test_file_executor.py
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Development Workflow
|
|
159
|
+
|
|
160
|
+
### Testing Commands
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Run all automated tests
|
|
164
|
+
make test
|
|
165
|
+
|
|
166
|
+
# Run specific test file with output
|
|
167
|
+
uv run pytest -s tests/test_schema.py
|
|
168
|
+
|
|
169
|
+
# Run tests with coverage report
|
|
170
|
+
make coverage
|
|
171
|
+
|
|
172
|
+
# Run a manual test
|
|
173
|
+
uv run python testsManual/test_parsing_tools.py
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Linting Commands
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Run all linters and formatters
|
|
180
|
+
make lint
|
|
181
|
+
|
|
182
|
+
# Run individual linters
|
|
183
|
+
uv run ruff check --fix src/
|
|
184
|
+
uv run ruff format src/
|
|
185
|
+
uv run basedpyright --stats src/
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Installation
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Install all dependencies
|
|
192
|
+
make install
|
|
193
|
+
|
|
194
|
+
# Run sync, lint, and test in one command
|
|
195
|
+
make
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Code Style Guidelines
|
|
199
|
+
|
|
200
|
+
- Use modern Python 3.11+ features and type annotations
|
|
201
|
+
- Keep comments concise and explanatory (focus on WHY, not WHAT)
|
|
202
|
+
- Avoid obvious or redundant comments
|
|
203
|
+
- Use `uv` for all Python operations, not `pip` or `python` directly
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
|
3
|
+
|
|
4
|
+
name: CI
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
# Use ["main", "master"] for CI only on the default branch.
|
|
9
|
+
# Use ["**"] for CI on all branches.
|
|
10
|
+
branches: ["main", "master"]
|
|
11
|
+
pull_request:
|
|
12
|
+
branches: ["main", "master"]
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
strategy:
|
|
20
|
+
matrix:
|
|
21
|
+
# Update this as needed:
|
|
22
|
+
# Common platforms: ["ubuntu-latest", "macos-latest", "windows-latest"]
|
|
23
|
+
os: ["ubuntu-latest"]
|
|
24
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
25
|
+
|
|
26
|
+
# Linux only by default. Use ${{ matrix.os }} for other OSes.
|
|
27
|
+
runs-on: ${{ matrix.os }}
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
# Generally following uv docs:
|
|
31
|
+
# https://docs.astral.sh/uv/guides/integration/github/
|
|
32
|
+
|
|
33
|
+
- name: Checkout (official GitHub action)
|
|
34
|
+
uses: actions/checkout@v4
|
|
35
|
+
with:
|
|
36
|
+
# Important for versioning plugins:
|
|
37
|
+
fetch-depth: 0
|
|
38
|
+
|
|
39
|
+
- name: Install uv (official Astral action)
|
|
40
|
+
uses: astral-sh/setup-uv@v5
|
|
41
|
+
with:
|
|
42
|
+
# Update this as needed:
|
|
43
|
+
version: "0.9.5"
|
|
44
|
+
enable-cache: true
|
|
45
|
+
python-version: ${{ matrix.python-version }}
|
|
46
|
+
|
|
47
|
+
- name: Set up Python (using uv)
|
|
48
|
+
run: uv python install
|
|
49
|
+
|
|
50
|
+
# Alternately can use the official Python action:
|
|
51
|
+
# - name: Set up Python (using actions/setup-python)
|
|
52
|
+
# uses: actions/setup-python@v5
|
|
53
|
+
# with:
|
|
54
|
+
# python-version: ${{ matrix.python-version }}
|
|
55
|
+
|
|
56
|
+
- name: Install all dependencies
|
|
57
|
+
run: uv sync --all-extras
|
|
58
|
+
|
|
59
|
+
- name: Run linting
|
|
60
|
+
run: uv run python devtools/lint.py
|
|
61
|
+
|
|
62
|
+
- name: Run tests
|
|
63
|
+
run: uv run pytest
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: "Copilot Setup Steps"
|
|
2
|
+
|
|
3
|
+
# Automatically run the setup steps when they are changed to allow for easy validation, and
|
|
4
|
+
# allow manual testing through the repository's "Actions" tab
|
|
5
|
+
on:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
push:
|
|
8
|
+
paths:
|
|
9
|
+
- .github/workflows/copilot-setup-steps.yml
|
|
10
|
+
pull_request:
|
|
11
|
+
paths:
|
|
12
|
+
- .github/workflows/copilot-setup-steps.yml
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
|
|
16
|
+
copilot-setup-steps:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
|
|
19
|
+
# Set the permissions to the lowest permissions possible needed for your steps.
|
|
20
|
+
# Copilot will be given its own token for its operations.
|
|
21
|
+
permissions:
|
|
22
|
+
# Clone the repository to install dependencies
|
|
23
|
+
contents: read
|
|
24
|
+
|
|
25
|
+
# Setup steps mirror the setup_env.sh script and setup.txt instructions
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout code
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Install uv
|
|
31
|
+
uses: astral-sh/setup-uv@v5
|
|
32
|
+
with:
|
|
33
|
+
version: "0.8.13"
|
|
34
|
+
enable-cache: true
|
|
35
|
+
|
|
36
|
+
- name: Install Python 3.13 using uv
|
|
37
|
+
run: uv python install 3.13
|
|
38
|
+
|
|
39
|
+
- name: Install project dependencies
|
|
40
|
+
run: make install
|