Install shared infrastructure files into *project_path*. Copies ``.specify/scripts/ /`` and ``.specify/templates/`` from the bundled core_pack or source checkout, where `` `` is ``bash`` when *script_type* is ``"sh"`` and ``powershell`` when it is ``"ps"``. Tracks a
(
project_path: Path,
script_type: str,
tracker: StepTracker | None = None,
force: bool = False,
invoke_separator: str = ".",
refresh_managed: bool = False,
refresh_hint: str | None = None,
)
| 129 | |
| 130 | |
| 131 | def _install_shared_infra( |
| 132 | project_path: Path, |
| 133 | script_type: str, |
| 134 | tracker: StepTracker | None = None, |
| 135 | force: bool = False, |
| 136 | invoke_separator: str = ".", |
| 137 | refresh_managed: bool = False, |
| 138 | refresh_hint: str | None = None, |
| 139 | ) -> bool: |
| 140 | """Install shared infrastructure files into *project_path*. |
| 141 | |
| 142 | Copies ``.specify/scripts/<variant>/`` and ``.specify/templates/`` from |
| 143 | the bundled core_pack or source checkout, where ``<variant>`` is |
| 144 | ``bash`` when *script_type* is ``"sh"`` and ``powershell`` when it is |
| 145 | ``"ps"``. Tracks all installed files in ``speckit.manifest.json``. |
| 146 | |
| 147 | Shared scripts and page templates are processed to resolve |
| 148 | ``__SPECKIT_COMMAND_<NAME>__`` placeholders using *invoke_separator* |
| 149 | (``"."`` for markdown agents, ``"-"`` for skills agents). |
| 150 | |
| 151 | Overwrite policy: |
| 152 | |
| 153 | * ``force=True`` — overwrite every existing file (still skips symlinks |
| 154 | to avoid following links outside the project root). |
| 155 | * ``refresh_managed=True`` — overwrite only files whose on-disk hash |
| 156 | still matches the previously recorded manifest hash (i.e. unmodified |
| 157 | files installed by spec-kit). Files with diverging hashes are |
| 158 | treated as user customizations and preserved with a warning. |
| 159 | * Default — only add missing files; existing ones are skipped. |
| 160 | |
| 161 | *refresh_hint* — caller-supplied rich-text fragment shown after the |
| 162 | "Preserved customized files" warning to tell the user which flag/command |
| 163 | they should re-run with to overwrite their customizations. Each caller |
| 164 | passes the flag that's actually valid in its CLI surface (e.g. |
| 165 | ``--refresh-shared-infra`` for ``integration switch``, |
| 166 | ``--force`` for ``init``/``integration upgrade``). When ``None``, no |
| 167 | remediation hint is printed for customizations. |
| 168 | |
| 169 | Returns ``True`` on success. |
| 170 | """ |
| 171 | return _install_shared_infra_impl( |
| 172 | project_path, |
| 173 | script_type, |
| 174 | version=get_speckit_version(), |
| 175 | core_pack=_locate_core_pack(), |
| 176 | repo_root=_repo_root(), |
| 177 | console=console, |
| 178 | force=force, |
| 179 | invoke_separator=invoke_separator, |
| 180 | refresh_managed=refresh_managed, |
| 181 | refresh_hint=refresh_hint, |
| 182 | ) |
| 183 | |
| 184 | |
| 185 | def _install_shared_infra_or_exit( |